mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Move unit tests to files they apply to (#15130)
* Move unit tests to files they apply to * Remove tests root
This commit is contained in:
217
api/src/middleware/authenticate.test.ts
Normal file
217
api/src/middleware/authenticate.test.ts
Normal file
@@ -0,0 +1,217 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import jwt from 'jsonwebtoken';
|
||||
import getDatabase from '../database';
|
||||
import emitter from '../emitter';
|
||||
import env from '../env';
|
||||
import { InvalidCredentialsException } from '../exceptions';
|
||||
import { handler } from './authenticate';
|
||||
import '../../src/types/express.d.ts';
|
||||
|
||||
jest.mock('../../src/database');
|
||||
jest.mock('../../src/env', () => ({
|
||||
SECRET: 'test',
|
||||
}));
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
test('Short-circuits when authenticate filter is used', async () => {
|
||||
const req = {
|
||||
ip: '127.0.0.1',
|
||||
get: jest.fn(),
|
||||
};
|
||||
|
||||
const res = {};
|
||||
const next = jest.fn();
|
||||
|
||||
const customAccountability = { admin: true };
|
||||
|
||||
jest.spyOn(emitter, 'emitFilter').mockResolvedValue(customAccountability);
|
||||
|
||||
await handler(req, res, next);
|
||||
|
||||
expect(req.accountability).toEqual(customAccountability);
|
||||
expect(next).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('Uses default public accountability when no token is given', async () => {
|
||||
const req = {
|
||||
ip: '127.0.0.1',
|
||||
get: jest.fn((string) => (string === 'user-agent' ? 'fake-user-agent' : null)),
|
||||
};
|
||||
|
||||
const res = {};
|
||||
const next = jest.fn();
|
||||
|
||||
jest.spyOn(emitter, 'emitFilter').mockImplementation((_, payload) => payload);
|
||||
|
||||
await handler(req, res, next);
|
||||
|
||||
expect(req.accountability).toEqual({
|
||||
user: null,
|
||||
role: null,
|
||||
admin: false,
|
||||
app: false,
|
||||
ip: '127.0.0.1',
|
||||
userAgent: 'fake-user-agent',
|
||||
});
|
||||
|
||||
expect(next).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('Sets accountability to payload contents if valid token is passed', async () => {
|
||||
const userID = '3fac3c02-607f-4438-8d6e-6b8b25109b52';
|
||||
const roleID = '38269fc6-6eb6-475a-93cb-479d97f73039';
|
||||
const share = 'ca0ad005-f4ad-4bfe-b428-419ee8784790';
|
||||
const shareScope = {
|
||||
collection: 'articles',
|
||||
item: 15,
|
||||
};
|
||||
const appAccess = true;
|
||||
const adminAccess = false;
|
||||
|
||||
const token = jwt.sign(
|
||||
{
|
||||
id: userID,
|
||||
role: roleID,
|
||||
app_access: appAccess,
|
||||
admin_access: adminAccess,
|
||||
share,
|
||||
share_scope: shareScope,
|
||||
},
|
||||
env.SECRET,
|
||||
{ issuer: 'directus' }
|
||||
);
|
||||
|
||||
const req = {
|
||||
ip: '127.0.0.1',
|
||||
get: jest.fn((string) => (string === 'user-agent' ? 'fake-user-agent' : null)),
|
||||
token,
|
||||
};
|
||||
|
||||
const res = {};
|
||||
const next = jest.fn();
|
||||
|
||||
await handler(req, res, next);
|
||||
|
||||
expect(req.accountability).toEqual({
|
||||
user: userID,
|
||||
role: roleID,
|
||||
app: appAccess,
|
||||
admin: adminAccess,
|
||||
share,
|
||||
share_scope: shareScope,
|
||||
ip: '127.0.0.1',
|
||||
userAgent: 'fake-user-agent',
|
||||
});
|
||||
|
||||
expect(next).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Test with 1/0 instead or true/false
|
||||
next.mockClear();
|
||||
|
||||
req.token = jwt.sign(
|
||||
{
|
||||
id: userID,
|
||||
role: roleID,
|
||||
app_access: 1,
|
||||
admin_access: 0,
|
||||
share,
|
||||
share_scope: shareScope,
|
||||
},
|
||||
env.SECRET,
|
||||
{ issuer: 'directus' }
|
||||
);
|
||||
|
||||
await handler(req, res, next);
|
||||
|
||||
expect(req.accountability).toEqual({
|
||||
user: userID,
|
||||
role: roleID,
|
||||
app: appAccess,
|
||||
admin: adminAccess,
|
||||
share,
|
||||
share_scope: shareScope,
|
||||
ip: '127.0.0.1',
|
||||
userAgent: 'fake-user-agent',
|
||||
});
|
||||
|
||||
expect(next).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('Throws InvalidCredentialsException when static token is used, but user does not exist', async () => {
|
||||
jest.mocked(getDatabase).mockReturnValue({
|
||||
select: jest.fn().mockReturnThis(),
|
||||
from: jest.fn().mockReturnThis(),
|
||||
leftJoin: jest.fn().mockReturnThis(),
|
||||
where: jest.fn().mockReturnThis(),
|
||||
first: jest.fn().mockResolvedValue(undefined),
|
||||
});
|
||||
|
||||
const req = {
|
||||
ip: '127.0.0.1',
|
||||
get: jest.fn((string) => (string === 'user-agent' ? 'fake-user-agent' : null)),
|
||||
token: 'static-token',
|
||||
};
|
||||
|
||||
const res = {};
|
||||
const next = jest.fn();
|
||||
|
||||
expect(handler(req, res, next)).rejects.toEqual(new InvalidCredentialsException());
|
||||
expect(next).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('Sets accountability to user information when static token is used', async () => {
|
||||
const req = {
|
||||
ip: '127.0.0.1',
|
||||
get: jest.fn((string) => (string === 'user-agent' ? 'fake-user-agent' : null)),
|
||||
token: 'static-token',
|
||||
};
|
||||
|
||||
const res = {};
|
||||
const next = jest.fn();
|
||||
|
||||
const testUser = { id: 'test-id', role: 'test-role', admin_access: true, app_access: false };
|
||||
|
||||
const expectedAccountability = {
|
||||
user: testUser.id,
|
||||
role: testUser.role,
|
||||
app: testUser.app_access,
|
||||
admin: testUser.admin_access,
|
||||
ip: '127.0.0.1',
|
||||
userAgent: 'fake-user-agent',
|
||||
};
|
||||
|
||||
jest.mocked(getDatabase).mockReturnValue({
|
||||
select: jest.fn().mockReturnThis(),
|
||||
from: jest.fn().mockReturnThis(),
|
||||
leftJoin: jest.fn().mockReturnThis(),
|
||||
where: jest.fn().mockReturnThis(),
|
||||
first: jest.fn().mockResolvedValue(testUser),
|
||||
});
|
||||
|
||||
await handler(req, res, next);
|
||||
|
||||
expect(req.accountability).toEqual(expectedAccountability);
|
||||
expect(next).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Test for 0 / 1 instead of false / true
|
||||
next.mockClear();
|
||||
testUser.admin_access = 1;
|
||||
testUser.app_access = 0;
|
||||
await handler(req, res, next);
|
||||
expect(req.accountability).toEqual(expectedAccountability);
|
||||
expect(next).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Test for "1" / "0" instead of true / false
|
||||
next.mockClear();
|
||||
testUser.admin_access = '0';
|
||||
testUser.app_access = '1';
|
||||
expectedAccountability.admin = false;
|
||||
expectedAccountability.app = true;
|
||||
await handler(req, res, next);
|
||||
expect(req.accountability).toEqual(expectedAccountability);
|
||||
expect(next).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
67
api/src/middleware/extract-token.test.ts
Normal file
67
api/src/middleware/extract-token.test.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import extractToken from '../../src/middleware/extract-token';
|
||||
import '../../src/types/express.d.ts';
|
||||
|
||||
let mockRequest: Partial<Request & { token?: string }>;
|
||||
let mockResponse: Partial<Response>;
|
||||
const nextFunction: NextFunction = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
mockRequest = {};
|
||||
mockResponse = {};
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('Token from query', () => {
|
||||
mockRequest = {
|
||||
query: {
|
||||
access_token: 'test',
|
||||
},
|
||||
};
|
||||
|
||||
extractToken(mockRequest as Request, mockResponse as Response, nextFunction);
|
||||
expect(mockRequest.token).toBe('test');
|
||||
expect(nextFunction).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
test('Token from Authorization header (capitalized)', () => {
|
||||
mockRequest = {
|
||||
headers: {
|
||||
authorization: 'Bearer test',
|
||||
},
|
||||
};
|
||||
|
||||
extractToken(mockRequest as Request, mockResponse as Response, nextFunction);
|
||||
expect(mockRequest.token).toBe('test');
|
||||
expect(nextFunction).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
test('Token from Authorization header (lowercase)', () => {
|
||||
mockRequest = {
|
||||
headers: {
|
||||
authorization: 'bearer test',
|
||||
},
|
||||
};
|
||||
|
||||
extractToken(mockRequest as Request, mockResponse as Response, nextFunction);
|
||||
expect(mockRequest.token).toBe('test');
|
||||
expect(nextFunction).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
test('Ignore the token if authorization header is too many parts', () => {
|
||||
mockRequest = {
|
||||
headers: {
|
||||
authorization: 'bearer test what another one',
|
||||
},
|
||||
};
|
||||
|
||||
extractToken(mockRequest as Request, mockResponse as Response, nextFunction);
|
||||
expect(mockRequest.token).toBeNull();
|
||||
expect(nextFunction).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
test('Null if no token passed', () => {
|
||||
extractToken(mockRequest as Request, mockResponse as Response, nextFunction);
|
||||
expect(mockRequest.token).toBeNull();
|
||||
expect(nextFunction).toBeCalledTimes(1);
|
||||
});
|
||||
Reference in New Issue
Block a user