agmission/Development/server/tests/integration/api_key.integration.test.js
2026-04-29 09:40:51 -04:00

190 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
/**
* Integration tests api_key controller (controllers/api_key.js)
*
* Note: bcrypt operations are slow (10 rounds) jest timeout is raised to
* 30 seconds per test.
*/
jest.setTimeout(30000);
const { connectDB, disconnectDB, clearCollection } = require('./jest.setup');
const { mockApplicator, mockReq, mockRes, newId } = require('./mock_data');
let ApiKey, Customer;
beforeAll(async () => {
await connectDB();
ApiKey = require('../../model/api_key');
Customer = require('../../model/customer');
});
afterAll(async () => {
await disconnectDB();
});
const apiKeyCtl = require('../../controllers/api_key');
describe('api_key controller data methods', () => {
let applicator;
beforeAll(async () => {
await clearCollection(ApiKey);
applicator = await Customer.create(mockApplicator());
});
afterAll(async () => {
await clearCollection(ApiKey);
await Customer.deleteMany({ _id: applicator._id });
});
const makeReq = (extra = {}) =>
mockReq({ uid: applicator._id, puid: applicator._id, ut: '1', ...extra });
// -------------------------------------------------------------------------
describe('createKey', () => {
it('creates an API key and returns the raw key once', async () => {
const req = makeReq({ body: { label: 'Key 1' } });
const res = mockRes();
await apiKeyCtl.createKey(req, res);
expect(res.json).toHaveBeenCalled();
expect(res._data.key).toBeDefined();
expect(typeof res._data.key).toBe('string');
expect(res._data.key.length).toBeGreaterThan(10);
});
it('throws when owner already has 10 keys', async () => {
await clearCollection(ApiKey);
// Create 10 keys first
const docs = [];
for (let i = 0; i < 10; i++) {
docs.push({
owner: applicator._id,
label: `Key ${i}`,
keyHash: `fakehash${i}`,
prefix: `pfx${i}`,
});
}
await ApiKey.insertMany(docs);
const req = makeReq({ body: { label: 'Extra Key' } });
const res = mockRes();
await expect(apiKeyCtl.createKey(req, res)).rejects.toThrow();
});
});
// -------------------------------------------------------------------------
describe('listKeys', () => {
beforeAll(async () => {
await clearCollection(ApiKey);
const req = makeReq({ body: { label: 'Listed Key' } });
const res = mockRes();
await apiKeyCtl.createKey(req, res);
});
it('returns list of API keys without hash field', async () => {
const req = makeReq();
const res = mockRes();
await apiKeyCtl.listKeys(req, res);
expect(res.json).toHaveBeenCalled();
expect(Array.isArray(res._data)).toBe(true);
expect(res._data.length).toBeGreaterThan(0);
expect(res._data[0].hash).toBeUndefined();
});
});
// -------------------------------------------------------------------------
describe('revokeKey', () => {
let keyId;
beforeAll(async () => {
await clearCollection(ApiKey);
const req = makeReq({ body: { label: 'Key to Revoke' } });
const res = mockRes();
await apiKeyCtl.createKey(req, res);
const listReq = makeReq();
const listRes = mockRes();
await apiKeyCtl.listKeys(listReq, listRes);
keyId = String(listRes._data[0]._id);
});
it('revokes an active API key', async () => {
const req = makeReq({ params: { keyId }, ut: '0' });
const res = mockRes();
await apiKeyCtl.revokeKey(req, res);
expect(res.end).toHaveBeenCalled();
const doc = await ApiKey.findById(keyId);
expect(doc.active).toBe(false);
});
it('returns 404 when key not found', async () => {
const req = makeReq({ params: { keyId: String(newId()) }, ut: '0' });
const res = mockRes();
await apiKeyCtl.revokeKey(req, res);
expect(res.statusCode).toBe(404);
});
});
// -------------------------------------------------------------------------
describe('regenerateKey', () => {
let keyId;
beforeAll(async () => {
await clearCollection(ApiKey);
const req = makeReq({ body: { label: 'Key to Regen' } });
const res = mockRes();
await apiKeyCtl.createKey(req, res);
const listReq = makeReq();
const listRes = mockRes();
await apiKeyCtl.listKeys(listReq, listRes);
keyId = String(listRes._data[0]._id);
});
it('regenerates key and returns new raw key', async () => {
const req = makeReq({ params: { keyId } });
const res = mockRes();
await apiKeyCtl.regenerateKey(req, res);
expect(res.json).toHaveBeenCalled();
expect(res._data.key).toBeDefined();
expect(typeof res._data.key).toBe('string');
});
});
// -------------------------------------------------------------------------
describe('deleteKey', () => {
let keyId;
beforeAll(async () => {
await clearCollection(ApiKey);
const req = makeReq({ body: { label: 'Key to Delete' } });
const res = mockRes();
await apiKeyCtl.createKey(req, res);
const listReq = makeReq();
const listRes = mockRes();
await apiKeyCtl.listKeys(listReq, listRes);
keyId = String(listRes._data[0]._id);
});
it('permanently deletes an API key', async () => {
const req = makeReq({ params: { keyId } });
const res = mockRes();
await apiKeyCtl.deleteKey(req, res);
expect(res.end).toHaveBeenCalled();
const found = await ApiKey.findById(keyId);
expect(found).toBeNull();
});
});
});