Merged PR 128: API実装(ソート条件変更)
## 概要 [Task1835: API実装(ソート条件変更)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/1835) - ソート条件変更APIを実装 - トークンからB2CのIDを取得→userテーブルからユーザー情報を取得 - ユーザーIDでソート条件テーブルを検索→レコードを更新 - ソート条件テーブルにレコードを作成する - アカウント作成時の処理にソート条件レコードを作成する処理を追加 - ユーザー追加時にも処理を追加 - テスト修正 ## レビューポイント - APIの引数をチェックする関数をControllerに配置してもよいか - ソート条件のレコードを作成するタイミングに漏れはないか - 実装漏れはないか ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認 ## 補足 - 相談、参考資料などがあれば
This commit is contained in:
parent
cfca98e53b
commit
d5e5e59f8c
@ -14,7 +14,6 @@ async function bootstrap(): Promise<void> {
|
||||
type: 'http',
|
||||
scheme: 'bearer',
|
||||
bearerFormat: 'JWT',
|
||||
in: 'header',
|
||||
})
|
||||
.build();
|
||||
const document = SwaggerModule.createDocument(app, options);
|
||||
|
||||
@ -37,6 +37,7 @@ import { BlobstorageModule } from './gateways/blobstorage/blobstorage.module';
|
||||
import { LicensesModule } from './features/licenses/licenses.module';
|
||||
import { LicensesService } from './features/licenses/licenses.service';
|
||||
import { LicensesController } from './features/licenses/licenses.controller';
|
||||
import { SortCriteriaRepositoryModule } from './repositories/sort_criteria/sort_criteria.repository.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -81,6 +82,7 @@ import { LicensesController } from './features/licenses/licenses.controller';
|
||||
NotificationhubModule,
|
||||
BlobstorageModule,
|
||||
AuthGuardsModule,
|
||||
SortCriteriaRepositoryModule,
|
||||
],
|
||||
controllers: [
|
||||
HealthController,
|
||||
|
||||
27
dictation_server/src/common/types/sort/index.ts
Normal file
27
dictation_server/src/common/types/sort/index.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import {
|
||||
TASK_LIST_SORTABLE_ATTRIBUTES,
|
||||
SORT_DIRECTIONS,
|
||||
} from '../../../constants';
|
||||
|
||||
export type TaskListSortableAttribute =
|
||||
(typeof TASK_LIST_SORTABLE_ATTRIBUTES)[number];
|
||||
|
||||
export type SortDirection = (typeof SORT_DIRECTIONS)[number];
|
||||
|
||||
export const isTaskListSortableAttribute = (
|
||||
arg: string,
|
||||
): arg is TaskListSortableAttribute => {
|
||||
const param = arg as TaskListSortableAttribute;
|
||||
if (TASK_LIST_SORTABLE_ATTRIBUTES.includes(param)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const isSortDirection = (arg: string): arg is SortDirection => {
|
||||
const param = arg as SortDirection;
|
||||
if (SORT_DIRECTIONS.includes(param)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
11
dictation_server/src/common/types/sort/util.ts
Normal file
11
dictation_server/src/common/types/sort/util.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SortDirection, TaskListSortableAttribute } from '.';
|
||||
|
||||
export const getDirection = (direction: SortDirection): SortDirection => {
|
||||
return direction;
|
||||
};
|
||||
|
||||
export const getTaskListSortableAttribute = (
|
||||
TaskListSortableAttribute: TaskListSortableAttribute,
|
||||
): TaskListSortableAttribute => {
|
||||
return TaskListSortableAttribute;
|
||||
};
|
||||
@ -149,5 +149,5 @@ export const TASK_LIST_SORTABLE_ATTRIBUTES = [
|
||||
'TRANSCRIPTION_FINISHED_DATE',
|
||||
] as const;
|
||||
|
||||
export type TaskListSortableAttribute =
|
||||
(typeof TASK_LIST_SORTABLE_ATTRIBUTES)[number];
|
||||
// export const SORT_DIRECTIONS = { asc: 'ASC', desc: 'DESC' } as const;
|
||||
export const SORT_DIRECTIONS = ['ASC', 'DESC'] as const;
|
||||
|
||||
@ -1,12 +1,19 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { NotificationController } from './notification.controller';
|
||||
import { NotificationService } from './notification.service';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
|
||||
describe('NotificationController', () => {
|
||||
let controller: NotificationController;
|
||||
const mockNotificationService = {};
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
envFilePath: ['.env.local', '.env'],
|
||||
isGlobal: true,
|
||||
}),
|
||||
],
|
||||
controllers: [NotificationController],
|
||||
providers: [NotificationService],
|
||||
})
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
import { ErrorResponse } from '../../common/error/types/types';
|
||||
import { RegisterRequest, RegisterResponse } from './types/types';
|
||||
import { NotificationService } from './notification.service';
|
||||
import { AuthGuard } from 'src/common/guards/auth/authguards';
|
||||
import { AuthGuard } from '../../common/guards/auth/authguards';
|
||||
|
||||
@ApiTags('notification')
|
||||
@Controller('notification')
|
||||
|
||||
@ -10,11 +10,17 @@ import { SendGridService } from '../../../gateways/sendgrid/sendgrid.service';
|
||||
import { User } from '../../../repositories/users/entity/user.entity';
|
||||
import { UsersRepositoryService } from '../../../repositories/users/users.repository.service';
|
||||
import { UsersService } from '../users.service';
|
||||
import { SortCriteria } from '../../../repositories/sort_criteria/entity/sort_criteria.entity';
|
||||
import { SortCriteriaRepositoryService } from '../../../repositories/sort_criteria/sort_criteria.repository.service';
|
||||
|
||||
export type CryptoMockValue = {
|
||||
getPublicKey: string | Error;
|
||||
};
|
||||
|
||||
export type SortCriteriaRepositoryMockValue = {
|
||||
updateSortCriteria: SortCriteria | Error;
|
||||
};
|
||||
|
||||
export type UsersRepositoryMockValue = {
|
||||
updateUserVerified: undefined | Error;
|
||||
findUserById: User | Error;
|
||||
@ -44,29 +50,58 @@ export type SendGridMockValue = {
|
||||
sendMail: undefined | Error;
|
||||
};
|
||||
|
||||
export const makeDefaultAdB2cMockValue = (): AdB2cMockValue => {
|
||||
return {
|
||||
getMetaData: {
|
||||
issuer: 'issuer',
|
||||
},
|
||||
getSignKeySets: [
|
||||
{
|
||||
kid: 'kid',
|
||||
nbf: 1111111111,
|
||||
use: 'sig',
|
||||
kty: 'RSA',
|
||||
e: 'e',
|
||||
n: 'n',
|
||||
},
|
||||
export const makeUsersServiceMock = async (
|
||||
cryptoMockValue: CryptoMockValue,
|
||||
usersRepositoryMockValue: UsersRepositoryMockValue,
|
||||
adB2cMockValue: AdB2cMockValue,
|
||||
sendGridMockValue: SendGridMockValue,
|
||||
configMockValue: ConfigMockValue,
|
||||
sortCriteriaRepositoryMockValue: SortCriteriaRepositoryMockValue,
|
||||
): Promise<UsersService> => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [UsersService],
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
ignoreEnvFile: true,
|
||||
ignoreEnvVars: true,
|
||||
}),
|
||||
],
|
||||
changePassword: {
|
||||
sub: 'TEST9999',
|
||||
},
|
||||
createUser: '001',
|
||||
getUser: {
|
||||
displayName: 'Hanako Sato',
|
||||
mail: 'hanako@sample.com',
|
||||
},
|
||||
})
|
||||
.useMocker((token) => {
|
||||
switch (token) {
|
||||
case CryptoService:
|
||||
return makeCryptoServiceMock(cryptoMockValue);
|
||||
case UsersRepositoryService:
|
||||
return makeUsersRepositoryMock(usersRepositoryMockValue);
|
||||
case AdB2cService:
|
||||
return makeAdB2cServiceMock(adB2cMockValue);
|
||||
case SendGridService:
|
||||
return makeSendGridMock(sendGridMockValue);
|
||||
case ConfigService:
|
||||
return makeConfigMock(configMockValue);
|
||||
case SortCriteriaRepositoryService:
|
||||
return makeSortCriteriaRepositoryMock(
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
}
|
||||
})
|
||||
.compile();
|
||||
|
||||
return module.get<UsersService>(UsersService);
|
||||
};
|
||||
|
||||
export const makeSortCriteriaRepositoryMock = (
|
||||
value: SortCriteriaRepositoryMockValue,
|
||||
) => {
|
||||
const { updateSortCriteria } = value;
|
||||
|
||||
return {
|
||||
updateSortCriteria:
|
||||
updateSortCriteria instanceof Error
|
||||
? jest.fn<Promise<void>, []>().mockRejectedValue(updateSortCriteria)
|
||||
: jest
|
||||
.fn<Promise<SortCriteria>, []>()
|
||||
.mockResolvedValue(updateSortCriteria),
|
||||
};
|
||||
};
|
||||
|
||||
@ -130,41 +165,6 @@ export type ConfigMockValue = {
|
||||
get: string | Error;
|
||||
};
|
||||
|
||||
export const makeUsersServiceMock = async (
|
||||
cryptoMockValue: CryptoMockValue,
|
||||
usersRepositoryMockValue: UsersRepositoryMockValue,
|
||||
adB2cMockValue: AdB2cMockValue,
|
||||
sendGridMockValue: SendGridMockValue,
|
||||
configMockValue: ConfigMockValue,
|
||||
): Promise<UsersService> => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [UsersService],
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
ignoreEnvFile: true,
|
||||
ignoreEnvVars: true,
|
||||
}),
|
||||
],
|
||||
})
|
||||
.useMocker((token) => {
|
||||
switch (token) {
|
||||
case CryptoService:
|
||||
return makeCryptoServiceMock(cryptoMockValue);
|
||||
case UsersRepositoryService:
|
||||
return makeUsersRepositoryMock(usersRepositoryMockValue);
|
||||
case AdB2cService:
|
||||
return makeAdB2cServiceMock(adB2cMockValue);
|
||||
case SendGridService:
|
||||
return makeSendGridMock(sendGridMockValue);
|
||||
case ConfigService:
|
||||
return makeConfigMock(configMockValue);
|
||||
}
|
||||
})
|
||||
.compile();
|
||||
|
||||
return module.get<UsersService>(UsersService);
|
||||
};
|
||||
|
||||
export const makeCryptoServiceMock = (value: CryptoMockValue) => {
|
||||
const { getPublicKey } = value;
|
||||
|
||||
@ -292,6 +292,46 @@ export const makeDefaultConfigValue = (): ConfigMockValue => {
|
||||
};
|
||||
};
|
||||
|
||||
export const makeDefaultSortCriteriaRepositoryMockValue =
|
||||
(): SortCriteriaRepositoryMockValue => {
|
||||
const sortCriteria = new SortCriteria();
|
||||
{
|
||||
sortCriteria.id = 1;
|
||||
sortCriteria.direction = 'ASC';
|
||||
sortCriteria.parameter = 'JOB_NUMBER';
|
||||
sortCriteria.user_id = 1;
|
||||
}
|
||||
return {
|
||||
updateSortCriteria: sortCriteria,
|
||||
};
|
||||
};
|
||||
|
||||
export const makeDefaultAdB2cMockValue = (): AdB2cMockValue => {
|
||||
return {
|
||||
getMetaData: {
|
||||
issuer: 'issuer',
|
||||
},
|
||||
getSignKeySets: [
|
||||
{
|
||||
kid: 'kid',
|
||||
nbf: 1111111111,
|
||||
use: 'sig',
|
||||
kty: 'RSA',
|
||||
e: 'e',
|
||||
n: 'n',
|
||||
},
|
||||
],
|
||||
changePassword: {
|
||||
sub: 'TEST9999',
|
||||
},
|
||||
createUser: '001',
|
||||
getUser: {
|
||||
displayName: 'Hanako Sato',
|
||||
mail: 'hanako@sample.com',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// 個別のテストケースに対応してそれぞれのMockを用意するのは無駄が多いのでテストケース内で個別の値を設定する
|
||||
export const makeDefaultUsersRepositoryMockValue =
|
||||
(): UsersRepositoryMockValue => {
|
||||
|
||||
@ -139,8 +139,12 @@ export class SortCriteriaRequest {
|
||||
@IsIn(['ASC', 'DESC'], { message: 'invalid direction' })
|
||||
direction: string;
|
||||
|
||||
@ApiProperty({ description: `${TASK_LIST_SORTABLE_ATTRIBUTES.join('/')}` })
|
||||
@IsIn(TASK_LIST_SORTABLE_ATTRIBUTES, { message: 'invalid attributes' })
|
||||
@ApiProperty({
|
||||
description: `${TASK_LIST_SORTABLE_ATTRIBUTES.join('/')}`,
|
||||
})
|
||||
@IsIn(TASK_LIST_SORTABLE_ATTRIBUTES, {
|
||||
message: 'invalid attributes',
|
||||
})
|
||||
paramName: string;
|
||||
}
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@ import {
|
||||
HttpStatus,
|
||||
Post,
|
||||
Req,
|
||||
UseGuards,
|
||||
HttpException,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
@ -33,9 +33,12 @@ import {
|
||||
SortCriteriaResponse,
|
||||
} from './types/types';
|
||||
import { UsersService } from './users.service';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { AuthGuard } from '../../common/guards/auth/authguards';
|
||||
import { RoleGuard } from '../../common/guards/role/roleguards';
|
||||
|
||||
import {
|
||||
isSortDirection,
|
||||
isTaskListSortableAttribute,
|
||||
} from '../../common/types/sort';
|
||||
@ApiTags('users')
|
||||
@Controller('users')
|
||||
export class UsersController {
|
||||
@ -284,6 +287,11 @@ export class UsersController {
|
||||
description: '認証エラー',
|
||||
type: ErrorResponse,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: HttpStatus.BAD_REQUEST,
|
||||
description: '不正なパラメータ',
|
||||
type: ErrorResponse,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
description: '想定外のサーバーエラー',
|
||||
@ -298,8 +306,27 @@ export class UsersController {
|
||||
@Post('sort-criteria')
|
||||
async updateSortCriteria(
|
||||
@Body() body: SortCriteriaRequest,
|
||||
@Req() req: Request,
|
||||
): Promise<SortCriteriaResponse> {
|
||||
console.log(body);
|
||||
const { direction, paramName } = body;
|
||||
const accessToken = retrieveAuthorizationToken(req);
|
||||
const decodedToken = jwt.decode(accessToken, { json: true }) as AccessToken;
|
||||
|
||||
//型チェック
|
||||
if (
|
||||
!isTaskListSortableAttribute(paramName) ||
|
||||
!isSortDirection(direction)
|
||||
) {
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E010001'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
}
|
||||
await this.usersService.updateSortCriteria(
|
||||
paramName,
|
||||
direction,
|
||||
decodedToken,
|
||||
);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,11 +6,13 @@ import { SendGridModule } from '../../gateways/sendgrid/sendgrid.module';
|
||||
import { UsersRepositoryModule } from '../../repositories/users/users.repository.module';
|
||||
import { UsersController } from './users.controller';
|
||||
import { UsersService } from './users.service';
|
||||
import { SortCriteriaRepositoryModule } from '../../repositories/sort_criteria/sort_criteria.repository.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
CryptoModule,
|
||||
UsersRepositoryModule,
|
||||
SortCriteriaRepositoryModule,
|
||||
AdB2cModule,
|
||||
SendGridModule,
|
||||
ConfigModule,
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
makeDefaultConfigValue,
|
||||
makeDefaultCryptoMockValue,
|
||||
makeDefaultSendGridlValue,
|
||||
makeDefaultSortCriteriaRepositoryMockValue,
|
||||
makeDefaultUsersRepositoryMockValue,
|
||||
makeUsersServiceMock,
|
||||
} from './test/users.service.mock';
|
||||
@ -20,12 +21,15 @@ describe('UsersService', () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendGridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const token =
|
||||
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
|
||||
@ -52,6 +56,8 @@ describe('UsersService', () => {
|
||||
};
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
@ -59,6 +65,7 @@ describe('UsersService', () => {
|
||||
adb2cParam,
|
||||
sendGridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
|
||||
const token =
|
||||
@ -72,12 +79,15 @@ describe('UsersService', () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const token = 'invalid.id.token';
|
||||
await expect(service.confirmUser(token)).rejects.toEqual(
|
||||
@ -106,12 +116,15 @@ describe('UsersService', () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendGridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const token = 'invalid.id.token';
|
||||
await expect(service.confirmUserAndInitPassword(token)).rejects.toEqual(
|
||||
@ -124,6 +137,8 @@ describe('UsersService', () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
|
||||
usersRepositoryMockValue.updateUserVerified =
|
||||
new EmailAlreadyVerifiedError();
|
||||
@ -134,6 +149,7 @@ describe('UsersService', () => {
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const token =
|
||||
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
|
||||
@ -162,6 +178,8 @@ describe('UsersService', () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
usersRepositoryMockValue.updateUserVerified =
|
||||
new EmailAlreadyVerifiedError();
|
||||
|
||||
@ -171,6 +189,7 @@ describe('UsersService', () => {
|
||||
adb2cParam,
|
||||
sendGridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const token =
|
||||
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
|
||||
@ -184,6 +203,8 @@ describe('UsersService', () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
usersRepositoryMockValue.updateUserVerified = new Error('DB error');
|
||||
|
||||
const service = await makeUsersServiceMock(
|
||||
@ -192,6 +213,7 @@ describe('UsersService', () => {
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const token =
|
||||
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
|
||||
@ -224,12 +246,15 @@ describe('UsersService', () => {
|
||||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||||
usersRepositoryMockValue.updateUserVerified = new Error('DB error');
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendGridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const token =
|
||||
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
|
||||
@ -246,12 +271,15 @@ describe('UsersService', () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const name = 'test_user1';
|
||||
const role = 'None';
|
||||
@ -281,12 +309,15 @@ describe('UsersService', () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const name = 'test_user2';
|
||||
const role = 'Author';
|
||||
@ -318,12 +349,15 @@ describe('UsersService', () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const name = 'test_user3';
|
||||
const role = 'Transcriptioninst';
|
||||
@ -355,6 +389,8 @@ it('DBネットワークエラーとなる場合、エラーとなる。', async
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
usersRepositoryMockValue.createNormalUser = new Error('DB error');
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
@ -362,6 +398,7 @@ it('DBネットワークエラーとなる場合、エラーとなる。', async
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const name = 'test_user5';
|
||||
const role = 'Transcriptioninst';
|
||||
@ -394,12 +431,15 @@ it('Azure ADB2Cでネットワークエラーとなる場合、エラーとな
|
||||
adb2cParam.createUser = new Error();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const name = 'test_user6';
|
||||
const role = 'Transcriptioninst';
|
||||
@ -432,12 +472,15 @@ it('メールアドレスが重複している場合、エラーとなる。', a
|
||||
adb2cParam.createUser = { reason: 'email', message: 'ObjectConflict' };
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const name = 'test_user7';
|
||||
const role = 'Transcriptioninst';
|
||||
@ -466,6 +509,8 @@ it('AuthorIDが重複している場合、エラーとなる。(AuthorID重複
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
usersRepositoryMockValue.createNormalUser = new Error();
|
||||
usersRepositoryMockValue.existsAuthorId = true;
|
||||
|
||||
@ -475,6 +520,7 @@ it('AuthorIDが重複している場合、エラーとなる。(AuthorID重複
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const name = 'test_user8';
|
||||
const role = 'Author';
|
||||
@ -505,6 +551,8 @@ it('AuthorIDが重複している場合、エラーとなる。(insert失敗)',
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
usersRepositoryMockValue.createNormalUser = new Error();
|
||||
usersRepositoryMockValue.createNormalUser.name = 'ER_DUP_ENTRY';
|
||||
|
||||
@ -514,6 +562,7 @@ it('AuthorIDが重複している場合、エラーとなる。(insert失敗)',
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const name = 'test_user9';
|
||||
const role = 'Author';
|
||||
@ -545,12 +594,15 @@ it('ユーザの一覧を取得する', async () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
const token =
|
||||
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
|
||||
@ -589,6 +641,8 @@ it('ユーザの一覧を取得に失敗する', async () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
usersRepositoryMockValue.findSameAccountUsers = new Error(
|
||||
'Failure to acquire',
|
||||
);
|
||||
@ -599,6 +653,7 @@ it('ユーザの一覧を取得に失敗する', async () => {
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
|
||||
const token =
|
||||
@ -615,6 +670,8 @@ it('ユーザの一覧を0件取得する', async () => {
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
|
||||
// モックでDBからのユーザ取得を空にする
|
||||
const noDbUsers: EntityUser[] = [];
|
||||
@ -626,6 +683,7 @@ it('ユーザの一覧を0件取得する', async () => {
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
|
||||
const token =
|
||||
@ -634,3 +692,98 @@ it('ユーザの一覧を0件取得する', async () => {
|
||||
const emptyMergedUsers: User[] = [];
|
||||
expect(await service.getUsers(token)).toEqual(emptyMergedUsers);
|
||||
});
|
||||
|
||||
it('ソート条件を変更できる', async () => {
|
||||
const cryptoMockValue = makeDefaultCryptoMockValue();
|
||||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
|
||||
expect(
|
||||
await service.updateSortCriteria('AUTHOR_ID', 'ASC', {
|
||||
role: 'none admin',
|
||||
userId: 'xxxxxxxxxxxx',
|
||||
}),
|
||||
).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('ユーザー情報が存在せず、ソート条件を変更できない', async () => {
|
||||
const cryptoMockValue = makeDefaultCryptoMockValue();
|
||||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
|
||||
// モックでDBからのユーザ取得がエラーとなる
|
||||
usersRepositoryMockValue.findUserByExternalId = new Error('user not found');
|
||||
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
|
||||
await expect(
|
||||
service.updateSortCriteria('AUTHOR_ID', 'ASC', {
|
||||
role: 'none admin',
|
||||
userId: 'xxxxxxxxxxxx',
|
||||
}),
|
||||
).rejects.toEqual(
|
||||
new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('ソート条件が存在せず、ソート条件を変更できない', async () => {
|
||||
const cryptoMockValue = makeDefaultCryptoMockValue();
|
||||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const sendgridMockValue = makeDefaultSendGridlValue();
|
||||
const configMockValue = makeDefaultConfigValue();
|
||||
const sortCriteriaRepositoryMockValue =
|
||||
makeDefaultSortCriteriaRepositoryMockValue();
|
||||
sortCriteriaRepositoryMockValue.updateSortCriteria = new Error(
|
||||
'sort criteria not found',
|
||||
);
|
||||
|
||||
// モックでDBからのユーザ取得を空にする
|
||||
|
||||
const service = await makeUsersServiceMock(
|
||||
cryptoMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendgridMockValue,
|
||||
configMockValue,
|
||||
sortCriteriaRepositoryMockValue,
|
||||
);
|
||||
|
||||
await expect(
|
||||
service.updateSortCriteria('AUTHOR_ID', 'ASC', {
|
||||
role: 'none admin',
|
||||
userId: 'xxxxxxxxxxxx',
|
||||
}),
|
||||
).rejects.toEqual(
|
||||
new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
@ -4,6 +4,10 @@ import { makeErrorResponse } from '../../common/error/makeErrorResponse';
|
||||
import { isVerifyError, verify } from '../../common/jwt';
|
||||
import { makePassword } from '../../common/password/password';
|
||||
import { AccessToken } from '../../common/token';
|
||||
import {
|
||||
TaskListSortableAttribute,
|
||||
SortDirection,
|
||||
} from '../../common/types/sort';
|
||||
import {
|
||||
AdB2cService,
|
||||
ConflictError,
|
||||
@ -11,6 +15,7 @@ import {
|
||||
} from '../../gateways/adb2c/adb2c.service';
|
||||
import { CryptoService } from '../../gateways/crypto/crypto.service';
|
||||
import { SendGridService } from '../../gateways/sendgrid/sendgrid.service';
|
||||
import { SortCriteriaRepositoryService } from '../../repositories/sort_criteria/sort_criteria.repository.service';
|
||||
import { User as EntityUser } from '../../repositories/users/entity/user.entity';
|
||||
import {
|
||||
EmailAlreadyVerifiedError,
|
||||
@ -23,6 +28,7 @@ export class UsersService {
|
||||
constructor(
|
||||
private readonly cryptoService: CryptoService,
|
||||
private readonly usersRepository: UsersRepositoryService,
|
||||
private readonly sortCriteriaRepository: SortCriteriaRepositoryService,
|
||||
private readonly adB2cService: AdB2cService,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly sendgridService: SendGridService,
|
||||
@ -336,4 +342,48 @@ export class UsersService {
|
||||
this.logger.log(`[OUT] ${this.getUsers.name}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Updates sort criteria
|
||||
* @param paramName
|
||||
* @param direction
|
||||
* @param token
|
||||
* @returns sort criteria
|
||||
*/
|
||||
async updateSortCriteria(
|
||||
paramName: TaskListSortableAttribute,
|
||||
direction: SortDirection,
|
||||
token: AccessToken,
|
||||
): Promise<void> {
|
||||
this.logger.log(`[IN] ${this.updateSortCriteria.name}`);
|
||||
let user: EntityUser;
|
||||
try {
|
||||
// ユーザー情報を取得
|
||||
const sub = token.userId;
|
||||
user = await this.usersRepository.findUserByExternalId(sub);
|
||||
} catch (e) {
|
||||
this.logger.error(`error=${e}`);
|
||||
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// ユーザーのソート条件を更新
|
||||
await this.sortCriteriaRepository.updateSortCriteria(
|
||||
user.id,
|
||||
paramName,
|
||||
direction,
|
||||
);
|
||||
} catch (e) {
|
||||
this.logger.error(`error=${e}`);
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
} finally {
|
||||
this.logger.log(`[OUT] ${this.updateSortCriteria.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,11 @@ import { Injectable } from '@nestjs/common';
|
||||
import { DataSource, UpdateResult } from 'typeorm';
|
||||
import { User } from '../users/entity/user.entity';
|
||||
import { Account } from './entity/account.entity';
|
||||
import { SortCriteria } from '../sort_criteria/entity/sort_criteria.entity';
|
||||
import {
|
||||
getDirection,
|
||||
getTaskListSortableAttribute,
|
||||
} from '../../common/types/sort/util';
|
||||
|
||||
export class AccountNotFoundError extends Error {}
|
||||
|
||||
@ -111,6 +116,17 @@ export class AccountsRepositoryService {
|
||||
throw new Error(`invalid update. result.affected=${result.affected}`);
|
||||
}
|
||||
|
||||
// ユーザーのタスクソート条件を作成
|
||||
const sortCriteria = new SortCriteria();
|
||||
{
|
||||
sortCriteria.parameter = getTaskListSortableAttribute('JOB_NUMBER');
|
||||
sortCriteria.direction = getDirection('ASC');
|
||||
sortCriteria.user_id = persistedUser.id;
|
||||
}
|
||||
const sortCriteriaRepo = entityManager.getRepository(SortCriteria);
|
||||
const newSortCriteria = sortCriteriaRepo.create(sortCriteria);
|
||||
await sortCriteriaRepo.save(newSortCriteria);
|
||||
|
||||
return { newAccount: persistedAccount, adminUser: persistedUser };
|
||||
});
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
@Entity({ name: 'sort_criteria' })
|
||||
export class SortCriteria {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
user_id: number;
|
||||
|
||||
@Column()
|
||||
parameter: string;
|
||||
|
||||
@Column()
|
||||
direction: string;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { SortCriteriaRepositoryService } from './sort_criteria.repository.service';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { SortCriteria } from './entity/sort_criteria.entity';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([SortCriteria])],
|
||||
providers: [SortCriteriaRepositoryService],
|
||||
exports: [SortCriteriaRepositoryService],
|
||||
})
|
||||
export class SortCriteriaRepositoryModule {}
|
||||
@ -0,0 +1,48 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { SortCriteria } from './entity/sort_criteria.entity';
|
||||
import {
|
||||
TaskListSortableAttribute,
|
||||
SortDirection,
|
||||
} from '../../common/types/sort';
|
||||
|
||||
export class SortCriteriaNotFoundError extends Error {}
|
||||
@Injectable()
|
||||
export class SortCriteriaRepositoryService {
|
||||
constructor(private dataSource: DataSource) {}
|
||||
private readonly logger = new Logger(SortCriteriaRepositoryService.name);
|
||||
/**
|
||||
* Updates sort criteria
|
||||
* @param userId
|
||||
* @param parameter
|
||||
* @param direction
|
||||
* @returns sort criteria
|
||||
*/
|
||||
async updateSortCriteria(
|
||||
userId: number,
|
||||
parameter: TaskListSortableAttribute,
|
||||
direction: SortDirection,
|
||||
): Promise<SortCriteria> {
|
||||
this.logger.log(
|
||||
` ${this.updateSortCriteria.name}; parameter:${parameter}, direction:${direction}`,
|
||||
);
|
||||
return await this.dataSource.transaction(async (entityManager) => {
|
||||
const repo = entityManager.getRepository(SortCriteria);
|
||||
const targetSortCriteria = await repo.findOne({
|
||||
where: {
|
||||
user_id: userId,
|
||||
},
|
||||
});
|
||||
// 運用上はあり得ないが、プログラム上発生しうるのでエラーとして処理
|
||||
if (!targetSortCriteria) {
|
||||
throw new Error('sort criteria not found ');
|
||||
}
|
||||
|
||||
targetSortCriteria.parameter = parameter;
|
||||
targetSortCriteria.direction = direction;
|
||||
|
||||
const persisted = await repo.save(targetSortCriteria);
|
||||
return persisted;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,11 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { DataSource, UpdateResult } from 'typeorm';
|
||||
import { User } from './entity/user.entity';
|
||||
import { SortCriteria } from '../sort_criteria/entity/sort_criteria.entity';
|
||||
import {
|
||||
getDirection,
|
||||
getTaskListSortableAttribute,
|
||||
} from '../../common/types/sort/util';
|
||||
|
||||
// UsersRepositoryServiceで発生するエラーを定義
|
||||
export class EmailAlreadyVerifiedError extends Error {}
|
||||
@ -73,6 +78,18 @@ export class UsersRepositoryService {
|
||||
const repo = entityManager.getRepository(User);
|
||||
const newUser = repo.create(user);
|
||||
const persisted = await repo.save(newUser);
|
||||
|
||||
// ユーザーのタスクソート条件を作成
|
||||
const sortCriteria = new SortCriteria();
|
||||
{
|
||||
sortCriteria.parameter = getTaskListSortableAttribute('JOB_NUMBER');
|
||||
sortCriteria.direction = getDirection('ASC');
|
||||
sortCriteria.user_id = persisted.id;
|
||||
}
|
||||
const sortCriteriaRepo = entityManager.getRepository(SortCriteria);
|
||||
const newSortCriteria = sortCriteriaRepo.create(sortCriteria);
|
||||
await sortCriteriaRepo.save(newSortCriteria);
|
||||
|
||||
return persisted;
|
||||
},
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user