import { Test, TestingModule } from '@nestjs/testing'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; import { ConfigModule } from '@nestjs/config'; import { AuthService } from '../auth/auth.service'; import { PostMultipleImportsCompleteRequest, PostMultipleImportsRequest, } from './types/types'; import { validate } from 'class-validator'; import { plainToClass } from 'class-transformer'; describe('UsersController', () => { let controller: UsersController; const mockUserService = {}; const mockAuthService = {}; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [ ConfigModule.forRoot({ envFilePath: ['.env.test', '.env'], isGlobal: true, }), ], controllers: [UsersController], providers: [UsersService, AuthService], }) .overrideProvider(UsersService) .useValue(mockUserService) .overrideProvider(AuthService) .useValue(mockAuthService) .compile(); controller = module.get(UsersController); }); it('should be defined', () => { expect(controller).toBeDefined(); }); describe('valdation PostMultipleImportsRequest', () => { it('role:noneの最低限の有効なリクエストが成功する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 0, autoRenew: 0, notification: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(0); }); it('role:authorの最低限の有効なリクエストが成功する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 1, authorId: 'AUTHOR', autoRenew: 0, notification: 0, encryption: 0, prompt: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(0); }); it('emailがメールアドレスではない場合、バリデーションエラーが発生する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge', role: 0, autoRenew: 0, notification: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('AuthorなのにAuthorIDがない場合、バリデーションエラーが発生する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 1, autoRenew: 0, notification: 0, encryption: 0, prompt: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); 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', 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.filename = 'test.csv'; 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(1); } }); it('Authorなのにencryptionがない場合、バリデーションエラーが発生する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 1, authorId: 'AUTHOR', autoRenew: 0, notification: 0, prompt: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('Authorなのにpromptがない場合、バリデーションエラーが発生する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 1, authorId: 'AUTHOR', autoRenew: 0, notification: 0, encryption: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('Authorでencryption:trueなのに、encryptionPasswordがない場合、バリデーションエラーが発生する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 1, authorId: 'AUTHOR', autoRenew: 0, notification: 0, encryption: 1, prompt: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('Authorでencryption:trueでencryptionPasswordが正常であれば成功する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 1, authorId: 'AUTHOR', autoRenew: 0, notification: 0, encryption: 1, encryptionPassword: 'abcd', prompt: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(0); }); it('encryptionPasswordが要件外(短い)の場合、バリデーションエラーが発生する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 1, authorId: 'AUTHOR', autoRenew: 0, notification: 0, encryption: 1, encryptionPassword: 'abc', prompt: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('encryptionPasswordが要件外(長い)の場合、バリデーションエラーが発生する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 1, authorId: 'AUTHOR', autoRenew: 0, notification: 0, encryption: 1, encryptionPassword: 'abcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', prompt: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('encryptionPasswordが要件外(全角が含まれる)の場合、バリデーションエラーが発生する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 1, authorId: 'AUTHOR', autoRenew: 0, notification: 0, encryption: 1, encryptionPassword: 'abcあいうえお', prompt: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('AuthorIDが要件外(小文字)の場合、バリデーションエラーが発生する', async () => { const request = new PostMultipleImportsRequest(); request.filename = 'test.csv'; request.users = [ { name: 'namae', email: 'hogehoge@example.com', role: 1, authorId: 'author', autoRenew: 0, notification: 0, encryption: 1, encryptionPassword: 'abc', prompt: 0, }, ]; const valdationObject = plainToClass(PostMultipleImportsRequest, request); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); }); describe('valdation PostMultipleImportsCompleteRequest', () => { it('最低限の有効なリクエストが成功する', async () => { const request = new PostMultipleImportsCompleteRequest(); request.accountId = 1; request.requestTime = new Date().getTime(); request.filename = 'test.csv'; request.errors = []; const valdationObject = plainToClass( PostMultipleImportsCompleteRequest, request, ); const errors = await validate(valdationObject); 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', line: 1, errorCode: 'E1101', }, { name: 'namae', line: 1, errorCode: 'E1101', }, ]; const valdationObject = plainToClass( PostMultipleImportsCompleteRequest, request, ); const errors = await validate(valdationObject); expect(errors.length).toBe(0); }); it('名前が足りないエラーがある場合、バリデーションエラーが発生する', async () => { const request = { accountId: 1, filename: 'test.csv', requestTime: new Date().getTime(), errors: [ { line: 1, errorCode: 'E1101', }, { name: 'namae', line: 1, errorCode: 'E1101', }, ], }; const valdationObject = plainToClass( PostMultipleImportsCompleteRequest, request, ); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('行指定が足りないエラーがある場合、バリデーションエラーが発生する', async () => { const request = { accountId: 1, filename: 'test.csv', requestTime: new Date().getTime(), errors: [ { name: 'namae', errorCode: 'E1101', }, { name: 'namae', line: 1, errorCode: 'E1101', }, ], }; const valdationObject = plainToClass( PostMultipleImportsCompleteRequest, request, ); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('errorCodeが足りないエラーがある場合、バリデーションエラーが発生する', async () => { const request = { accountId: 1, filename: 'test.csv', requestTime: new Date().getTime(), errors: [ { name: 'namae', line: 1, }, { name: 'namae', line: 1, errorCode: 'E1101', }, ], }; const valdationObject = plainToClass( PostMultipleImportsCompleteRequest, request, ); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('名前が空のエラーがある場合、バリデーションエラーが発生する', async () => { const request = { accountId: 1, filename: 'test.csv', requestTime: new Date().getTime(), errors: [ { name: '', line: 1, errorCode: 'E1101', }, { name: 'namae', line: 1, errorCode: 'E1101', }, ], }; const valdationObject = plainToClass( PostMultipleImportsCompleteRequest, request, ); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('行数が空のエラーがある場合、バリデーションエラーが発生する', async () => { const request = { accountId: 1, filename: 'test.csv', requestTime: new Date().getTime(), errors: [ { name: 'namae', errorCode: 'E1101', }, { name: 'namae', line: 1, errorCode: 'E1101', }, ], }; const valdationObject = plainToClass( PostMultipleImportsCompleteRequest, request, ); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); it('エラーコードが空のエラーがある場合、バリデーションエラーが発生する', async () => { const request = { accountId: 1, filename: 'test.csv', requestTime: new Date().getTime(), errors: [ { name: 'namae', line: 1, errorCode: '', }, { name: 'namae', line: 1, errorCode: 'E1101', }, ], }; const valdationObject = plainToClass( PostMultipleImportsCompleteRequest, request, ); const errors = await validate(valdationObject); expect(errors.length).toBe(1); }); }); });