Fix tests
This commit is contained in:
943
server/package-lock.json
generated
943
server/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,7 @@
|
|||||||
"@nestjs/serve-static": "^3.0.0",
|
"@nestjs/serve-static": "^3.0.0",
|
||||||
"@nestjs/terminus": "^9.2.2",
|
"@nestjs/terminus": "^9.2.2",
|
||||||
"@prisma/client": "^4.13.0",
|
"@prisma/client": "^4.13.0",
|
||||||
|
"jest-mock-extended": "^3.0.4",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rxjs": "^7.2.0"
|
"rxjs": "^7.2.0"
|
||||||
|
|||||||
@ -13,4 +13,8 @@ describe('AppController', () => {
|
|||||||
|
|
||||||
appController = app.get<AppController>(AppController);
|
appController = app.get<AppController>(AppController);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(appController).toBeDefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -6,16 +6,17 @@ import { TerminusModule } from '@nestjs/terminus';
|
|||||||
import { HasuraModule } from '@golevelup/nestjs-hasura';
|
import { HasuraModule } from '@golevelup/nestjs-hasura';
|
||||||
import { UserService } from './user/user.service';
|
import { UserService } from './user/user.service';
|
||||||
import { UserModule } from './user/user.module';
|
import { UserModule } from './user/user.module';
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [UserModule, TerminusModule, HasuraModule.forRoot(HasuraModule, {
|
imports: [
|
||||||
webhookConfig: {
|
UserModule,
|
||||||
secretFactory: process.env.HASURA_EVENT_HANDLER_SECRET_HEADER,
|
TerminusModule,
|
||||||
secretHeader: 'secret-header',
|
HasuraModule.forRoot(HasuraModule, {
|
||||||
},
|
webhookConfig: {
|
||||||
})
|
secretFactory: process.env.HASURA_EVENT_HANDLER_SECRET_HEADER,
|
||||||
],
|
secretHeader: 'secret-header',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
controllers: [AppController, HealthController],
|
controllers: [AppController, HealthController],
|
||||||
providers: [AppService, UserService],
|
providers: [AppService, UserService],
|
||||||
})
|
})
|
||||||
|
|||||||
16
server/src/database/client-mock/context.ts
Normal file
16
server/src/database/client-mock/context.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
import { mockDeep, DeepMockProxy } from 'jest-mock-extended';
|
||||||
|
|
||||||
|
export type Context = {
|
||||||
|
prisma: PrismaClient;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type MockContext = {
|
||||||
|
prisma: DeepMockProxy<PrismaClient>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createMockContext = (): MockContext => {
|
||||||
|
return {
|
||||||
|
prisma: mockDeep<PrismaClient>(),
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -8,22 +8,22 @@ datasource db {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model WorkspaceMember {
|
model WorkspaceMember {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
created_at DateTime @default(now())
|
created_at DateTime @default(now())
|
||||||
updated_at DateTime @updatedAt
|
updated_at DateTime @updatedAt
|
||||||
deleted_at DateTime?
|
deleted_at DateTime?
|
||||||
user_id String @unique
|
user_id String @unique
|
||||||
workspace_id Int
|
workspace_id Int
|
||||||
|
|
||||||
@@map("workspace_members")
|
@@map("workspace_members")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Workspace {
|
model Workspace {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
created_at DateTime @default(now())
|
created_at DateTime @default(now())
|
||||||
updated_at DateTime @updatedAt
|
updated_at DateTime @updatedAt
|
||||||
deleted_at DateTime?
|
deleted_at DateTime?
|
||||||
domain_name String @unique
|
domain_name String @unique
|
||||||
display_name String
|
display_name String
|
||||||
|
|
||||||
@@map("workspaces")
|
@@map("workspaces")
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Prisma, WorkspaceMember } from '@prisma/client';
|
import { Prisma, WorkspaceMember } from '@prisma/client';
|
||||||
import { PrismaService } from 'src/database/prisma.service';
|
import { PrismaService } from '../database/prisma.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserRepository {
|
export class UserRepository {
|
||||||
@ -8,7 +8,8 @@ export class UserRepository {
|
|||||||
|
|
||||||
async upsertWorkspaceMember(params: { data: Prisma.WorkspaceMemberCreateInput }): Promise<WorkspaceMember> {
|
async upsertWorkspaceMember(params: { data: Prisma.WorkspaceMemberCreateInput }): Promise<WorkspaceMember> {
|
||||||
const { data } = params;
|
const { data } = params;
|
||||||
return this.prisma.workspaceMember.upsert({
|
|
||||||
|
return await this.prisma.workspaceMember.upsert({
|
||||||
where: {
|
where: {
|
||||||
user_id: data.user_id,
|
user_id: data.user_id,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,18 +1,104 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { UserService } from './user.service';
|
import { UserService } from './user.service';
|
||||||
|
import { UserRepository } from './user.repository';
|
||||||
|
import { WorkspaceRepository } from './workspace.repository';
|
||||||
|
import { PrismaService } from '../database/prisma.service';
|
||||||
|
import {
|
||||||
|
MockContext,
|
||||||
|
createMockContext,
|
||||||
|
} from '../database/client-mock/context';
|
||||||
|
import { DeepMockProxy } from 'jest-mock-extended';
|
||||||
|
|
||||||
describe('UserService', () => {
|
describe('UserService', () => {
|
||||||
|
let mockCtx: MockContext;
|
||||||
let service: UserService;
|
let service: UserService;
|
||||||
|
let mockedPrismaService: DeepMockProxy<PrismaService>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
mockCtx = createMockContext();
|
||||||
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
providers: [UserService],
|
providers: [
|
||||||
}).compile();
|
UserService,
|
||||||
|
UserRepository,
|
||||||
|
WorkspaceRepository,
|
||||||
|
PrismaService,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.overrideProvider(PrismaService)
|
||||||
|
.useValue(mockCtx.prisma)
|
||||||
|
.compile();
|
||||||
|
|
||||||
service = module.get<UserService>(UserService);
|
service = module.get<UserService>(UserService);
|
||||||
|
mockedPrismaService =
|
||||||
|
module.get<DeepMockProxy<PrismaService>>(PrismaService);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be defined', () => {
|
it('should be defined', () => {
|
||||||
expect(service).toBeDefined();
|
expect(service).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('upsertWorkspaceMember should not upsert if email is absent', () => {
|
||||||
|
service.handleUserCreated({
|
||||||
|
event: {
|
||||||
|
data: { new: { id: 1, email: ''}, old: null },
|
||||||
|
session_variables: {},
|
||||||
|
op: 'INSERT'
|
||||||
|
},
|
||||||
|
id: '1',
|
||||||
|
table: { schema: 'auth', name: 'users' },
|
||||||
|
trigger: { name: 'user-created' },
|
||||||
|
delivery_info: { current_retry: 0, max_retries: 0},
|
||||||
|
created_at: '2021-03-01T00:00:00.000Z',
|
||||||
|
});
|
||||||
|
expect(mockedPrismaService.workspace.findUnique).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('upsertWorkspaceMember should upsert if domain name is found from email', async () => {
|
||||||
|
mockedPrismaService.workspace.findUnique.mockResolvedValue({
|
||||||
|
id: 2,
|
||||||
|
display_name: 'test',
|
||||||
|
domain_name: 'domain.namexxx',
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
deleted_at: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
mockedPrismaService.workspaceMember.upsert.mockResolvedValue({
|
||||||
|
id: 1,
|
||||||
|
user_id: '1',
|
||||||
|
workspace_id: 1,
|
||||||
|
created_at: new Date(),
|
||||||
|
updated_at: new Date(),
|
||||||
|
deleted_at: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
await service.handleUserCreated({
|
||||||
|
event: {
|
||||||
|
data: { new: { id: 1, email: 'test@domain.name' }, old: null },
|
||||||
|
session_variables: {},
|
||||||
|
op: 'INSERT',
|
||||||
|
},
|
||||||
|
id: '1',
|
||||||
|
table: { schema: 'auth', name: 'users' },
|
||||||
|
trigger: { name: 'user-created' },
|
||||||
|
delivery_info: { current_retry: 0, max_retries: 0 },
|
||||||
|
created_at: '2021-03-01T00:00:00.000Z',
|
||||||
|
});
|
||||||
|
expect(mockedPrismaService.workspace.findUnique).toHaveBeenCalledWith({
|
||||||
|
where: { domain_name: 'domain.name' },
|
||||||
|
});
|
||||||
|
expect(mockedPrismaService.workspaceMember.upsert).toHaveBeenCalledWith(
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
user_id: '1',
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
user_id: '1',
|
||||||
|
workspace_id: 2,
|
||||||
|
},
|
||||||
|
update: {},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
import { HasuraInsertEvent, TrackedHasuraEventHandler } from '@golevelup/nestjs-hasura';
|
import {
|
||||||
import { UserRepository} from "./user.repository"
|
HasuraInsertEvent,
|
||||||
|
TrackedHasuraEventHandler,
|
||||||
|
} from '@golevelup/nestjs-hasura';
|
||||||
|
import { UserRepository } from './user.repository';
|
||||||
import { Injectable, Response } from '@nestjs/common';
|
import { Injectable, Response } from '@nestjs/common';
|
||||||
import { WorkspaceRepository } from './workspace.repository';
|
import { WorkspaceRepository } from './workspace.repository';
|
||||||
import { response } from 'express';
|
import { response } from 'express';
|
||||||
@ -11,7 +14,10 @@ interface User {
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
constructor(private repository: UserRepository, private workspaceRepository: WorkspaceRepository) {}
|
constructor(
|
||||||
|
private repository: UserRepository,
|
||||||
|
private workspaceRepository: WorkspaceRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
@TrackedHasuraEventHandler({
|
@TrackedHasuraEventHandler({
|
||||||
triggerName: 'user-created',
|
triggerName: 'user-created',
|
||||||
@ -20,11 +26,15 @@ export class UserService {
|
|||||||
definition: { type: 'insert' },
|
definition: { type: 'insert' },
|
||||||
})
|
})
|
||||||
async handleUserCreated(evt: HasuraInsertEvent<User>) {
|
async handleUserCreated(evt: HasuraInsertEvent<User>) {
|
||||||
const workspace = await this.workspaceRepository.findWorkspaceByDomainName(
|
const emailDomain = evt.event.data.new.email.split('@')[1];
|
||||||
{ where: { domain_name:evt.event.data.new.email.split('@')[1] }
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(workspace)
|
if (!emailDomain) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const workspace = await this.workspaceRepository.findWorkspaceByDomainName({
|
||||||
|
where: { domain_name: emailDomain },
|
||||||
|
});
|
||||||
|
|
||||||
if (!workspace) {
|
if (!workspace) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Prisma, Workspace } from '@prisma/client';
|
import { Prisma, Workspace } from '@prisma/client';
|
||||||
import { PrismaService } from 'src/database/prisma.service';
|
import { PrismaService } from '../database/prisma.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkspaceRepository {
|
export class WorkspaceRepository {
|
||||||
constructor(private prisma: PrismaService) {}
|
constructor(private prisma: PrismaService) {}
|
||||||
|
|
||||||
async findWorkspaceByDomainName(data: Prisma.WorkspaceFindUniqueArgs): Promise<Workspace> {
|
async findWorkspaceByDomainName(
|
||||||
return this.prisma.workspace.findUnique(data);
|
data: Prisma.WorkspaceFindUniqueArgs,
|
||||||
}
|
): Promise<Workspace | null> {
|
||||||
|
return await this.prisma.workspace.findUnique(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -12,10 +12,10 @@
|
|||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strictNullChecks": false,
|
"strictNullChecks": true,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"strictBindCallApply": false,
|
"strictBindCallApply": false,
|
||||||
"forceConsistentCasingInFileNames": false,
|
"forceConsistentCasingInFileNames": false,
|
||||||
"noFallthroughCasesInSwitch": false
|
"noFallthroughCasesInSwitch": false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user