diff --git a/README.md b/README.md index 7db8b87..21a3bcb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Store Box +# StoreBox-Api Store PandoraBox Firmware Images and its packages diff --git a/TODOLIST.md b/TODOLIST.md index 6260308..248fa7c 100644 --- a/TODOLIST.md +++ b/TODOLIST.md @@ -6,9 +6,11 @@ - [x] 上传到指定Categroy - [x] 上传时追加Catogroy - [x] 整顿collectin info的goods 列表 -- [ ] Token 使用日志显示 -- [ ] Good 下载次数统计 -- [ ] 接入统计 +- [ ] 统计 + - [ ] Token 使用日志显示 + - [ ] 用户登录记录 + - [x] Good 下载次数统计 + - [ ] 接入统计 - [x] 配置文件写入初始化用户账号密码 - [ ] 接入AuthBox - [x] Redis 接入 diff --git a/src/express.ts b/src/express.ts index 3fd5e1d..6763927 100644 --- a/src/express.ts +++ b/src/express.ts @@ -6,7 +6,7 @@ import connectRedis = require("connect-redis"); import { config } from "@utils/config"; import helmet = require("helmet"); -import { error } from "./modules/common/middlewares/logger.middleware"; +import { error } from "./middlewares/logger.middleware"; import { isTest } from "@utils/env"; const RedisStore = connectRedis(session); diff --git a/src/modules/common/interceptors/regexp-count-check.interceptor.ts b/src/interceptors/regexp-count-check.interceptor.ts similarity index 100% rename from src/modules/common/interceptors/regexp-count-check.interceptor.ts rename to src/interceptors/regexp-count-check.interceptor.ts diff --git a/src/modules/common/middlewares/logger.middleware.ts b/src/middlewares/logger.middleware.ts similarity index 100% rename from src/modules/common/middlewares/logger.middleware.ts rename to src/middlewares/logger.middleware.ts diff --git a/src/modules/common/middlewares/noCache.middleware.ts b/src/middlewares/noCache.middleware.ts similarity index 100% rename from src/modules/common/middlewares/noCache.middleware.ts rename to src/middlewares/noCache.middleware.ts diff --git a/src/modules/common/middlewares/reloadSession.middleware.ts b/src/middlewares/reloadSession.middleware.ts similarity index 100% rename from src/modules/common/middlewares/reloadSession.middleware.ts rename to src/middlewares/reloadSession.middleware.ts diff --git a/src/modules/common/middlewares/roles.middleware.ts b/src/middlewares/roles.middleware.ts similarity index 100% rename from src/modules/common/middlewares/roles.middleware.ts rename to src/middlewares/roles.middleware.ts diff --git a/src/modules/common/middlewares/upload.middleware.ts b/src/middlewares/upload.middleware.ts similarity index 100% rename from src/modules/common/middlewares/upload.middleware.ts rename to src/middlewares/upload.middleware.ts diff --git a/src/models/Log.ts b/src/models/Log.ts new file mode 100644 index 0000000..368cf38 --- /dev/null +++ b/src/models/Log.ts @@ -0,0 +1,27 @@ +import { model, SchemaDefinition, Model as M } from "mongoose"; +import { Base, IDoc, IDocRaw } from "./common"; +import newCache = require("@utils/newCache"); + +const Definition: SchemaDefinition = { + key: { type: String, required: true }, + type: { type: String, required: true }, + ua: { type: String, required: true }, + ipaddr: { type: String, required: true } +}; + +export interface ILogs extends IDocRaw { + key: string; + type: string; + ua: string; + ipaddr: string; +} + +export const FLAG = "logs"; + +export const cache = newCache(FLAG); + +const Schema = new Base(Definition).createSchema(); + +export type LogDoc = IDoc; + +export const Model: M = model(FLAG, Schema); diff --git a/src/modules/app.module.ts b/src/modules/app.module.ts index 5a4e6e7..030e220 100644 --- a/src/modules/app.module.ts +++ b/src/modules/app.module.ts @@ -2,7 +2,7 @@ import { Module, MiddlewaresConsumer } from "@nestjs/common"; // Modules import { DatabaseModule } from "./database/database.module"; import {controllers, ControllersModule} from "./controllers.module"; -import { NoCacheMiddleware } from "./common/middlewares/noCache.middleware"; +import { NoCacheMiddleware } from "../middlewares/noCache.middleware"; @Module({ modules: [ DatabaseModule, ControllersModule ] diff --git a/src/modules/collections/collections.admin.controller.ts b/src/modules/collections/collections.admin.controller.ts index ba0bfbd..9b58c80 100644 --- a/src/modules/collections/collections.admin.controller.ts +++ b/src/modules/collections/collections.admin.controller.ts @@ -9,6 +9,7 @@ import { CollectionDoc } from "@models/Collection"; import { ObjectId } from "@models/common"; import { RolesGuard } from "@guards/roles"; import { CollectionsService } from "@services/collections"; +import { LogsService } from "@services/logs"; import { UtilService } from "@services/util"; import { Roles } from "@decorators/roles"; import { ParseIntPipe } from "@pipes/parse-int"; @@ -27,7 +28,10 @@ import { // endregion Swagger Docs export class CollectionsAdminController { - constructor(private readonly collectionsSvr: CollectionsService) { } + constructor( + private readonly collectionsSvr: CollectionsService, + private readonly logsSvr: LogsService + ) { } private async getCollectionsRes(uid: ObjectId, query: PerPageDto) { const arr = await this.collectionsSvr.list(uid, { @@ -102,12 +106,17 @@ export class CollectionsAdminController { @ApiOperation({ title: "Get One Collection's Info" }) // endregion Swagger Docs public async getCollection(@Param() param: CCidDto) { - const obj = await this.collectionsSvr.getById(param.cid); + const obj = await this.collectionsSvr.getObjectById(param.cid); if (!obj) { return null; } - obj.goods = UtilService.toListRespone(obj.goods as any[], { - perNum: obj.goods.length + const goods = [ ]; + for (const good of obj.goods) { + good.downloaded = await this.logsSvr.goodDownloadCount(good._id); + goods.push(good); + } + obj.goods = UtilService.toListRespone(goods, { + perNum: goods.length }) as any; return obj; } diff --git a/src/modules/collections/collections.controller.ts b/src/modules/collections/collections.controller.ts index bb3fea1..ab2a285 100644 --- a/src/modules/collections/collections.controller.ts +++ b/src/modules/collections/collections.controller.ts @@ -9,6 +9,7 @@ import { Roles } from "@decorators/roles"; import { GetCollectionNameDto } from "./collections.dto"; import { PerPageDto } from "@dtos/page"; import { ParseIntPipe } from "@pipes/parse-int"; +import { LogsService } from "@services/logs"; @UseGuards(RolesGuard) @Controller("/collections") @@ -17,7 +18,10 @@ import { ParseIntPipe } from "@pipes/parse-int"; // endregion Swagger Docs export class CollectionsController { - constructor(private readonly collectionsSvr: CollectionsService) { } + constructor( + private readonly collectionsSvr: CollectionsService, + private readonly logsSvr: LogsService + ) { } @Roles("guest") @Get("/:name") @@ -29,25 +33,27 @@ export class CollectionsController { @Param() param: GetCollectionNameDto, @Query(new ParseIntPipe()) query: PerPageDto ) { - const doc = await this.collectionsSvr.getByName(param.name); + const doc = await this.collectionsSvr.getObjectByName(param.name); if (!doc) { return null; } - let obj; - obj = doc.toObject(); - obj.creator = obj.creator.nickname; - obj.goods.map((good) => { + const obj = doc; + // obj = doc.toObject(); + obj.creator = obj.creator.nickname as any; + const goods = [ ]; + for (const good of obj.goods) { const keys = [ "__v", "uploader", "hidden" ]; for (const key of keys) { delete good[key]; } - return good; - }); - obj.goods = UtilService.toListRespone(obj.goods, { - perNum: obj.goods.length - }); + good.downloaded = await this.logsSvr.goodDownloadCount(good._id); + goods.push(good); + } + obj.goods = UtilService.toListRespone(goods, { + perNum: goods.length + }) as any; return obj; } diff --git a/src/modules/controllers.module.ts b/src/modules/controllers.module.ts index cb817d1..f528153 100644 --- a/src/modules/controllers.module.ts +++ b/src/modules/controllers.module.ts @@ -21,14 +21,14 @@ import { SystemController } from "./system/system.controller"; // region Middlewares import { UploadFileMiddleware, UploadFilesMiddleware -} from "./common/middlewares/upload.middleware"; +} from "../middlewares/upload.middleware"; import { ApiLoggerMiddleware, DownloadLoggerMiddleware -} from "./common/middlewares/logger.middleware"; -import { RolesMiddleware } from "./common/middlewares/roles.middleware"; +} from "../middlewares/logger.middleware"; +import { RolesMiddleware } from "../middlewares/roles.middleware"; import { ReloadSessionMiddleware -} from "./common/middlewares/reloadSession.middleware"; +} from "../middlewares/reloadSession.middleware"; // endregion Middlewares // region Services @@ -40,6 +40,7 @@ import { UsergroupsService } from "@services/usergroups"; import { SystemService } from "@services/system"; import { CategoriesService } from "@services/categories"; import { GoodsService } from "@services/goods"; +import { LogsService } from "@services/logs"; // endregion Services export const controllers = [ @@ -56,7 +57,7 @@ export const controllers = [ export const services = [ RegexpsService, CategoriesService, GoodsService, CollectionsService, TokensService, UsersService, UsergroupsService, - SystemService + SystemService, LogsService ]; @Module({ diff --git a/src/modules/files/files.controller.ts b/src/modules/files/files.controller.ts index fce6fb6..69f6dc9 100644 --- a/src/modules/files/files.controller.ts +++ b/src/modules/files/files.controller.ts @@ -9,6 +9,7 @@ import { Roles } from "@decorators/roles"; import { RolesGuard } from "@guards/roles"; import { ParseIntPipe } from "@pipes/parse-int"; import { GoodsService } from "@services/goods"; +import { LogsService } from "@services/logs"; import { Response } from "express"; import pathExists = require("path-exists"); @@ -26,7 +27,10 @@ import { DownlaodDto } from "./files.dto"; @ApiUseTags("Good Download") export class FilesController { - constructor(private readonly goodsSvr: GoodsService) { } + constructor( + private readonly goodsSvr: GoodsService, + private readonly logsSvr: LogsService + ) { } @Roles("guest") @Get("/categories/:cid/goods/:id") @@ -52,6 +56,7 @@ export class FilesController { if (!good.active) { throw new BadRequestException("Disallow download the File"); } + await this.logsSvr.stepGoodDownloadCount(params.id, req); res.download(filepath, good.originname, (err) => { /* istanbul ignore if */ if (err) { diff --git a/src/modules/files/goods.controller.ts b/src/modules/files/goods.controller.ts index 67b3914..7b6edbe 100644 --- a/src/modules/files/goods.controller.ts +++ b/src/modules/files/goods.controller.ts @@ -10,7 +10,9 @@ import { GoodsService } from "@services/goods"; import { CategoriesService } from "@services/categories"; import { Roles } from "@decorators/roles"; import { ParseIntPipe } from "@pipes/parse-int"; +import { ToArrayPipe } from "@pipes/to-array"; import { ListResponse, DEF_PER_COUNT } from "@dtos/page"; +import { LogsService } from "@services/logs"; import { reduce } from "lodash"; import { GoodsQueryDto } from "./goods.dto"; @@ -22,7 +24,8 @@ export class GoodsController { constructor( private readonly goodsSvr: GoodsService, - private readonly categoriesSvr: CategoriesService + private readonly categoriesSvr: CategoriesService, + private readonly logsSvr: LogsService ) { } @Roles("guest") @@ -32,7 +35,9 @@ export class GoodsController { @ApiOperation({ title: "Get Good List" }) @ApiResponse({ status: HttpStatus.OK, type: ListResponse }) // endregion Swagger Docs - public async getList(@Query(new ParseIntPipe()) query: GoodsQueryDto) { + public async getList( + @Query(new ParseIntPipe(), new ToArrayPipe("tags")) query: GoodsQueryDto + ) { const categoryModels = await this.categoriesSvr.getByTags(query.tags); const categories = reduce(categoryModels, (obj, cate) => { obj[cate._id.toString()] = cate; @@ -41,7 +46,6 @@ export class GoodsController { if (Object.keys(categories).length === 0) { return UtilService.toListRespone([ ]); } - const perNum = query.perNum || DEF_PER_COUNT; const cids = Object.keys(categories); const goods = @@ -56,6 +60,7 @@ export class GoodsController { good.attributes = Array.from(new Set( good.attributes.concat(category.attributes) )) as any; + good.downloaded = this.logsSvr.goodDownloadCount(good._id); return good; }); return UtilService.toListRespone(goods, Object.assign({ diff --git a/src/modules/goods/goods.controller.ts b/src/modules/goods/goods.controller.ts index fbe32b8..f4c406b 100644 --- a/src/modules/goods/goods.controller.ts +++ b/src/modules/goods/goods.controller.ts @@ -34,6 +34,7 @@ import { isArray } from "util"; import { CreateValueDto, EditValueDto } from "../values/values.dto"; import { GoodAttributeParamDto, UploadQueryDto, EditBodyDto } from "./goods.dto"; import { RegexpCountCheckInterceptor } from "@interceptors/regexp-count-check"; +import { LogsService } from "@services/logs"; @UseGuards(RolesGuard) @Controller("api/v1/goods") @@ -47,7 +48,8 @@ export class GoodsAdminController { private readonly collectionsSvr: CollectionsService, private readonly regexpSvr: RegexpsService, private readonly categoriesSvr: CategoriesService, - private readonly goodsSvr: GoodsService + private readonly goodsSvr: GoodsService, + private readonly logsSvr: LogsService ) { } private toMd5sum(filepath: string) { @@ -233,7 +235,7 @@ export class GoodsAdminController { }); const collection = isArray(collections) ? collections[0] : collections; - return this.collectionsSvr.getById(collection._id, { + return this.collectionsSvr.getObjectById(collection._id, { populate: [ "goods" ] }); } @@ -248,13 +250,14 @@ export class GoodsAdminController { public async get(@Param() param: GidDto) { let obj; try { - obj = await this.goodsSvr.getById(param.gid, { + obj = await this.goodsSvr.getObjectById(param.gid, { populate: [ "attributes", { path: "uploader", select: "nickname" }, { path: "category", select: "name attributes tags" } ] }); + obj.downloaded = await this.logsSvr.goodDownloadCount(param.gid); } catch (error) { throw new BadRequestException(error.toString()); } diff --git a/src/services/collections.service.ts b/src/services/collections.service.ts index 35b93d4..6f4967c 100644 --- a/src/services/collections.service.ts +++ b/src/services/collections.service.ts @@ -1,7 +1,7 @@ import { Component, Param, BadRequestException } from "@nestjs/common"; import { UidDto } from "@dtos/ids"; import { - Model as CollectionsModel, cache, ICollections + Model as CollectionsModel, cache, ICollections, ICollectionsRaw } from "@models/Collection"; import { ObjectId } from "@models/common"; import { DEF_PER_COUNT } from "@dtos/page"; @@ -51,10 +51,10 @@ export class CollectionsService extends BaseService { * Get By Collection Name * @param name Collection Name */ - public getByName(name: string, opts = this.GET_OPTIONS) { + public getObjectByName(name: string, opts = this.GET_OPTIONS) { return this.loadAndCache( `getByName_${name}`, - () => this.findObject({ name }, opts), + () => this.findObject({ name }, opts) as Promise, 1000 ); } @@ -63,10 +63,10 @@ export class CollectionsService extends BaseService { * Get By Collection ID * @param id Collection ID */ - public getById(id: ObjectId, opts = this.GET_OPTIONS) { + public getObjectById(id: ObjectId, opts = this.GET_OPTIONS) { return this.loadAndCache( `getById_${id.toString()}`, - () => this.findObjectById(id, opts), + () => this.findObjectById(id, opts) as Promise, 1000 ); } diff --git a/src/services/goods.service.ts b/src/services/goods.service.ts index 98f002e..93fea6c 100644 --- a/src/services/goods.service.ts +++ b/src/services/goods.service.ts @@ -124,6 +124,14 @@ export class GoodsService extends BaseService { return super.findById(id, opts); } + /** + * Get Good by Good ID + * @param id Good ID + */ + public getObjectById(id: ObjectId, opts?: IGetOptions) { + return super.findObjectById(id, opts); + } + /** * Edit Good by Good ID * @param id Good ID diff --git a/src/services/logs.service.ts b/src/services/logs.service.ts new file mode 100644 index 0000000..86a0017 --- /dev/null +++ b/src/services/logs.service.ts @@ -0,0 +1,41 @@ +import { Component } from "@nestjs/common"; +import { BaseService } from "@services/base"; +import { Model as LogsModel, cache } from "@models/Log"; +import { ObjectId } from "@models/common"; +import { getMeta } from "@utils/log"; + +@Component() +export class LogsService extends BaseService { + + constructor() { + super(); + this.setCache(cache); + this.setModel(LogsModel); + } + + public stepGoodDownloadCount(gid: ObjectId, req) { + const key = `good_${gid.toString()}`; + const meta = getMeta(null, req); + return this.create({ + key, type: "download", ua: JSON.stringify(meta.ua), ipaddr: meta.ip + }); + } + + public async goodDownloadCount(gid: ObjectId) { + const flag = `good_download_${gid.toString()}`; + const key = `good_${gid.toString()}`; + + return await this.loadAndCache(flag, () => { + return this.total({ key, type: "download" }); + } , 60 * 1000 /* 1 min */); + } + + public async goodsDownloadCount() { + const flag = "goods_download"; + + return await this.loadAndCache(flag, () => { + return this.total({ key: /^good_/i , type: "download" }); + } , 2 * 60 * 1000 /* 2 min */); + } + +} diff --git a/test/api/goods/downloaded_count.e2e.ts b/test/api/goods/downloaded_count.e2e.ts new file mode 100644 index 0000000..edada8e --- /dev/null +++ b/test/api/goods/downloaded_count.e2e.ts @@ -0,0 +1,104 @@ + +import { + connect, drop, addCategoryAndRegexp +} from "../../helpers/database"; +import { init } from "../../helpers/server"; +import { newIds } from "../../helpers/utils"; +import { AdminRequest, GuestRequest } from "../../helpers/request"; +import * as files from "../../helpers/files"; +import { Model as LogsModel } from "@models/Log"; +import { Model as CollectionsModel } from "@models/Collection"; + +describe("Good Downloaded Count Api e2e Test Unit", () => { + + let request: AdminRequest; + + before(() => { + return connect(); + }); + + const ids = newIds(); + + after(() => { + return drop(ids); + }); + + const filepaths = [ ]; + + after(() => { + return files.remove(filepaths); + }); + + before("login", async () => { + const req = new GuestRequest(await init(), ids, filepaths); + request = await req.login(); + }); + + before("Add Category With Regexp And Upload File", async () => { + await request.newFile(); + await request.addCategoryWithRegexp(); + await request.uploadFile(); + }); + + step("Download Once", async () => { + const cid = ids.categories[ids.categories.length - 1]; + const gid = ids.goods[ids.goods.length - 1]; + const { status } = await request.downloadFile(cid, gid); + status.should.be.eql(200); + }); + + step("Download should be one time", async () => { + const gid = ids.goods[ids.goods.length - 1]; + const url = `/api/v1/goods/${gid}`; + const { status, body } = await request.get(url).then(); + status.should.be.eql(200); + body.should.have.property("downloaded", 1); + }); + + step("Collection have the good download count", async () => { + const gid = ids.goods[ids.goods.length - 1]; + await request.addCollection([ gid ]); + const cid = ids.collections[ids.collections.length - 1]; + const { body } = await request.get(`/api/v1/collections/${cid}`).then(); + body.goods.data.should.matchEach((good) => { + should(good).have.property("downloaded"); + }); + }); + + step("Download Once Again", async () => { + const cid = ids.categories[ids.categories.length - 1]; + const gid = ids.goods[ids.goods.length - 1]; + const { status } = await request.downloadFile(cid, gid); + status.should.be.eql(200); + }); + + step("Download Info still one time", async () => { + const gid = ids.goods[ids.goods.length - 1]; + const url = `/api/v1/goods/${gid}`; + const { status, body } = await request.get(url).then(); + status.should.be.eql(200); + body.should.have.property("downloaded", 1); // because the cache + }); + + step("Download should be two time", async () => { + const gid = ids.goods[ids.goods.length - 1]; + const cond = { key: `good_${gid}`, type: "download" }; + const count = await LogsModel.count(cond).exec(); + count.should.be.eql(2); + }); + + step("Collection have the good download count", async () => { + const gid = ids.goods[ids.goods.length - 1]; + await request.addCollection([ gid ]); + const cid = ids.collections[ids.collections.length - 1]; + const req = await request.logout(); + const name = encodeURI( + (await CollectionsModel.findById(cid).exec()).toObject().name + ); + const { body } = await req.get(`/collections/${name}`).then(); + body.goods.data.should.matchEach((good) => { + should(good).have.property("downloaded"); + }); + }); + +}); diff --git a/test/helpers/database.ts b/test/helpers/database.ts index 9a86e58..998da50 100644 --- a/test/helpers/database.ts +++ b/test/helpers/database.ts @@ -10,6 +10,7 @@ import { Model as CollectionsModel } from "@models/Collection"; import { Model as CategoriesModel, CategoryDoc } from "@models/Categroy"; import { Model as UsergroupsModel } from "@models/Usergroup"; import { Model as UserUsergroupsModel } from "@models/User-Usergroup"; +import { Model as LogsModel } from "@models/Log"; import { connectDatabase } from "../../src/modules/database/database.providers"; import { newUser as newUserFn } from "./database/user"; @@ -30,6 +31,7 @@ export interface IIds { collections?: ObjectId[]; usergroups?: ObjectId[]; userusergroups?: ObjectId[]; + logs?: ObjectId[]; } /** @@ -48,7 +50,8 @@ export const drop = async (ids?: IIds) => { "categories": CategoriesModel, "collections": CollectionsModel, "usergroups": UsergroupsModel, - "userusergroups": UserUsergroupsModel + "userusergroups": UserUsergroupsModel, + "logs": LogsModel }; for (const method of Object.keys(MODEL_IDMETHOD_MAP)) { const model = MODEL_IDMETHOD_MAP[method]; diff --git a/test/helpers/request.ts b/test/helpers/request.ts index 83c4485..bd74015 100644 --- a/test/helpers/request.ts +++ b/test/helpers/request.ts @@ -1,13 +1,17 @@ +import path = require("path"); import supertest = require("supertest"); import auth = require("@db/auth"); -import { IIds } from "./database"; +import { IIds, addCategoryAndRegexp } from "./database"; import { newUser } from "@db/user"; import { Model as TokensModel } from "@models/Token"; import { isNumber } from "util"; -import { newName } from "./utils"; +import { newName, sleep } from "./utils"; import { IUploadFileOptions, addQuery, IUploadFilesOptions, newFile } from "./files"; +import { ObjectId } from "@models/common"; +import { LogsService } from "@services/logs"; +import { Model as LogsModel } from "@models/Log"; type ST = supertest.SuperTest; @@ -61,6 +65,38 @@ class BaseRequest { return this; } + /** + * New A Category And add a regexp to it + * @param regexp It will new one file and filename will as the regexp value if non-exist value + * @param pid Parent Category ID + */ + public async addCategoryWithRegexp(regexp?: RegExp, pid?: ObjectId) { + if (!regexp) { + if (this.newFilepaths.length === 0) { + throw new TypeError("No New File"); + } + await this.newFile(); + const filepath = this.newFilepaths[this.newFilepaths.length - 1]; + const filename = path.basename(filepath); + regexp = new RegExp(`^${filename}$`); + } + const docs = await addCategoryAndRegexp(regexp, pid); + this.ids.categories.push(docs[0]._id); + this.ids.regexps.push(docs[1]._id); + return this; + } + + public async downloadFile(cid: ObjectId, gid: ObjectId) { + const url = + `/files/categories/${cid.toString()}/goods/${gid.toString()}`; + const ref = await this.get(url).then(); + const key = `good_${gid.toString()}`; + this.ids.logs.push( + ...(await LogsModel.find({ key }).exec()).map((log) => log._id) + ); + return ref; + } + } export class GuestRequest extends BaseRequest { @@ -107,6 +143,10 @@ class LoginedRequest extends BaseRequest { return new GuestRequest(this.req, this.ids, this.filepaths); } + /** + * Upload File to StoreBox + * @param filepath if filepath is empty value, it will upload last new file. if havnt new-file, will genertor one. + */ public async uploadFile(filepath?: string, opts: IUploadFileOptions = { }) { let url = "/api/v1/goods"; url = addQuery(url, opts); @@ -158,6 +198,16 @@ class LoginedRequest extends BaseRequest { export class AdminRequest extends LoginedRequest { + public async addCollection(goods: ObjectId[], name = newName()) { + const { status, body } = await this.post("/api/v1/collections") + .send({ name, goods }).then(); + if (status === 201) { + this.ids.collections.push(body._id); + } + await sleep(200); + return this; + } + } export class TokenRequest extends LoginedRequest { diff --git a/test/helpers/utils.ts b/test/helpers/utils.ts index ec7ad25..ed258fc 100644 --- a/test/helpers/utils.ts +++ b/test/helpers/utils.ts @@ -23,6 +23,7 @@ export const newIds = (): IIds => { categories: [ ], collections: [ ], usergroups: [ ], - userusergroups: [ ] + userusergroups: [ ], + logs: [ ] }; }; diff --git a/test/tsconfig.json b/test/tsconfig.json index 1fa5afd..b647d11 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -26,7 +26,7 @@ "@guards/*": [ "./src/modules/common/guards/*.guard" ], "@dtos/*": [ "./src/modules/common/dtos/*.dto" ], "@services/*": [ "./src/services/*.service" ], - "@interceptors/*": [ "./src/modules/common/interceptors/*.interceptor" ], + "@interceptors/*": [ "./src/interceptors/*.interceptor" ], "@db/*": [ "./test/helpers/database/*" ] } }, diff --git a/tsconfig.json b/tsconfig.json index a56a1d7..b4e8e50 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -35,8 +35,8 @@ "./dist/modules/common/dtos/*.dto" ], "@interceptors/*": [ - "./src/modules/common/interceptors/*.interceptor", - "./dist/modules/common/interceptors/*.interceptor" + "./src/interceptors/*.interceptor", + "./dist/interceptors/*.interceptor" ], "@services/*": [ "./src/services/*.service",