Skip to content

Commit

Permalink
test: 🧪 add integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Manuel Ruck committed Jul 13, 2024
1 parent f344142 commit aa18592
Show file tree
Hide file tree
Showing 15 changed files with 433 additions and 57 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/bearer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: 🧸 Bearer

on:
push:
branches:
- main

permissions:
contents: read

jobs:
rule_check:
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout
uses: actions/checkout@v4

- name: 🧸 Bearer
uses: bearer/bearer-action@v2
27 changes: 27 additions & 0 deletions graphql.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3591,6 +3591,33 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "removeUser",
"description": "",
"args": [
{
"name": "phoneNumber",
"description": "",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "requestCode",
"description": "",
Expand Down
17 changes: 1 addition & 16 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,9 @@ const optionalConfigs = {
LOGGING_DISCORD: process.env.LOGGING_DISCORD,
LOGGING_DISCORD_TOKEN: process.env.LOGGING_DISCORD_TOKEN,
LOGGING_DISCORD_WEBHOOK: process.env.LOGGING_DISCORD_WEBHOOK,
LOGGING_MONGO: process.env.LOGGING_MONGO || false,
LOGGING_MONGO: process.env.LOGGING_MONGO !== 'false' || false,
};

if (process.env.NODE_ENV === 'development') {
console.log(
'CONFIG',
JSON.stringify(
{
...requiredConfigs,
...recommendedConfigs,
...optionalConfigs,
},
null,
2,
),
);
}

export default {
...requiredConfigs,
...recommendedConfigs,
Expand Down
51 changes: 38 additions & 13 deletions src/express/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,16 @@ export const authMiddleware = async (req: ExpressReqContext, res: Response, next
}
// Set new timestamps
req.user.markModified('updatedAt');
await req.user.save();
await req.user.save().catch((e) => {
logger.error("Couldn't save User 1", req.user);
logger.error(e);
});
if (req.device) {
req.device.markModified('updatedAt');
await req.device.save();
await req.device.save().catch((e) => {
logger.error("Couldn't save Device 1", req.device);
logger.error(e);
});
}
if (req.phone) {
req.phone.markModified('updatedAt');
Expand Down Expand Up @@ -168,10 +174,16 @@ export const authMiddleware = async (req: ExpressReqContext, res: Response, next
}
// Set new timestamps
req.user.markModified('updatedAt');
await req.user.save();
await req.user.save().catch((e) => {
logger.error("Couldn't save User 2", req.user);
logger.error(e);
});
if (req.device) {
req.device.markModified('updatedAt');
await req.device.save();
await req.device.save().catch((e) => {
logger.error("Couldn't save Device 2", req.device);
logger.error(e);
});
}
if (req.phone) {
req.phone.markModified('updatedAt');
Expand All @@ -193,7 +205,7 @@ export const authMiddleware = async (req: ExpressReqContext, res: Response, next
// logger.jwt('JWT: Credentials present');
// User
device = await DeviceModel.findOne({
deviceHash: crypto.createHash('sha256').update(deviceHash).digest('hex'),
deviceHash,
});
phone = phoneHash
? await PhoneModel.findOne({
Expand All @@ -205,33 +217,46 @@ export const authMiddleware = async (req: ExpressReqContext, res: Response, next
// logger.jwt('JWT: Create new User');

device = await DeviceModel.findOne({
deviceHash: crypto.createHash('sha256').update(deviceHash).digest('hex'),
deviceHash,
});
// Device
if (!device) {
device = new DeviceModel({
deviceHash: crypto.createHash('sha256').update(deviceHash).digest('hex'),
deviceHash,
});
await device.save().catch((e) => {
logger.error("Couldn't save Device")
try {
device = await device.save();
} catch (e) {
logger.error("Couldn't save Device 3", device.toObject(), { deviceHash });
logger.error(e);
});
}
}

// Create user
logger.debug('Create new User');
user = new UserModel({ device, phone });
await user.save();
try {
user = await user.save();
} catch (e) {
logger.error("Couldn't save User 3", user.toObject());
logger.error(e);
}
}
// logger.jwt(`JWT: Token New for User: ${user._id}`);
const [createToken, createRefreshToken] = await createTokens(user._id);
headerToken({ res, token: createToken, refreshToken: createRefreshToken });
// Set new timestamps
user.markModified('updatedAt');
await user.save();
await user.save().catch((e) => {
logger.error("Couldn't save User 4", user.toObject());
logger.error(e);
});
if (device) {
device.markModified('updatedAt');
await device.save();
await device.save().catch((e) => {
logger.error("Couldn't save Device 4", device.toObject());
logger.error(e);
});
}
if (phone) {
phone.markModified('updatedAt');
Expand Down
7 changes: 7 additions & 0 deletions src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ export type Mutation = {
addToken: TokenResult;
finishSearch: SearchTerm;
increaseActivity?: Maybe<ActivityIndex>;
removeUser?: Maybe<Scalars['Boolean']['output']>;
requestCode: CodeResult;
requestVerification: VerificationResult;
signUp?: Maybe<Auth>;
Expand All @@ -466,6 +467,11 @@ export type MutationIncreaseActivityArgs = {
};


export type MutationRemoveUserArgs = {
phoneNumber: Scalars['String']['input'];
};


export type MutationRequestCodeArgs = {
newPhone: Scalars['String']['input'];
oldPhoneHash?: InputMaybe<Scalars['String']['input']>;
Expand Down Expand Up @@ -956,6 +962,7 @@ export type MutationResolvers<ContextType = GraphQlContext, ParentType extends R
addToken?: Resolver<ResolversTypes['TokenResult'], ParentType, ContextType, RequireFields<MutationAddTokenArgs, 'os' | 'token'>>;
finishSearch?: Resolver<ResolversTypes['SearchTerm'], ParentType, ContextType, RequireFields<MutationFinishSearchArgs, 'term'>>;
increaseActivity?: Resolver<Maybe<ResolversTypes['ActivityIndex']>, ParentType, ContextType, RequireFields<MutationIncreaseActivityArgs, 'procedureId'>>;
removeUser?: Resolver<Maybe<ResolversTypes['Boolean']>, ParentType, ContextType, RequireFields<MutationRemoveUserArgs, 'phoneNumber'>>;
requestCode?: Resolver<ResolversTypes['CodeResult'], ParentType, ContextType, RequireFields<MutationRequestCodeArgs, 'newPhone'>>;
requestVerification?: Resolver<ResolversTypes['VerificationResult'], ParentType, ContextType, RequireFields<MutationRequestVerificationArgs, 'code' | 'newPhoneHash'>>;
signUp?: Resolver<Maybe<ResolversTypes['Auth']>, ParentType, ContextType, RequireFields<MutationSignUpArgs, 'deviceHashEncrypted'>>;
Expand Down
140 changes: 140 additions & 0 deletions src/graphql/resolvers/Activity.integ.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import {
IProcedure,
Device,
Phone,
User,
ProcedureModel,
DeviceModel,
PhoneModel,
UserModel,
ActivityModel,
} from '@democracy-deutschland/democracy-common';
import axios from 'axios';
import crypto from 'crypto';
import { connectDB, disconnectDB } from '../../services/mongoose';
import config from '../../config';

const GRAPHQL_API_URL = process.env.GRAPHQL_API_URL || 'http://localhost:3000';

describe('Activity Resolvers', () => {
describe('Mutations', () => {
describe('increaseActivity', () => {
const DEVICE_HASH = 'SOME_DEVICE_HASH_ACTIVITY_RESOLVER_INCREASE_ACTIVITY';
const PHONE_NUMBER = `+49111111111`;
const xPhoneHash = crypto.createHash('sha256').update(PHONE_NUMBER).digest('hex');
const phoneHash = crypto.createHash('sha256').update(xPhoneHash).digest('hex');
let procedure: IProcedure;
let device: Device;
let phone: Phone;
let user: User;

beforeAll(async () => {
await connectDB(config.DB_URL, { debug: false });

// create tmp procedure
procedure = await ProcedureModel.create({
procedureId: '0000000',
title: 'tmp procedure for increaseActivity test',
period: 1,
type: 'Antrag',
voteResults: {
yes: 0,
no: 0,
abstination: 0,
},
});

device = await DeviceModel.create({
deviceHash: DEVICE_HASH,
});

phone = await PhoneModel.create({
phoneHash,
});

// create tmp user
user = await UserModel.create({
verified: true,
device,
phone,
});
});

afterAll(async () => {
await Promise.all([
ActivityModel.deleteOne({ procedure: procedure }),
procedure.remove(),
phone.remove(),
device.remove(),
user.remove(),
]);

await disconnectDB();
});

it('fail to increase activity on non-existing procedure', async () => {
const response = await axios.post(
GRAPHQL_API_URL,
{
query: `
mutation IncreaseActivity($procedureId: String!) {
increaseActivity(procedureId: $procedureId) {
activityIndex
active
}
}
`,
variables: {
procedureId: 'non-existing-procedure-id',
},
},
{
headers: {
'Content-Type': 'application/json',
'x-device-hash': device.deviceHash,
'x-phone-hash': xPhoneHash,
},
},
);

const { data } = response.data;

expect(data).toBeDefined();
expect(data.increaseActivity).toBeNull();
});

it('increase activity', async () => {
const response = await axios.post(
GRAPHQL_API_URL,
{
query: `
mutation IncreaseActivity($procedureId: String!) {
increaseActivity(procedureId: $procedureId) {
activityIndex
active
}
}
`,
variables: {
procedureId: '0000000',
},
},
{
headers: {
'Content-Type': 'application/json',
'x-device-hash': device.deviceHash,
'x-phone-hash': xPhoneHash,
},
},
);

const { data } = response.data;

expect(data).toBeDefined();
expect(data.increaseActivity).toBeDefined();
expect(data.increaseActivity.activityIndex).toBeDefined();
expect(data.increaseActivity.active).toBeTruthy();
});
});
});
});
4 changes: 3 additions & 1 deletion src/graphql/resolvers/Activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ const ActivityApi: Resolvers = {
searchQuery = { procedureId };
}
const procedure = await ProcedureModel.findOne(searchQuery);

if (!procedure) {
throw new Error('Procedure not found');
logger.error('Procedure not found', { procedureId });
throw new Error(`Procedure not found: ${procedureId}`);
}
let active = await ActivityModel.findOne({
actor: CONFIG.SMS_VERIFICATION ? phone._id : device._id,
Expand Down
Loading

0 comments on commit aa18592

Please sign in to comment.