Merged PR 784: テスト失敗修正(I/F実装)

## 概要
[Task3791: テスト失敗修正(I/F実装)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3791)

- AuthorIDのチェックを行うバリデータが特定リスクエストに対してしか利用できなかったので、もっと単純な同一ロジックのバリデータを追加して利用するよう変更
- 上記ケースに対するテストを追加

## レビューポイント
- 既存実装へは影響がなさそうか

## 動作確認状況
- npm run testを通過
This commit is contained in:
湯本 開 2024-02-26 07:48:08 +00:00
parent c1f370faaf
commit c95fb1e1f6
3 changed files with 96 additions and 7 deletions

View File

@ -12,10 +12,10 @@ import {
import { USER_ROLES } from '../../constants';
// 大文字英数字とアンダースコアのみを許可するバリデータ
@ValidatorConstraint({ name: 'IsAuthorId', async: false })
export class IsAuthorId implements ValidatorConstraintInterface {
@ValidatorConstraint({ name: 'IsAuthorIdValidConstraint', async: false })
export class IsAuthorIdValidConstraint implements ValidatorConstraintInterface {
validate(value: any, args: ValidationArguments) {
const request = args.object as SignupRequest | PostUpdateUserRequest;
const request = args.object as SignupRequest | PostUpdateUserRequest;
// requestの存在チェック
if (!request) {
return false;
@ -40,12 +40,44 @@ export class IsAuthorId implements ValidatorConstraintInterface {
export function IsAuthorIdValid(validationOptions?: ValidationOptions) {
return function (object: object, propertyName: string) {
registerDecorator({
name: 'IsAuthorId',
name: 'IsAuthorIdValidConstraint',
target: object.constructor,
propertyName: propertyName,
constraints: [],
options: validationOptions,
validator: IsAuthorId,
validator: IsAuthorIdValidConstraint,
});
};
}
@ValidatorConstraint({ async: false })
class IsAuhtorIDConstraint implements ValidatorConstraintInterface {
validate(value: any, args: ValidationArguments) {
// null or undefinedであれば不合格
if (value == null) {
return false;
}
// 文字列型でなければ不合格
if (typeof value !== 'string') {
return false;
}
return /^[A-Z0-9_]*$/.test(value);
}
defaultMessage(args: ValidationArguments) {
return `${args.property} should be uppercase alphanumeric and underscore only`;
}
}
export function IsAuthorID(validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
constraints: [],
validator: IsAuhtorIDConstraint,
});
};
}

View File

@ -23,7 +23,10 @@ import {
} from '../../../common/validators/encryptionPassword.validator';
import { IsRoleAuthorDataValid } from '../../../common/validators/roleAuthor.validator';
import { Type } from 'class-transformer';
import { IsAuthorIdValid } from '../../../common/validators/authorId.validator';
import {
IsAuthorID,
IsAuthorIdValid,
} from '../../../common/validators/authorId.validator';
export class ConfirmRequest {
@ApiProperty()
@ -288,8 +291,9 @@ export class MultipleImportUser {
role: number;
@ApiProperty({ required: false })
@IsAuthorIdValid()
@ValidateIf((o) => o.role === 1) // roleがauthorの場合のみバリデーションを実施
@IsAuthorID()
@IsNotEmpty()
authorId?: string;
@ApiProperty({ description: '0(false)/1(true)' })

View File

@ -115,6 +115,59 @@ describe('UsersController', () => {
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
});
it('AuthorIDがルールに違反していた場合、バリデーションエラーが発生する', async () => {
// ルールに合致したAuthorIDではエラーが発生しない
const validAuthorIDs = ['A', '_', 'AB', 'A1', '1A', '_1', 'A_B'];
for await (const authorId of validAuthorIDs) {
const request = new PostMultipleImportsRequest();
request.users = [
{
name: 'namae',
email: 'hogehoge@example.com',
role: 1,
authorId: authorId,
autoRenew: 0,
notification: 0,
encryption: 0,
prompt: 0,
},
];
const valdationObject = plainToClass(
PostMultipleImportsRequest,
request,
);
const errors = await validate(valdationObject);
expect(errors.length).toBe(0);
}
// ルールに違反したAuthorIDではエラーが発生する
const invalidAuthorIDs = ['a', '+', 'AB.', 'Ab', '1a', '_.', 'A/B', ''];
for await (const authorId of invalidAuthorIDs) {
const request = new PostMultipleImportsRequest();
request.users = [
{
name: 'namae',
email: 'hogehoge@example.com',
role: 1,
authorId: authorId,
autoRenew: 0,
notification: 0,
encryption: 0,
prompt: 0,
},
];
const valdationObject = plainToClass(
PostMultipleImportsRequest,
request,
);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
}
});
it('Authorなのにencryptionがない場合、バリデーションエラーが発生する', async () => {
const request = new PostMultipleImportsRequest();
request.users = [