mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-06-05 21:04:28 +08:00
feat(api): setup jest in new api (#49709)
* feat(api): setup jest in new api * feat: sample tests
This commit is contained in:
parent
32a2838714
commit
7aeb4ab76b
18
api/index.test.ts
Normal file
18
api/index.test.ts
Normal 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
11
api/jest.config.ts
Normal 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;
|
||||
@ -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"
|
||||
}
|
||||
|
||||
@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@ -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",
|
||||
|
||||
734
pnpm-lock.yaml
734
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -69,3 +69,9 @@ PEER=stuff
|
||||
DEBUG=true
|
||||
LOCAL_MOCK_AUTH=true
|
||||
CODESEE=false
|
||||
|
||||
# ---------------------
|
||||
# New API
|
||||
# ---------------------
|
||||
NODE_ENV=development
|
||||
PORT=3000
|
||||
|
||||
Loading…
Reference in New Issue
Block a user