Skip to content

Commit 2613baa

Browse files
committed
test: align file ownership fixtures and validation reports
1 parent 25d7280 commit 2613baa

16 files changed

Lines changed: 73 additions & 47 deletions

File tree

‎.claude/rules/sim-testing.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ contracts, and demonstrated regressions.
4747
(`sim_test`); `TEST_REDIS_URL` must be loopback. `packages/db/testing/test-infrastructure.ts` owns
4848
those checks. Isolate with a unique schema or generated IDs, and clean up in `afterAll`.
4949
- Integration files run one at a time against one shared database. A new `*.integration.ts` is
50-
picked up by CI with no workflow change, and the run writes `test-results/integration.json`, which
51-
CI uploads. Never add a passing suite to the quarantine list in `apps/sim/vitest.config.ts`.
50+
picked up by CI with no workflow change. By default, each workspace writes its generated report
51+
to `<workspace>/test-results/integration.json`, which CI uploads. Never add a passing suite to the
52+
quarantine list in `apps/sim/vitest.config.ts`.
5253
- `bun run test:integration` starts disposable Postgres and Redis containers, provisions the schema,
5354
and runs both workspaces; pass filenames to narrow the `apps/sim` run.
5455

‎.cursor/rules/sim-testing.mdc‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ contracts, and demonstrated regressions.
4545
(`sim_test`); `TEST_REDIS_URL` must be loopback. `packages/db/testing/test-infrastructure.ts` owns
4646
those checks. Isolate with a unique schema or generated IDs, and clean up in `afterAll`.
4747
- Integration files run one at a time against one shared database. A new `*.integration.ts` is
48-
picked up by CI with no workflow change, and the run writes `test-results/integration.json`, which
49-
CI uploads. Never add a passing suite to the quarantine list in `apps/sim/vitest.config.ts`.
48+
picked up by CI with no workflow change. By default, each workspace writes its generated report
49+
to `<workspace>/test-results/integration.json`, which CI uploads. Never add a passing suite to the
50+
quarantine list in `apps/sim/vitest.config.ts`.
5051
- `bun run test:integration` starts disposable Postgres and Redis containers, provisions the schema,
5152
and runs both workspaces; pass filenames to narrow the `apps/sim` run.
5253

‎apps/realtime/src/routes/http.test.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ describe('createHttpHandler', () => {
6363

6464
await handler(req, res)
6565

66-
expect(mockInvalidateDocument).toHaveBeenCalledWith('file-1', 100)
6766
expect(to).toHaveBeenCalledWith(['workspace-file-doc:file-1', 'file-doc-admission:file-1'])
6867
expect(emit).toHaveBeenCalledWith(
6968
'file-doc-invalidated',

‎apps/realtime/vitest.config.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ export default defineConfig(({ mode }) =>
1717
? {
1818
fileParallelism: false,
1919
reporters: ['default', 'json'],
20-
outputFile: { json: 'test-results/integration.json' },
20+
outputFile: {
21+
json: process.env.INTEGRATION_REPORT_PATH ?? 'test-results/integration.json',
22+
},
2123
}
2224
: {}),
2325
},

‎apps/sim/ee/workspace-forking/lib/mapping/resources.test.ts‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,22 @@ describe('listForkResourceCandidates', () => {
3939
{ id: 'workspace/WS/notes.md', label: 'notes.md' },
4040
])
4141
.mockResolvedValueOnce([
42-
{ id: 'folder-reports', name: 'Reports', parentId: null },
43-
{ id: 'folder-q3', name: 'Q3 Results', parentId: 'folder-reports' },
42+
{
43+
id: 'folder-reports',
44+
name: 'Reports',
45+
parentId: null,
46+
workspaceId: 'ws-1',
47+
entityType: 'workspace',
48+
entityId: 'ws-1',
49+
},
50+
{
51+
id: 'folder-q3',
52+
name: 'Q3 Results',
53+
parentId: 'folder-reports',
54+
workspaceId: 'ws-1',
55+
entityType: 'workspace',
56+
entityId: 'ws-1',
57+
},
4458
])
4559

4660
const result = await listForkResourceCandidates(executor, 'ws-1')

‎apps/sim/lib/billing/core/billing-attribution.test.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,6 @@ describe('resolveBillingAttribution', () => {
112112
},
113113
workspaceId: 'workspace-b',
114114
})
115-
expect(mockGetOrganizationSubscription).toHaveBeenCalledWith('org-b', {
116-
onError: 'throw',
117-
})
118115
expect(mockGetHighestPriorityPersonalSubscription).not.toHaveBeenCalled()
119116
expect(Object.isFrozen(attribution)).toBe(true)
120117
expect(Object.isFrozen(attribution.billingEntity)).toBe(true)

‎apps/sim/lib/logs/folder-scope.test.ts‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,15 @@ const FOLDERS: FolderRow[] = [
1919
describe('resolveLogFolderScope', () => {
2020
beforeEach(() => {
2121
resetDbChainMock()
22-
queueTableRows(schemaMock.folder, FOLDERS)
22+
queueTableRows(
23+
schemaMock.folder,
24+
FOLDERS.map((row) => ({
25+
...row,
26+
workspaceId: 'workspace-1',
27+
entityType: 'workspace',
28+
entityId: 'workspace-1',
29+
}))
30+
)
2331
})
2432

2533
it('covers the whole subtree of a selected folder', async () => {

‎apps/sim/lib/mothership/agent-cli/file-round-trip-provenance.test.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { billingStorageMock, billingStorageMockFns } from '@sim/testing/mocks/bi
1212
import { encryptionMock, encryptionMockFns } from '@sim/testing/mocks/encryption.mock'
1313
import { getMockLogger } from '@sim/testing/mocks/logger.mock'
1414
import { permissionsMock } from '@sim/testing/mocks/permissions.mock'
15+
import { projectMembershipMock } from '@sim/testing/mocks/project-membership.mock'
1516
import { realtimeNotifyMock } from '@sim/testing/mocks/realtime-notify.mock'
1617
import { redisConfigMockFns } from '@sim/testing/mocks/redis-config.mock'
1718
import {
@@ -46,6 +47,7 @@ vi.mock('@/lib/api/server/routes/v2-api-key-auth', () => v2ApiKeyAuthModuleMock)
4647
vi.mock('@/lib/mothership/chat/delegation', () => ({ mintDelegationToken: async () => 'fixture' }))
4748
vi.mock('@/lib/core/security/encryption', () => encryptionMock)
4849
vi.mock('@/lib/realtime/notify', () => realtimeNotifyMock)
50+
vi.mock('@/lib/projects/membership', () => projectMembershipMock)
4951
vi.mock('@/lib/billing/storage', () => billingStorageMock)
5052
vi.mock('@/lib/uploads', () => uploadsMock)
5153
vi.mock('@/lib/uploads/core/storage-service', () => storageServiceMock)
@@ -137,6 +139,9 @@ const SOURCE = {
137139
key: `workspace/${WORKSPACE}/123-abc-source.txt`,
138140
userId: 'reader',
139141
workspaceId: WORKSPACE,
142+
entityType: 'workspace',
143+
entityId: WORKSPACE,
144+
organizationId: null,
140145
folderId: null,
141146
context: 'workspace',
142147
chatId: null,
@@ -179,6 +184,7 @@ function queueRead(file: typeof SOURCE, provenance: WorkspaceFileSecretProvenanc
179184
{
180185
workspaceId: WORKSPACE,
181186
fileId: file.id,
187+
ownership: file,
182188
workspaceOrganizationId: null,
183189
allowPersonalApiKeys: true,
184190
billedAccountUserId: 'owner',

‎apps/sim/lib/uploads/contexts/workspace/workspace-file-manager-page.test.ts‎

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { dbChainMockFns } from '@sim/testing'
1+
import { dbChainMockFns, resetDbChainMock } from '@sim/testing'
22
import { billingStorageMock } from '@sim/testing/mocks/billing-storage.mock'
3+
import { projectMembershipMock } from '@sim/testing/mocks/project-membership.mock'
34
import { realtimeNotifyMock } from '@sim/testing/mocks/realtime-notify.mock'
45
import { storageServiceMock, storageServiceMockFns } from '@sim/testing/mocks/storage-service.mock'
56
import { uploadsMock } from '@sim/testing/mocks/uploads.mock'
@@ -9,16 +10,7 @@ import {
910
} from '@sim/testing/mocks/workspace-file-folders.mock'
1011
import { beforeEach, expect, it, vi } from 'vitest'
1112

12-
const mocks = vi.hoisted(() => {
13-
const values = vi.fn()
14-
const insert = vi.fn(() => ({
15-
values: (metadata: Record<string, unknown>) => {
16-
values(metadata)
17-
return { onConflictDoNothing: () => ({ returning: async () => [metadata] }) }
18-
},
19-
}))
20-
return { values, insert }
21-
})
13+
vi.mock('@/lib/projects/membership', () => projectMembershipMock)
2214
vi.mock('@/lib/billing/storage', () => billingStorageMock)
2315
vi.mock('@/lib/folders/locks', () => ({ acquireFolderMutationLock: vi.fn() }))
2416
vi.mock('@/lib/realtime/notify', () => realtimeNotifyMock)
@@ -41,11 +33,12 @@ workspaceFileFoldersMockFns.mockNormalizeWorkspaceFileItemName.mockImplementatio
4133
const mockUpload = storageServiceMockFns.mockUploadFile
4234

4335
beforeEach(() => {
44-
dbChainMockFns.transaction.mockImplementation(
45-
async (run: (tx: { insert: typeof mocks.insert }) => Promise<unknown>) =>
46-
run({ insert: mocks.insert })
47-
)
48-
mockUpload.mockImplementation(async ({ fileName }: { fileName: string }) => ({ key: fileName }))
36+
resetDbChainMock()
37+
dbChainMockFns.returning.mockImplementation(async () => {
38+
const metadata = dbChainMockFns.values.mock.calls.at(-1)?.[0]
39+
return metadata ? [metadata] : []
40+
})
41+
mockUpload.mockImplementation(async ({ customKey }) => ({ key: customKey }))
4942
})
5043

5144
it('registers agent-authored Page source as a native Page and preserves editable source', async () => {
@@ -68,7 +61,7 @@ it('registers agent-authored Page source as a native Page and preserves editable
6861
type: SIM_PAGE_CONTENT_TYPE,
6962
size: bytes.length,
7063
})
71-
expect(mocks.values).toHaveBeenCalledWith(
64+
expect(dbChainMockFns.values).toHaveBeenCalledWith(
7265
expect.objectContaining({ originalName: 'Team handbook', contentType: SIM_PAGE_CONTENT_TYPE })
7366
)
7467
expect(mockUpload).toHaveBeenCalledWith(
@@ -83,7 +76,7 @@ it('keeps a complete HTML document as HTML rather than mislabeling it a native P
8376
exactName: true,
8477
})
8578
expect(file).toMatchObject({ name: 'report.html', type: 'text/html' })
86-
expect(mocks.values).toHaveBeenCalledWith(
79+
expect(dbChainMockFns.values).toHaveBeenCalledWith(
8780
expect.objectContaining({ originalName: 'report.html', contentType: 'text/html' })
8881
)
8982
})

‎apps/sim/lib/uploads/contexts/workspace/workspace-file-storage-billing.test.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { dbChainMockFns, resetDbChainMock } from '@sim/testing'
22
import { billingStorageMock, billingStorageMockFns } from '@sim/testing/mocks/billing-storage.mock'
3+
import { projectMembershipMock } from '@sim/testing/mocks/project-membership.mock'
34
import { storageServiceMock, storageServiceMockFns } from '@sim/testing/mocks/storage-service.mock'
45
import { uploadsMock, uploadsMockFns } from '@sim/testing/mocks/uploads.mock'
56
import {
@@ -8,6 +9,7 @@ import {
89
} from '@sim/testing/mocks/workspace-file-folders.mock'
910
import { beforeEach, describe, expect, it, vi } from 'vitest'
1011

12+
vi.mock('@/lib/projects/membership', () => projectMembershipMock)
1113
vi.mock('@/lib/billing/storage', () => billingStorageMock)
1214

1315
vi.mock('@/lib/uploads', () => uploadsMock)
@@ -52,19 +54,17 @@ describe('workspace file storage attribution', () => {
5254
mockResolveWorkspaceFileFolderTarget.mockResolvedValue(null)
5355
mockIncrementStorageUsageForBillingContextInTx.mockResolvedValue(5)
5456
mockMaybeNotifyStorageLimitForBillingContext.mockResolvedValue(undefined)
55-
mockUploadFile.mockResolvedValue({
56-
key: 'workspace/workspace-1/123-abc-note.txt',
57-
})
57+
mockUploadFile.mockImplementation(async ({ customKey }) => ({ key: customKey }))
5858
})
5959

6060
it.each(['external-collaborator', 'personal-api-key-user'])(
6161
'charges the workspace payer while retaining %s as uploader metadata',
6262
async (actorUserId) => {
6363
dbChainMockFns.returning
64-
.mockResolvedValueOnce([
64+
.mockImplementationOnce(async () => [
6565
{
6666
id: 'file-1',
67-
key: 'workspace/workspace-1/123-abc-note.txt',
67+
key: mockUploadFile.mock.calls.at(-1)?.[0].customKey,
6868
userId: actorUserId,
6969
workspaceId: 'workspace-1',
7070
folderId: null,

0 commit comments

Comments
 (0)