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:
Rijk van Zanten
2022-08-17 16:01:16 -04:00
committed by GitHub
parent 122f8cfed0
commit 19ddd89d8d
27 changed files with 20 additions and 20 deletions

View 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);
});

View 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);
});