Merged PR 787: API I/F修正

## 概要
[Task3793: API I/F修正](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3793)

- OMDS様とのメール文面調整の結果、csvファイル名もAPIで受け渡す必要が出てきたためAPI I/Fを修正する
  - 一括登録依頼API、一括登録完了APIの両方に「ファイル名」を追加
- 増えたプロパティのバリデーションをするテストを追加

## レビューポイント
- プロパティ名は妥当か
- テストの内容は十分か

## 動作確認状況
- npm run testを通過
This commit is contained in:
湯本 開 2024-02-28 05:30:09 +00:00
parent dd8bddc971
commit 71127a6db9
2 changed files with 97 additions and 35 deletions

View File

@ -331,6 +331,11 @@ export class MultipleImportUser {
}
export class PostMultipleImportsRequest {
@ApiProperty({ description: 'CSVファイル名' })
@IsString()
@IsNotEmpty()
filename: string;
@ApiProperty({ type: [MultipleImportUser] })
@IsArray()
@ValidateNested({ each: true })
@ -345,10 +350,11 @@ export class MultipleImportErrors {
@IsNotEmpty()
name: string;
@ApiProperty({ description: 'メールアドレス' })
@IsEmail({ blacklisted_chars: '*' })
@ApiProperty({ description: 'エラー発生行数' })
@IsInt()
@IsNotEmpty()
email: string;
@Type(() => Number)
line: number;
@ApiProperty({ description: 'エラーコード' })
@IsString()
@ -362,6 +368,17 @@ export class PostMultipleImportsCompleteRequest {
@IsInt()
accountId: number;
@ApiProperty({ description: 'CSVファイル名' })
@IsString()
@IsNotEmpty()
filename: string;
@ApiProperty({ description: '一括登録受付時刻(UNIXTIME/ミリ秒)' })
@IsInt()
@IsNotEmpty()
@Type(() => Number)
requestTime: number;
@ApiProperty({ type: [MultipleImportErrors] })
@IsArray()
@ValidateNested({ each: true })

View File

@ -42,6 +42,7 @@ describe('UsersController', () => {
describe('valdation PostMultipleImportsRequest', () => {
it('role:noneの最低限の有効なリクエストが成功する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -60,6 +61,7 @@ describe('UsersController', () => {
it('role:authorの最低限の有効なリクエストが成功する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -81,6 +83,7 @@ describe('UsersController', () => {
it('emailがメールアドレスではない場合、バリデーションエラーが発生する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -94,10 +97,11 @@ describe('UsersController', () => {
const valdationObject = plainToClass(PostMultipleImportsRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('AuthorなのにAuthorIDがない場合、バリデーションエラーが発生する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -113,13 +117,14 @@ describe('UsersController', () => {
const valdationObject = plainToClass(PostMultipleImportsRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('AuthorIDがルールに違反していた場合、バリデーションエラーが発生する', async () => {
// ルールに合致したAuthorIDではエラーが発生しない
const validAuthorIDs = ['A', '_', 'AB', 'A1', '1A', '_1', 'A_B'];
for await (const authorId of validAuthorIDs) {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -146,6 +151,7 @@ describe('UsersController', () => {
const invalidAuthorIDs = ['a', '+', 'AB.', 'Ab', '1a', '_.', 'A/B', ''];
for await (const authorId of invalidAuthorIDs) {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -165,11 +171,12 @@ describe('UsersController', () => {
);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
}
});
it('Authorなのにencryptionがない場合、バリデーションエラーが発生する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -185,10 +192,11 @@ describe('UsersController', () => {
const valdationObject = plainToClass(PostMultipleImportsRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('Authorなのにpromptがない場合、バリデーションエラーが発生する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -204,10 +212,11 @@ describe('UsersController', () => {
const valdationObject = plainToClass(PostMultipleImportsRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('Authorでencryption:trueなのに、encryptionPasswordがない場合、バリデーションエラーが発生する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -224,11 +233,12 @@ describe('UsersController', () => {
const valdationObject = plainToClass(PostMultipleImportsRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('Authorでencryption:trueでencryptionPasswordが正常であれば成功する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -251,6 +261,7 @@ describe('UsersController', () => {
it('encryptionPasswordが要件外(短い)の場合、バリデーションエラーが発生する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -268,10 +279,11 @@ describe('UsersController', () => {
const valdationObject = plainToClass(PostMultipleImportsRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('encryptionPasswordが要件外(長い)の場合、バリデーションエラーが発生する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -289,10 +301,11 @@ describe('UsersController', () => {
const valdationObject = plainToClass(PostMultipleImportsRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('encryptionPasswordが要件外(全角が含まれる)の場合、バリデーションエラーが発生する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -310,11 +323,12 @@ describe('UsersController', () => {
const valdationObject = plainToClass(PostMultipleImportsRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('AuthorIDが要件外(小文字)の場合、バリデーションエラーが発生する', async () => {
const request = new PostMultipleImportsRequest();
request.filename = 'test.csv';
request.users = [
{
name: 'namae',
@ -332,7 +346,7 @@ describe('UsersController', () => {
const valdationObject = plainToClass(PostMultipleImportsRequest, request);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
});
@ -340,6 +354,8 @@ describe('UsersController', () => {
it('最低限の有効なリクエストが成功する', async () => {
const request = new PostMultipleImportsCompleteRequest();
request.accountId = 1;
request.requestTime = new Date().getTime();
request.filename = 'test.csv';
request.errors = [];
const valdationObject = plainToClass(
@ -351,18 +367,36 @@ describe('UsersController', () => {
expect(errors.length).toBe(0);
});
it('ファイル名が存在しなかった場合、バリデーションエラーが発生する', async () => {
const request = {
accountId: 1,
requestTime: new Date().getTime(),
errors: [],
};
const valdationObject = plainToClass(
PostMultipleImportsCompleteRequest,
request,
);
const errors = await validate(valdationObject);
expect(errors.length).toBe(1);
});
it('エラーが存在するリクエストが成功する', async () => {
const request = new PostMultipleImportsCompleteRequest();
request.accountId = 1;
request.requestTime = new Date().getTime();
request.filename = 'test.csv';
request.errors = [
{
name: 'namae',
email: 'hogehoge@example.com',
line: 1,
errorCode: 'E1101',
},
{
name: 'namae',
email: 'hogehoge@example.com',
line: 1,
errorCode: 'E1101',
},
];
@ -379,14 +413,16 @@ describe('UsersController', () => {
it('名前が足りないエラーがある場合、バリデーションエラーが発生する', async () => {
const request = {
accountId: 1,
filename: 'test.csv',
requestTime: new Date().getTime(),
errors: [
{
email: 'hogehoge@example.com',
line: 1,
errorCode: 'E1101',
},
{
name: 'namae',
email: 'hogehoge@example.com',
line: 1,
errorCode: 'E1101',
},
],
@ -398,12 +434,14 @@ describe('UsersController', () => {
);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('emailが足りないエラーがある場合、バリデーションエラーが発生する', async () => {
it('行指定が足りないエラーがある場合、バリデーションエラーが発生する', async () => {
const request = {
accountId: 1,
filename: 'test.csv',
requestTime: new Date().getTime(),
errors: [
{
name: 'namae',
@ -411,7 +449,7 @@ describe('UsersController', () => {
},
{
name: 'namae',
email: 'hogehoge@example.com',
line: 1,
errorCode: 'E1101',
},
],
@ -423,20 +461,22 @@ describe('UsersController', () => {
);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('errorCodeが足りないエラーがある場合、バリデーションエラーが発生する', async () => {
const request = {
accountId: 1,
filename: 'test.csv',
requestTime: new Date().getTime(),
errors: [
{
name: 'namae',
email: 'hogehoge@example.com',
line: 1,
},
{
name: 'namae',
email: 'hogehoge@example.com',
line: 1,
errorCode: 'E1101',
},
],
@ -448,21 +488,23 @@ describe('UsersController', () => {
);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('名前が空のエラーがある場合、バリデーションエラーが発生する', async () => {
const request = {
accountId: 1,
filename: 'test.csv',
requestTime: new Date().getTime(),
errors: [
{
name: '',
email: 'hogehoge@example.com',
line: 1,
errorCode: 'E1101',
},
{
name: 'namae',
email: 'hogehoge@example.com',
line: 1,
errorCode: 'E1101',
},
],
@ -474,20 +516,21 @@ describe('UsersController', () => {
);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('emailが空のエラーがある場合、バリデーションエラーが発生する', async () => {
it('行数が空のエラーがある場合、バリデーションエラーが発生する', async () => {
const request = {
accountId: 1,
filename: 'test.csv',
requestTime: new Date().getTime(),
errors: [
{
name: 'namae',
email: '',
errorCode: 'E1101',
},
{
name: 'namae',
email: 'hogehoge@example.com',
line: 1,
errorCode: 'E1101',
},
],
@ -499,20 +542,22 @@ describe('UsersController', () => {
);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
it('emailが空のエラーがある場合、バリデーションエラーが発生する', async () => {
it('エラーコードが空のエラーがある場合、バリデーションエラーが発生する', async () => {
const request = {
accountId: 1,
filename: 'test.csv',
requestTime: new Date().getTime(),
errors: [
{
name: 'namae',
email: 'hogehoge@example.com',
line: 1,
errorCode: '',
},
{
name: 'namae',
email: 'hogehoge@example.com',
line: 1,
errorCode: 'E1101',
},
],
@ -524,7 +569,7 @@ describe('UsersController', () => {
);
const errors = await validate(valdationObject);
expect(errors.length).toBeGreaterThan(0);
expect(errors.length).toBe(1);
});
});
});