mirror of
https://github.com/Permissionless-Software-Foundation/x402-base-facilitator.git
synced 2026-09-21 16:52:01 -07:00
307 lines
8.6 KiB
JavaScript
307 lines
8.6 KiB
JavaScript
/*
|
|||
|
|
Unit tests for the REST API middleware that validates users.
|
||
|
|
*/
|
||
|
|
|
||
|
|
// Public npm libraries
|
||
|
|
import { assert } from 'chai'
|
||
|
|
import sinon from 'sinon'
|
||
|
|
|
||
|
|
// Local libraries
|
||
|
|
import Validators from '../../../../../src/controllers/rest-api/middleware/validators.js'
|
||
|
|
import { context as mockContext } from '../../../../unit/mocks/ctx-mock.js'
|
||
|
|
|
||
|
|
describe('#Validators', () => {
|
||
|
|
let uut
|
||
|
|
let ctx
|
||
|
|
let sandbox
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
uut = new Validators()
|
||
|
|
|
||
|
|
// Mock the context object.
|
||
|
|
ctx = mockContext()
|
||
|
|
|
||
|
|
sandbox = sinon.createSandbox()
|
||
|
|
})
|
||
|
|
|
||
|
|
afterEach(() => sandbox.restore())
|
||
|
|
|
||
|
|
describe('#getToken', () => {
|
||
|
|
it('should return null if no header is provided', () => {
|
||
|
|
const result = uut.getToken(ctx)
|
||
|
|
|
||
|
|
assert.equal(result, null)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should return null if header is not in two parts', () => {
|
||
|
|
ctx.request.header.authorization = 'Bearer'
|
||
|
|
|
||
|
|
const result = uut.getToken(ctx)
|
||
|
|
|
||
|
|
assert.equal(result, null)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should return null if first part of header does not container the word bearer', () => {
|
||
|
|
ctx.request.header.authorization = 'some thing'
|
||
|
|
|
||
|
|
const result = uut.getToken(ctx)
|
||
|
|
|
||
|
|
assert.equal(result, null)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should return the JWT token from the header', () => {
|
||
|
|
const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYzMjNiNTUwNzgxYWYzNTc4YzI0ZmU5YiIsImlhdCI6MTY2MzQ0NDczNCwiZXhwIjoxNjYzNTMxMTM0fQ.BY5sOfXc4z5axS98CdTfyqnO9y2wijOlwnv52rcvxHA'
|
||
|
|
ctx.request.header.authorization = `Bearer ${jwt}`
|
||
|
|
|
||
|
|
const result = uut.getToken(ctx)
|
||
|
|
|
||
|
|
assert.equal(result, jwt)
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
describe('#ensureUser', () => {
|
||
|
|
it('should throw error if token is not provided', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns()
|
||
|
|
|
||
|
|
await uut.ensureUser(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should throw error if token can not be verified', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').throws(new Error('test error'))
|
||
|
|
|
||
|
|
await uut.ensureUser(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should throw error if user can not be found in database', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||
|
|
sandbox.stub(uut.User, 'findById').resolves(false)
|
||
|
|
|
||
|
|
await uut.ensureUser(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should return true if the user is verified', async () => {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||
|
|
sandbox.stub(uut.User, 'findById').resolves({ user: 'alice' })
|
||
|
|
|
||
|
|
const result = await uut.ensureUser(ctx)
|
||
|
|
|
||
|
|
assert.equal(result, true)
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
describe('#ensureUser', () => {
|
||
|
|
it('should throw error if token is not provided', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns()
|
||
|
|
|
||
|
|
await uut.ensureAdmin(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should throw error if token can not be verified', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').throws(new Error('test error'))
|
||
|
|
|
||
|
|
await uut.ensureAdmin(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should throw error if user can not be found in database', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||
|
|
sandbox.stub(uut.User, 'findById').resolves(false)
|
||
|
|
|
||
|
|
await uut.ensureAdmin(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should throw error if user is not an admin', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||
|
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'user' })
|
||
|
|
|
||
|
|
await uut.ensureAdmin(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should return true if the user is an admin', async () => {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||
|
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'admin' })
|
||
|
|
|
||
|
|
const result = await uut.ensureAdmin(ctx)
|
||
|
|
|
||
|
|
assert.equal(result, true)
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
describe('#ensureTargetUserOrAdmin', () => {
|
||
|
|
it('should throw error if token is not provided', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns()
|
||
|
|
|
||
|
|
await uut.ensureTargetUserOrAdmin(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should throw error if token can not be verified', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').throws(new Error('test error'))
|
||
|
|
|
||
|
|
ctx.params = {
|
||
|
|
id: '456'
|
||
|
|
}
|
||
|
|
|
||
|
|
await uut.ensureTargetUserOrAdmin(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should throw error if user can not be found in database', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||
|
|
sandbox.stub(uut.User, 'findById').resolves(false)
|
||
|
|
|
||
|
|
ctx.params = {
|
||
|
|
id: '456'
|
||
|
|
}
|
||
|
|
|
||
|
|
await uut.ensureTargetUserOrAdmin(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should throw error if user is not an admin', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||
|
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'user' })
|
||
|
|
|
||
|
|
ctx.params = {
|
||
|
|
id: '456'
|
||
|
|
}
|
||
|
|
|
||
|
|
await uut.ensureTargetUserOrAdmin(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should throw error is user is not admin or target user', async () => {
|
||
|
|
try {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||
|
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'user', _id: '123' })
|
||
|
|
|
||
|
|
ctx.params = {
|
||
|
|
id: '456'
|
||
|
|
}
|
||
|
|
|
||
|
|
await uut.ensureTargetUserOrAdmin(ctx)
|
||
|
|
|
||
|
|
assert.fail('Unexpected result')
|
||
|
|
} catch (err) {
|
||
|
|
assert.equal(ctx.status, 401)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should return true if the user is an admin', async () => {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||
|
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'admin', _id: '123' })
|
||
|
|
|
||
|
|
ctx.params = {
|
||
|
|
id: '456'
|
||
|
|
}
|
||
|
|
|
||
|
|
const result = await uut.ensureTargetUserOrAdmin(ctx)
|
||
|
|
|
||
|
|
assert.equal(result, true)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should return true if the user is the target user', async () => {
|
||
|
|
// Mock dependencies and force desired code path
|
||
|
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||
|
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||
|
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'user', _id: '123' })
|
||
|
|
|
||
|
|
ctx.params = {
|
||
|
|
id: '123'
|
||
|
|
}
|
||
|
|
|
||
|
|
const result = await uut.ensureTargetUserOrAdmin(ctx)
|
||
|
|
|
||
|
|
assert.equal(result, true)
|
||
|
|
})
|
||
|
|
})
|
||
|
|
})
|