feat(api): setup jest in new api (#49709)

* feat(api): setup jest in new api

* feat: sample tests
This commit is contained in:
Tom 2023-03-16 10:03:40 -05:00 committed by GitHub
parent 32a2838714
commit 7aeb4ab76b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 819 additions and 50 deletions

18
api/index.test.ts Normal file
View File

@ -0,0 +1,18 @@
import request, { Response } from 'supertest';
import { API_LOCATION as api } from './utils/env';
describe('GET /', () => {
let res: undefined | Response;
beforeAll(async () => {
res = await request(api).get('/');
});
test('have a 200 response', () => {
expect(res?.statusCode).toBe(200);
});
test('return { "hello": "world"}', () => {
expect(res?.body).toEqual({ hello: 'world' });
});
});

11
api/jest.config.ts Normal file
View File

@ -0,0 +1,11 @@
import type { Config } from 'jest';
const config: Config = {
verbose: true,
testRegex: '\\.test\\.ts$',
transform: {
'^.+\\.ts$': 'ts-jest'
}
};
export default config;

View File

@ -8,14 +8,22 @@
"@fastify/middie": "8.1",
"@fastify/session": "^10.1.1",
"@prisma/client": "4.10.1",
"connect-mongo": "4.6.0",
"@sinclair/typebox": "0.25.24",
"connect-mongo": "4.6.0",
"fastify": "4.14.1",
"fastify-auth0-verify": "^1.0.0",
"fastify-plugin": "^4.3.0",
"nodemon": "2.0.21"
},
"description": "The freeCodeCamp.org open-source codebase and curriculum",
"devDependencies": {
"@fastify/type-provider-typebox": "2.4.0",
"@types/supertest": "2.0.12",
"jest": "29.5.0",
"prisma": "4.10.1",
"supertest": "6.3.3",
"ts-jest": "29.0.5"
},
"engines": {
"node": ">=18",
"npm": ">=8"
@ -40,14 +48,10 @@
"scripts": {
"build": "tsc",
"develop": "nodemon index.ts",
"start": "NODE_ENV=production node index.js",
"start": "NODE_ENV=production node index.ts",
"test": "node --test -r ts-node/register **/*.test.ts",
"prisma": "MONGOHQ_URL=mongodb://localhost:27017/freecodecamp?directConnection=true prisma",
"postinstall": "prisma generate"
},
"version": "0.0.1",
"devDependencies": {
"prisma": "4.10.1",
"@fastify/type-provider-typebox": "2.4.0"
}
"version": "0.0.1"
}

View File

@ -22,9 +22,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import assert from 'node:assert';
// eslint-disable-next-line import/no-unresolved
import { describe, it } from 'node:test';
import Fastify from 'fastify';
import jwtAuthz from './fastify-jwt-authz';
@ -34,13 +31,14 @@ interface ErrorResponse {
message: string;
}
describe('fastify-jwt-authz', { only: true }, () => {
it('should decorate request instance with jwtAuthz method', async () => {
describe('fastify-jwt-authz', () => {
test('should decorate request instance with jwtAuthz method', async () => {
const fastify = Fastify();
await fastify.register(jwtAuthz);
fastify.get('/test', function (request) {
assert(request.jwtAuthz);
fastify.get('/', req => {
expect(req).toHaveProperty('jwtAuthz');
expect(req.jwtAuthz).toBeInstanceOf(Function);
return { foo: 'bar' };
});
@ -50,13 +48,13 @@ describe('fastify-jwt-authz', { only: true }, () => {
const res = await fastify.inject({
method: 'GET',
url: '/test'
url: '/'
});
assert.strictEqual(res.statusCode, 200);
expect(res.statusCode).toEqual(200);
});
it('should throw an error "Scopes cannot be empty" with an empty scopes parameter', async () => {
test('should throw an error "Scopes cannot be empty" with an empty scopes parameter', async () => {
const fastify = Fastify();
await fastify.register(jwtAuthz);
@ -82,11 +80,11 @@ describe('fastify-jwt-authz', { only: true }, () => {
});
const resData: ErrorResponse = res.json();
assert.strictEqual(res.statusCode, 500);
assert.strictEqual(resData.message, 'Scopes cannot be empty');
expect(res.statusCode).toEqual(500);
expect(resData.message).toEqual('Scopes cannot be empty');
});
it('should throw an error "request.user does not exist" non existing request.user', async () => {
test('should throw an error "request.user does not exist" non existing request.user', async () => {
const fastify = Fastify();
await fastify.register(jwtAuthz);
@ -112,11 +110,11 @@ describe('fastify-jwt-authz', { only: true }, () => {
});
const resData: ErrorResponse = res.json();
assert.strictEqual(res.statusCode, 500);
assert.strictEqual(resData.message, 'request.user does not exist');
expect(res.statusCode).toEqual(500);
expect(resData.message).toEqual('request.user does not exist');
});
it('should throw an error "request.user.scope must be a string"', async () => {
test('should throw an error "request.user.scope must be a string"', async () => {
const fastify = Fastify();
await fastify.register(jwtAuthz);
@ -146,11 +144,11 @@ describe('fastify-jwt-authz', { only: true }, () => {
});
const resData: ErrorResponse = res.json();
assert.strictEqual(res.statusCode, 500);
assert.strictEqual(resData.message, 'request.user.scope must be a string');
expect(res.statusCode).toEqual(500);
expect(resData.message).toEqual('request.user.scope must be a string');
});
it('should throw an error "Insufficient scope"', async () => {
test('should throw an error "Insufficient scope"', async () => {
const fastify = Fastify();
await fastify.register(jwtAuthz);
@ -180,11 +178,11 @@ describe('fastify-jwt-authz', { only: true }, () => {
});
const resData: ErrorResponse = res.json();
assert.strictEqual(res.statusCode, 500);
assert.strictEqual(resData.message, 'Insufficient scope');
expect(res.statusCode).toEqual(500);
expect(resData.message).toEqual('Insufficient scope');
});
it('should verify user scope', async () => {
test('should verify user scope', async () => {
const fastify = Fastify();
await fastify.register(jwtAuthz);
@ -215,11 +213,11 @@ describe('fastify-jwt-authz', { only: true }, () => {
const resData: { foo: string } = res.json();
assert.strictEqual(res.statusCode, 200);
assert.strictEqual(resData.foo, 'bar');
expect(res.statusCode).toEqual(200);
expect(resData.foo).toEqual('bar');
});
it('should throw an error when there is no callback', async () => {
test('should throw an error when there is no callback', async () => {
const fastify = Fastify();
await fastify.register(jwtAuthz);
@ -251,11 +249,11 @@ describe('fastify-jwt-authz', { only: true }, () => {
});
const resData: ErrorResponse = res.json();
assert.strictEqual(res.statusCode, 500);
assert.strictEqual(resData.message, 'request.user.scope must be a string');
expect(res.statusCode).toEqual(500);
expect(resData.message).toEqual('request.user.scope must be a string');
});
it('should verify user scope when there is no callback', async () => {
test('should verify user scope when there is no callback', async () => {
const fastify = Fastify();
await fastify.register(jwtAuthz);
@ -286,7 +284,7 @@ describe('fastify-jwt-authz', { only: true }, () => {
});
const resData: { foo: string } = res.json();
assert.strictEqual(res.statusCode, 200);
assert.strictEqual(resData.foo, 'bar');
expect(res.statusCode).toEqual(200);
expect(resData.foo).toEqual('bar');
});
});

View File

@ -21,6 +21,7 @@ if (error) {
assert.ok(process.env.NODE_ENV);
assert.ok(process.env.AUTH0_DOMAIN);
assert.ok(process.env.AUTH0_AUDIENCE);
assert.ok(process.env.API_LOCATION);
assert.ok(process.env.SESSION_SECRET);
if (process.env.NODE_ENV !== 'development') {
@ -35,4 +36,5 @@ export const NODE_ENV = process.env.NODE_ENV;
export const AUTH0_DOMAIN = process.env.AUTH0_DOMAIN;
export const AUTH0_AUDIENCE = process.env.AUTH0_AUDIENCE;
export const PORT = process.env.PORT || '3000';
export const API_LOCATION = process.env.API_LOCATION;
export const SESSION_SECRET = process.env.SESSION_SECRET;

View File

@ -1,18 +1,15 @@
import assert from 'node:assert';
// eslint-disable-next-line import/no-unresolved
import { describe, it } from 'node:test';
import { base64URLEncode, challenge, verifier } from '.';
describe('utils', { only: true }, () => {
it('base64URLEncode', () => {
assert.strictEqual(base64URLEncode(Buffer.from('test')), 'dGVzdA');
describe('utils', () => {
test('base64URLEncode', () => {
expect(base64URLEncode(Buffer.from('test'))).toEqual('dGVzdA');
});
it('verifier', () => {
const v = verifier;
assert.strictEqual(v.length, 43);
test('verifier', () => {
expect(verifier).toHaveLength(43);
});
it('challenge', () => {
const c = challenge;
assert.strictEqual(c.length, 43);
test('challenge', () => {
expect(challenge).toHaveLength(43);
});
});

View File

@ -86,6 +86,7 @@
"test": "run-s create:* build:curriculum build-workers test:*",
"test:source": "jest",
"test:curriculum": "cd ./curriculum && pnpm test",
"test-api": "cd api && jest",
"test-curriculum-full-output": "cd ./curriculum && pnpm run test:full-output",
"test-client": "jest client",
"test-config": "jest config",

File diff suppressed because it is too large Load Diff

View File

@ -69,3 +69,9 @@ PEER=stuff
DEBUG=true
LOCAL_MOCK_AUTH=true
CODESEE=false
# ---------------------
# New API
# ---------------------
NODE_ENV=development
PORT=3000