-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
329 additions
and
0 deletions.
There are no files selected for viewing
138 changes: 138 additions & 0 deletions
138
packages/tom-server/src/active-contacts-api/tests/controllers.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/* eslint-disable @typescript-eslint/consistent-type-assertions */ | ||
import bodyParser from 'body-parser' | ||
import express, { type NextFunction, type Response } from 'express' | ||
import supertest from 'supertest' | ||
import type { AuthRequest, Config, IdentityServerDb } from '../../types' | ||
import router, { PATH } from '../routes' | ||
import type { TwakeLogger } from '@twake/logger' | ||
|
||
const app = express() | ||
|
||
const dbMock = { | ||
get: jest.fn(), | ||
insert: jest.fn(), | ||
update: jest.fn(), | ||
deleteEqual: jest.fn(), | ||
getCount: jest.fn() | ||
} | ||
|
||
const loggerMock = { | ||
info: jest.fn(), | ||
error: jest.fn(), | ||
warn: jest.fn() | ||
} | ||
|
||
const authenticatorMock = jest | ||
.fn() | ||
.mockImplementation((_req, _res, callbackMethod) => { | ||
callbackMethod('test', 'test') | ||
}) | ||
|
||
jest.mock('../middlewares/index.ts', () => { | ||
const passiveMiddlewareMock = ( | ||
_req: AuthRequest, | ||
_res: Response, | ||
next: NextFunction | ||
): void => { | ||
next() | ||
} | ||
|
||
return function () { | ||
return { | ||
checkCreationRequirements: passiveMiddlewareMock | ||
} | ||
} | ||
}) | ||
|
||
app.use(bodyParser.json()) | ||
app.use(bodyParser.urlencoded({ extended: true })) | ||
app.use( | ||
router( | ||
dbMock as unknown as IdentityServerDb, | ||
{} as Config, | ||
authenticatorMock, | ||
loggerMock as unknown as TwakeLogger | ||
) | ||
) | ||
|
||
describe('the active contacts API controller', () => { | ||
describe('active contacts fetch', () => { | ||
it('should try to fetch the saved active contacts', async () => { | ||
dbMock.get.mockResolvedValue([ | ||
{ | ||
userId: 'test', | ||
contacts: 'test' | ||
} | ||
]) | ||
|
||
const response = await supertest(app).get(PATH).send() | ||
|
||
expect(response.status).toBe(200) | ||
expect(response.body).toEqual({ contacts: 'test' }) | ||
}) | ||
|
||
it('should return an error if no active contacts are found', async () => { | ||
dbMock.get.mockResolvedValue([]) | ||
|
||
const response = await supertest(app).get(PATH).send() | ||
|
||
expect(response.status).toBe(404) | ||
expect(response.body).toEqual({ message: 'No active contacts found' }) | ||
}) | ||
|
||
it('should return an error if an error occurs while fetching active contacts', async () => { | ||
dbMock.get.mockRejectedValue(new Error('test')) | ||
|
||
const response = await supertest(app).get(PATH).send() | ||
|
||
expect(response.status).toBe(500) | ||
}) | ||
}) | ||
|
||
describe('active contacts save', () => { | ||
it('should try to save active contacts', async () => { | ||
dbMock.insert.mockResolvedValue([]) | ||
|
||
const response = await supertest(app) | ||
.post(PATH) | ||
.send({ contacts: 'test' }) | ||
|
||
expect(response.status).toBe(201) | ||
}) | ||
|
||
it('should return an error if an error occurs while saving active contacts', async () => { | ||
dbMock.insert.mockRejectedValue(new Error('test')) | ||
|
||
const response = await supertest(app) | ||
.post(PATH) | ||
.send({ contacts: 'test' }) | ||
|
||
expect(response.status).toBe(500) | ||
}) | ||
|
||
it('should return an error if the parameters are missing', async () => { | ||
const response = await supertest(app).post(PATH).send({}) | ||
|
||
expect(response.status).toBe(400) | ||
expect(response.body).toEqual({ message: 'Bad Request' }) | ||
}) | ||
}) | ||
|
||
describe('active contacts delete', () => { | ||
it('should try to delete active contacts', async () => { | ||
dbMock.deleteEqual.mockResolvedValue([]) | ||
|
||
const response = await supertest(app).delete(PATH).send() | ||
|
||
expect(response.status).toBe(200) | ||
}) | ||
|
||
it('should return an error if an error occurs while deleting active contacts', async () => { | ||
dbMock.deleteEqual.mockRejectedValue(new Error('test')) | ||
|
||
const response = await supertest(app).delete(PATH).send() | ||
|
||
expect(response.status).toBe(500) | ||
}) | ||
}) | ||
}) |
52 changes: 52 additions & 0 deletions
52
packages/tom-server/src/active-contacts-api/tests/middlewares.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import type { AuthRequest } from '../../types' | ||
import type { Response, NextFunction } from 'express' | ||
import ActiveContactsMiddleware from '../middlewares' | ||
|
||
describe('The active contacts API middleware', () => { | ||
let mockRequest: Partial<AuthRequest> | ||
let mockResponse: Partial<Response> | ||
const nextFunction: NextFunction = jest.fn() | ||
|
||
const activeContactsMiddleware = new ActiveContactsMiddleware() | ||
|
||
beforeEach(() => { | ||
mockRequest = { | ||
body: {}, | ||
query: {}, | ||
userId: 'test' | ||
} | ||
mockResponse = { | ||
json: jest.fn(), | ||
status: jest.fn().mockReturnThis() | ||
} | ||
}) | ||
|
||
describe('the checkCreationRequirements middleware', () => { | ||
it('should return a 400 error if data is missing', async () => { | ||
mockRequest.body = {} | ||
|
||
activeContactsMiddleware.checkCreationRequirements( | ||
mockRequest as AuthRequest, | ||
mockResponse as Response, | ||
nextFunction | ||
) | ||
|
||
expect(mockResponse.status).toHaveBeenCalledWith(400) | ||
expect(mockResponse.json).toHaveBeenCalledWith({ | ||
message: 'Bad Request' | ||
}) | ||
}) | ||
|
||
it('should call the next handler if the requirements are met', async () => { | ||
mockRequest.body = { contacts: 'test' } | ||
|
||
activeContactsMiddleware.checkCreationRequirements( | ||
mockRequest as AuthRequest, | ||
mockResponse as Response, | ||
nextFunction | ||
) | ||
|
||
expect(nextFunction).toHaveBeenCalledWith() | ||
}) | ||
}) | ||
}) |
139 changes: 139 additions & 0 deletions
139
packages/tom-server/src/active-contacts-api/tests/routes.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import express, { type Response, type NextFunction } from 'express' | ||
import bodyParser from 'body-parser' | ||
import type { AuthRequest, Config } from '../../types' | ||
import IdServer from '../../identity-server' | ||
import type { ConfigDescription } from '@twake/config-parser' | ||
import type { TwakeLogger } from '@twake/logger' | ||
import { IdentityServerDb, type MatrixDB } from '@twake/matrix-identity-server' | ||
import router, { PATH } from '../routes' | ||
import errorMiddleware from '../../utils/middlewares/error.middleware' | ||
import JEST_PROCESS_ROOT_PATH from '../../../jest.globals' | ||
import fs from 'fs' | ||
import path from 'path' | ||
import supertest from 'supertest' | ||
|
||
const mockLogger: Partial<TwakeLogger> = { | ||
debug: jest.fn(), | ||
error: jest.fn(), | ||
warn: jest.fn(), | ||
close: jest.fn() | ||
} | ||
|
||
jest | ||
.spyOn(IdentityServerDb.default.prototype, 'get') | ||
.mockResolvedValue([{ data: '"test"' }]) | ||
|
||
const idServer = new IdServer( | ||
{ | ||
get: jest.fn() | ||
} as unknown as MatrixDB, | ||
{} as unknown as Config, | ||
{ | ||
database_engine: 'sqlite', | ||
database_host: 'test.db', | ||
rate_limiting_window: 10000, | ||
rate_limiting_nb_requests: 100, | ||
template_dir: './templates', | ||
userdb_host: './tokens.db' | ||
} as unknown as ConfigDescription, | ||
mockLogger as TwakeLogger | ||
) | ||
|
||
const app = express() | ||
const middlewareSpy = jest.fn().mockImplementation((_req, _res, next) => { | ||
next() | ||
}) | ||
|
||
jest.mock('../middlewares', () => { | ||
return function () { | ||
return { | ||
checkCreationRequirements: middlewareSpy | ||
} | ||
} | ||
}) | ||
|
||
jest.mock('../controllers', () => { | ||
const passiveController = ( | ||
_req: AuthRequest, | ||
res: Response, | ||
_next: NextFunction | ||
): void => { | ||
res.status(200).json({ message: 'test' }) | ||
} | ||
|
||
return function () { | ||
return { | ||
get: passiveController, | ||
save: passiveController, | ||
delete: passiveController | ||
} | ||
} | ||
}) | ||
|
||
app.use(bodyParser.json()) | ||
app.use(bodyParser.urlencoded({ extended: true })) | ||
|
||
describe('The active contacts API router', () => { | ||
beforeAll((done) => { | ||
idServer.ready | ||
.then(() => { | ||
app.use( | ||
router( | ||
idServer.db, | ||
idServer.conf, | ||
idServer.authenticate, | ||
idServer.logger | ||
) | ||
) | ||
|
||
app.use(errorMiddleware(idServer.logger)) | ||
done() | ||
}) | ||
.catch((e) => { | ||
done(e) | ||
}) | ||
}) | ||
|
||
afterAll(() => { | ||
idServer.cleanJobs() | ||
|
||
const pathFilesToDelete = [ | ||
path.join(JEST_PROCESS_ROOT_PATH, 'test.db'), | ||
path.join(JEST_PROCESS_ROOT_PATH, 'tokens.db') | ||
] | ||
|
||
pathFilesToDelete.forEach((path) => { | ||
if (fs.existsSync(path)) fs.unlinkSync(path) | ||
}) | ||
}) | ||
|
||
it('should reject if rate limit is exceeded', async () => { | ||
let response | ||
|
||
for (let i = 0; i < 101; i++) { | ||
response = await supertest(app).get(PATH).set('Authorization', 'Bearer test') | ||
} | ||
|
||
expect((response as unknown as Response).status).toEqual(429) | ||
await new Promise((resolve) => setTimeout(resolve, 11000)) | ||
}) | ||
|
||
it('should not call the validation middleware if the Bearer token is not set', async () => { | ||
const response = await supertest(app).get(PATH) | ||
|
||
expect(response.status).toEqual(401) | ||
expect(middlewareSpy).not.toHaveBeenCalled() | ||
}) | ||
|
||
it('should call the validation middleware if the Bearer token is set', async () => { | ||
await supertest(app).get(PATH).set('Authorization', 'Bearer test') | ||
|
||
expect(middlewareSpy).toHaveBeenCalled() | ||
}) | ||
|
||
it('should call the validation middleware if the access_token is set in the query', async () => { | ||
await supertest(app).get(PATH).query({ access_token: 'test' }) | ||
|
||
expect(middlewareSpy).toHaveBeenCalled() | ||
}) | ||
}) |
Empty file.