Skip to content

Commit

Permalink
add a test to user api
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzabuzaid committed Oct 9, 2019
1 parent 3b770f2 commit 4193b27
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 51 deletions.
2 changes: 2 additions & 0 deletions src/app/api/portal/portal.specs.ts
Expand Up @@ -16,3 +16,5 @@
// // request.send(exclude(user, 'email'));

// });

// in login check login test cases
11 changes: 6 additions & 5 deletions src/app/api/users/users.model.ts
Expand Up @@ -3,26 +3,26 @@ import { BaseModel, Entity, Field } from '@lib/mongoose';
import { ValidationPatterns } from '@shared/common';
import { parsePhoneNumberFromString } from 'libphonenumber-js';
import { Query } from 'mongoose';
import { translate } from '@lib/translation';

@Entity(Constants.Schemas.USERS)
export class UsersSchema {
@Field({ lowercase: false }) public password: string;
@Field({ pure: true, }) public password: string;
@Field({
match: [ValidationPatterns.NoSpecialChar, 'Value contain special char'],
match: [ValidationPatterns.NoSpecialChar, translate('no_speical_char')],
unique: true,
}) public username: string;
@Field({
match: [ValidationPatterns.EmailValidation, 'Please provide a valid email address'],
match: [ValidationPatterns.EmailValidation, translate('wrong_email')],
unique: true,
}) public email: string;

@Field({
validate: [
(value) => {
const phonenumber = parsePhoneNumberFromString(value);
return !!phonenumber && phonenumber.isValid();
},
'Please enter correct phonenumber'
translate('wrong_mobile_number')
],
unique: true,
}) public mobile: string;
Expand All @@ -38,6 +38,7 @@ export class UsersSchema {
}

export const UsersModel = BaseModel<UsersSchema>(UsersSchema);

UsersModel.schema.pre('find', () => {
(this as unknown as Query<any>).select({ password: 0 });
});
Expand Down
45 changes: 27 additions & 18 deletions src/app/api/users/users.spec.ts
Expand Up @@ -33,21 +33,35 @@ describe('CREATE USER', () => {
const deleteReq = await (await superAgent).delete(`${ENDPOINT}/${res1.body.id}`);
expect(res2.status).toBe(NetworkStatus.BAD_REQUEST);
});
test('Special Char is not allowed', async () => {
const body = {
email: 'test@create2.com',
mobile: '0792807794',
password: '123456789',
username: 'testCreate2#$'
} as Body<UsersSchema>;
const req = (await superAgent).post(ENDPOINT);
const res = await req.send(body);
const deleteReq = await (await superAgent).delete(`${ENDPOINT}/${res.body.id}`);
expect(res.status).toBe(NetworkStatus.BAD_REQUEST);
});
test('Mobile number shouldn"t be wrong', async () => {
const body = {
email: 'test@create3.com',
mobile: '079280779',
password: '123456789',
username: 'testCreate3'
} as Body<UsersSchema>;
const req = (await superAgent).post(ENDPOINT);
const res = await req.send(body);
const deleteReq = await (await superAgent).delete(`${ENDPOINT}/${res.body.id}`);
expect(res.status).toBe(NetworkStatus.BAD_REQUEST);
});
});

// describe('GET ALL', () => {
// test('Reject request without token', async () => {
// const res = (await (await superAgent).get(`${ENDPOINT}`));
// expect(res.status).toBe(NetworkStatus.UNAUTHORIZED);
// });

// test('Should return list', async () => {
// const req = (await superAgent).get(`${ENDPOINT}`);
// const res = await req.set('Authorization', user.token);
// expect(res.status).toBe(NetworkStatus.OK);
// expect(res.body.data).toBeInstanceOf(Array);
// });
// });
// STUB CREATE: user password should be hashed
// STUB CREATE: user should have an account
// STUB DELETE: remove associated account

// describe('GET BY ${id}/', () => {
// test('Reject request without token', async () => {
Expand Down Expand Up @@ -110,8 +124,3 @@ describe('CREATE USER', () => {
// });

// tslint:disable-next-line: max-line-length
// REVIEW in create and update you should check and verify if the data was update or created successfully other that the failur test
// and in delete you must check that the entity no longer in database
// in update and create you must test the validation by insert Wrong data
// in login check login test cases
// try to send wrong mobile, email
10 changes: 6 additions & 4 deletions src/app/server.ts
Expand Up @@ -24,8 +24,8 @@ export class NodeServer extends Application {
const server = new NodeServer();
const httpServer = await server.populateServer();
// server.application.get('/socket/:name', handleSocket);
server.application.get('/webhooks/github/deploy', deploy);
await server.init();
// server.application.get('/webhooks/github/deploy', deploy);
return server.init();
}

public static test() {
Expand Down Expand Up @@ -65,10 +65,12 @@ export class NodeServer extends Application {
}

private init() {
const { MONGO_USER: user,
const {
MONGO_USER: user,
MONGO_PASSWORD: password,
MONGO_PATH: path,
MONGO_HOST: host } = envirnoment.env;
MONGO_HOST: host
} = envirnoment.env;
log.debug(stage.LEVEL);
try {
return Promise.all([
Expand Down
4 changes: 4 additions & 0 deletions src/app/shared/crud/crud.spec.ts
Expand Up @@ -39,3 +39,7 @@ describe('Add router to wrapper', () => {
// in update and create you must test the validation by insert Wrong data
// in login check login test cases
// try to send wrong mobile, email

// REVIEW in create and update you should check and verify if the data was update or created successfully
// other that the failur test
// and in delete you must check that the entity no longer in database
5 changes: 4 additions & 1 deletion src/assets/languages/en.json
Expand Up @@ -16,5 +16,8 @@
"not_exist": "Entity not exist",
"success": "Sucesss",
"error": "Error",
"email_exist": "email_exist"
"email_exist": "email_exist",
"no_speical_char": "Value contains special char",
"wrong_email": "Please provide a valid email address",
"wrong_mobile_number": "Please enter correct phonenumber"
}
6 changes: 4 additions & 2 deletions src/lib/mongoose/field.ts
Expand Up @@ -2,15 +2,17 @@ import { AppUtils } from '@core/utils';
import 'reflect-metadata';
import { MongooseTypes } from '.';

export function Field<T = any>(options: Exclude<MongooseTypes.FieldOptions, 'type'> = {}) {
// TODO: the `type` property should be in the `options` type

export function Field<T = any>(options: MongooseTypes.FieldOptions) {
return (instance: MongooseTypes.IFieldAttr & T, propertyKey: string) => {
if (instance && !instance.fields) {
AppUtils.defineProperty(instance, 'fields', { value: {} });
}
const fields = instance.fields;
const propertyType = Reflect.getMetadata('design:type', instance, propertyKey);
let defaults: typeof options = {};
if (propertyType.name === String.name) {
if (!!options.pure && propertyType.name === String.name) {
defaults = {
lowercase: true,
trim: true,
Expand Down
4 changes: 3 additions & 1 deletion src/lib/mongoose/index.ts
Expand Up @@ -6,7 +6,9 @@ import { Schema, SchemaType, SchemaTypeOpts } from 'mongoose';

export namespace MongooseTypes {

export type FieldOptions = SchemaTypeOpts<any> | Schema | SchemaType;
export type FieldOptions = SchemaTypeOpts<any> | Schema | SchemaType & {
pure?: boolean
};
export interface IFieldAttr {
fields: { [keys: string]: FieldOptions };
}
Expand Down
13 changes: 5 additions & 8 deletions src/lib/translation/local.ts
@@ -1,4 +1,4 @@
import { development } from '@core/helpers';
import { stage, StageLevel } from '@core/helpers';

import { Logger } from '@core/utils';
const log = new Logger('Local Class');
Expand All @@ -19,7 +19,7 @@ export class Local {
* @param name name of the local
* @param language local object
*/
constructor(name, language: object) {
constructor(name: string, language: object) {
this.name = name;
this._language = language;
}
Expand All @@ -37,11 +37,9 @@ export class Local {
* @param value
*/
public set(key: string, value: any) {
development(
() => {
log.warn(`a key with name ${key} is already hold a value`);
}
);
stage.test(StageLevel.DEV, () => {
log.warn(`a key with name ${key} is already hold a value`);
});
this.language[key] = value;
}

Expand All @@ -55,7 +53,6 @@ export class Local {
if (!value) {
throw new Error(`the key { ${key} } is not found in local { ${this.name} }`);
}

return value;
}
}
20 changes: 12 additions & 8 deletions src/lib/translation/translation.ts
Expand Up @@ -109,13 +109,17 @@ export const translation = new Translation();
* @returns the value of the key from the active local
*/
export function translate(key: string, params: object = {}) {
let value = translation.local.get(key);
const rawParams = value.match(/\{(.*?)\}/ig);
if (rawParams) {
value = rawParams.reduce((acc, el) => {
const param = el.substring(1, el.length - 1);
return `${acc}${value.replace(/\{(.*?)\}/, params[param])}`;
}, '');
try {
let value = translation.local.get(key);
const rawParams = value.match(/\{(.*?)\}/ig);
if (rawParams) {
value = rawParams.reduce((acc, el) => {
const param = el.substring(1, el.length - 1);
return `${acc}${value.replace(/\{(.*?)\}/, params[param])}`;
}, '');
}
return value;
} catch (error) {
return key;
}
return value;
}
8 changes: 6 additions & 2 deletions src/main.ts
@@ -1,4 +1,8 @@
import { NodeServer } from './app/server';
NodeServer.bootstrap();
process.chdir('./src/');
console.log('Node verions is => ', process.version);

NodeServer.bootstrap()
.then(() => {
console.log('Node verions is => ', process.version);
console.log('Node title is => ', process.title);
});
4 changes: 2 additions & 2 deletions src/test/fixture.ts
Expand Up @@ -15,9 +15,9 @@ export function getUri(value: string) {
export async function createUser() {
const req = (await superAgent).post(usersUri);
const res = await req.send({
email: 'test@test.com',
email: `test@test.com`,
password: '123456789',
username: 'test',
username: `test`,
mobile: '+962792807794'
});
user.id = res.body.data._id;
Expand Down

0 comments on commit 4193b27

Please sign in to comment.