OMDSCloud/dictation_server/src/features/files/files.service.spec.ts
saito.k 96848f5e54 Merged PR 499: 修正②(files,licenses , Repositoiesのlicenses)
## 概要
[Task2836: 修正②(files,licenses , Repositoiesのlicenses)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2836)

- feature
  - files
  - licenses
- repositories
  - licenses
  - users
  - worktypes
- entity
  - licenses
  - audio_files
  - audio_option_item
  - checkout_permission
- アクセストークンをそのままService層に渡している箇所を修正し、必要なパラメータのみ渡すように修正
- クライアントの型生成
  - 割り当て可能ライセンス取得APIのIFが変わったため

## レビューポイント
-

## UIの変更
- Before/Afterのスクショなど
- スクショ置き場

## 動作確認状況
- ローカルでテストが通ることを確認

## 補足
- 相談、参考資料などがあれば
2023-10-19 01:04:14 +00:00

1097 lines
32 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { HttpException, HttpStatus } from '@nestjs/common';
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
import {
makeBlobstorageServiceMockValue,
makeDefaultTasksRepositoryMockValue,
makeDefaultUsersRepositoryMockValue,
makeFilesServiceMock,
} from './test/files.service.mock';
import { DataSource } from 'typeorm';
import { createTask, makeTestingModuleWithBlob } from './test/utility';
import { FilesService } from './files.service';
import { makeContext } from '../../common/log';
import {
makeTestAccount,
makeTestSimpleAccount,
makeTestUser,
} from '../../common/test/utility';
import { makeTestingModule } from '../../common/test/modules';
import { overrideBlobstorageService } from '../../common/test/overrides';
import {
createTemplateFile,
getTemplateFiles,
} from '../templates/test/utility';
import { TemplateFilesRepositoryService } from '../../repositories/template_files/template_files.repository.service';
describe('音声ファイルアップロードURL取得', () => {
it('アップロードSASトークンが乗っているURLを返却する', async () => {
const blobParam = makeBlobstorageServiceMockValue();
const userRepoParam = makeDefaultUsersRepositoryMockValue();
const taskRepoParam = makeDefaultTasksRepositoryMockValue();
const service = await makeFilesServiceMock(
blobParam,
userRepoParam,
taskRepoParam,
);
expect(
await service.publishUploadSas(
makeContext('trackingId'),
'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx',
),
).toEqual('https://blob-storage?sas-token');
});
it('アカウント専用コンテナが無い場合でも、コンテナ作成しURLを返却する', async () => {
const blobParam = makeBlobstorageServiceMockValue();
const userRepoParam = makeDefaultUsersRepositoryMockValue();
const taskRepoParam = makeDefaultTasksRepositoryMockValue();
blobParam.containerExists = false;
const service = await makeFilesServiceMock(
blobParam,
userRepoParam,
taskRepoParam,
);
expect(
await service.publishUploadSas(
makeContext('trackingId'),
'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx',
),
).toEqual('https://blob-storage?sas-token');
});
it('ユーザー情報の取得に失敗した場合、例外エラーを返却する', async () => {
const blobParam = makeBlobstorageServiceMockValue();
const taskRepoParam = makeDefaultTasksRepositoryMockValue();
const service = await makeFilesServiceMock(
blobParam,
{
findUserByExternalId: new Error(''),
},
taskRepoParam,
);
await expect(
service.publishUploadSas(
makeContext('trackingId'),
'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx',
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E009999'), HttpStatus.UNAUTHORIZED),
);
});
it('コンテナ作成に失敗した場合、例外エラーを返却する', async () => {
const blobParam = makeBlobstorageServiceMockValue();
const taskRepoParam = makeDefaultTasksRepositoryMockValue();
const service = await makeFilesServiceMock(
blobParam,
{
findUserByExternalId: new Error(''),
},
taskRepoParam,
);
blobParam.publishUploadSas = new Error('Azure service down');
await expect(
service.publishUploadSas(
makeContext('trackingId'),
'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx',
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E009999'), HttpStatus.UNAUTHORIZED),
);
});
});
describe('タスク作成', () => {
it('文字起こしタスクを作成できる', async () => {
const blobParam = makeBlobstorageServiceMockValue();
const userRepoParam = makeDefaultUsersRepositoryMockValue();
const taskRepoParam = makeDefaultTasksRepositoryMockValue();
const service = await makeFilesServiceMock(
blobParam,
userRepoParam,
taskRepoParam,
);
expect(
await service.uploadFinished(
makeContext('trackingId'),
'userId',
'http://blob/url/file.zip',
'AUTHOR_01',
'file.zip',
'11:22:33',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
256,
'01',
'DS2',
'comment',
'workTypeID',
optionItemList,
false,
),
).toEqual({ jobNumber: '00000001' });
});
it('日付フォーマットが不正な場合、エラーを返却する', async () => {
const blobParam = makeBlobstorageServiceMockValue();
const userRepoParam = makeDefaultUsersRepositoryMockValue();
const taskRepoParam = makeDefaultTasksRepositoryMockValue();
const service = await makeFilesServiceMock(
blobParam,
userRepoParam,
taskRepoParam,
);
await expect(
service.uploadFinished(
makeContext('trackingId'),
'userId',
'http://blob/url/file.zip',
'AUTHOR_01',
'file.zip',
'11:22:33',
'yyyy-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
256,
'01',
'DS2',
'comment',
'workTypeID',
optionItemList,
false,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010001'), HttpStatus.BAD_REQUEST),
);
});
it('オプションアイテムが10個ない場合、エラーを返却する', async () => {
const blobParam = makeBlobstorageServiceMockValue();
const userRepoParam = makeDefaultUsersRepositoryMockValue();
const taskRepoParam = makeDefaultTasksRepositoryMockValue();
const service = await makeFilesServiceMock(
blobParam,
userRepoParam,
taskRepoParam,
);
await expect(
service.uploadFinished(
makeContext('trackingId'),
'userId',
'http://blob/url/file.zip',
'AUTHOR_01',
'file.zip',
'11:22:33',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
256,
'01',
'DS2',
'comment',
'workTypeID',
[
{
optionItemLabel: 'label_01',
optionItemValue: 'value_01',
},
],
false,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010001'), HttpStatus.BAD_REQUEST),
);
});
it('タスク追加でユーザー情報の取得に失敗した場合、エラーを返却する', async () => {
const blobParam = makeBlobstorageServiceMockValue();
const taskRepoParam = makeDefaultTasksRepositoryMockValue();
const service = await makeFilesServiceMock(
blobParam,
{
findUserByExternalId: new Error(''),
},
taskRepoParam,
);
await expect(
service.uploadFinished(
makeContext('trackingId'),
'userId',
'http://blob/url/file.zip',
'AUTHOR_01',
'file.zip',
'11:22:33',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
256,
'01',
'DS2',
'comment',
'workTypeID',
optionItemList,
false,
),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
it('タスクのDBへの追加に失敗した場合、エラーを返却する', async () => {
const blobParam = makeBlobstorageServiceMockValue();
const userRepoParam = makeDefaultUsersRepositoryMockValue();
const service = await makeFilesServiceMock(blobParam, userRepoParam, {
create: new Error(''),
getTasksFromAccountId: new Error(),
});
await expect(
service.uploadFinished(
makeContext('trackingId'),
'userId',
'http://blob/url/file.zip',
'AUTHOR_01',
'file.zip',
'11:22:33',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
256,
'01',
'DS2',
'comment',
'workTypeID',
optionItemList,
false,
),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
});
describe('音声ファイルダウンロードURL取得', () => {
let source: DataSource | null = null;
beforeEach(async () => {
source = new DataSource({
type: 'sqlite',
database: ':memory:',
logging: false,
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
});
return source.initialize();
});
afterEach(async () => {
if (!source) return;
await source.destroy();
source = null;
});
it('ダウンロードSASトークンが乗っているURLを取得できる', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const {
external_id: externalId,
id: userId,
author_id: authorId,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const url = `https://saodmsusdev.blob.core.windows.net/account-${accountId}/${userId}`;
const { audioFileId } = await createTask(
source,
accountId,
url,
'test.zip',
'InProgress',
undefined,
authorId ?? '',
);
const blobParam = makeBlobstorageServiceMockValue();
blobParam.publishDownloadSas = `${url}?sas-token`;
blobParam.fileExists = true;
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
expect(
await service.publishAudioFileDownloadSas(
makeContext('trackingId'),
externalId,
audioFileId,
),
).toEqual(`${url}?sas-token`);
});
it('Typistの場合、タスクのステータスが[Inprogress,Pending]以外でエラー', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId, id: userId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const url = `https://saodmsusdev.blob.core.windows.net/account-${accountId}/${authorUserId}`;
const { audioFileId } = await createTask(
source,
accountId,
url,
'test.zip',
'Finished',
userId,
);
const blobParam = makeBlobstorageServiceMockValue();
blobParam.publishDownloadSas = `${url}?sas-token`;
blobParam.fileExists = true;
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
await expect(
service.publishAudioFileDownloadSas(
makeContext('trackingId'),
externalId,
audioFileId,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.BAD_REQUEST),
);
});
it('Typistの場合、自身が担当するタスクでない場合エラー', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: otherId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'other-typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const url = `https://saodmsusdev.blob.core.windows.net/account-${accountId}/${authorUserId}`;
const { audioFileId } = await createTask(
source,
accountId,
url,
'test.zip',
'InProgress',
otherId,
);
const blobParam = makeBlobstorageServiceMockValue();
blobParam.publishDownloadSas = `${url}?sas-token`;
blobParam.fileExists = true;
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
await expect(
service.publishTemplateFileDownloadSas(
makeContext('tracking'),
externalId,
audioFileId,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.BAD_REQUEST),
);
});
it('Authorの場合、自身が登録したタスクでない場合エラー', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId, id: userId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const url = `https://saodmsusdev.blob.core.windows.net/account-${accountId}/${userId}`;
const { audioFileId } = await createTask(
source,
accountId,
url,
'test.zip',
'InProgress',
undefined,
'OTHOR_ID',
);
const blobParam = makeBlobstorageServiceMockValue();
blobParam.publishDownloadSas = `${url}?sas-token`;
blobParam.fileExists = true;
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
await expect(
service.publishAudioFileDownloadSas(
makeContext('trackingId'),
externalId,
audioFileId,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.BAD_REQUEST),
);
});
it('Taskが存在しない場合はエラーとなる', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const blobParam = makeBlobstorageServiceMockValue();
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
await expect(
service.publishAudioFileDownloadSas(
makeContext('trackingId'),
externalId,
1,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.BAD_REQUEST),
);
});
it('blobストレージにファイルが存在しない場合はエラーとなる', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const {
external_id: externalId,
id: userId,
author_id: authorId,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const url = `https://saodmsusdev.blob.core.windows.net/account-${accountId}/${userId}`;
const { audioFileId } = await createTask(
source,
accountId,
url,
'test.zip',
'InProgress',
undefined,
authorId ?? '',
);
const blobParam = makeBlobstorageServiceMockValue();
blobParam.publishDownloadSas = `${url}?sas-token`;
blobParam.fileExists = false;
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
await expect(
service.publishAudioFileDownloadSas(
makeContext('trackingId'),
externalId,
audioFileId,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010701'), HttpStatus.BAD_REQUEST),
);
});
});
describe('テンプレートファイルダウンロードURL取得', () => {
let source: DataSource | null = null;
beforeEach(async () => {
source = new DataSource({
type: 'sqlite',
database: ':memory:',
logging: false,
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
});
return source.initialize();
});
afterEach(async () => {
if (!source) return;
await source.destroy();
source = null;
});
it('ダウンロードSASトークンが乗っているURLを取得できる', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId, author_id: authorId } = await makeTestUser(
source,
{
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
},
);
const url = `https://saodmsusdev.blob.core.windows.net/account-${accountId}/Templates`;
const { audioFileId } = await createTask(
source,
accountId,
url,
'test.zip',
'InProgress',
undefined,
authorId ?? '',
);
const blobParam = makeBlobstorageServiceMockValue();
blobParam.publishDownloadSas = `${url}?sas-token`;
blobParam.fileExists = true;
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
expect(
await service.publishTemplateFileDownloadSas(
makeContext('tracking'),
externalId,
audioFileId,
),
).toEqual(`${url}?sas-token`);
});
it('Typistの場合、タスクのステータスが[Inprogress,Pending]以外でエラー', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId, id: userId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
author_id: undefined,
});
const url = `https://saodmsusdev.blob.core.windows.net/account-${accountId}/Templates`;
const { audioFileId } = await createTask(
source,
accountId,
url,
'test.zip',
'Finished',
userId,
);
const blobParam = makeBlobstorageServiceMockValue();
blobParam.publishDownloadSas = `${url}?sas-token`;
blobParam.fileExists = true;
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
await expect(
service.publishTemplateFileDownloadSas(
makeContext('tracking'),
externalId,
audioFileId,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.BAD_REQUEST),
);
});
it('Typistの場合、自身が担当するタスクでない場合エラー', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
author_id: undefined,
});
const { id: otherId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'other-typist-user-external-id',
role: 'typist',
author_id: undefined,
});
const url = `https://saodmsusdev.blob.core.windows.net/account-${accountId}/Templates`;
const { audioFileId } = await createTask(
source,
accountId,
url,
'test.zip',
'InProgress',
otherId,
);
const blobParam = makeBlobstorageServiceMockValue();
blobParam.publishDownloadSas = `${url}?sas-token`;
blobParam.fileExists = true;
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
await expect(
service.publishTemplateFileDownloadSas(
makeContext('tracking'),
externalId,
audioFileId,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.BAD_REQUEST),
);
});
it('Authorの場合、自身が登録したタスクでない場合エラー', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const url = `https://saodmsusdev.blob.core.windows.net/account-${accountId}/Templates`;
const { audioFileId } = await createTask(
source,
accountId,
url,
'test.zip',
'InProgress',
undefined,
'OTHOR_ID',
);
const blobParam = makeBlobstorageServiceMockValue();
blobParam.publishDownloadSas = `${url}?sas-token`;
blobParam.fileExists = true;
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
await expect(
service.publishTemplateFileDownloadSas(
makeContext('tracking'),
externalId,
audioFileId,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.BAD_REQUEST),
);
});
it('Taskが存在しない場合はエラーとなる', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const blobParam = makeBlobstorageServiceMockValue();
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
await expect(
service.publishTemplateFileDownloadSas(
makeContext('tracking'),
externalId,
1,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.BAD_REQUEST),
);
});
it('blobストレージにファイルが存在しない場合はエラーとなる', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId, author_id: authorId } = await makeTestUser(
source,
{
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
},
);
const url = `https://saodmsusdev.blob.core.windows.net/account-${accountId}/Templates`;
const { audioFileId } = await createTask(
source,
accountId,
url,
'test.zip',
'InProgress',
undefined,
authorId ?? '',
);
const blobParam = makeBlobstorageServiceMockValue();
blobParam.publishDownloadSas = `${url}?sas-token`;
blobParam.fileExists = false;
const module = await makeTestingModuleWithBlob(source, blobParam);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
await expect(
service.publishTemplateFileDownloadSas(
makeContext('tracking'),
externalId,
audioFileId,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010701'), HttpStatus.BAD_REQUEST),
);
});
});
describe('publishTemplateFileUploadSas', () => {
let source: DataSource | null = null;
beforeEach(async () => {
source = new DataSource({
type: 'sqlite',
database: ':memory:',
logging: false,
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
});
return source.initialize();
});
afterEach(async () => {
if (!source) return;
await source.destroy();
source = null;
});
it('テンプレートファイルアップロードSASトークンが乗っているURLを取得できる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const context = makeContext(admin.external_id);
const baseUrl = `https://saodmsusdev.blob.core.windows.net/account-${account.id}/Templates`;
//SASトークンを返却する
overrideBlobstorageService(service, {
containerExists: async () => true,
publishTemplateUploadSas: async () => `${baseUrl}?sas-token`,
});
const url = await service.publishTemplateFileUploadSas(
context,
admin.external_id,
);
expect(url).toBe(`${baseUrl}?sas-token`);
});
it('blobストレージにコンテナが存在しない場合はエラーとなる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
// 第五階層のアカウント作成
const { admin } = await makeTestAccount(source, { tier: 5 });
const context = makeContext(admin.external_id);
//Blobコンテナ存在チェックに失敗するようにする
overrideBlobstorageService(service, {
containerExists: async () => false,
publishTemplateUploadSas: async () => '',
});
try {
await service.publishTemplateFileUploadSas(context, admin.external_id);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
});
it('SASトークンの取得に失敗した場合はエラーとなる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
// 第五階層のアカウント作成
const { admin } = await makeTestAccount(source, { tier: 5 });
const context = makeContext(admin.external_id);
//BlobのSASトークン生成に失敗するようにする
overrideBlobstorageService(service, {
containerExists: async () => true,
publishTemplateUploadSas: async () => {
throw new Error('blob failed');
},
});
try {
await service.publishTemplateFileUploadSas(context, admin.external_id);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
});
});
describe('templateUploadFinished', () => {
let source: DataSource | null = null;
beforeEach(async () => {
source = new DataSource({
type: 'sqlite',
database: ':memory:',
logging: false,
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
});
return source.initialize();
});
afterEach(async () => {
if (!source) return;
await source.destroy();
source = null;
});
it('アップロード完了後のテンプレートファイル情報をDBに保存できる新規追加', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const context = makeContext(admin.external_id);
const fileName = 'test.docs';
const url = `https://blob.url/account-${account.id}/Templates`;
// 事前にDBを確認
{
const templates = await getTemplateFiles(source, account.id);
expect(templates.length).toBe(0);
}
await service.templateUploadFinished(
context,
admin.external_id,
url,
fileName,
);
//実行結果を確認
{
const templates = await getTemplateFiles(source, account.id);
expect(templates.length).toBe(1);
expect(templates[0].file_name).toBe(fileName);
expect(templates[0].url).toBe(url);
}
});
it('アップロード完了後のテンプレートファイル情報をDBに保存できる更新', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const context = makeContext(admin.external_id);
const fileName = 'test.docs';
const url = `https://blob.url/account-${account.id}/Templates`;
await createTemplateFile(source, account.id, fileName, url);
// 事前にDBを確認
{
const templates = await getTemplateFiles(source, account.id);
expect(templates.length).toBe(1);
expect(templates[0].file_name).toBe(fileName);
expect(templates[0].url).toBe(url);
}
const updateUrl = `https://blob.update.url/account-${account.id}/Templates`;
await service.templateUploadFinished(
context,
admin.external_id,
updateUrl,
fileName,
);
//実行結果を確認
{
const templates = await getTemplateFiles(source, account.id);
expect(templates.length).toBe(1);
expect(templates[0].file_name).toBe(fileName);
expect(templates[0].url).toBe(updateUrl);
}
});
it('DBへの保存に失敗した場合はエラーとなる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const context = makeContext(admin.external_id);
const fileName = 'test.docs';
const url = `https://blob.url/account-${account.id}/Templates`;
// 事前にDBを確認
{
const templates = await getTemplateFiles(source, account.id);
expect(templates.length).toBe(0);
}
//DBアクセスに失敗するようにする
const templatesService = module.get<TemplateFilesRepositoryService>(
TemplateFilesRepositoryService,
);
templatesService.upsertTemplateFile = jest
.fn()
.mockRejectedValue('DB failed');
try {
await service.templateUploadFinished(
context,
admin.external_id,
url,
fileName,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
});
});
const optionItemList = [
{
optionItemLabel: 'label_01',
optionItemValue: 'value_01',
},
{
optionItemLabel: 'label_02',
optionItemValue: 'value_02',
},
{
optionItemLabel: 'label_03',
optionItemValue: 'value_03',
},
{
optionItemLabel: 'label_04',
optionItemValue: 'value_04',
},
{
optionItemLabel: 'label_05',
optionItemValue: 'value_05',
},
{
optionItemLabel: 'label_06',
optionItemValue: 'value_06',
},
{
optionItemLabel: 'label_07',
optionItemValue: 'value_07',
},
{
optionItemLabel: 'label_08',
optionItemValue: 'value_08',
},
{
optionItemLabel: 'label_09',
optionItemValue: 'value_09',
},
{
optionItemLabel: 'label_10',
optionItemValue: 'value_10',
},
];