chore: refacto NestJS in modules (#308)

* chore: wip refacto in modules

* fix: rollback port

* fix: jwt guard in wrong folder

* chore: rename folder exception-filter in filters

* fix: tests are running

* fix: excessive stack depth comparing types

* fix: auth issue

* chore: move createUser in UserService

* fix: test

* fix: guards

* fix: jwt guard don't handle falsy user
This commit is contained in:
Jérémy M
2023-06-16 10:38:11 +02:00
committed by GitHub
parent 5921c7f11d
commit 2cd081234f
1084 changed files with 2251 additions and 758 deletions

View File

@ -0,0 +1,35 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CompanyRelationsResolver } from './company-relations.resolver';
import { CompanyService } from './company.service';
import { CommentThreadService } from '../comment/services/comment-thread.service';
import { CommentService } from '../comment/services/comment.service';
describe('CompanyRelationsResolver', () => {
let resolver: CompanyRelationsResolver;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
CompanyRelationsResolver,
{
provide: CompanyService,
useValue: {},
},
{
provide: CommentThreadService,
useValue: {},
},
{
provide: CommentService,
useValue: {},
},
],
}).compile();
resolver = module.get<CompanyRelationsResolver>(CompanyRelationsResolver);
});
it('should be defined', () => {
expect(resolver).toBeDefined();
});
});

View File

@ -0,0 +1,86 @@
import * as TypeGraphQL from '@nestjs/graphql';
import { CommentThread } from 'src/core/@generated/comment-thread/comment-thread.model';
import { Comment } from 'src/core/@generated/comment/comment.model';
import { Company } from 'src/core/@generated/company/company.model';
import { User } from 'src/core/@generated/user/user.model';
import { CompanyService } from './company.service';
import { CommentThreadService } from '../comment/services/comment-thread.service';
import { CommentService } from '../comment/services/comment.service';
@TypeGraphQL.Resolver(() => Company)
export class CompanyRelationsResolver {
constructor(
private readonly companyService: CompanyService,
private readonly commentThreadService: CommentThreadService,
private readonly commentService: CommentService,
) {}
@TypeGraphQL.ResolveField(() => User, {
nullable: true,
})
async accountOwner(
@TypeGraphQL.Parent() company: Company,
): Promise<User | null> {
return this.companyService
.findUniqueOrThrow({
where: {
id: company.id,
},
})
.accountOwner({});
}
@TypeGraphQL.ResolveField(() => [CommentThread], {
nullable: false,
})
async commentThreads(
@TypeGraphQL.Root() company: Company,
): Promise<CommentThread[]> {
return this.commentThreadService.findMany({
where: {
commentThreadTargets: {
some: {
commentableId: company.id,
commentableType: 'Company',
},
},
},
});
}
@TypeGraphQL.ResolveField(() => [Comment], {
nullable: false,
})
async comments(@TypeGraphQL.Root() company: Company): Promise<Comment[]> {
return this.commentService.findMany({
where: {
commentThread: {
commentThreadTargets: {
some: {
commentableId: company.id,
commentableType: 'Company',
},
},
},
},
});
}
@TypeGraphQL.ResolveField(() => TypeGraphQL.Int, {
nullable: false,
})
async _commentCount(@TypeGraphQL.Root() company: Company): Promise<number> {
return this.commentService.count({
where: {
commentThread: {
commentThreadTargets: {
some: {
commentableId: company.id,
commentableType: 'Company',
},
},
},
},
});
}
}

View File

@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { CompanyService } from './company.service';
import { CompanyResolver } from './company.resolver';
import { CompanyRelationsResolver } from './company-relations.resolver';
import { CommentModule } from '../comment/comment.module';
@Module({
imports: [CommentModule, CommentModule],
providers: [CompanyService, CompanyResolver, CompanyRelationsResolver],
exports: [CompanyService],
})
export class CompanyModule {}

View File

@ -0,0 +1,38 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CompanyResolver } from './company.resolver';
import { CompanyService } from './company.service';
import { UpdateOneGuard } from 'src/guards/update-one.guard';
import { CanActivate } from '@nestjs/common';
import { DeleteManyGuard } from 'src/guards/delete-many.guard';
import { CreateOneGuard } from 'src/guards/create-one.guard';
describe('CompanyResolver', () => {
let resolver: CompanyResolver;
beforeEach(async () => {
const mockGuard: CanActivate = { canActivate: jest.fn(() => true) };
const module: TestingModule = await Test.createTestingModule({
providers: [
CompanyResolver,
{
provide: CompanyService,
useValue: {},
},
],
})
.overrideGuard(UpdateOneGuard)
.useValue(mockGuard)
.overrideGuard(DeleteManyGuard)
.useValue(mockGuard)
.overrideGuard(CreateOneGuard)
.useValue(mockGuard)
.compile();
resolver = module.get<CompanyResolver>(CompanyResolver);
});
it('should be defined', () => {
expect(resolver).toBeDefined();
});
});

View File

@ -0,0 +1,79 @@
import { Resolver, Query, Args, Mutation } from '@nestjs/graphql';
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
import { UseGuards } from '@nestjs/common';
import { AuthWorkspace } from '../../decorators/auth-workspace.decorator';
import { Company } from '../../core/@generated/company/company.model';
import { FindManyCompanyArgs } from '../../core/@generated/company/find-many-company.args';
import { UpdateOneCompanyArgs } from '../../core/@generated/company/update-one-company.args';
import { CreateOneCompanyArgs } from '../../core/@generated/company/create-one-company.args';
import { AffectedRows } from '../../core/@generated/prisma/affected-rows.output';
import { DeleteManyCompanyArgs } from '../../core/@generated/company/delete-many-company.args';
import { Workspace } from '@prisma/client';
import { Prisma } from '@prisma/client';
import { UpdateOneGuard } from '../../guards/update-one.guard';
import { DeleteManyGuard } from '../../guards/delete-many.guard';
import { CreateOneGuard } from '../../guards/create-one.guard';
import { CompanyService } from './company.service';
import { prepareFindManyArgs } from 'src/utils/prepare-find-many';
@UseGuards(JwtAuthGuard)
@Resolver(() => Company)
export class CompanyResolver {
constructor(private readonly companyService: CompanyService) {}
@Query(() => [Company])
async findManyCompany(
@Args() args: FindManyCompanyArgs,
@AuthWorkspace() workspace: Workspace,
) {
const preparedArgs = prepareFindManyArgs<FindManyCompanyArgs>(
args,
workspace,
);
return this.companyService.findMany(preparedArgs);
}
@UseGuards(UpdateOneGuard)
@Mutation(() => Company, {
nullable: true,
})
async updateOneCompany(
@Args() args: UpdateOneCompanyArgs,
): Promise<Company | null> {
if (!args.data.accountOwner?.connect?.id) {
args.data.accountOwner = { disconnect: true };
}
return this.companyService.update({
...args,
} satisfies UpdateOneCompanyArgs as Prisma.CompanyUpdateArgs);
}
@UseGuards(DeleteManyGuard)
@Mutation(() => AffectedRows, {
nullable: false,
})
async deleteManyCompany(
@Args() args: DeleteManyCompanyArgs,
): Promise<AffectedRows> {
return this.companyService.deleteMany({
...args,
});
}
@UseGuards(CreateOneGuard)
@Mutation(() => Company, {
nullable: false,
})
async createOneCompany(
@Args() args: CreateOneCompanyArgs,
@AuthWorkspace() workspace: Workspace,
): Promise<Company> {
return this.companyService.create({
data: {
...args.data,
...{ workspace: { connect: { id: workspace.id } } },
},
} satisfies CreateOneCompanyArgs as Prisma.CompanyCreateArgs);
}
}

View File

@ -0,0 +1,26 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CompanyService } from './company.service';
import { PrismaService } from 'src/database/prisma.service';
import { prismaMock } from 'src/prisma-mock/jest-prisma-singleton';
describe('CompanyService', () => {
let service: CompanyService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
CompanyService,
{
provide: PrismaService,
useValue: prismaMock,
},
],
}).compile();
service = module.get<CompanyService>(CompanyService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/database/prisma.service';
@Injectable()
export class CompanyService {
constructor(private readonly prismaService: PrismaService) {}
// Find
findFirst = this.prismaService.company.findFirst;
findFirstOrThrow = this.prismaService.company.findFirstOrThrow;
findUnique = this.prismaService.company.findUnique;
findUniqueOrThrow = this.prismaService.company.findUniqueOrThrow;
findMany = this.prismaService.company.findMany;
// Create
create = this.prismaService.company.create;
createMany = this.prismaService.company.createMany;
// Update
update = this.prismaService.company.update;
upsert = this.prismaService.company.upsert;
updateMany = this.prismaService.company.updateMany;
// Delete
delete = this.prismaService.company.delete;
deleteMany = this.prismaService.company.deleteMany;
// Aggregate
aggregate = this.prismaService.company.aggregate;
// Count
count = this.prismaService.company.count;
// GroupBy
groupBy = this.prismaService.company.groupBy;
}