@nestjs/core#ContextIdFactory TypeScript Examples
The following examples show how to use
@nestjs/core#ContextIdFactory.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: mikro-orm.module.test.ts From nestjs with MIT License | 6 votes |
getEntityManagerLoop = async (module: TestingModule): Promise<Set<number | string>> => {
// this function mocks the contextId factory which is called on each request
// it's looped 5 times and resolves the EntityManager provider 10 times
// set only allows unique values, it should only return 5 items as it should resolve the same em with the same contextId
const generatedIds = new Set<number | string>();
for (let i = 0; i < 5; i++) {
const contextId = ContextIdFactory.create();
jest
.spyOn(ContextIdFactory, 'getByRequest')
.mockImplementation(() => contextId);
(await Promise.all([
module.resolve(EntityManager, contextId),
module.resolve(EntityManager, contextId),
])).forEach(em => generatedIds.add(em.id));
}
return generatedIds;
}
Example #2
Source File: prepare-options.service.ts From typegraphql-nestjs with MIT License | 5 votes |
prepareOptions<TOptions extends TypeGraphQLFeatureModuleOptions>(
featureModuleToken: string,
globalMiddlewares: Middleware<any>[] = [],
) {
const globalResolvers = getMetadataStorage().resolverClasses.map(
metadata => metadata.target,
);
const globalMiddlewareClasses = globalMiddlewares.filter(
it => it.prototype,
) as Function[];
const featureModuleOptionsArray: TOptions[] = [];
const resolversClasses: ClassType[] = [];
const providersMetadataMap = new Map<Function, InstanceWrapper<any>>();
for (const module of this.modulesContainer.values()) {
for (const provider of module.providers.values()) {
if (
typeof provider.name === "string" &&
provider.name.includes(featureModuleToken)
) {
featureModuleOptionsArray.push(provider.instance as TOptions);
}
if (globalResolvers.includes(provider.metatype)) {
providersMetadataMap.set(provider.metatype, provider);
resolversClasses.push(provider.metatype as ClassType);
}
if (globalMiddlewareClasses.includes(provider.metatype)) {
providersMetadataMap.set(provider.metatype, provider);
}
}
}
const orphanedTypes = flatten(
featureModuleOptionsArray.map(it => it.orphanedTypes),
);
const container: ContainerType = {
get: (cls, { context }) => {
let contextId = context[REQUEST_CONTEXT_ID];
if (!contextId) {
contextId = ContextIdFactory.create();
context[REQUEST_CONTEXT_ID] = contextId;
}
const providerMetadata = providersMetadataMap.get(cls)!;
if (
providerMetadata.isDependencyTreeStatic() &&
!providerMetadata.isTransient
) {
return this.moduleRef.get(cls, { strict: false });
}
return this.moduleRef.resolve(cls, contextId, { strict: false });
},
};
return {
resolversClasses,
orphanedTypes,
container,
featureModuleOptionsArray,
};
}
Example #3
Source File: stage.e2e-spec.ts From codeclannigeria-backend with MIT License | 4 votes |
describe('StagesController (e2e)', () => {
let app: INestApplication;
let route: request.SuperTest<request.Test>;
let trackService: TracksService;
let stageService: StagesService;
let mongo: typeof mongoose;
const validEmail = '[email protected]';
const validPass = 'pass@45Pdd';
let currentUser: JwtPayload;
let TrackModel: ReturnModelType<typeof Track>;
let StageModel: ReturnModelType<typeof Stage>;
const jwtGuard = {
canActivate: (context: ExecutionContext): boolean => {
const req = context.switchToHttp().getRequest();
req.user = currentUser;
throw new UnauthorizedException();
}
};
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [StagesModule, DbTest],
providers: [JwtStrategy]
})
.overrideGuard(JwtAuthGuard)
.useValue(jwtGuard)
.compile();
app = module.createNestApplication();
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidUnknownValues: true,
forbidNonWhitelisted: true,
transform: true,
transformOptions: {
enableImplicitConversion: true
}
})
);
await app.init();
const contextId = ContextIdFactory.getByRequest(request);
stageService = await module.resolve<StagesService>(
StagesService,
contextId
);
trackService = await module.resolve<TracksService>(
TracksService,
contextId
);
const { uri } = await inMemoryDb.runningInstance;
mongoose.Promise = Promise;
mongo = await mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false
});
TrackModel = getModelForClass(Track, { existingMongoose: mongo });
StageModel = getModelForClass(Stage, { existingMongoose: mongo });
const UserModel = getModelForClass(User, { existingMongoose: mongo });
const user = await UserModel.create({
email: validEmail,
firstName: 'firstName',
lastName: 'lastName',
password: validPass
});
currentUser = {
email: user.email,
userId: user.id,
role: user.role
};
route = request(app.getHttpServer());
});
describe('/stages (POST)', () => {
const input: CreateStageDto = {
title: 'Stage1',
description: 'Description',
track: '',
taskCount: 1,
level: 0
};
it('should return 401 if user not logged in', () => {
return route.post('/stages').send(input).expect(401);
});
it('should return 403 if user role is neither ADMIN nor MENTOR', async () => {
jest
.spyOn(jwtGuard, 'canActivate')
.mockImplementation((context: ExecutionContext) => {
const req = context.switchToHttp().getRequest();
req.user = currentUser;
return true;
});
return route.post('/stages').send(input).expect(403);
});
let stage: Stage;
let track: Track;
let task: Task;
it('should return 201 if user role is permitted', async () => {
const trackModel = await TrackModel.create({
title: 'title',
description: 'description'
});
input.track = trackModel.id;
currentUser.role = UserRole.ADMIN;
const { body } = await route.post('/stages').send(input).expect(201);
stage = await stageService.findByIdAsync(body.id);
track = await trackService.findByIdAsync(trackModel.id);
expect(stage.createdBy.toString()).toBe(currentUser.userId);
expect(track.stages.includes(stage.id as any)).toBe(true);
expect(body.track.id).toBe(trackModel.id);
const taskModel = getModelForClass(Task, { existingMongoose: mongo });
task = await taskModel.create({
title: 'title',
description: 'description',
track: track.id,
stage: stage.id,
course: mongo.Types.ObjectId().toHexString()
});
});
it('should return 409 for existing stage title', async () => {
return route.post('/stages').send(input).expect(409);
});
it('should return 200 when stage is updated', async () => {
const newTitle = 'NEW_TITLE';
const { body } = await route
.put(`/stages/${stage.id}`)
.send({ ...input, title: newTitle })
.expect(200);
const { updatedBy } = await stageService.findById(body.id);
expect(body.title).toBe(newTitle);
expect(updatedBy.toString()).toBe(currentUser.userId);
});
it('should return a stage with its associated track', async () => {
const { body } = await route.get(`/stages/${stage.id}`).expect(200);
expect(track.id.toString()).toBe(body.track.id);
});
it('should return stages with their associated tracks', async () => {
const { body } = await route.get('/stages').expect(200);
expect(body.items[0].track.id).toBe(track.id.toString());
});
it('should return tasks per stage ID', async () => {
const { body } = await route.get(`/stages/${stage.id}/tasks`).expect(200);
expect(body.items[0].id).toBe(task.id.toString());
});
it('should return 403 for non-permitted user trying to UPDATE stage', async () => {
currentUser.role = UserRole.MENTEE;
return route.put(`/stages/${stage.id}`).send(input).expect(403);
});
it('should return 403 for non-permitted user trying to DELETE stage', async () => {
return route.delete(`/stages/${stage.id}`).send(input).expect(403);
});
it('should soft delete stage', async () => {
currentUser.role = UserRole.ADMIN;
await route.delete(`/stages/${stage.id}`).send(input).expect(200);
const { deletedBy, isDeleted } = await StageModel.findById(stage.id);
const res = await stageService.findByIdAsync(stage.id);
expect(deletedBy.toString()).toBe(currentUser.userId);
expect(isDeleted).toBe(true);
expect(res).toBeFalsy();
});
});
afterAll(async () => {
const { collections } = mongoose.connection;
const foo = await inMemoryDb.getDbPath();
console.log(foo);
Object.keys(collections).forEach(
async (k) => await collections[`${k}`].deleteMany({})
);
await app.close();
});
});
Example #4
Source File: tasks.e2e-spec.ts From codeclannigeria-backend with MIT License | 4 votes |
describe('TasksController (e2e)', () => {
let app: INestApplication;
let route: request.SuperTest<request.Test>;
let service: TasksService;
let mongo: typeof mongoose;
const validEmail = '[email protected]';
const validPass = 'pass@45Pdd';
let currentUser: JwtPayload;
let track: Track;
let TaskModel: ReturnModelType<typeof Task>;
let UserModel: ReturnModelType<typeof User>;
let TrackModel: ReturnModelType<typeof Track>;
let StageModel: ReturnModelType<typeof Stage>;
let TrackMentorModel: ReturnModelType<typeof TrackMentor>;
let MentorMenteeModel: ReturnModelType<typeof MentorMentee>;
let CourseModel: ReturnModelType<typeof Course>;
const jwtGuard = {
canActivate: (context: ExecutionContext): boolean => {
const req = context.switchToHttp().getRequest();
req.user = currentUser;
throw new UnauthorizedException();
}
};
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [TasksModule, DbTest],
providers: [JwtStrategy]
})
.overrideGuard(JwtAuthGuard)
.useValue(jwtGuard)
.overrideProvider(MailService)
.useValue({ sendMailAsync: () => Promise.resolve() })
.compile();
app = module.createNestApplication();
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidUnknownValues: true,
forbidNonWhitelisted: true,
transform: true,
transformOptions: {
enableImplicitConversion: true
}
})
);
await app.init();
const contextId = ContextIdFactory.getByRequest(request);
service = await module.resolve<TasksService>(TasksService, contextId);
const { uri } = await inMemoryDb.runningInstance;
mongoose.Promise = Promise;
mongo = await mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false
});
TaskModel = getModelForClass(Task, { existingMongoose: mongo });
StageModel = getModelForClass(Stage, { existingMongoose: mongo });
TrackModel = getModelForClass(Track, { existingMongoose: mongo });
CourseModel = getModelForClass(Course, { existingMongoose: mongo });
TrackMentorModel = getModelForClass(TrackMentor, {
existingMongoose: mongo
});
MentorMenteeModel = getModelForClass(MentorMentee, {
existingMongoose: mongo
});
UserModel = getModelForClass(User, { existingMongoose: mongo });
const user = await UserModel.create({
email: validEmail,
firstName: 'firstName',
lastName: 'lastName',
password: validPass
});
currentUser = {
email: user.email,
userId: user.id,
role: user.role
};
route = request(app.getHttpServer());
});
describe('/tasks (POST)', () => {
const input: CreateTaskDto = {
title: 'Task1',
description: 'Description',
stage: '',
track: '',
course: ''
};
it('should return 401 if user not logged in', async () => {
return route.post('/tasks').send(input).expect(401);
});
it('should return 403 if user role is neither ADMIN nor MENTOR', async () => {
jest
.spyOn(jwtGuard, 'canActivate')
.mockImplementation((context: ExecutionContext) => {
const req = context.switchToHttp().getRequest();
req.user = currentUser;
return true;
});
return route.post('/tasks').send(input).expect(403);
});
let task: Task;
it('should return 201 if user role is permitted', async () => {
track = await TrackModel.create({
title: 'title',
description: 'description'
});
const newStage = await StageModel.create({
title: 'title',
description: 'description',
track: track.id,
level: 0
});
const newCourse = await CourseModel.create({
title: 'title',
description: 'description',
playlistUrl: 'www.google.com',
enrollmentCount: 0
});
input.stage = newStage.id;
input.track = track.id;
input.course = newCourse.id;
currentUser.role = UserRole.ADMIN;
const { body } = await route.post('/tasks').send(input).expect(201);
task = await service.findById(body.id);
expect(task.createdBy.toString()).toBe(currentUser.userId);
});
it('should return 409 for existing task title', async () => {
return route.post('/tasks').send(input).expect(409);
});
it('should return 200 when task is updated', async () => {
const newTitle = 'NEW_TITLE';
const { body } = await route
.put(`/tasks/${task.id}`)
.send({ ...input, title: newTitle })
.expect(200);
const { updatedBy } = await service.findById(body.id);
expect(body.title).toBe(newTitle);
expect(updatedBy.toString()).toBe(currentUser.userId);
});
it('should return 403 for non-permitted user trying to UPDATE track', async () => {
currentUser.role = UserRole.MENTEE;
return route.put(`/tasks/${task.id}`).send(input).expect(403);
});
it('should return 403 for non-permitted user trying to DELETE track', async () => {
return route.delete(`/tasks/${task.id}`).send(input).expect(403);
});
describe('/submission', () => {
let submissionDto: SubmissionDto;
it('should submit task', async () => {
const promise = fs.promises;
jest.spyOn(promise, 'readFile').mockResolvedValue('');
const mentor = await UserModel.create({
email: 'mentor' + validEmail,
firstName: 'Mentor',
lastName: 'Mentor',
password: validPass,
role: UserRole.MENTOR
});
currentUser.role = UserRole.MENTEE;
await MentorMenteeModel.create({
mentor: mentor.id,
mentee: currentUser.userId,
track: track
});
await TrackMentorModel.create({ mentor: mentor.id, track: track });
const dto: CreateSubmissionDto = {
menteeComment: 'comment',
taskUrl: 'www.google.com'
};
const { body } = await route
.post(`/tasks/${task.id}/submissions`)
.send(dto)
.expect(201);
const dbTask = await TaskModel.findById(task.id);
expect(dbTask.updatedBy.toString()).toBe(currentUser.userId);
expect(body.id).toBeDefined();
submissionDto = body;
});
it('should update already submitted task', async () => {
const updatedComment = 'updated_comment';
const dto: CreateSubmissionDto = {
menteeComment: updatedComment,
taskUrl: 'www.google.com'
};
const { body } = await route
.post(`/tasks/${task.id}/submissions`)
.send(dto)
.expect(201);
const dbTask = await TaskModel.findById(task.id);
expect(dbTask.updatedBy.toString()).toBe(currentUser.userId);
expect(body.menteeComment).toBe(updatedComment);
submissionDto = body;
});
it('should get task submissions', async () => {
const { body } = await route
.get(`/tasks/${task.id}/submissions`)
.expect(200);
const { items } = body;
expect(items.length).toBeGreaterThan(0);
expect(items).toContainEqual(submissionDto);
});
});
it('should soft delete track', async () => {
currentUser.role = UserRole.ADMIN;
await route.delete(`/tasks/${task.id}`).send(input).expect(200);
const { deletedBy, isDeleted } = await TaskModel.findById(task.id);
const res = await service.findById(task.id);
expect(deletedBy.toString()).toBe(currentUser.userId);
expect(isDeleted).toBe(true);
expect(res).toBeFalsy();
});
});
afterAll(async () => {
const { collections } = mongoose.connection;
Object.keys(collections).forEach(
async (k) => await collections[`${k}`].deleteMany({})
);
// await mongo.disconnect();
// await inMemoryDb.stop();
await app.close();
});
});
Example #5
Source File: tracks.e2e-spec.ts From codeclannigeria-backend with MIT License | 4 votes |
describe('TracksController (e2e)', () => {
let app: INestApplication;
let route: request.SuperTest<request.Test>;
let service: TracksService;
let mongo: typeof mongoose;
const validEmail = '[email protected]';
const validPass = 'pass@45Pdd';
let mentor: User;
let currentUser: JwtPayload;
let TrackModel: ReturnModelType<typeof Track>;
let UserModel: ReturnModelType<typeof User>;
let StageModel: ReturnModelType<typeof Stage>;
const jwtGuard = {
canActivate: (context: ExecutionContext): boolean => {
const req = context.switchToHttp().getRequest();
req.user = currentUser;
throw new UnauthorizedException();
}
};
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [TracksModule, DbTest],
providers: [JwtStrategy]
})
.overrideGuard(JwtAuthGuard)
.useValue(jwtGuard)
.compile();
app = module.createNestApplication();
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidUnknownValues: true,
forbidNonWhitelisted: true,
transform: true,
transformOptions: {
enableImplicitConversion: true
}
})
);
await app.init();
const contextId = ContextIdFactory.getByRequest(request);
service = await module.resolve<TracksService>(TracksService, contextId);
const { uri } = await inMemoryDb.runningInstance;
mongoose.Promise = Promise;
mongo = await mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false
});
UserModel = getModelForClass(User, { existingMongoose: mongo });
TrackModel = getModelForClass(Track, { existingMongoose: mongo });
const user = await UserModel.create({
email: validEmail,
firstName: 'firstName',
lastName: 'lastName',
password: validPass
});
currentUser = {
email: user.email,
userId: user.id,
role: user.role
};
route = request(app.getHttpServer());
});
describe('/tracks (POST)', () => {
const input: CreateTrackDto = {
title: 'Track1',
description: 'Description'
};
it('should return 401 if user not logged in', () => {
return route.post('/tracks').send(input).expect(401);
});
it('should return 403 if user role is neither ADMIN nor MENTOR', async () => {
jest
.spyOn(jwtGuard, 'canActivate')
.mockImplementation((context: ExecutionContext) => {
const req = context.switchToHttp().getRequest();
req.user = currentUser;
return true;
});
return route.post('/tracks').send(input).expect(403);
});
let track: Track;
let stageId: string;
it('should return 201 if user role is permitted', async () => {
currentUser.role = UserRole.ADMIN;
const { body } = await route.post('/tracks').send(input).expect(201);
track = await service.findById(body.id);
expect(track.createdBy.toString()).toBe(currentUser.userId);
StageModel = getModelForClass(Stage, { existingMongoose: mongo });
const stage: CreateStageDto = {
description: 'description',
title: 'title',
track: track.id,
level: 0
};
stageId = await (await StageModel.create({ ...stage })).id;
});
it('should create track with a thumbnail', async () => {
currentUser.role = UserRole.MENTOR;
const thumbnailUrl = 'https://www.securePhtotUrl.com';
jest.spyOn(uploader, 'uploadFileToCloud').mockResolvedValue(thumbnailUrl);
const { body } = await route
.post('/tracks/create_with_thumbnail')
.set('Content-Type', 'multipart/form-data')
.attach('thumbnail', './docs/images/compodoc-vectorise.png')
.field({
description: 'desc',
title: 'title'
})
.expect(HttpStatus.CREATED);
expect(body.thumbnailUrl).toBe(thumbnailUrl);
});
it('should return user stages via track ID', async () => {
const UserStageModel = getModelForClass(UserStage, {
existingMongoose: mongo
});
await UserStageModel.create({
user: currentUser.userId,
stage: stageId,
track: track.id
});
currentUser.role = UserRole.MENTEE;
const { body } = await route
.get(`/tracks/${track.id}/my_stages`)
.expect(200);
expect(body.items.length).toBeGreaterThan(0);
expect(body.items[0].stage.id).toBe(stageId);
});
it('should return user stages via track ID', async () => {
currentUser.role = UserRole.MENTEE;
const { body } = await route
.get(`/tracks/${track.id}/stages`)
.expect(200);
expect(body.items.length).toBeGreaterThan(0);
expect(body.items[0].track.id).toBe(track.id);
});
it('should create mentors of a track', async () => {
currentUser.role = UserRole.ADMIN;
const user = await UserModel.create({
email: '[email protected]',
firstName: 'Mentor',
lastName: 'Mentor',
password: validPass,
role: UserRole.MENTOR,
technologies: ['node'],
description: 'description'
});
const input: MentorInput = {
mentorId: user.id
};
await route.post(`/tracks/${track.id}/mentors`).send(input).expect(200);
mentor = user;
});
it('should return mentors of a track', async () => {
const { body } = await route
.get(`/tracks/${track.id}/mentors`)
.expect(200);
expect(body.items[0].id).toBe(mentor.id);
});
it('should enroll to a track', async () => {
const input: MentorInput = {
mentorId: mentor.id
};
await route.post(`/tracks/${track.id}/enroll`).send(input).expect(200);
const MentorMenteeModel = getModelForClass(MentorMentee);
const mentorMentee = await MentorMenteeModel.findOne({
mentor: mentor.id
});
expect(mentorMentee).toBeDefined();
expect((mentorMentee.mentee as any).id).toBe(currentUser.userId);
});
it('should return 409 for existing track title', async () => {
return route.post('/tracks').send(input).expect(409);
});
it('should return 200 when track is updated', async () => {
const newTitle = 'NEW_TITLE';
const { body } = await route
.put(`/tracks/${track.id}`)
.send({ ...input, title: newTitle })
.expect(200);
const { updatedBy } = await service.findById(body.id);
expect(body.title).toBe(newTitle);
expect(updatedBy.toString()).toBe(currentUser.userId);
});
it('should return 403 for non-permitted user trying to UPDATE track', async () => {
currentUser.role = UserRole.MENTEE;
return route.put(`/tracks/${track.id}`).send(input).expect(403);
});
it('should return 403 for non-permitted user trying to DELETE track', async () => {
await route.delete(`/tracks/${track.id}`).send(input).expect(403);
});
it('should soft delete track', async () => {
currentUser.role = UserRole.ADMIN;
await route.delete(`/tracks/${track.id}`).send(input).expect(200);
const { deletedBy, isDeleted } = await TrackModel.findById(track.id);
const res = await service.findById(track.id);
expect(deletedBy.toString()).toBe(currentUser.userId);
expect(isDeleted).toBe(true);
expect(res).toBeFalsy();
});
it('should return 403 for non-permitted user trying to soft delete track', async () => {
currentUser.role = UserRole.MENTEE;
await route.delete(`/tracks/${track.id}`).send(input).expect(403);
});
describe('Deactivate/Activate Track', () => {
it.todo('should deactivate track');
it.todo('should reactivate track');
it('should return 403 for non-permitted user trying to deactivate track', async () => {
currentUser.role = UserRole.MENTEE;
await route.put(`/tracks/${track.id}/deactivate`).expect(403);
});
it('should return 403 for non-permitted user trying to reactivate track', async () => {
currentUser.role = UserRole.MENTEE;
await route.put(`/tracks/${track.id}/reactivate`).expect(403);
});
});
});
afterAll(async () => {
const { collections } = mongoose.connection;
Object.keys(collections).forEach(
async (k) => await collections[`${k}`].deleteMany({})
);
// await mongo.disconnect();
// await inMemoryDb.stop();
await app.close();
});
});