oauth.test.js
2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import { describe, it, expect } from 'vitest'
import { createAuth, createFakeUserRepo } from '../src/index.js'
import { createFakeHasher, createFakeSigner, createFakeOauth, createFakeEmail } from './fakes.js'
function build(oauth) {
const userRepo = createFakeUserRepo()
const auth = createAuth({
userRepo,
hasher: createFakeHasher(),
tokenSigner: createFakeSigner(),
oauth,
email: createFakeEmail(),
})
return { userRepo, auth }
}
describe('oauthLogin', () => {
it('first login auto-creates user (is_new_user true)', async () => {
const oauth = createFakeOauth({
'google:CODE1': { provider_user_id: 'g-1', email: 'g@x.com', email_verified: true },
})
const { auth, userRepo } = build(oauth)
const res = await auth.oauthLogin({ provider: 'google', code: 'CODE1', redirect_uri: 'https://app/cb' })
expect(res.is_new_user).toBe(true)
expect(res.user.email).toBe('g@x.com')
expect(res.access_token).toBeTruthy()
const stored = await userRepo.findByEmail('g@x.com')
expect(stored.oauth_providers).toContainEqual({ provider: 'google', provider_user_id: 'g-1' })
})
it('existing email merges into same user (is_new_user false)', async () => {
const oauth = createFakeOauth({
'google:CODE1': { provider_user_id: 'g-1', email: 'merge@x.com', email_verified: true },
})
const { auth, userRepo } = build(oauth)
// pre-existing password user with same email
await userRepo.create({ email: 'merge@x.com', password_hash: 'h$pw' })
const res = await auth.oauthLogin({ provider: 'google', code: 'CODE1' })
expect(res.is_new_user).toBe(false)
const stored = await userRepo.findByEmail('merge@x.com')
expect(stored.oauth_providers).toContainEqual({ provider: 'google', provider_user_id: 'g-1' })
})
it('verify failure -> OAUTH_VERIFY_FAILED', async () => {
const oauth = createFakeOauth({}, { throwOn: 'BAD' })
const { auth } = build(oauth)
await expect(auth.oauthLogin({ provider: 'apple', code: 'BAD' }))
.rejects.toMatchObject({ code: 'OAUTH_VERIFY_FAILED' })
})
it('unsupported provider rejected', async () => {
const { auth } = build(createFakeOauth())
await expect(auth.oauthLogin({ provider: 'wechat', code: 'x' }))
.rejects.toMatchObject({ code: 'UNSUPPORTED_PROVIDER' })
})
})