Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/fix tests for node20 #147

Merged
merged 4 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions .babelrc

This file was deleted.

4 changes: 1 addition & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
FROM node:20
ARG ENVIRONMENT_NAME
ARG BUILD_NAME
ENV NODE_OPTIONS=--openssl-legacy-provider

RUN mkdir -p /app-build
ADD . /app-build
Expand All @@ -14,12 +13,11 @@ RUN yarn build:$BUILD_NAME
FROM node:20-alpine
ARG ENVIRONMENT_NAME
ARG BUILD_NAME
ENV NODE_OPTIONS=--openssl-legacy-provider

RUN mkdir -p /dist
RUN apk add yarn
RUN yarn global add sequelize-cli@6.2.0
RUN yarn add shelljs bull dotenv pg sequelize@6.6.5
RUN yarn add shelljs dotenv pg sequelize@6.6.5
ADD scripts/migrate-and-run.sh /
ADD package.json /
ADD . /
Expand Down
37 changes: 37 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module.exports = function(api) {
api.cache(true); // Caches the computed configuration

const presets = ['@babel/preset-env', '@babel/preset-flow'];
const plugins = [
'@babel/plugin-proposal-throw-expressions',
'@babel/plugin-proposal-class-properties',
'@babel/transform-runtime'
];

// Environment-specific configuration
const env = process.env.BABEL_ENV || process.env.NODE_ENV;
if (env !== 'test') {
plugins.push([
'module-resolver',
{
root: ['./src'],
alias: {
'@server': './server',
'@root': '',
'@utils': './server/utils',
'@middleware': './server/middleware',
'@services': './server/services',
'@daos': './server/daos',
'@database': './server/database',
'@gql': './server/gql',
'@config': './config'
}
}
]);
}

return {
presets,
plugins
};
};
1 change: 1 addition & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jest.doMock('ioredis', () =>
);

process.env.ENVIRONMENT_NAME = 'test';

beforeEach(() => {
process.env = { ...process.env, ...DB_ENV, ENVIRONMENT_NAME: 'test' };
});
Expand Down
63 changes: 24 additions & 39 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
"start:local": "nodemon",
"start:docker": "yarn build:docker && yarn start",
"local": "kill-port 9000 && export ENVIRONMENT_NAME=local && yarn build:local && yarn start",
"build:local": "export ENVIRONMENT_NAME=local NODE_OPTIONS=--openssl-legacy-provider && rm -rf dist && webpack --mode development --config webpack.dev.config.js",
"build:dev": "export ENVIRONMENT_NAME=development NODE_OPTIONS=--openssl-legacy-provider && rm -rf dist && webpack --mode development --config webpack.dev.config.js",
"build:qa": "export ENVIRONMENT_NAME=qa NODE_OPTIONS=--openssl-legacy-provider && rm -rf dist && webpack --mode development --config webpack.dev.config.js",
"build:prod": "export ENVIRONMENT_NAME=production NODE_OPTIONS=--openssl-legacy-provider && rm -rf dist && webpack --mode production --config webpack.prod.config.js",
"build:docker": "export ENVIRONMENT_NAME=docker NODE_OPTIONS=--openssl-legacy-provider && rm -rf dist && webpack --mode production --config webpack.prod.config.js",
"build:local": "export ENVIRONMENT_NAME=local && rm -rf dist && webpack --mode development --config webpack.dev.config.js",
"build:dev": "export ENVIRONMENT_NAME=development && rm -rf dist && webpack --mode development --config webpack.dev.config.js",
"build:qa": "export ENVIRONMENT_NAME=qa && rm -rf dist && webpack --mode development --config webpack.dev.config.js",
"build:prod": "export ENVIRONMENT_NAME=production && rm -rf dist && webpack --mode production --config webpack.prod.config.js",
"build:docker": "export ENVIRONMENT_NAME=docker && rm -rf dist && webpack --mode production --config webpack.prod.config.js",
"start": "node ./dist/main.js",
"clean": "rimraf dist",
"format": "prettier-standard './**/**/*.js'",
Expand All @@ -33,27 +33,17 @@
"prettify": "prettier --write",
"precommit": "lint:staged",
"test": "export ENVIRONMENT_NAME=test && npx jest --silent --forceExit --ci --coverage --testLocationInResults --json --outputFile=\"report.json\"",
"test:badges": "npm run test && jest-coverage-badges --output './badges'",
"postinstall": "link-module-alias",
"preinstall": "command -v link-module-alias && link-module-alias clean || true"
"test:badges": "npm run test && jest-coverage-badges --output './badges'"
},
"dependencies": {
"@apollo/server": "^4.10.4",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.11.6",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-optional-chaining": "^7.14.5",
"@babel/plugin-syntax-optional-chaining": "^7.8.3",
"@babel/preset-env": "^7.14.7",
"@babel/preset-flow": "^7.12.1",
"aws-sdk": "^2.949.0",
"axios": "^0.26.0",
"babel-eslint": "^10.1.0",
"bull": "^4.8.1",
"bufferutil": "^4.0.8",
"bull": "^4.14.0",
"cls-hooked": "^4.2.2",
"cls-rtracer": "^2.6.0",
"cors": "^2.8.5",
"crypto": "^1.0.1",
"deep-map-keys": "^2.0.1",
"dotenv": "^10.0.0",
"eslint-loader": "^4.0.2",
Expand All @@ -74,7 +64,6 @@
"loadash": "^1.0.0",
"lodash": "^4.17.21",
"map-keys-deep": "^0.0.2",
"md5": "^2.3.0",
"moment": "^2.29.1",
"multer": "^1.4.2",
"net": "^1.0.2",
Expand All @@ -95,30 +84,39 @@
"supertest": "^6.1.3",
"tedious": "^11.2.0",
"tls": "^0.0.1",
"webpack": "5.45.1",
"utf-8-validate": "^6.0.4",
"webpack": "^5.92.1",
"webpack-bundle-analyzer": "^4.4.2",
"webpack-cli": "4.7.2",
"webpack-dev-middleware": "5.0.0",
"webpack-hot-middleware": "2.25.0",
"webpack-cli": "^5.1.4",
"webpack-dev-middleware": "^7.2.1",
"webpack-hot-middleware": "^2.26.1",
"webpack-node-externals": "^3.0.0",
"whatwg-fetch": "^3.6.2",
"winston": "^3.3.3",
"ws": "^8.17.1",
"zlib": "^1.0.5"
},
"devDependencies": {
"@babel/node": "^7.6.3",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.24.7",
"@babel/node": "^7.24.7",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-optional-chaining": "^7.14.5",
"@babel/plugin-proposal-throw-expressions": "^7.12.1",
"@babel/plugin-syntax-optional-chaining": "^7.8.3",
"@babel/plugin-transform-modules-commonjs": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.11.5",
"@babel/polyfill": "^7.11.5",
"@babel/preset-env": "^7.24.7",
"@babel/preset-es2015": "^7.0.0-beta.53",
"@babel/preset-flow": "^7.24.7",
"@babel/preset-stage-0": "^7.8.3",
"@babel/preset-stage-2": "^7.8.3",
"@babel/register": "^7.6.2",
"@babel/runtime": "^7.6.3",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.3.0",
"babel-loader": "^8.1.0",
"babel-loader": "8.1.0",
"babel-plugin-module-resolver": "^5.0.2",
"eslint": "7.31.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-prettier-standard": "^4.0.1",
Expand All @@ -134,7 +132,6 @@
"jest-environment-node": "^26.3.0",
"jest-sonar": "^0.2.12",
"kill-port": "^1.6.0",
"link-module-alias": "^1.2.0",
"lint-staged": "^11.0.1",
"nodemon": "^2.0.4",
"npm-run-all": "^4.1.5",
Expand All @@ -156,18 +153,6 @@
"git add --force"
]
},
"_moduleAliasIgnoreWarning": true,
"_moduleAliases": {
"@root": "./server",
"@server": "./server",
"@services": "./server/services",
"@utils": "./server/utils",
"@database": "./server/database",
"@daos": "./server/daos",
"@middleware": "./server/middleware",
"@gql": "./server/gql",
"@config": "config"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
Expand Down
7 changes: 4 additions & 3 deletions seeders/08_users.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ module.exports = {
up: queryInterface => {
const faker = require('faker');
const range = require('lodash/range');
const md5 = require('md5');

const arr = range(1, 100).map((value, index) => {
const createdBefore = parseInt(Math.random() * 1000);
const crypto = require('crypto');
const salt = crypto.randomBytes(16).toString('hex');
const hashedPassword = `${salt}:${crypto.scryptSync('wednesdaySolutions', salt, 64).toString('hex')}`;
return {
first_name: faker.name.firstName(),
last_name: faker.name.lastName(),
email: `mac+${index}@wednesday.is`,
password: md5('wednesdaySolutions'),
password: hashedPassword,
created_at: faker.date.recent(createdBefore)
};
});
Expand Down
15 changes: 9 additions & 6 deletions server/daos/tests/auth.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import md5 from 'md5';
import { getUserByEmailPassword, createUserBySignup } from '../auth';
import db from '@database/models';
import { checkPassword, createPassword } from '@server/utils/passwordUtils';

describe('getUserBySign tests', () => {
const email = 'rohansaroha2@wednesday.is';
const password = 1234;
const md5Password = md5(password);
const user = { email, password: md5Password };
const password = '1234';
const hashedPassword = createPassword(password);
const user = { email, password: hashedPassword };
let mock;

beforeEach(() => {
Expand All @@ -25,9 +25,12 @@
const firstName = 'abc';
const lastName = 'x';
const email = 'abc@wednesday.is';
const password = 1234;
const password = '1234';
const mock = jest.spyOn(db.users, 'create');
await createUserBySignup(firstName, lastName, email, password);
expect(mock).toHaveBeenCalledWith({ firstName, lastName, email, password: md5(password) });
expect(mock).toHaveBeenCalledWith({ firstName, lastName, email, password: expect.any(String) });
expect(mock.mock.calls[0][0].password.length).toEqual(161);
const hashedPassword = mock.mock.calls[0][0].password;
expect(checkPassword(password, hashedPassword));

Check failure on line 34 in server/daos/tests/auth.test.js

View check run for this annotation

SonarQube WS / node-express-graphql-template Sonarqube Results

server/daos/tests/auth.test.js#L34

Complete this assertion; 'expect' doesn't assert anything by itself.
});
});
3 changes: 2 additions & 1 deletion server/gql/auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export const handleSignUp = async (parent, args, context, resolveInfo) => {
delete dataValues.password;
return { ...dataValues, token };
} catch (err) {
logger().error(err);
logger().info('error:::', err);
logger().info(err);
throw err;
}
};
Expand Down
2 changes: 1 addition & 1 deletion server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import 'whatwg-fetch';
import dotenv from 'dotenv';
import { createServer } from 'http';
import axios from 'axios';
import { newCircuitBreaker } from '@services/circuitbreaker';
import { corsOptionsDelegate, apolloServerContextResolver } from '@middleware/gqlAuth';
import { newCircuitBreaker } from '@services/circuitbreaker';
import rTracer from 'cls-rtracer';
import bodyParser from 'body-parser';
import { connect } from '@database';
Expand Down
14 changes: 11 additions & 3 deletions server/utils/passwordUtils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import md5 from 'md5';
import crypto from 'crypto';

export const createPassword = password => md5(password);
export const createPassword = password => {
const salt = crypto.randomBytes(16).toString('hex'); // Generate a random salt
const hashedPassword = crypto.scryptSync(password, salt, 64).toString('hex'); // Generate a hash
return `${salt}:${hashedPassword}`;
};

export const checkPassword = (password, hash) => md5(password) === hash;
export const checkPassword = (passwordToVerify, storedHash) => {
const [salt, key] = storedHash.split(':');
const derivedKey = crypto.scryptSync(passwordToVerify, salt, 64).toString('hex');
return key === derivedKey;
};
4 changes: 2 additions & 2 deletions server/utils/testUtils/mockData.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import range from 'lodash/range';
import faker from 'faker';
import md5 from 'md5';
import { createPassword } from '../passwordUtils';
const createdBefore = parseInt(Math.random() * 1000);

export const addressesTable = range(1, 10).map((_, index) => ({
Expand All @@ -18,7 +18,7 @@ export const usersTable = range(1, 10).map((_, index) => ({
firstName: faker.name.firstName(),
lastName: faker.name.lastName(),
email: faker.internet.email(),
password: md5(faker.internet.password()),
password: createPassword(faker.internet.password()),
created_at: faker.date.recent(createdBefore)
}));

Expand Down
2 changes: 1 addition & 1 deletion server/utils/testUtils/testApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { MutationRoot } from '@gql/mutations';
import { client } from '@database';
import { SubscriptionRoot } from '@gql/subscriptions';
import { ApolloServer } from '@apollo/server';
import { logger } from '..';
import { logger } from '../index';

const connect = async () => {
await client.authenticate();
Expand Down
25 changes: 13 additions & 12 deletions server/utils/tests/passwordUtils.test.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { createPassword, checkPassword } from '../passwordUtils';
import md5 from 'md5';
import crypto from 'crypto';

describe('createPassword tests', () => {
it('should ensure that it create correct password', () => {
const password = 1234;
const md5Password = md5(password);
expect(createPassword(password)).toEqual(md5Password);
const password = '1234';
const salt = crypto.randomBytes(16).toString('hex');
const hashedPassword = crypto.scryptSync(password, salt, 64).toString('hex');
expect(createPassword(password).length).toEqual(`${salt}:${hashedPassword}`.length);
});
});

describe('check password tests', () => {
const password = 1234;
const md5Password = md5(1234);
const password = '1234';
const salt = crypto.randomBytes(16).toString('hex');
const hashedPassword = `${salt}:${crypto.scryptSync(password, salt, 64).toString('hex')}`;

it('should ensure it returns true when password is correct', () => {
expect(checkPassword(password, md5Password)).toBeTruthy();
it('should ensure it returns true when password is correct', async () => {
expect(await checkPassword(password, hashedPassword)).toBeTruthy();
});
it('should ensure it returns false when password is incorrect', () => {
expect(checkPassword(123, md5Password)).toBeFalsy();
expect(checkPassword('123', md5Password)).toBeFalsy();
expect(checkPassword('', md5Password)).toBeFalsy();
it('should ensure it returns false when password is incorrect', async () => {
expect(await checkPassword('123', hashedPassword)).toBeFalsy();
expect(await checkPassword('', hashedPassword)).toBeFalsy();
});
});
Loading
Loading