Skip to content

Commit

Permalink
Merge pull request #956 from ChuckMoe/openapi-dependency-inversion
Browse files Browse the repository at this point in the history
Dependencies inverted for DTO's
  • Loading branch information
nitrosx authored Feb 9, 2024
2 parents d69437b + 6c287bf commit 0cc0529
Show file tree
Hide file tree
Showing 52 changed files with 1,060 additions and 1,050 deletions.
1 change: 1 addition & 0 deletions src/attachments/attachments.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const mockAttachment: Attachment = {
updatedBy: "testUser",
createdAt: new Date(),
updatedAt: new Date(),
isPublished: false,
};

describe("AttachmentsService", () => {
Expand Down
4 changes: 2 additions & 2 deletions src/attachments/attachments.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Request } from "express";
import { InjectModel } from "@nestjs/mongoose";
import { FilterQuery, Model } from "mongoose";
import { CreateAttachmentDto } from "./dto/create-attachment.dto";
import { UpdateAttachmentDto } from "./dto/update-attachment.dto";
import { PartialUpdateAttachmentDto } from "./dto/update-attachment.dto";
import { Attachment, AttachmentDocument } from "./schemas/attachment.schema";
import { JWTUser } from "src/auth/interfaces/jwt-user.interface";
import { addCreatedByFields, addUpdatedByField } from "src/common/utils";
Expand Down Expand Up @@ -39,7 +39,7 @@ export class AttachmentsService {

async findOneAndUpdate(
filter: FilterQuery<AttachmentDocument>,
updateAttachmentDto: UpdateAttachmentDto,
updateAttachmentDto: PartialUpdateAttachmentDto,
): Promise<Attachment | null> {
const username = (this.request?.user as JWTUser).username;
return this.attachmentModel
Expand Down
11 changes: 2 additions & 9 deletions src/attachments/dto/create-attachment.dto.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import { IsOptional, IsString } from "class-validator";
import { OwnableDto } from "src/common/dto/ownable.dto";
import { UpdateAttachmentDto } from "./update-attachment.dto";

export class CreateAttachmentDto extends OwnableDto {
export class CreateAttachmentDto extends UpdateAttachmentDto {
@IsOptional()
@IsString()
readonly id?: string;

@IsOptional()
@IsString()
readonly thumbnail?: string;

@IsString()
readonly caption: string;

@IsOptional()
@IsString()
readonly datasetId?: string;
Expand Down
28 changes: 11 additions & 17 deletions src/attachments/dto/update-attachment.dto.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { IsOptional, IsString } from "class-validator";
import { OwnableDto } from "../../common/dto/ownable.dto";
import { PartialType } from "@nestjs/swagger";
import { Exclude } from "class-transformer";
import { IsOptional } from "class-validator";
import { CreateAttachmentDto } from "./create-attachment.dto";

export class UpdateAttachmentDto extends PartialType(CreateAttachmentDto) {
export class UpdateAttachmentDto extends OwnableDto {
@IsOptional()
@Exclude()
readonly id?: string;
@IsString()
readonly thumbnail?: string;

@IsOptional()
@Exclude()
readonly datasetId?: string;

@IsOptional()
@Exclude()
readonly proposalId?: string;

@IsOptional()
@Exclude()
readonly sampleId?: string;
@IsString()
readonly caption: string;
}

export class PartialUpdateAttachmentDto extends PartialType(
UpdateAttachmentDto,
) {}
1 change: 1 addition & 0 deletions src/datablocks/datablocks.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const mockDatablock: Datablock = {
updatedBy: "testUser",
createdAt: new Date(),
updatedAt: new Date(),
isPublished: false,
dataFileList: [
{
path: "testFile.hdf5",
Expand Down
4 changes: 2 additions & 2 deletions src/datablocks/datablocks.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { InjectModel } from "@nestjs/mongoose";
import { FilterQuery, Model } from "mongoose";
import { addCreatedByFields, addUpdatedByField } from "src/common/utils";
import { CreateDatablockDto } from "./dto/create-datablock.dto";
import { UpdateDatablockDto } from "./dto/update-datablock.dto";
import { PartialUpdateDatablockDto } from "./dto/update-datablock.dto";
import { Datablock, DatablockDocument } from "./schemas/datablock.schema";
import { JWTUser } from "src/auth/interfaces/jwt-user.interface";

Expand Down Expand Up @@ -37,7 +37,7 @@ export class DatablocksService {

async update(
filter: FilterQuery<DatablockDocument>,
updateDatablockDto: UpdateDatablockDto,
updateDatablockDto: PartialUpdateDatablockDto,
): Promise<Datablock | null> {
const username = (this.request.user as JWTUser).username;
return this.datablockModel
Expand Down
70 changes: 3 additions & 67 deletions src/datablocks/dto/create-datablock.dto.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
import { ApiProperty } from "@nestjs/swagger";
import { Type } from "class-transformer";
import {
ArrayNotEmpty,
IsArray,
IsInt,
IsNotEmpty,
IsOptional,
IsString,
ValidateNested,
} from "class-validator";
import { DataFileDto } from "src/common/dto/datafile.dto";
import { OwnableDto } from "src/common/dto/ownable.dto";
import { DataFile } from "src/common/schemas/datafile.schema";
import { IsString } from "class-validator";
import { UpdateDatablockDto } from "./update-datablock.dto";

export class CreateDatablockDto extends OwnableDto {
export class CreateDatablockDto extends UpdateDatablockDto {
@ApiProperty({
type: String,
required: true,
Expand All @@ -22,57 +11,4 @@ export class CreateDatablockDto extends OwnableDto {
})
@IsString()
readonly datasetId: string;

@ApiProperty({
type: String,
required: true,
description:
"Unique identifier given by the archive system to the stored datablock. This id is used when data is retrieved back.",
})
@IsString()
readonly archiveId: string;

@ApiProperty({
type: Number,
required: true,
description:
"Total size in bytes of all files in the datablock when on accessible.",
})
@IsInt()
readonly size: number;

@ApiProperty({
type: Number,
required: true,
description:
"Total size in bytes of all files in the datablock when on archived.",
})
@IsInt()
readonly packedSize: number;

@ApiProperty({
type: String,
required: false,
description:
"Name of the hasing algorithm used to compute the hash for each file.",
})
@IsOptional()
@IsString()
@IsNotEmpty()
readonly chkAlg: string;

@ApiProperty({
type: String,
required: true,
description:
"Version string defining the format of how data is packed and stored in archive.",
})
@IsString()
readonly version: string;

@IsArray()
@ArrayNotEmpty()
@ValidateNested({ each: true })
@Type(() => DataFileDto)
readonly dataFileList: DataFile[];
}
75 changes: 72 additions & 3 deletions src/datablocks/dto/update-datablock.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,73 @@
import { PartialType } from "@nestjs/swagger";
import { CreateDatablockDto } from "./create-datablock.dto";
import { ApiProperty, PartialType } from "@nestjs/swagger";
import {
ArrayNotEmpty,
IsArray,
IsInt,
IsNotEmpty,
IsOptional,
IsString,
ValidateNested,
} from "class-validator";
import { Type } from "class-transformer";
import { DataFileDto } from "../../common/dto/datafile.dto";
import { DataFile } from "../../common/schemas/datafile.schema";
import { OwnableDto } from "../../common/dto/ownable.dto";

export class UpdateDatablockDto extends PartialType(CreateDatablockDto) {}
export class UpdateDatablockDto extends OwnableDto {
@ApiProperty({
type: String,
required: true,
description:
"Unique identifier given by the archive system to the stored datablock. This id is used when data is retrieved back.",
})
@IsString()
readonly archiveId: string;

@ApiProperty({
type: Number,
required: true,
description:
"Total size in bytes of all files in the datablock when on accessible.",
})
@IsInt()
readonly size: number;

@ApiProperty({
type: Number,
required: true,
description:
"Total size in bytes of all files in the datablock when on archived.",
})
@IsInt()
readonly packedSize: number;

@ApiProperty({
type: String,
required: false,
description:
"Name of the hashing algorithm used to compute the hash for each file.",
})
@IsOptional()
@IsString()
@IsNotEmpty()
readonly chkAlg: string;

@ApiProperty({
type: String,
required: true,
description:
"Version string defining the format of how data is packed and stored in archive.",
})
@IsString()
readonly version: string;

@IsArray()
@ArrayNotEmpty()
@ValidateNested({ each: true })
@Type(() => DataFileDto)
readonly dataFileList: DataFile[];
}

export class PartialUpdateDatablockDto extends PartialType(
UpdateDatablockDto,
) {}
36 changes: 19 additions & 17 deletions src/datasets/datasets.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import { UpdateOrigDatablockDto } from "src/origdatablocks/dto/update-origdatabl
import { DatablocksService } from "src/datablocks/datablocks.service";
import { Datablock } from "src/datablocks/schemas/datablock.schema";
import { CreateDatablockDto } from "src/datablocks/dto/create-datablock.dto";
import { UpdateDatablockDto } from "src/datablocks/dto/update-datablock.dto";
import { PartialUpdateDatablockDto } from "src/datablocks/dto/update-datablock.dto";
import { UpdateQuery } from "mongoose";
import { FilterPipe } from "src/common/pipes/filter.pipe";
import { UTCTimeInterceptor } from "src/common/interceptors/utc-time.interceptor";
Expand Down Expand Up @@ -98,6 +98,7 @@ import { JWTUser } from "src/auth/interfaces/jwt-user.interface";
import { LogbooksService } from "src/logbooks/logbooks.service";
import { Logbook } from "src/logbooks/schemas/logbook.schema";
import configuration from "src/config/configuration";
import { DatasetType } from "./dataset-type.enum";

@ApiBearerAuth()
@ApiExtraModels(
Expand Down Expand Up @@ -469,7 +470,6 @@ export class DatasetsController {
| UpdateDerivedDatasetDto
>,
) {
const type = inputDatasetDto.type;
const validateOptions: ValidatorOptions = {
whitelist: true,
forbidNonWhitelisted: true,
Expand All @@ -480,14 +480,19 @@ export class DatasetsController {
},
};

if (type !== "raw" && type !== "derived") {
throw new HttpException(
{
status: HttpStatus.BAD_REQUEST,
message: "Wrong dataset type!",
},
HttpStatus.BAD_REQUEST,
);
if (
inputDatasetDto instanceof
(CreateRawDatasetDto || CreateDerivedDatasetDto)
) {
if (!(inputDatasetDto.type in DatasetType)) {
throw new HttpException(
{
status: HttpStatus.BAD_REQUEST,
message: "Wrong dataset type!",
},
HttpStatus.BAD_REQUEST,
);
}
}

const outputDatasetDto = plainToInstance(dto, inputDatasetDto);
Expand Down Expand Up @@ -1089,13 +1094,10 @@ export class DatasetsController {
throw new NotFoundException();
}

// NOTE: Type is a must have because validation is based on it
const datasetType = updateDatasetDto.type ?? foundDataset.type;

// NOTE: Default validation pipe does not validate union types. So we need custom validation.
await this.validateDataset(
{ ...updateDatasetDto, type: datasetType },
datasetType === "raw"
updateDatasetDto,
foundDataset.type === "raw"
? PartialUpdateRawDatasetDto
: PartialUpdateDerivedDatasetDto,
);
Expand Down Expand Up @@ -1175,7 +1177,7 @@ export class DatasetsController {
// NOTE: Default validation pipe does not validate union types. So we need custom validation.
const outputDto = await this.validateDataset(
updateDatasetDto,
updateDatasetDto.type === "raw"
foundDataset.type === "raw"
? UpdateRawDatasetDto
: UpdateDerivedDatasetDto,
);
Expand Down Expand Up @@ -1960,7 +1962,7 @@ export class DatasetsController {
@Req() request: Request,
@Param("pid") pid: string,
@Param("did") did: string,
@Body() updateDatablockDto: UpdateDatablockDto,
@Body() updateDatablockDto: PartialUpdateDatablockDto,
): Promise<Datablock | null> {
const dataset = await this.checkPermissionsForDatasetExtended(
request,
Expand Down
Loading

0 comments on commit 0cc0529

Please sign in to comment.