From 3d349b2121876a969ed3a674042c5a34d43b4743 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 27 Dec 2021 15:57:04 +0100 Subject: [PATCH 01/18] feat: Test Create User Mutation --- backend/jest.config.js | 2 ++ backend/package.json | 4 ++- .../src/graphql/resolver/UserResolver.test.ts | 30 +++++++++++++++++ backend/tsconfig.json | 4 ++- database/package.json | 3 ++ database/src/config/index.ts | 2 +- database/src/helpers.ts | 33 +++++++++++++++++++ database/src/index.ts | 26 ++------------- database/tsconfig.json | 4 ++- 9 files changed, 81 insertions(+), 27 deletions(-) create mode 100644 backend/src/graphql/resolver/UserResolver.test.ts create mode 100644 database/src/helpers.ts diff --git a/backend/jest.config.js b/backend/jest.config.js index 3cee980c5..18cf4c2f1 100644 --- a/backend/jest.config.js +++ b/backend/jest.config.js @@ -6,5 +6,7 @@ module.exports = { collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**'], moduleNameMapper: { '@entity/(.*)': '/../database/entity/$1', + '@dbTools/(.*)': '/../database/src/$1', + '@migrations/(.*)': '/../database/migrations/$1', }, } diff --git a/backend/package.json b/backend/package.json index e573a2704..9dcb8ec9a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -59,6 +59,8 @@ "typescript": "^4.3.4" }, "_moduleAliases": { - "@entity": "../database/build/entity" + "@entity": "../database/build/entity", + "@migrations": "../database/migrations", + "@dbTools": "../database/src" } } diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts new file mode 100644 index 000000000..bd653b6df --- /dev/null +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -0,0 +1,30 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ + +import { createTestClient } from 'apollo-server-testing' +import createServer from '../../server/createServer' +import { resetDB, initialize } from '@dbTools/helpers' + +let mutate: any +let con: any + +beforeAll(async () => { + const server = await createServer({}) + con = server.con + mutate = createTestClient(server.apollo).mutate + await initialize() + await resetDB() +}) + +describe('UserResolver', () => { + describe('createUser', () => { + it('works', () => { + expect(true).toBeTruthy() + }) + }) +}) + +afterAll(async () => { + await resetDB(true) + await con.close() +}) diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 73e00a1a0..9d010b198 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -47,7 +47,9 @@ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - "@entity/*": ["../database/entity/*"] + "@entity/*": ["../database/entity/*"], + "@dbTools/*": ["../database/src/*"], + "@migrations/*": ["../database/migrations/*"] }, // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ diff --git a/database/package.json b/database/package.json index 7ff5c60d3..6a061607a 100644 --- a/database/package.json +++ b/database/package.json @@ -45,5 +45,8 @@ "ts-mysql-migrate": "^1.0.2", "typeorm": "^0.2.38", "typeorm-seeding": "^1.6.1" + }, + "_moduleAliases": { + "@migrations": "./migrations" } } diff --git a/database/src/config/index.ts b/database/src/config/index.ts index 908d40311..86f96b9b6 100644 --- a/database/src/config/index.ts +++ b/database/src/config/index.ts @@ -13,7 +13,7 @@ const database = { const migrations = { MIGRATIONS_TABLE: process.env.MIGRATIONS_TABLE || 'migrations', - MIGRATIONS_DIRECTORY: process.env.MIGRATIONS_DIRECTORY || './migrations/', + MIGRATIONS_DIRECTORY: process.env.MIGRATIONS_DIRECTORY || '@migrations/', } const CONFIG = { ...database, ...migrations } diff --git a/database/src/helpers.ts b/database/src/helpers.ts new file mode 100644 index 000000000..1ef8b5d1f --- /dev/null +++ b/database/src/helpers.ts @@ -0,0 +1,33 @@ +import CONFIG from './config' +import { createPool, PoolConfig } from 'mysql' +import { Migration } from 'ts-mysql-migrate' + +const poolConfig: PoolConfig = { + host: CONFIG.DB_HOST, + port: CONFIG.DB_PORT, + user: CONFIG.DB_USER, + password: CONFIG.DB_PASSWORD, + database: CONFIG.DB_DATABASE, +} + +// Pool? +const pool = createPool(poolConfig) + +// Create & Initialize Migrations +const migration = new Migration({ + conn: pool, + tableName: CONFIG.MIGRATIONS_TABLE, + silent: true, + dir: '../database/migrations/', // CONFIG.MIGRATIONS_DIRECTORY, +}) + +const initialize = async () => { + await migration.initialize() +} + +const resetDB = async (closePool = false): Promise => { + await migration.reset() // use for resetting database + if (closePool) pool.end() +} + +export { resetDB, pool, migration, initialize } diff --git a/database/src/index.ts b/database/src/index.ts index 94566c9f5..5be8f4edb 100644 --- a/database/src/index.ts +++ b/database/src/index.ts @@ -1,7 +1,4 @@ import 'reflect-metadata' -import { createPool, PoolConfig } from 'mysql' -import { Migration } from 'ts-mysql-migrate' -import CONFIG from './config' import prepare from './prepare' import connection from './typeorm/connection' import { useSeeding, runSeeder } from 'typeorm-seeding' @@ -10,36 +7,19 @@ import { CreateBibiBloxbergSeed } from './seeds/users/bibi-bloxberg.seed' import { CreateRaeuberHotzenplotzSeed } from './seeds/users/raeuber-hotzenplotz.seed' import { CreateBobBaumeisterSeed } from './seeds/users/bob-baumeister.seed' import { DecayStartBlockSeed } from './seeds/decay-start-block.seed' +import { resetDB, pool, migration } from './helpers' const run = async (command: string) => { // Database actions not supported by our migration library await prepare() - // Database connection for Migrations - const poolConfig: PoolConfig = { - host: CONFIG.DB_HOST, - port: CONFIG.DB_PORT, - user: CONFIG.DB_USER, - password: CONFIG.DB_PASSWORD, - database: CONFIG.DB_DATABASE, - } - - // Pool? - const pool = createPool(poolConfig) - - // Create & Initialize Migrations - const migration = new Migration({ - conn: pool, - tableName: CONFIG.MIGRATIONS_TABLE, - dir: CONFIG.MIGRATIONS_DIRECTORY, - }) - // Database connection for TypeORM const con = await connection() if (!con || !con.isConnected) { throw new Error(`Couldn't open connection to database`) } + // Database connection for Migrations await migration.initialize() // Execute command @@ -52,7 +32,7 @@ const run = async (command: string) => { break case 'reset': // TODO protect from production - await migration.reset() // use for resetting database + await resetDB(false) // use for resetting database break case 'seed': // TODO protect from production diff --git a/database/tsconfig.json b/database/tsconfig.json index 445b9d11f..f0e707dd2 100644 --- a/database/tsconfig.json +++ b/database/tsconfig.json @@ -46,7 +46,9 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + "@migrations/*": ["./migrations/*"], + }, // "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ From 28520d6de81871161fcd68b9801547873bc5eac0 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 27 Dec 2021 16:03:20 +0100 Subject: [PATCH 02/18] minor improvements --- database/src/helpers.ts | 2 +- database/src/index.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/database/src/helpers.ts b/database/src/helpers.ts index 1ef8b5d1f..0c15042a8 100644 --- a/database/src/helpers.ts +++ b/database/src/helpers.ts @@ -21,7 +21,7 @@ const migration = new Migration({ dir: '../database/migrations/', // CONFIG.MIGRATIONS_DIRECTORY, }) -const initialize = async () => { +const initialize = async (): Promise => { await migration.initialize() } diff --git a/database/src/index.ts b/database/src/index.ts index 5be8f4edb..488d098d3 100644 --- a/database/src/index.ts +++ b/database/src/index.ts @@ -19,7 +19,6 @@ const run = async (command: string) => { throw new Error(`Couldn't open connection to database`) } - // Database connection for Migrations await migration.initialize() // Execute command @@ -32,7 +31,7 @@ const run = async (command: string) => { break case 'reset': // TODO protect from production - await resetDB(false) // use for resetting database + await resetDB() // use for resetting database break case 'seed': // TODO protect from production From fbac95f352caa1f340c5f62bcdc0190f344359cc Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 27 Dec 2021 17:26:58 +0100 Subject: [PATCH 03/18] remove emoty file, test content of user tables after registration --- .../src/graphql/resolver/UserResolver.test.ts | 127 +++++++++++++++++- .../src/middleware/userResolverMiddleware.ts | 0 2 files changed, 125 insertions(+), 2 deletions(-) delete mode 100644 backend/src/middleware/userResolverMiddleware.ts diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index bd653b6df..0990cb852 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -4,6 +4,11 @@ import { createTestClient } from 'apollo-server-testing' import createServer from '../../server/createServer' import { resetDB, initialize } from '@dbTools/helpers' +import { getRepository } from 'typeorm' +import { LoginUser } from '@entity/LoginUser' +import { LoginUserBackup } from '@entity/LoginUserBackup' +import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' +import { User } from '@entity/User' let mutate: any let con: any @@ -18,8 +23,126 @@ beforeAll(async () => { describe('UserResolver', () => { describe('createUser', () => { - it('works', () => { - expect(true).toBeTruthy() + const variables = { + email: 'peter@lustig.de', + firstName: 'Peter', + lastName: 'Lustig', + language: 'de', + publisherId: 1234, + } + + const mutation = ` + mutation( + $email: String! + $firstName: String! + $lastName: String! + $language: String! + $publisherId: Int + ) { + createUser( + email: $email + firstName: $firstName + lastName: $lastName + language: $language + publisherId: $publisherId + ) + } + ` + + let result: any + + beforeAll(async () => { + result = await mutate({ mutation, variables }) + }) + + afterAll(async () => { + await resetDB() + }) + + it('returns success', () => { + expect(result).toEqual(expect.objectContaining({ data: { createUser: 'success' } })) + }) + + describe('different user tables', () => { + let loginUser: LoginUser[] + let user: User[] + let loginUserBackup: LoginUserBackup[] + let loginEmailOptIn: LoginEmailOptIn[] + beforeAll(async () => { + loginUser = await getRepository(LoginUser).createQueryBuilder('login_user').getMany() + user = await getRepository(User).createQueryBuilder('state_user').getMany() + loginUserBackup = await getRepository(LoginUserBackup) + .createQueryBuilder('login_user_backup') + .getMany() + loginEmailOptIn = await getRepository(LoginEmailOptIn) + .createQueryBuilder('login_email_optin') + .getMany() + }) + + it('saves the user in login_user table', () => { + expect(loginUser).toEqual([ + { + id: expect.any(Number), + email: 'peter@lustig.de', + firstName: 'Peter', + lastName: 'Lustig', + username: '', + description: '', + password: '0', + pubKey: null, + privKey: null, + emailHash: expect.any(Buffer), + createdAt: expect.any(Date), + emailChecked: false, + passphraseShown: false, + language: 'de', + disabled: false, + groupId: 1, + publisherId: 1234, + }, + ]) + }) + + it('saves the user in state_user table', () => { + expect(user).toEqual([ + { + id: expect.any(Number), + indexId: 0, + groupId: 0, + pubkey: expect.any(Buffer), + email: 'peter@lustig.de', + firstName: 'Peter', + lastName: 'Lustig', + username: '', + disabled: false, + }, + ]) + }) + + it('saves the user in login_user_backup table', () => { + expect(loginUserBackup).toEqual([ + { + id: expect.any(Number), + passphrase: expect.any(String), + userId: loginUser[0].id, + mnemonicType: 2, + }, + ]) + }) + + it('creates an email optin', () => { + expect(loginEmailOptIn).toEqual([ + { + id: expect.any(Number), + userId: loginUser[0].id, + verificationCode: expect.any(String), + emailOptInTypeId: 1, + createdAt: expect.any(Date), + resendCount: 0, + updatedAt: expect.any(Date), + }, + ]) + }) }) }) }) diff --git a/backend/src/middleware/userResolverMiddleware.ts b/backend/src/middleware/userResolverMiddleware.ts deleted file mode 100644 index e69de29bb..000000000 From 6a666edc9f7d049bd9465eca406187b0167c04af Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 27 Dec 2021 20:48:39 +0100 Subject: [PATCH 04/18] test account activation email is sent --- backend/src/graphql/resolver/AdminResolver.ts | 2 - .../src/graphql/resolver/UserResolver.test.ts | 195 +++++++++++------- backend/src/graphql/resolver/UserResolver.ts | 7 +- 3 files changed, 121 insertions(+), 83 deletions(-) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 3ccb0fa63..85cb3a0fe 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -321,7 +321,5 @@ function isCreationValid(creations: number[], amount: number, creationDate: Date async function hasActivatedEmail(email: string): Promise { const repository = getCustomRepository(LoginUserRepository) const user = await repository.findByEmail(email) - let emailActivate = false - if (user) emailActivate = user.emailChecked return user ? user.emailChecked : false } diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 0990cb852..b64b6b719 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -2,6 +2,8 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { createTestClient } from 'apollo-server-testing' +import gql from 'graphql-tag' +import { GraphQLError } from 'graphql' import createServer from '../../server/createServer' import { resetDB, initialize } from '@dbTools/helpers' import { getRepository } from 'typeorm' @@ -9,6 +11,15 @@ import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User } from '@entity/User' +import CONFIG from '../../config' +import { sendEMail } from '../../util/sendEMail' + +jest.mock('../../util/sendEMail', () => { + return { + __esModule: true, + sendEMail: jest.fn(), + } +}) let mutate: any let con: any @@ -31,25 +42,27 @@ describe('UserResolver', () => { publisherId: 1234, } - const mutation = ` - mutation( - $email: String! - $firstName: String! - $lastName: String! - $language: String! - $publisherId: Int - ) { - createUser( - email: $email - firstName: $firstName - lastName: $lastName - language: $language - publisherId: $publisherId - ) - } + const mutation = gql` + mutation ( + $email: String! + $firstName: String! + $lastName: String! + $language: String! + $publisherId: Int + ) { + createUser( + email: $email + firstName: $firstName + lastName: $lastName + language: $language + publisherId: $publisherId + ) + } ` let result: any + let emailOptIn: string + let newUser: User beforeAll(async () => { result = await mutate({ mutation, variables }) @@ -63,7 +76,7 @@ describe('UserResolver', () => { expect(result).toEqual(expect.objectContaining({ data: { createUser: 'success' } })) }) - describe('different user tables', () => { + describe('valid input data', () => { let loginUser: LoginUser[] let user: User[] let loginUserBackup: LoginUserBackup[] @@ -77,71 +90,99 @@ describe('UserResolver', () => { loginEmailOptIn = await getRepository(LoginEmailOptIn) .createQueryBuilder('login_email_optin') .getMany() + newUser = user[0] + emailOptIn = loginEmailOptIn[0].verificationCode.toString() }) - it('saves the user in login_user table', () => { - expect(loginUser).toEqual([ - { - id: expect.any(Number), - email: 'peter@lustig.de', - firstName: 'Peter', - lastName: 'Lustig', - username: '', - description: '', - password: '0', - pubKey: null, - privKey: null, - emailHash: expect.any(Buffer), - createdAt: expect.any(Date), - emailChecked: false, - passphraseShown: false, - language: 'de', - disabled: false, - groupId: 1, - publisherId: 1234, - }, - ]) - }) + describe('filling all tables', () => { + it('saves the user in login_user table', () => { + expect(loginUser).toEqual([ + { + id: expect.any(Number), + email: 'peter@lustig.de', + firstName: 'Peter', + lastName: 'Lustig', + username: '', + description: '', + password: '0', + pubKey: null, + privKey: null, + emailHash: expect.any(Buffer), + createdAt: expect.any(Date), + emailChecked: false, + passphraseShown: false, + language: 'de', + disabled: false, + groupId: 1, + publisherId: 1234, + }, + ]) + }) - it('saves the user in state_user table', () => { - expect(user).toEqual([ - { - id: expect.any(Number), - indexId: 0, - groupId: 0, - pubkey: expect.any(Buffer), - email: 'peter@lustig.de', - firstName: 'Peter', - lastName: 'Lustig', - username: '', - disabled: false, - }, - ]) - }) + it('saves the user in state_user table', () => { + expect(user).toEqual([ + { + id: expect.any(Number), + indexId: 0, + groupId: 0, + pubkey: expect.any(Buffer), + email: 'peter@lustig.de', + firstName: 'Peter', + lastName: 'Lustig', + username: '', + disabled: false, + }, + ]) + }) - it('saves the user in login_user_backup table', () => { - expect(loginUserBackup).toEqual([ - { - id: expect.any(Number), - passphrase: expect.any(String), - userId: loginUser[0].id, - mnemonicType: 2, - }, - ]) - }) + it('saves the user in login_user_backup table', () => { + expect(loginUserBackup).toEqual([ + { + id: expect.any(Number), + passphrase: expect.any(String), + userId: loginUser[0].id, + mnemonicType: 2, + }, + ]) + }) - it('creates an email optin', () => { - expect(loginEmailOptIn).toEqual([ - { - id: expect.any(Number), - userId: loginUser[0].id, - verificationCode: expect.any(String), - emailOptInTypeId: 1, - createdAt: expect.any(Date), - resendCount: 0, - updatedAt: expect.any(Date), - }, - ]) + it('creates an email optin', () => { + expect(loginEmailOptIn).toEqual([ + { + id: expect.any(Number), + userId: loginUser[0].id, + verificationCode: expect.any(String), + emailOptInTypeId: 1, + createdAt: expect.any(Date), + resendCount: 0, + updatedAt: expect.any(Date), + }, + ]) + }) + }) + }) + + describe('account activation email', () => { + it('sends an account activation email', () => { + const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(/\$1/g, emailOptIn) + expect(sendEMail).toBeCalledWith({ + from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, + to: `${newUser.firstName} ${newUser.lastName} <${newUser.email}>`, + subject: 'Gradido: E-Mail Überprüfung', + text: + expect.stringContaining(`Hallo ${newUser.firstName} ${newUser.lastName},`) && + expect.stringContaining(activationLink), + }) + }) + }) + + describe('email already exists', () => { + it('throws an error', async () => { + await expect(mutate({ mutation, variables })).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('User already exists.')], + }), + ) }) }) }) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 20bd01cec..3875fc538 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -471,13 +471,13 @@ export class UserResolver { return 'success' } - private async sendAccountActivationEmail( + private sendAccountActivationEmail( activationLink: string, firstName: string, lastName: string, email: string, - ) { - const emailSent = await sendEMail({ + ): Promise { + return sendEMail({ from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, to: `${firstName} ${lastName} <${email}>`, subject: 'Gradido: E-Mail Überprüfung', @@ -492,7 +492,6 @@ export class UserResolver { Mit freundlichen Grüßen, dein Gradido-Team`, }) - return emailSent } @Mutation(() => Boolean) From dc6459f45c8144f43d032c70c1a746628fc37449 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 27 Dec 2021 20:57:17 +0100 Subject: [PATCH 05/18] coverage unit tests backend to 40% --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 526c15cca..438d04aa2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -491,7 +491,7 @@ jobs: report_name: Coverage Backend type: lcov result_path: ./backend/coverage/lcov.info - min_coverage: 37 + min_coverage: 40 token: ${{ github.token }} ############################################################################## From 5c79d34ef37cc5d4eea1d1fdf29ee84a9244a8be Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 28 Dec 2021 17:36:41 +0100 Subject: [PATCH 06/18] test language, make pubkey unique, migrations dir from config --- .../src/graphql/resolver/UserResolver.test.ts | 19 +++++++++++++++++++ backend/src/graphql/resolver/UserResolver.ts | 3 ++- database/src/helpers.ts | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index b64b6b719..af605f222 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -185,6 +185,25 @@ describe('UserResolver', () => { ) }) }) + + describe('unknown language', () => { + it('sets "de" as default language', async () => { + await mutate({ + mutation, + variables: { ...variables, email: 'bibi@bloxberg.de', language: 'es' }, + }) + await expect( + getRepository(LoginUser).createQueryBuilder('login_user').getMany(), + ).resolves.toEqual( + expect.arrayContaining([ + expect.objectContaining({ + email: 'bibi@bloxberg.de', + language: 'de', + }), + ]), + ) + }) + }) }) }) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 3875fc538..ccdef9794 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -26,6 +26,7 @@ import { signIn } from '../../apis/KlicktippController' import { RIGHTS } from '../../auth/RIGHTS' import { ServerUserRepository } from '../../typeorm/repository/ServerUser' import { ROLE_ADMIN } from '../../auth/ROLES' +import { randomBytes } from 'crypto' const EMAIL_OPT_IN_RESET_PASSWORD = 2 const EMAIL_OPT_IN_REGISTER = 1 @@ -432,7 +433,7 @@ export class UserResolver { dbUser.lastName = lastName dbUser.username = username // TODO this field has no null allowed unlike the loginServer table - dbUser.pubkey = Buffer.alloc(32, 0) // default to 0000... + dbUser.pubkey = Buffer.from(randomBytes(32)) // Buffer.alloc(32, 0) default to 0000... // dbUser.pubkey = keyPair[0] await queryRunner.manager.save(dbUser).catch((er) => { diff --git a/database/src/helpers.ts b/database/src/helpers.ts index 0c15042a8..199af5f7f 100644 --- a/database/src/helpers.ts +++ b/database/src/helpers.ts @@ -18,7 +18,7 @@ const migration = new Migration({ conn: pool, tableName: CONFIG.MIGRATIONS_TABLE, silent: true, - dir: '../database/migrations/', // CONFIG.MIGRATIONS_DIRECTORY, + dir: CONFIG.MIGRATIONS_DIRECTORY, }) const initialize = async (): Promise => { From b6c66dd2daf2d24b867680773482e52697809bc3 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 28 Dec 2021 17:47:43 +0100 Subject: [PATCH 07/18] try relative path to migrations --- database/src/config/index.ts | 2 +- database/src/helpers.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/database/src/config/index.ts b/database/src/config/index.ts index 86f96b9b6..98fae114f 100644 --- a/database/src/config/index.ts +++ b/database/src/config/index.ts @@ -13,7 +13,7 @@ const database = { const migrations = { MIGRATIONS_TABLE: process.env.MIGRATIONS_TABLE || 'migrations', - MIGRATIONS_DIRECTORY: process.env.MIGRATIONS_DIRECTORY || '@migrations/', + MIGRATIONS_DIRECTORY: process.env.MIGRATIONS_DIRECTORY || '../database/migrations/', } const CONFIG = { ...database, ...migrations } diff --git a/database/src/helpers.ts b/database/src/helpers.ts index 199af5f7f..821d1e5c4 100644 --- a/database/src/helpers.ts +++ b/database/src/helpers.ts @@ -2,6 +2,8 @@ import CONFIG from './config' import { createPool, PoolConfig } from 'mysql' import { Migration } from 'ts-mysql-migrate' +console.log(__dirname) + const poolConfig: PoolConfig = { host: CONFIG.DB_HOST, port: CONFIG.DB_PORT, From dc3f86f0c6f9989903d693c7a24f62731d402104 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 12:53:00 +0100 Subject: [PATCH 08/18] Undo path change --- database/src/config/index.ts | 2 +- database/src/helpers.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/database/src/config/index.ts b/database/src/config/index.ts index 98fae114f..908d40311 100644 --- a/database/src/config/index.ts +++ b/database/src/config/index.ts @@ -13,7 +13,7 @@ const database = { const migrations = { MIGRATIONS_TABLE: process.env.MIGRATIONS_TABLE || 'migrations', - MIGRATIONS_DIRECTORY: process.env.MIGRATIONS_DIRECTORY || '../database/migrations/', + MIGRATIONS_DIRECTORY: process.env.MIGRATIONS_DIRECTORY || './migrations/', } const CONFIG = { ...database, ...migrations } diff --git a/database/src/helpers.ts b/database/src/helpers.ts index 821d1e5c4..199af5f7f 100644 --- a/database/src/helpers.ts +++ b/database/src/helpers.ts @@ -2,8 +2,6 @@ import CONFIG from './config' import { createPool, PoolConfig } from 'mysql' import { Migration } from 'ts-mysql-migrate' -console.log(__dirname) - const poolConfig: PoolConfig = { host: CONFIG.DB_HOST, port: CONFIG.DB_PORT, From 0cd6a40304092309f0bbec1cfe2bac8e398d741d Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 12:59:25 +0100 Subject: [PATCH 09/18] try with path.join --- database/src/helpers.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/database/src/helpers.ts b/database/src/helpers.ts index 199af5f7f..eba909a3d 100644 --- a/database/src/helpers.ts +++ b/database/src/helpers.ts @@ -1,6 +1,7 @@ import CONFIG from './config' import { createPool, PoolConfig } from 'mysql' import { Migration } from 'ts-mysql-migrate' +import path from 'path' const poolConfig: PoolConfig = { host: CONFIG.DB_HOST, @@ -18,7 +19,7 @@ const migration = new Migration({ conn: pool, tableName: CONFIG.MIGRATIONS_TABLE, silent: true, - dir: CONFIG.MIGRATIONS_DIRECTORY, + dir: path.join(__dirname, '..', CONFIG.MIGRATIONS_DIRECTORY), }) const initialize = async (): Promise => { From 56afb18e81954e5aefc2555d205f278dd5a9d9d9 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 14:02:17 +0100 Subject: [PATCH 10/18] test publisher id --- .../src/graphql/resolver/UserResolver.test.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index af605f222..d0c144e22 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -204,6 +204,25 @@ describe('UserResolver', () => { ) }) }) + + describe('no publisher id', () => { + it('sets publisher id to null', async () => { + await mutate({ + mutation, + variables: { ...variables, email: 'raeuber@hotzenplotz.de', publisherId: undefined }, + }) + await expect( + getRepository(LoginUser).createQueryBuilder('login_user').getMany(), + ).resolves.toEqual( + expect.arrayContaining([ + expect.objectContaining({ + email: 'raeuber@hotzenplotz.de', + publisherId: null, + }), + ]), + ) + }) + }) }) }) From fda657671490639bce2ca9d9f721ceaf5fb5b3fa Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 22:09:56 +0100 Subject: [PATCH 11/18] change paths of up, down and reset --- backend/jest.config.js | 1 - backend/package.json | 3 +-- backend/tsconfig.json | 3 +-- database/.env.dist | 1 - database/build/.env.dist | 2 -- database/package.json | 9 +++------ database/src/config/index.ts | 1 - database/src/helpers.ts | 2 +- database/tsconfig.json | 4 +--- 9 files changed, 7 insertions(+), 19 deletions(-) delete mode 100644 database/build/.env.dist diff --git a/backend/jest.config.js b/backend/jest.config.js index 18cf4c2f1..8ef08f580 100644 --- a/backend/jest.config.js +++ b/backend/jest.config.js @@ -7,6 +7,5 @@ module.exports = { moduleNameMapper: { '@entity/(.*)': '/../database/entity/$1', '@dbTools/(.*)': '/../database/src/$1', - '@migrations/(.*)': '/../database/migrations/$1', }, } diff --git a/backend/package.json b/backend/package.json index 9dcb8ec9a..e6f203000 100644 --- a/backend/package.json +++ b/backend/package.json @@ -60,7 +60,6 @@ }, "_moduleAliases": { "@entity": "../database/build/entity", - "@migrations": "../database/migrations", - "@dbTools": "../database/src" + "@dbTools": "../database/build/src" } } diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 9d010b198..eabdc75b0 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -48,8 +48,7 @@ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ "@entity/*": ["../database/entity/*"], - "@dbTools/*": ["../database/src/*"], - "@migrations/*": ["../database/migrations/*"] + "@dbTools/*": ["../database/src/*"] }, // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ diff --git a/database/.env.dist b/database/.env.dist index 644dcaaf4..689e4f509 100644 --- a/database/.env.dist +++ b/database/.env.dist @@ -4,6 +4,5 @@ DB_USER=root DB_PASSWORD= DB_DATABASE=gradido_community MIGRATIONS_TABLE=migrations -MIGRATIONS_DIRECTORY=./migrations/ TYPEORM_SEEDING_FACTORIES=src/factories/**/*{.ts,.js} diff --git a/database/build/.env.dist b/database/build/.env.dist deleted file mode 100644 index 505546e1b..000000000 --- a/database/build/.env.dist +++ /dev/null @@ -1,2 +0,0 @@ -// For production you need to put your env file in here. -// Please copy the dist file from the root folder in here and rename it to .env \ No newline at end of file diff --git a/database/package.json b/database/package.json index 6a061607a..515fbcd74 100644 --- a/database/package.json +++ b/database/package.json @@ -10,9 +10,9 @@ "scripts": { "build": "tsc --build", "clean": "tsc --build --clean", - "up": "cd build && node src/index.js up", - "down": "cd build && node src/index.js down", - "reset": "cd build && node src/index.js reset", + "up": "node build/src/index.js up", + "down": "node build/src/index.js down", + "reset": "node build/src/index.js reset", "dev_up": "ts-node src/index.ts up", "dev_down": "ts-node src/index.ts down", "dev_reset": "ts-node src/index.ts reset", @@ -45,8 +45,5 @@ "ts-mysql-migrate": "^1.0.2", "typeorm": "^0.2.38", "typeorm-seeding": "^1.6.1" - }, - "_moduleAliases": { - "@migrations": "./migrations" } } diff --git a/database/src/config/index.ts b/database/src/config/index.ts index 908d40311..2dde06c96 100644 --- a/database/src/config/index.ts +++ b/database/src/config/index.ts @@ -13,7 +13,6 @@ const database = { const migrations = { MIGRATIONS_TABLE: process.env.MIGRATIONS_TABLE || 'migrations', - MIGRATIONS_DIRECTORY: process.env.MIGRATIONS_DIRECTORY || './migrations/', } const CONFIG = { ...database, ...migrations } diff --git a/database/src/helpers.ts b/database/src/helpers.ts index eba909a3d..710094548 100644 --- a/database/src/helpers.ts +++ b/database/src/helpers.ts @@ -19,7 +19,7 @@ const migration = new Migration({ conn: pool, tableName: CONFIG.MIGRATIONS_TABLE, silent: true, - dir: path.join(__dirname, '..', CONFIG.MIGRATIONS_DIRECTORY), + dir: path.join(__dirname, '..', 'migrations'), }) const initialize = async (): Promise => { diff --git a/database/tsconfig.json b/database/tsconfig.json index f0e707dd2..c2e0ae6c2 100644 --- a/database/tsconfig.json +++ b/database/tsconfig.json @@ -46,9 +46,7 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - "@migrations/*": ["./migrations/*"], - }, + // "paths": {} /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ From c678552fa66436447a8a3b98823313fd5d478241 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 22:25:21 +0100 Subject: [PATCH 12/18] add yarn build to backend tests for database --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 438d04aa2..426871d72 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -480,7 +480,7 @@ jobs: - name: backend | docker-compose run: docker-compose -f docker-compose.yml -f docker-compose.test.yml up --detach --no-deps mariadb database - name: backend Unit tests | test - run: cd database && yarn && cd ../backend && yarn && yarn test + run: cd database && yarn && yarn build && cd ../backend && yarn && yarn test # run: docker-compose -f docker-compose.yml -f docker-compose.test.yml exec -T backend yarn test ########################################################################## # COVERAGE CHECK BACKEND ################################################# From db82409d0843eb31b575bb7c57d97c4142544533 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 22:45:22 +0100 Subject: [PATCH 13/18] always take exposed files from build --- backend/jest.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/jest.config.js b/backend/jest.config.js index 8ef08f580..eedbcf181 100644 --- a/backend/jest.config.js +++ b/backend/jest.config.js @@ -5,7 +5,7 @@ module.exports = { collectCoverage: true, collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**'], moduleNameMapper: { - '@entity/(.*)': '/../database/entity/$1', - '@dbTools/(.*)': '/../database/src/$1', + '@entity/(.*)': '/../database/build/entity/$1', + '@dbTools/(.*)': '/../database/build/src/$1', }, } From 341402d96517b17f5c0faa0618de5e40bc40296e Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 23:06:23 +0100 Subject: [PATCH 14/18] CI_worklfow_test as new yarn command to get backend unit test working in CI --- .github/workflows/test.yml | 2 +- backend/jest.config.js | 2 +- backend/package.json | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 426871d72..9547c6ba4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -480,7 +480,7 @@ jobs: - name: backend | docker-compose run: docker-compose -f docker-compose.yml -f docker-compose.test.yml up --detach --no-deps mariadb database - name: backend Unit tests | test - run: cd database && yarn && yarn build && cd ../backend && yarn && yarn test + run: cd database && yarn && yarn build && cd ../backend && yarn && yarn CI_worklfow_test # run: docker-compose -f docker-compose.yml -f docker-compose.test.yml exec -T backend yarn test ########################################################################## # COVERAGE CHECK BACKEND ################################################# diff --git a/backend/jest.config.js b/backend/jest.config.js index eedbcf181..9e6ca4602 100644 --- a/backend/jest.config.js +++ b/backend/jest.config.js @@ -6,6 +6,6 @@ module.exports = { collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**'], moduleNameMapper: { '@entity/(.*)': '/../database/build/entity/$1', - '@dbTools/(.*)': '/../database/build/src/$1', + '@dbTools/(.*)': process.env.NODE_ENV === 'development' ? '/../database/src/$1' : '/../database/build/src/$1', }, } diff --git a/backend/package.json b/backend/package.json index e6f203000..c9314f0fd 100644 --- a/backend/package.json +++ b/backend/package.json @@ -13,7 +13,8 @@ "start": "node build/index.js", "dev": "nodemon -w src --ext ts --exec ts-node src/index.ts", "lint": "eslint . --ext .js,.ts", - "test": "jest --runInBand --coverage " + "CI_worklfow_test": "jest --runInBand --coverage ", + "test": "NODE_ENV=development jest --runInBand --coverage " }, "dependencies": { "@types/jest": "^27.0.2", From e39d51d33565ba53a5cca642d0f8d6dde8915896 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 23:16:33 +0100 Subject: [PATCH 15/18] Update backend/src/graphql/resolver/UserResolver.ts Co-authored-by: Ulf Gebhardt --- backend/src/graphql/resolver/UserResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index ccdef9794..2f98a2f6f 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -477,7 +477,7 @@ export class UserResolver { firstName: string, lastName: string, email: string, - ): Promise { + ): Promise { return sendEMail({ from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, to: `${firstName} ${lastName} <${email}>`, From 69d983b891f14bb6cc5668c986f4979c8f6ee8c1 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 23:16:47 +0100 Subject: [PATCH 16/18] Update backend/jest.config.js Co-authored-by: Ulf Gebhardt --- backend/jest.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/jest.config.js b/backend/jest.config.js index 9e6ca4602..79add8789 100644 --- a/backend/jest.config.js +++ b/backend/jest.config.js @@ -6,6 +6,7 @@ module.exports = { collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**'], moduleNameMapper: { '@entity/(.*)': '/../database/build/entity/$1', + // This is hack to fix a problem with the library `ts-mysql-migrate` which does differentiate between its ts/js state '@dbTools/(.*)': process.env.NODE_ENV === 'development' ? '/../database/src/$1' : '/../database/build/src/$1', }, } From 1b16e80ad485ea95b976feb69b2619a11b24e667 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 23:17:27 +0100 Subject: [PATCH 17/18] Update database/tsconfig.json Co-authored-by: Ulf Gebhardt --- database/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/tsconfig.json b/database/tsconfig.json index c2e0ae6c2..445b9d11f 100644 --- a/database/tsconfig.json +++ b/database/tsconfig.json @@ -46,7 +46,7 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {} /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ From d28ad456b5028beb148ea3a17b2ff71fe098b2b5 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 29 Dec 2021 23:30:08 +0100 Subject: [PATCH 18/18] linting --- backend/jest.config.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/jest.config.js b/backend/jest.config.js index 79add8789..9d99c68f6 100644 --- a/backend/jest.config.js +++ b/backend/jest.config.js @@ -7,6 +7,9 @@ module.exports = { moduleNameMapper: { '@entity/(.*)': '/../database/build/entity/$1', // This is hack to fix a problem with the library `ts-mysql-migrate` which does differentiate between its ts/js state - '@dbTools/(.*)': process.env.NODE_ENV === 'development' ? '/../database/src/$1' : '/../database/build/src/$1', + '@dbTools/(.*)': + process.env.NODE_ENV === 'development' + ? '/../database/src/$1' + : '/../database/build/src/$1', }, }