Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aghomari/link resource pack #77

Merged
merged 2 commits into from
May 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/minio-client/minio-client.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export enum BucketName {
Resources = 'resources',
Tracks = 'tracks',
Images = 'images',
Previews = 'previews',
}

@Injectable()
Expand Down Expand Up @@ -49,6 +50,13 @@ export class MinioClientService {
'Content-Type': file.mimetype,
};

if (!file.mimetype) {
this.logger.error(
`Can not upload file ${file.originalFileName} mimetype undefined`,
);
throw new BadRequestException('Error uploading file mimetype undefined');
}

this.client.putObject(
bucketName,
fileName,
Expand Down
24 changes: 20 additions & 4 deletions src/resource-packs/dto/create-resource-pack.dto.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import {
IsArray,
IsEnum,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
MaxLength,
MinLength,
} from 'class-validator';
import AuthorDto from '../../users/dto/author.dto';

export enum AccessType {
Free = 'free',
Paid = 'paid',
Donation = 'donation',
}
export class CreateResourcePackDto {
@IsNotEmpty()
@IsString()
Expand All @@ -20,10 +28,12 @@ export class CreateResourcePackDto {
readonly description: string;

@IsNotEmpty()
@IsString()
@MinLength(1)
@MaxLength(1024)
readonly previewUrl: string;
@IsEnum(AccessType)
readonly accessType: AccessType;

@IsOptional()
@IsNumber()
readonly amount?: number;

@IsArray()
@IsNotEmpty()
Expand All @@ -45,4 +55,10 @@ export class CreateReleaseResourceDto {

@IsNotEmpty()
readonly author: AuthorDto;

@IsOptional()
@IsString()
@MinLength(1)
@MaxLength(1024)
readonly previewFileName: string;
}
14 changes: 12 additions & 2 deletions src/resource-packs/interfaces/create-resource-pack.interface.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import ICreateTrack from '../../tracks/interfaces/create-track.interface';
import ICreateUser from '../../users/interfaces/create-user.interface';
import { AccessType } from '../dto/create-resource-pack.dto';

export default interface ICreateResourcePack {
title: string;
description: string;
coverUrl: string;
resources: ICreateTrack[];
resources: ICreateResource[];
}

export interface ICreateResource {
title: string;
originalFileName: string;
previewFileName: string;
author: ICreateUser;
accessType: AccessType;
amount?: number;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ export interface IResourcePackResponse {
title: string;
description: string;
coverName: string;
previewUrl: string;
author: IUserResponse;
}
26 changes: 20 additions & 6 deletions src/resource-packs/resource-packs.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
UploadedFiles,
UseGuards,
UseInterceptors,
Logger,
} from '@nestjs/common';
import { ResourcePacksService } from './resource-packs.service';
import { UpdateResourcePackDto } from './dto/update-resource-pack.dto';
Expand All @@ -22,10 +23,7 @@ import {
} from '@nestjs/swagger';
import { IRequestWithUser } from '../users/interfaces/request-with-user.interface';
import { CreateResourcePackWraperDto } from './dto/create-resource-pack-wraper.dto';
import {
FileMimeType,
SimpleCreateFileDto,
} from '../files/dto/simple-create-file.dto';
import { SimpleCreateFileDto } from '../files/dto/simple-create-file.dto';
import { FileFieldsInterceptor } from '@nestjs/platform-express';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { ResourcePackFormDataParserInterceptor } from '../utils/interceptors/create-resource-pack.interceptor copy';
Expand All @@ -37,6 +35,8 @@ import { ValidIdInterceptor } from '../utils/interceptors/valid-id.interceptor';
export class ResourcePacksController {
constructor(private readonly resourcePacksService: ResourcePacksService) {}

private readonly logger: Logger = new Logger(ResourcePacksController.name);

@Post()
@UseGuards(JwtAuthGuard)
@ApiCookieAuth('Set-Cookie')
Expand All @@ -47,20 +47,33 @@ export class ResourcePacksController {
FileFieldsInterceptor([
{ name: 'resources', maxCount: 20 },
{ name: 'cover', maxCount: 1 },
{ name: 'previews', maxCount: 20 },
]),
ResourcePackFormDataParserInterceptor,
)
create(
@UploadedFiles()
files: { resources: Express.Multer.File[]; cover: Express.Multer.File[] },
files: {
resources: Express.Multer.File[];
cover: Express.Multer.File[];
previews: Express.Multer.File[];
},
@Body() body: CreateResourcePackWraperDto,
@Request() request: IRequestWithUser,
) {
const filesBuffers: SimpleCreateFileDto[] = files.resources.map((file) => ({
originalFileName: file.originalname,
buffer: file.buffer,
size: file.size,
mimetype: FileMimeType[file.mimetype],
mimetype: file.mimetype,
}));

const previews = files.previews ? files.previews : [];
const previewFilesBuffers: SimpleCreateFileDto[] = previews.map((file) => ({
originalFileName: file.originalname,
buffer: file.buffer,
size: file.size,
mimetype: file.mimetype,
}));

const simpleCreateImage: SimpleCreateFileDto | undefined = files.cover
Expand All @@ -74,6 +87,7 @@ export class ResourcePacksController {

return this.resourcePacksService.createResourcePack(
filesBuffers,
previewFilesBuffers,
simpleCreateImage,
body.data,
request.user,
Expand Down
136 changes: 86 additions & 50 deletions src/resource-packs/resource-packs.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,10 @@ import { UserSearchServiceMock } from '../test-utils/mocks/users-search.service.
import { MinioServiceMock } from '../test-utils/mocks/minio.service.test';
import { PaymentServiceMock } from '../test-utils/mocks/payment.service.test';
import { FileMimeType } from '../files/dto/simple-create-file.dto';
import { AccessType } from './dto/create-resource-pack.dto';

const resource_packs = data2list(data.resource_packs);

const create_resource_packs = data2list(data.create_resource_packs);
const files = [
data.create_files.resources_pack_1,
data.create_files.resources_pack_2,
];

const abdou_user = data.create_users.abdou;
const yoni_user = data.create_users.yoni;

Expand Down Expand Up @@ -102,47 +97,92 @@ describe('ResourcePacksService', () => {
users = [abdou, yoni];
});

create_resource_packs.forEach((resourcePack, resourcePackIndex) => {
const test = files[resourcePackIndex];
const coverFile = data.create_files.coverFile;
const coverName = 'https://www.example.com';
const files_resource_packs = (test as Array<any>).map((file) => ({
...file,
buffer: Buffer.from(JSON.parse(JSON.stringify(file.buffer))),
}));
const cover = {
...coverFile,
mimetype: FileMimeType[coverFile.mimetype],
buffer: Buffer.from(JSON.parse(JSON.stringify(coverFile.buffer))),
const coverFile = data.create_files.coverFile;
const coverName = 'https://www.example.com';
const cover = {
...coverFile,
mimetype: FileMimeType[coverFile.mimetype],
buffer: Buffer.from(JSON.parse(JSON.stringify(coverFile.buffer))),
};
const previews = [
{
...data.create_files.preview_1,
buffer: Buffer.from(
JSON.parse(JSON.stringify(data.create_files.preview_1.buffer)),
),
},
];

const rp_1_files = data.create_files.resources_pack_1;
const resource_packs1_files = (rp_1_files as Array<any>).map((file) => ({
...file,
buffer: Buffer.from(JSON.parse(JSON.stringify(file.buffer))),
}));
const resouce_pack_1 = data.create_resource_packs.resource_pack1;
it('should return first resource pack infos', async () => {
const resources = data2list(resouce_pack_1.resources);

const create_resource_pack = {
...resouce_pack_1,
accessType: AccessType.Free,
resources,
};
it('should return one resource pack infos', async () => {
const resources = data2list(resourcePack.resources);

const create_resource_pack = {
...resourcePack,
resources,
};

const expected = {
title: resourcePack.title,
description: resourcePack.description,
coverName,
previewUrl: resourcePack.previewUrl,
author: {
id: users[resourcePackIndex].id,
username: users[resourcePackIndex].username,
email: users[resourcePackIndex].email,
},
};

const result = await resourcePacksService.createResourcePack(
files_resource_packs,
cover,
create_resource_pack,
users[resourcePackIndex],
);
expect(result).toStrictEqual(expected);
});

const expected = {
title: resouce_pack_1.title,
description: resouce_pack_1.description,
coverName,
author: {
id: users[0].id,
username: users[0].username,
email: users[0].email,
},
};

const result = await resourcePacksService.createResourcePack(
resource_packs1_files,
previews,
cover,
create_resource_pack,
users[0],
);
expect(result).toStrictEqual(expected);
});

const rp_2_files = data.create_files.resources_pack_2;
const resource_packs2_files = (rp_2_files as Array<any>).map((file) => ({
...file,
buffer: Buffer.from(JSON.parse(JSON.stringify(file.buffer))),
}));
const resouce_pack_2 = data.create_resource_packs.resource_pack2;
it('should return second resource pack infos', async () => {
const resources = data2list(resouce_pack_2.resources);

const create_resource_pack = {
...resouce_pack_2,
accessType: AccessType.Free,
resources,
};

const expected = {
title: resouce_pack_2.title,
description: resouce_pack_2.description,
coverName,
author: {
id: users[0].id,
username: users[0].username,
email: users[0].email,
},
};

const result = await resourcePacksService.createResourcePack(
resource_packs2_files,
previews,
cover,
create_resource_pack,
users[0],
);
expect(result).toStrictEqual(expected);
});
});

Expand Down Expand Up @@ -181,7 +221,6 @@ describe('ResourcePacksService', () => {
describe('When find one resource pack by title', () => {
it('should return one resource pack', async () => {
const coverName = 'https://www.example.com';
const previewUrl = 'https://www.resource-pack.com';
const description = 'my resource pack 1';
const title = 'resource pack 1';

Expand All @@ -194,7 +233,6 @@ describe('ResourcePacksService', () => {
expect(result.title).toBe(title);
expect(result.description).toBe(description);
expect(result.coverName).toBe(coverName);
expect(result.previewUrl).toBe(previewUrl);
expect(result.author).toStrictEqual(abdou._id);
expect(result.resources).toBeDefined();
});
Expand All @@ -203,7 +241,6 @@ describe('ResourcePacksService', () => {
describe('When find one resource pack by id', () => {
it('should return one resource pack', async () => {
const coverName = 'https://www.example.com';
const previewUrl = 'https://www.resource-pack.com';
const description = 'my resource pack 1';
const title = 'resource pack 1';

Expand All @@ -214,7 +251,6 @@ describe('ResourcePacksService', () => {
expect(result.title).toBe(title);
expect(result.description).toBe(description);
expect(result.coverName).toBe(coverName);
expect(result.previewUrl).toBe(previewUrl);
expect(result.author).toStrictEqual(abdou._id);
expect(result.resources).toBeDefined();
});
Expand Down
11 changes: 10 additions & 1 deletion src/resource-packs/resource-packs.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class ResourcePacksService {

async createResourcePack(
files: SimpleCreateFileDto[],
previewFiles: SimpleCreateFileDto[],
cover: SimpleCreateFileDto,
createResourcePack: CreateResourcePackDto,
author: UserDocument,
Expand All @@ -45,6 +46,12 @@ export class ResourcePacksService {
await this.isResourcePackUnique(createResourcePack.title);

const orderedResources = this.orderedResources(files, createResourcePack);
const previewFilesMap: Map<string, SimpleCreateFileDto> = new Map(
previewFiles.map((previewFile) => [
previewFile.originalFileName,
previewFile,
]),
);

const session = await this.connection.startSession();
try {
Expand All @@ -60,6 +67,9 @@ export class ResourcePacksService {
orderedResources,
resource.originalFileName,
),
previewFile:
resource.previewFileName &&
buildSimpleFile(previewFilesMap, resource.previewFileName),
})),
);

Expand Down Expand Up @@ -220,7 +230,6 @@ export class ResourcePacksService {
title: resourcePack.title,
description: resourcePack.description,
coverName: resourcePack.coverName,
previewUrl: resourcePack.previewUrl,
author: {
id: resourcePack.author._id.toString(),
username: resourcePack.author.username,
Expand Down
Loading