universo-platform-3d
160 строк · 4.4 Кб
1import { Provider, Type } from '@nestjs/common'2import { getModelToken } from '@nestjs/mongoose'3import { Model } from 'mongoose'4import { vi } from 'vitest'5import { CreateScriptEntityDto } from '../../src/script-entity/dto/create-script-entity.dto'6import { UpdateScriptEntityDto } from '../../src/script-entity/dto/update-script-entity.dto'7import { ScriptEntityDocument } from '../../src/script-entity/script-entity.schema'8import { MockMongooseClass } from './mongoose-module.mock'9
10/**
11* @description This is used as a convenience to mock many classes in the providers array. It results in:
12{
13provide: ZoneService,
14useClass: createViMockClass(ZoneService)
15},
16{
17provide: SpaceService,
18useClass: createViMockClass(SpaceService)
19},
20{
21provide: SpaceObjectService,
22useClass: createViMockClass(SpaceObjectService)
23}
24
25Then in providers, it can be used as
26...getMockClassesForProvidersArray([ZoneService, SpaceService, SpaceObjectService])
27* @date 2023-07-03 18:07
28*/
29export function getMockClassesForProvidersArray(classes: any[]): Provider[] {30return classes.map((c: any) => {31return {32provide: c,33useValue: createViMockClass(c)34}35})36}
37
38export function createViMockClass(targetClass: Type<any>): Type<any> {39const propertyNames = Object.getOwnPropertyNames(targetClass.prototype)40
41for (const propertyName of propertyNames) {42const propertyValue = targetClass.prototype[propertyName]43
44if (typeof propertyValue === 'function') {45targetClass.prototype[propertyName] = vi.fn()46}47}48
49return targetClass50}
51
52/**
53* @description Similar to the above, this results in
54[{
55provide: getModelToken('Zone'),
56useValue: MockMongooseClass
57},
58{
59provide: getModelToken('Terrain'),
60useValue: MockMongooseClass
61}]
62* @date 2023-07-03 18:09
63*/
64export function getMockMongooseModelsForProvidersArray(65modelNames: string[] = [66// The default list here is everything, which will cover most use caes67'Asset',68'CustomData',69'Environment',70'MapAsset',71'Material',72'Role',73'Space',74'SpaceObject',75'SpaceVariable',76'SpaceVariablesData',77'SpaceVersion',78'Terrain',79'Texture',80'User',81'UserAccessKey',82'UserEntityAction',83'PurchaseOption'84]85): Provider[] {86return modelNames.map((c: any) => {87return {88provide: getModelToken(c),89useClass: MockMongooseClass90}91})92}
93
94/**
95* ScriptEntityService
96*/
97export class MockScriptEntityService {98private scriptEntities: ScriptEntityDocument[] = []99private readonly model: Model<ScriptEntityDocument>100
101constructor() {102this.model = {103create: vi.fn().mockResolvedValue(null),104findById: vi.fn().mockImplementation((id: string) => {105const found = this.scriptEntities.find((entity) => entity._id === id)106return Promise.resolve(found || null)107}),108findByIdAndUpdate: vi109.fn()110.mockImplementation((id: string, update: any) => {111const found = this.scriptEntities.find((entity) => entity._id === id)112if (found) {113const updated = { ...found, ...update }114this.scriptEntities = this.scriptEntities.map((entity) =>115entity._id === id ? updated : entity116)117return Promise.resolve(updated)118}119return Promise.resolve(null)120}),121findOneAndDelete: vi.fn().mockImplementation((condition: any) => {122const found = this.scriptEntities.find(123(entity) => entity._id === condition._id124)125if (found) {126this.scriptEntities = this.scriptEntities.filter(127(entity) => entity._id !== condition._id128)129return Promise.resolve(found)130}131return Promise.resolve(null)132})133} as unknown as Model<ScriptEntityDocument>134}135
136create(137createScriptEntityDto: CreateScriptEntityDto138): Promise<ScriptEntityDocument> {139const created: ScriptEntityDocument = {140_id: (this.scriptEntities.length + 1).toString(),141...createScriptEntityDto142} as ScriptEntityDocument143this.scriptEntities.push(created)144return Promise.resolve(created)145}146
147findOne(id: string) {148return this.model.findById(id)149}150
151update(id: string, updateScriptEntityDto: UpdateScriptEntityDto) {152return this.model.findByIdAndUpdate(id, updateScriptEntityDto, {153new: true154})155}156
157delete(id: string) {158return this.model.findOneAndDelete({ _id: id })159}160}
161