Skip to content

Commit

Permalink
test: add tests to core functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Barbapapazes committed Jun 13, 2024
1 parent b6f5578 commit 35d4470
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 33 deletions.
24 changes: 24 additions & 0 deletions test/ability.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { describe, expect, it } from 'vitest'
import { allow, deny } from '../src/utils'

describe('Ability', () => {
describe('allow', () => {
it('should return an object with authorized', () => {
expect(allow()).toEqual({ authorized: true })
})
})

describe('deny', () => {
it('should return an object with authorized', () => {
expect(deny()).toEqual({ authorized: false })
})

it('should return an object with message', () => {
expect(deny({ message: 'Custom message' })).toEqual({ authorized: false, message: 'Custom message' })
})

it('should return an object with statusCode', () => {
expect(deny({ statusCode: 401 })).toEqual({ authorized: false, statusCode: 401 })
})
})
})
15 changes: 0 additions & 15 deletions test/basic.test.ts

This file was deleted.

185 changes: 185 additions & 0 deletions test/bouncer.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import { describe, expect, it } from 'vitest'
import { allow, allows, denies, defineAbility, authorize, deny, AuthorizationError } from '../src/utils'

describe('Bouncer', () => {
interface User {
id: number
}
const user: User = { id: 1 }

describe('allows', () => {
it('should return true if the user is authorized', async () => {
const ability = defineAbility(() => true)

const result = await allows(ability, {})
expect(result).toBe(true)
})

it('should return false if the user is not authorized', async () => {
const ability = defineAbility(() => false)

const result = await allows(ability, {})
expect(result).toBe(false)
})

it('should handle async authorizers', async () => {
const ability = defineAbility(async () => Promise.resolve(true))

const result = await allows(ability, {})
expect(result).toBe(true)
})

it('should pass user to the ability', async () => {
const ability = defineAbility((user: User) => Boolean(user.id))

const result = await allows(ability, user)
expect(result).toBe(true)
})

it('should pass additional arguments to the ability', async () => {
const ability = defineAbility((user: User, id: number) => Boolean(user.id === id))

const result = await allows(ability, user, 1)
expect(result).toBe(true)
})

it('should not allow guest by default', async () => {
const ability = defineAbility(() => true)

const result = await allows(ability, null)
expect(result).toBe(false)
})

it('should allow guest if specified', async () => {
const ability = defineAbility({ allowGuest: true }, () => true)

const result = await allows(ability, null)
expect(result).toBe(true)
})

it('should always return a boolean', async () => {
const ability = defineAbility(() => allow())

const result = await allows(ability, {})
expect(result).toBe(true)
})
})

describe('denies', () => {
it('should return false if the user is authorized', async () => {
const ability = defineAbility(() => true)

const result = await denies(ability, {})
expect(result).toBe(false)
})

it('should return true if the user is not authorized', async () => {
const ability = defineAbility(() => false)

const result = await denies(ability, {})
expect(result).toBe(true)
})

it('should handle async authorizers', async () => {
const ability = defineAbility(async () => Promise.resolve(true))

const result = await denies(ability, {})
expect(result).toBe(false)
})

it('should pass user to the ability', async () => {
const ability = defineAbility((user: User) => Boolean(user.id))

const result = await denies(ability, user)
expect(result).toBe(false)
})

it('should pass additional arguments to the ability', async () => {
const ability = defineAbility((user: User, id: number) => Boolean(user.id === id))

const result = await denies(ability, user, 1)
expect(result).toBe(false)
})

it('should not allow guest by default', async () => {
const ability = defineAbility(() => true)

const result = await denies(ability, null)
expect(result).toBe(true)
})

it('should allow guest if specified', async () => {
const ability = defineAbility({ allowGuest: true }, () => true)

const result = await denies(ability, null)
expect(result).toBe(false)
})

it('should always return a boolean', async () => {
const ability = defineAbility(() => allow())

const result = await denies(ability, {})
expect(result).toBe(false)
})
})

describe('authorize', () => {
it('should not throw if the user is authorized', async () => {
const ability = defineAbility(() => true)

await expect(authorize(ability, {})).resolves.not.toThrow()
})

it('should throw if the user is not authorized', async () => {
const ability = defineAbility(() => false)

const rejects = await expect(authorize(ability, {})).rejects

rejects.toThrow('Unauthorized')
rejects.toBeInstanceOf(AuthorizationError)
rejects.toHaveProperty('statusCode', 403)
rejects.toHaveProperty('message', 'Unauthorized')
})

it('should handle async authorizers', async () => {
const ability = defineAbility(async () => Promise.resolve(true))

await expect(authorize(ability, {})).resolves.not.toThrow()
})

it('should pass user to the ability', async () => {
const ability = defineAbility((user: User) => Boolean(user.id))

await expect(authorize(ability, user)).resolves.not.toThrow()
})

it('should pass additional arguments to the ability', async () => {
const ability = defineAbility((user: User, id: number) => Boolean(user.id === id))

await expect(authorize(ability, user, 1)).resolves.not.toThrow()
})

it('should not allow guest by default', async () => {
const ability = defineAbility(() => true)

await expect(authorize(ability, null)).rejects.toThrow('Unauthorized')
})

it('should allow guest if specified', async () => {
const ability = defineAbility({ allowGuest: true }, () => true)

await expect(authorize(ability, null)).resolves.not.toThrow()
})

it('should throw an error with the specified message', async () => {
const ability = defineAbility(() => deny({ message: 'Not Found', statusCode: 404 }))

const rejects = await expect(authorize(ability, {})).rejects

rejects.toThrow('Not Found')
rejects.toBeInstanceOf(AuthorizationError)
rejects.toHaveProperty('statusCode', 404)
rejects.toHaveProperty('message', 'Not Found')
})
})
})
36 changes: 36 additions & 0 deletions test/error.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { describe, expect, it } from 'vitest'
import { AuthorizationError, createAuthorizationError } from '../src/utils'

describe('createAuthorizationError', () => {
it('should return an AuthorizationError with correct defaults', () => {
const error = createAuthorizationError()
expect(error).toBeInstanceOf(AuthorizationError)
expect(error.message).toBe('Unauthorized')
expect(error.statusCode).toBe(403)
})

it('should allow custom message', () => {
const error = createAuthorizationError('Custom message')
expect(error.message).toBe('Custom message')
})

it('should allow custom status code', () => {
const error = createAuthorizationError('Custom message', 401)
expect(error.message).toBe('Custom message')
expect(error.statusCode).toBe(401)
})

it('should return a throw-able error', async () => {
const error = createAuthorizationError()
expect(() => {
throw error
}).toThrowError('Unauthorized')
})

it('should return a throw-able error with custom message', async () => {
const error = createAuthorizationError('Custom message')
expect(() => {
throw error
}).toThrowError('Custom message')
})
})
6 changes: 0 additions & 6 deletions test/fixtures/basic/app.vue

This file was deleted.

7 changes: 0 additions & 7 deletions test/fixtures/basic/nuxt.config.ts

This file was deleted.

5 changes: 0 additions & 5 deletions test/fixtures/basic/package.json

This file was deleted.

0 comments on commit 35d4470

Please sign in to comment.