Skip to content

Commit 35d4470

Browse files
committed
test: add tests to core functions
1 parent b6f5578 commit 35d4470

File tree

7 files changed

+245
-33
lines changed

7 files changed

+245
-33
lines changed

test/ability.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { allow, deny } from '../src/utils'
3+
4+
describe('Ability', () => {
5+
describe('allow', () => {
6+
it('should return an object with authorized', () => {
7+
expect(allow()).toEqual({ authorized: true })
8+
})
9+
})
10+
11+
describe('deny', () => {
12+
it('should return an object with authorized', () => {
13+
expect(deny()).toEqual({ authorized: false })
14+
})
15+
16+
it('should return an object with message', () => {
17+
expect(deny({ message: 'Custom message' })).toEqual({ authorized: false, message: 'Custom message' })
18+
})
19+
20+
it('should return an object with statusCode', () => {
21+
expect(deny({ statusCode: 401 })).toEqual({ authorized: false, statusCode: 401 })
22+
})
23+
})
24+
})

test/basic.test.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

test/bouncer.spec.ts

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { allow, allows, denies, defineAbility, authorize, deny, AuthorizationError } from '../src/utils'
3+
4+
describe('Bouncer', () => {
5+
interface User {
6+
id: number
7+
}
8+
const user: User = { id: 1 }
9+
10+
describe('allows', () => {
11+
it('should return true if the user is authorized', async () => {
12+
const ability = defineAbility(() => true)
13+
14+
const result = await allows(ability, {})
15+
expect(result).toBe(true)
16+
})
17+
18+
it('should return false if the user is not authorized', async () => {
19+
const ability = defineAbility(() => false)
20+
21+
const result = await allows(ability, {})
22+
expect(result).toBe(false)
23+
})
24+
25+
it('should handle async authorizers', async () => {
26+
const ability = defineAbility(async () => Promise.resolve(true))
27+
28+
const result = await allows(ability, {})
29+
expect(result).toBe(true)
30+
})
31+
32+
it('should pass user to the ability', async () => {
33+
const ability = defineAbility((user: User) => Boolean(user.id))
34+
35+
const result = await allows(ability, user)
36+
expect(result).toBe(true)
37+
})
38+
39+
it('should pass additional arguments to the ability', async () => {
40+
const ability = defineAbility((user: User, id: number) => Boolean(user.id === id))
41+
42+
const result = await allows(ability, user, 1)
43+
expect(result).toBe(true)
44+
})
45+
46+
it('should not allow guest by default', async () => {
47+
const ability = defineAbility(() => true)
48+
49+
const result = await allows(ability, null)
50+
expect(result).toBe(false)
51+
})
52+
53+
it('should allow guest if specified', async () => {
54+
const ability = defineAbility({ allowGuest: true }, () => true)
55+
56+
const result = await allows(ability, null)
57+
expect(result).toBe(true)
58+
})
59+
60+
it('should always return a boolean', async () => {
61+
const ability = defineAbility(() => allow())
62+
63+
const result = await allows(ability, {})
64+
expect(result).toBe(true)
65+
})
66+
})
67+
68+
describe('denies', () => {
69+
it('should return false if the user is authorized', async () => {
70+
const ability = defineAbility(() => true)
71+
72+
const result = await denies(ability, {})
73+
expect(result).toBe(false)
74+
})
75+
76+
it('should return true if the user is not authorized', async () => {
77+
const ability = defineAbility(() => false)
78+
79+
const result = await denies(ability, {})
80+
expect(result).toBe(true)
81+
})
82+
83+
it('should handle async authorizers', async () => {
84+
const ability = defineAbility(async () => Promise.resolve(true))
85+
86+
const result = await denies(ability, {})
87+
expect(result).toBe(false)
88+
})
89+
90+
it('should pass user to the ability', async () => {
91+
const ability = defineAbility((user: User) => Boolean(user.id))
92+
93+
const result = await denies(ability, user)
94+
expect(result).toBe(false)
95+
})
96+
97+
it('should pass additional arguments to the ability', async () => {
98+
const ability = defineAbility((user: User, id: number) => Boolean(user.id === id))
99+
100+
const result = await denies(ability, user, 1)
101+
expect(result).toBe(false)
102+
})
103+
104+
it('should not allow guest by default', async () => {
105+
const ability = defineAbility(() => true)
106+
107+
const result = await denies(ability, null)
108+
expect(result).toBe(true)
109+
})
110+
111+
it('should allow guest if specified', async () => {
112+
const ability = defineAbility({ allowGuest: true }, () => true)
113+
114+
const result = await denies(ability, null)
115+
expect(result).toBe(false)
116+
})
117+
118+
it('should always return a boolean', async () => {
119+
const ability = defineAbility(() => allow())
120+
121+
const result = await denies(ability, {})
122+
expect(result).toBe(false)
123+
})
124+
})
125+
126+
describe('authorize', () => {
127+
it('should not throw if the user is authorized', async () => {
128+
const ability = defineAbility(() => true)
129+
130+
await expect(authorize(ability, {})).resolves.not.toThrow()
131+
})
132+
133+
it('should throw if the user is not authorized', async () => {
134+
const ability = defineAbility(() => false)
135+
136+
const rejects = await expect(authorize(ability, {})).rejects
137+
138+
rejects.toThrow('Unauthorized')
139+
rejects.toBeInstanceOf(AuthorizationError)
140+
rejects.toHaveProperty('statusCode', 403)
141+
rejects.toHaveProperty('message', 'Unauthorized')
142+
})
143+
144+
it('should handle async authorizers', async () => {
145+
const ability = defineAbility(async () => Promise.resolve(true))
146+
147+
await expect(authorize(ability, {})).resolves.not.toThrow()
148+
})
149+
150+
it('should pass user to the ability', async () => {
151+
const ability = defineAbility((user: User) => Boolean(user.id))
152+
153+
await expect(authorize(ability, user)).resolves.not.toThrow()
154+
})
155+
156+
it('should pass additional arguments to the ability', async () => {
157+
const ability = defineAbility((user: User, id: number) => Boolean(user.id === id))
158+
159+
await expect(authorize(ability, user, 1)).resolves.not.toThrow()
160+
})
161+
162+
it('should not allow guest by default', async () => {
163+
const ability = defineAbility(() => true)
164+
165+
await expect(authorize(ability, null)).rejects.toThrow('Unauthorized')
166+
})
167+
168+
it('should allow guest if specified', async () => {
169+
const ability = defineAbility({ allowGuest: true }, () => true)
170+
171+
await expect(authorize(ability, null)).resolves.not.toThrow()
172+
})
173+
174+
it('should throw an error with the specified message', async () => {
175+
const ability = defineAbility(() => deny({ message: 'Not Found', statusCode: 404 }))
176+
177+
const rejects = await expect(authorize(ability, {})).rejects
178+
179+
rejects.toThrow('Not Found')
180+
rejects.toBeInstanceOf(AuthorizationError)
181+
rejects.toHaveProperty('statusCode', 404)
182+
rejects.toHaveProperty('message', 'Not Found')
183+
})
184+
})
185+
})

test/error.spec.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { AuthorizationError, createAuthorizationError } from '../src/utils'
3+
4+
describe('createAuthorizationError', () => {
5+
it('should return an AuthorizationError with correct defaults', () => {
6+
const error = createAuthorizationError()
7+
expect(error).toBeInstanceOf(AuthorizationError)
8+
expect(error.message).toBe('Unauthorized')
9+
expect(error.statusCode).toBe(403)
10+
})
11+
12+
it('should allow custom message', () => {
13+
const error = createAuthorizationError('Custom message')
14+
expect(error.message).toBe('Custom message')
15+
})
16+
17+
it('should allow custom status code', () => {
18+
const error = createAuthorizationError('Custom message', 401)
19+
expect(error.message).toBe('Custom message')
20+
expect(error.statusCode).toBe(401)
21+
})
22+
23+
it('should return a throw-able error', async () => {
24+
const error = createAuthorizationError()
25+
expect(() => {
26+
throw error
27+
}).toThrowError('Unauthorized')
28+
})
29+
30+
it('should return a throw-able error with custom message', async () => {
31+
const error = createAuthorizationError('Custom message')
32+
expect(() => {
33+
throw error
34+
}).toThrowError('Custom message')
35+
})
36+
})

test/fixtures/basic/app.vue

Lines changed: 0 additions & 6 deletions
This file was deleted.

test/fixtures/basic/nuxt.config.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

test/fixtures/basic/package.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)