fix(ci)+feat(M3-010/011): skip DB-gated tests in CI + provider_credentials migration (#317)
Some checks failed
ci/woodpecker/push/ci Pipeline failed
Some checks failed
ci/woodpecker/push/ci Pipeline failed
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #317.
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
* pgvector enabled and the Mosaic schema already applied.
|
||||
*/
|
||||
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
||||
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
||||
import { createDb } from '@mosaic/db';
|
||||
import { createConversationsRepo } from '@mosaic/brain';
|
||||
import { createAgentsRepo } from '@mosaic/brain';
|
||||
@@ -45,133 +45,148 @@ const INSIGHT_B_ID = 'bbbbbbbb-0000-0000-0000-000000000005';
|
||||
// ─── Test fixture ─────────────────────────────────────────────────────────────
|
||||
|
||||
let handle: DbHandle;
|
||||
let dbAvailable = false;
|
||||
|
||||
beforeAll(async () => {
|
||||
handle = createDb();
|
||||
const db = handle.db;
|
||||
try {
|
||||
handle = createDb();
|
||||
const db = handle.db;
|
||||
|
||||
// Insert two users
|
||||
await db
|
||||
.insert(users)
|
||||
.values([
|
||||
{
|
||||
id: USER_A_ID,
|
||||
name: 'Isolation Test User A',
|
||||
email: 'test-iso-user-a@example.invalid',
|
||||
emailVerified: false,
|
||||
},
|
||||
{
|
||||
id: USER_B_ID,
|
||||
name: 'Isolation Test User B',
|
||||
email: 'test-iso-user-b@example.invalid',
|
||||
emailVerified: false,
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
// Insert two users
|
||||
await db
|
||||
.insert(users)
|
||||
.values([
|
||||
{
|
||||
id: USER_A_ID,
|
||||
name: 'Isolation Test User A',
|
||||
email: 'test-iso-user-a@example.invalid',
|
||||
emailVerified: false,
|
||||
},
|
||||
{
|
||||
id: USER_B_ID,
|
||||
name: 'Isolation Test User B',
|
||||
email: 'test-iso-user-b@example.invalid',
|
||||
emailVerified: false,
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
|
||||
// Conversations — one per user
|
||||
await db
|
||||
.insert(conversations)
|
||||
.values([
|
||||
{ id: CONV_A_ID, userId: USER_A_ID, title: 'User A conversation' },
|
||||
{ id: CONV_B_ID, userId: USER_B_ID, title: 'User B conversation' },
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
// Conversations — one per user
|
||||
await db
|
||||
.insert(conversations)
|
||||
.values([
|
||||
{ id: CONV_A_ID, userId: USER_A_ID, title: 'User A conversation' },
|
||||
{ id: CONV_B_ID, userId: USER_B_ID, title: 'User B conversation' },
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
|
||||
// Messages — one per conversation
|
||||
await db
|
||||
.insert(messages)
|
||||
.values([
|
||||
{
|
||||
id: MSG_A_ID,
|
||||
conversationId: CONV_A_ID,
|
||||
role: 'user',
|
||||
content: 'Hello from User A',
|
||||
},
|
||||
{
|
||||
id: MSG_B_ID,
|
||||
conversationId: CONV_B_ID,
|
||||
role: 'user',
|
||||
content: 'Hello from User B',
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
// Messages — one per conversation
|
||||
await db
|
||||
.insert(messages)
|
||||
.values([
|
||||
{
|
||||
id: MSG_A_ID,
|
||||
conversationId: CONV_A_ID,
|
||||
role: 'user',
|
||||
content: 'Hello from User A',
|
||||
},
|
||||
{
|
||||
id: MSG_B_ID,
|
||||
conversationId: CONV_B_ID,
|
||||
role: 'user',
|
||||
content: 'Hello from User B',
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
|
||||
// Agent configs — private agents (one per user) + one system agent
|
||||
await db
|
||||
.insert(agents)
|
||||
.values([
|
||||
{
|
||||
id: AGENT_A_ID,
|
||||
name: 'Agent A (private)',
|
||||
provider: 'test',
|
||||
model: 'test-model',
|
||||
ownerId: USER_A_ID,
|
||||
isSystem: false,
|
||||
},
|
||||
{
|
||||
id: AGENT_B_ID,
|
||||
name: 'Agent B (private)',
|
||||
provider: 'test',
|
||||
model: 'test-model',
|
||||
ownerId: USER_B_ID,
|
||||
isSystem: false,
|
||||
},
|
||||
{
|
||||
id: AGENT_SYS_ID,
|
||||
name: 'Shared System Agent',
|
||||
provider: 'test',
|
||||
model: 'test-model',
|
||||
ownerId: null,
|
||||
isSystem: true,
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
// Agent configs — private agents (one per user) + one system agent
|
||||
await db
|
||||
.insert(agents)
|
||||
.values([
|
||||
{
|
||||
id: AGENT_A_ID,
|
||||
name: 'Agent A (private)',
|
||||
provider: 'test',
|
||||
model: 'test-model',
|
||||
ownerId: USER_A_ID,
|
||||
isSystem: false,
|
||||
},
|
||||
{
|
||||
id: AGENT_B_ID,
|
||||
name: 'Agent B (private)',
|
||||
provider: 'test',
|
||||
model: 'test-model',
|
||||
ownerId: USER_B_ID,
|
||||
isSystem: false,
|
||||
},
|
||||
{
|
||||
id: AGENT_SYS_ID,
|
||||
name: 'Shared System Agent',
|
||||
provider: 'test',
|
||||
model: 'test-model',
|
||||
ownerId: null,
|
||||
isSystem: true,
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
|
||||
// Preferences — one per user (same key, different values)
|
||||
await db
|
||||
.insert(preferences)
|
||||
.values([
|
||||
{
|
||||
id: PREF_A_ID,
|
||||
userId: USER_A_ID,
|
||||
key: 'theme',
|
||||
value: 'dark',
|
||||
category: 'appearance',
|
||||
},
|
||||
{
|
||||
id: PREF_B_ID,
|
||||
userId: USER_B_ID,
|
||||
key: 'theme',
|
||||
value: 'light',
|
||||
category: 'appearance',
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
// Preferences — one per user (same key, different values)
|
||||
await db
|
||||
.insert(preferences)
|
||||
.values([
|
||||
{
|
||||
id: PREF_A_ID,
|
||||
userId: USER_A_ID,
|
||||
key: 'theme',
|
||||
value: 'dark',
|
||||
category: 'appearance',
|
||||
},
|
||||
{
|
||||
id: PREF_B_ID,
|
||||
userId: USER_B_ID,
|
||||
key: 'theme',
|
||||
value: 'light',
|
||||
category: 'appearance',
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
|
||||
// Insights — no embedding to keep the fixture simple; embedding-based search
|
||||
// is tested separately with a zero-vector that falls outside maxDistance
|
||||
await db
|
||||
.insert(insights)
|
||||
.values([
|
||||
{
|
||||
id: INSIGHT_A_ID,
|
||||
userId: USER_A_ID,
|
||||
content: 'User A insight',
|
||||
source: 'user',
|
||||
category: 'general',
|
||||
relevanceScore: 1.0,
|
||||
},
|
||||
{
|
||||
id: INSIGHT_B_ID,
|
||||
userId: USER_B_ID,
|
||||
content: 'User B insight',
|
||||
source: 'user',
|
||||
category: 'general',
|
||||
relevanceScore: 1.0,
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
// Insights — no embedding to keep the fixture simple; embedding-based search
|
||||
// is tested separately with a zero-vector that falls outside maxDistance
|
||||
await db
|
||||
.insert(insights)
|
||||
.values([
|
||||
{
|
||||
id: INSIGHT_A_ID,
|
||||
userId: USER_A_ID,
|
||||
content: 'User A insight',
|
||||
source: 'user',
|
||||
category: 'general',
|
||||
relevanceScore: 1.0,
|
||||
},
|
||||
{
|
||||
id: INSIGHT_B_ID,
|
||||
userId: USER_B_ID,
|
||||
content: 'User B insight',
|
||||
source: 'user',
|
||||
category: 'general',
|
||||
relevanceScore: 1.0,
|
||||
},
|
||||
])
|
||||
.onConflictDoNothing();
|
||||
|
||||
dbAvailable = true;
|
||||
} catch {
|
||||
// Database is not reachable (e.g., CI environment without Postgres on port 5433).
|
||||
// All tests in this suite will be skipped.
|
||||
}
|
||||
});
|
||||
|
||||
// Skip all tests in this file when the database is not reachable (e.g., CI without Postgres).
|
||||
beforeEach((ctx) => {
|
||||
if (!dbAvailable) {
|
||||
ctx.skip();
|
||||
}
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
|
||||
Reference in New Issue
Block a user