@@ -2,9 +2,6 @@ import { Injectable, Logger } from '@nestjs/common'
|
||||
|
||||
import { ArticleType } from '~/constants/article.constant'
|
||||
import { RedisKeys } from '~/constants/cache.constant'
|
||||
import { NoteModel } from '~/modules/note/note.model'
|
||||
import { PostModel } from '~/modules/post/post.model'
|
||||
import { InjectModel } from '~/transformers/model.transformer'
|
||||
import { getRedisKey } from '~/utils/redis.util'
|
||||
|
||||
import { DatabaseService } from '../database/database.service'
|
||||
@@ -14,10 +11,6 @@ import { CacheService } from '../redis/cache.service'
|
||||
export class CountingService {
|
||||
private logger: Logger
|
||||
constructor(
|
||||
@InjectModel(PostModel)
|
||||
private readonly postModel: MongooseModel<PostModel>,
|
||||
@InjectModel(NoteModel)
|
||||
private readonly noteModel: MongooseModel<NoteModel>,
|
||||
private readonly redis: CacheService,
|
||||
private readonly databaseService: DatabaseService,
|
||||
) {
|
||||
|
||||
@@ -7,6 +7,14 @@ export const defineProvider = <T>(provider: Provider<T>) => {
|
||||
return provider
|
||||
}
|
||||
|
||||
export const defineProviders = (providers: Provider[]) => {
|
||||
export function defineProviders<T>(providers: [Provider<T>]): [Provider<T>]
|
||||
export function defineProviders<T1, T2>(
|
||||
providers: [Provider<T1>, Provider<T2>],
|
||||
): [Provider<T1>, Provider<T2>]
|
||||
export function defineProviders<T1, T2, T3>(
|
||||
providers: [Provider<T1>, Provider<T2>, Provider<T3>],
|
||||
): [Provider<T1>, Provider<T2>, Provider<T3>]
|
||||
|
||||
export function defineProviders(providers: Provider[]) {
|
||||
return providers
|
||||
}
|
||||
|
||||
41
test/mock/interceptors/counting.interceptor.ts
Normal file
41
test/mock/interceptors/counting.interceptor.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { map } from 'rxjs'
|
||||
|
||||
import {
|
||||
CallHandler,
|
||||
ExecutionContext,
|
||||
Inject,
|
||||
Injectable,
|
||||
NestInterceptor,
|
||||
} from '@nestjs/common'
|
||||
import { Reflector } from '@nestjs/core'
|
||||
|
||||
import { HTTP_RES_UPDATE_DOC_COUNT_TYPE } from '~/constants/meta.constant'
|
||||
import { REFLECTOR } from '~/constants/system.constant'
|
||||
import { CountingService } from '~/processors/helper/helper.counting.service'
|
||||
|
||||
@Injectable()
|
||||
export class MockingCountingInterceptor<T> implements NestInterceptor<T> {
|
||||
constructor(
|
||||
@Inject(REFLECTOR) private readonly reflector: Reflector,
|
||||
private readonly countingService: CountingService,
|
||||
) {}
|
||||
|
||||
intercept(context: ExecutionContext, next: CallHandler) {
|
||||
const handler = context.getHandler()
|
||||
return next.handle().pipe(
|
||||
map((data) => {
|
||||
// 计数处理
|
||||
const documentType = this.reflector.get(
|
||||
HTTP_RES_UPDATE_DOC_COUNT_TYPE,
|
||||
handler,
|
||||
)
|
||||
if (documentType && data) {
|
||||
// @ts-ignore
|
||||
this.countingService.updateReadCount()
|
||||
}
|
||||
|
||||
return data
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,9 @@ export const countingServiceProvider = defineProvider({
|
||||
async getThisRecordIsLiked() {
|
||||
return true
|
||||
},
|
||||
async updateReadCount() {
|
||||
updateReadCount: vi.fn().mockImplementation(async () => {
|
||||
return
|
||||
},
|
||||
}),
|
||||
},
|
||||
provide: CountingService,
|
||||
})
|
||||
|
||||
16
test/mock/processors/email.mock.ts
Normal file
16
test/mock/processors/email.mock.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { defineProvider } from 'test/helper/defineProvider'
|
||||
|
||||
import { EmailService } from '~/processors/helper/helper.email.service'
|
||||
|
||||
export const emailProvider = defineProvider({
|
||||
provide: EmailService,
|
||||
useValue: {
|
||||
async send(options) {},
|
||||
render(template, source) {
|
||||
return ''
|
||||
},
|
||||
sendTestEmail() {
|
||||
return Promise.resolve()
|
||||
},
|
||||
},
|
||||
})
|
||||
40
test/mock/processors/event.mock.ts
Normal file
40
test/mock/processors/event.mock.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { defineProviders } from 'test/helper/defineProvider'
|
||||
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter'
|
||||
|
||||
import { EventManagerService } from '~/processors/helper/helper.event.service'
|
||||
import { SubPubBridgeService } from '~/processors/redis/subpub.service'
|
||||
|
||||
export const eventEmitterProvider = defineProviders([
|
||||
{
|
||||
provide: EventEmitter2,
|
||||
useValue: {
|
||||
emit(event, data) {
|
||||
return true
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: SubPubBridgeService,
|
||||
useValue: {
|
||||
async publish(event, data) {},
|
||||
async subscribe(event, callback) {},
|
||||
async unsubscribe(event, callback) {},
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: EventManagerService,
|
||||
useValue: {
|
||||
async broadcast(event, data) {},
|
||||
async emit() {},
|
||||
on() {
|
||||
return noop
|
||||
},
|
||||
registerHandler() {
|
||||
return noop
|
||||
},
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
const noop = () => {}
|
||||
@@ -1,8 +1,9 @@
|
||||
import { createE2EApp } from 'test/helper/create-e2e-app'
|
||||
import { gatewayProviders } from 'test/mock/modules/gateway.mock'
|
||||
import { userProvider } from 'test/mock/modules/user.mock'
|
||||
import { emailProvider } from 'test/mock/processors/email.mock'
|
||||
import { eventEmitterProvider } from 'test/mock/processors/event.mock'
|
||||
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter'
|
||||
import { ReturnModelType } from '@typegoose/typegoose'
|
||||
|
||||
import { OptionModel } from '~/modules/configs/configs.model'
|
||||
@@ -13,11 +14,7 @@ import {
|
||||
} from '~/modules/link/link.controller'
|
||||
import { LinkModel, LinkState } from '~/modules/link/link.model'
|
||||
import { LinkService } from '~/modules/link/link.service'
|
||||
import { AssetService } from '~/processors/helper/helper.asset.service'
|
||||
import { EmailService } from '~/processors/helper/helper.email.service'
|
||||
import { EventManagerService } from '~/processors/helper/helper.event.service'
|
||||
import { HttpService } from '~/processors/helper/helper.http.service'
|
||||
import { SubPubBridgeService } from '~/processors/redis/subpub.service'
|
||||
|
||||
describe('Test LinkController(E2E)', () => {
|
||||
const proxy = createE2EApp({
|
||||
@@ -26,14 +23,14 @@ describe('Test LinkController(E2E)', () => {
|
||||
providers: [
|
||||
...gatewayProviders,
|
||||
LinkService,
|
||||
ConfigsService,
|
||||
EmailService,
|
||||
|
||||
emailProvider,
|
||||
HttpService,
|
||||
EventManagerService,
|
||||
|
||||
userProvider,
|
||||
SubPubBridgeService,
|
||||
AssetService,
|
||||
EventEmitter2,
|
||||
|
||||
ConfigsService,
|
||||
...eventEmitterProvider,
|
||||
],
|
||||
async pourData(modelMap) {
|
||||
const linkModel = modelMap.get(LinkModel)
|
||||
|
||||
@@ -259,6 +259,39 @@ exports[`NoteController (e2e) > GET /notes 1`] = `
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`NoteController (e2e) > GET /notes/nid/:nid 1`] = `
|
||||
{
|
||||
"data": {
|
||||
"allow_comment": true,
|
||||
"comments_index": 0,
|
||||
"count": {
|
||||
"like": 0,
|
||||
"read": 0,
|
||||
},
|
||||
"created": "2023-01-17T11:01:57.851Z",
|
||||
"hide": false,
|
||||
"images": [],
|
||||
"liked": true,
|
||||
"modified": null,
|
||||
"mood": "happy",
|
||||
"music": [],
|
||||
"nid": 21,
|
||||
"text": "Content 2 (updated)",
|
||||
"title": "Note 2 (updated)",
|
||||
"topic": null,
|
||||
"weather": "sunny",
|
||||
},
|
||||
"next": {
|
||||
"created": "2021-03-20T00:00:00.000Z",
|
||||
"modified": null,
|
||||
"nid": 20,
|
||||
"title": "Note 20",
|
||||
"topic": null,
|
||||
},
|
||||
"prev": null,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`NoteController (e2e) > Get patched note 1`] = `
|
||||
{
|
||||
"allow_comment": true,
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { createE2EApp } from 'test/helper/create-e2e-app'
|
||||
import { MockingCountingInterceptor } from 'test/mock/interceptors/counting.interceptor'
|
||||
import { authProvider } from 'test/mock/modules/auth.mock'
|
||||
import { commentProvider } from 'test/mock/modules/comment.mock'
|
||||
import { configProvider } from 'test/mock/modules/config.mock'
|
||||
import { gatewayProviders } from 'test/mock/modules/gateway.mock'
|
||||
import { countingServiceProvider } from 'test/mock/processors/counting.mock'
|
||||
import { eventEmitterProvider } from 'test/mock/processors/event.mock'
|
||||
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter'
|
||||
import { APP_INTERCEPTOR } from '@nestjs/core'
|
||||
import { ReturnModelType } from '@typegoose/typegoose'
|
||||
|
||||
import { OptionModel } from '~/modules/configs/configs.model'
|
||||
@@ -14,12 +16,9 @@ import { NoteModel } from '~/modules/note/note.model'
|
||||
import { NoteService } from '~/modules/note/note.service'
|
||||
import { UserModel } from '~/modules/user/user.model'
|
||||
import { UserService } from '~/modules/user/user.service'
|
||||
import { CountingService } from '~/processors/helper/helper.counting.service'
|
||||
import { EventManagerService } from '~/processors/helper/helper.event.service'
|
||||
import { HttpService } from '~/processors/helper/helper.http.service'
|
||||
import { ImageService } from '~/processors/helper/helper.image.service'
|
||||
import { TextMacroService } from '~/processors/helper/helper.macro.service'
|
||||
import { SubPubBridgeService } from '~/processors/redis/subpub.service'
|
||||
|
||||
import MockDbData from './note.e2e-mock.db'
|
||||
|
||||
@@ -30,7 +29,12 @@ describe('NoteController (e2e)', () => {
|
||||
providers: [
|
||||
NoteService,
|
||||
ImageService,
|
||||
EventManagerService,
|
||||
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useClass: MockingCountingInterceptor,
|
||||
},
|
||||
|
||||
commentProvider,
|
||||
|
||||
{
|
||||
@@ -43,12 +47,12 @@ describe('NoteController (e2e)', () => {
|
||||
},
|
||||
HttpService,
|
||||
configProvider,
|
||||
EventEmitter2,
|
||||
|
||||
UserService,
|
||||
SubPubBridgeService,
|
||||
...eventEmitterProvider,
|
||||
...gatewayProviders,
|
||||
authProvider,
|
||||
CountingService,
|
||||
|
||||
countingServiceProvider,
|
||||
],
|
||||
imports: [],
|
||||
@@ -156,6 +160,29 @@ describe('NoteController (e2e)', () => {
|
||||
expect(data).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('GET /notes/nid/:nid', async () => {
|
||||
const { app } = proxy
|
||||
const res = await app.inject({
|
||||
method: 'GET',
|
||||
url: `/notes/nid/${createdNoteData.nid}`,
|
||||
})
|
||||
|
||||
expect(res.statusCode).toBe(200)
|
||||
const data = res.json()
|
||||
delete data.id
|
||||
delete data.data.id
|
||||
if (data.prev) {
|
||||
delete data.prev.id
|
||||
}
|
||||
if (data.next) {
|
||||
delete data.next.id
|
||||
}
|
||||
|
||||
expect(data).toMatchSnapshot()
|
||||
|
||||
expect(countingServiceProvider.useValue.updateReadCount).toBeCalled()
|
||||
})
|
||||
|
||||
test('DEL /notes/:id', async () => {
|
||||
const { app } = proxy
|
||||
const res = await app.inject({
|
||||
|
||||
Reference in New Issue
Block a user