Skip to content

Commit fafded6

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
test(selectors): cover credential provider binding
1 parent 0b8f18c commit fafded6

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* @vitest-environment node
3+
*/
4+
import { account, credential } from '@sim/db/schema'
5+
import {
6+
dbChainMock,
7+
dbChainMockFns,
8+
drizzleOrmMock,
9+
hasMockCondition,
10+
queueTableRows,
11+
resetDbChainMock,
12+
} from '@sim/testing'
13+
import { beforeEach, describe, expect, it, vi } from 'vitest'
14+
15+
vi.mock('@sim/db', () => dbChainMock)
16+
vi.mock('drizzle-orm', () => drizzleOrmMock)
17+
18+
import { selectorCredentialMatchesService } from '@/lib/selectors/application/credential-provider'
19+
20+
describe('selectorCredentialMatchesService', () => {
21+
beforeEach(() => {
22+
vi.clearAllMocks()
23+
resetDbChainMock()
24+
})
25+
26+
it.each([
27+
['OAuth', 'jira', 'jira', true],
28+
['Atlassian service account', 'atlassian-service-account', 'confluence', true],
29+
['Slack custom bot', 'slack-custom-bot', 'slack', true],
30+
['unrelated provider', 'pipedrive', 'slack', false],
31+
])(
32+
'binds a stored %s provider to the requested service',
33+
async (_, providerId, serviceId, ok) => {
34+
queueTableRows(credential, [{ accountId: null, providerId }])
35+
36+
await expect(
37+
selectorCredentialMatchesService({
38+
credentialId: 'credential-1',
39+
credentialOwnerUserId: 'owner-1',
40+
serviceId,
41+
})
42+
).resolves.toBe(ok)
43+
44+
expect(dbChainMockFns.from).toHaveBeenCalledTimes(1)
45+
}
46+
)
47+
48+
it('falls back to an owner-scoped legacy account provider', async () => {
49+
queueTableRows(credential, [])
50+
queueTableRows(account, [{ providerId: 'slack' }])
51+
52+
await expect(
53+
selectorCredentialMatchesService({
54+
credentialId: 'legacy-account-1',
55+
credentialOwnerUserId: 'owner-1',
56+
serviceId: 'slack',
57+
})
58+
).resolves.toBe(true)
59+
60+
const accountWhere = dbChainMockFns.where.mock.calls.at(-1)?.[0]
61+
expect(
62+
hasMockCondition(
63+
accountWhere,
64+
(condition) =>
65+
condition.type === 'eq' &&
66+
condition.left === account.id &&
67+
condition.right === 'legacy-account-1'
68+
)
69+
).toBe(true)
70+
expect(
71+
hasMockCondition(
72+
accountWhere,
73+
(condition) =>
74+
condition.type === 'eq' &&
75+
condition.left === account.userId &&
76+
condition.right === 'owner-1'
77+
)
78+
).toBe(true)
79+
})
80+
81+
it('rejects a legacy account with no owner-matched provider row', async () => {
82+
queueTableRows(credential, [])
83+
queueTableRows(account, [])
84+
85+
await expect(
86+
selectorCredentialMatchesService({
87+
credentialId: 'legacy-account-1',
88+
credentialOwnerUserId: 'owner-1',
89+
serviceId: 'slack',
90+
})
91+
).resolves.toBe(false)
92+
})
93+
})

0 commit comments

Comments
 (0)