## 概要 [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のスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認 ## 補足 - 相談、参考資料などがあれば
384 lines
12 KiB
TypeScript
384 lines
12 KiB
TypeScript
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
import { Test, TestingModule } from '@nestjs/testing';
|
|
import { Aadb2cUser, B2cMetadata, JwkSignKey } from '../../../common/token';
|
|
import {
|
|
AdB2cService,
|
|
ConflictError,
|
|
} from '../../../gateways/adb2c/adb2c.service';
|
|
import { CryptoService } from '../../../gateways/crypto/crypto.service';
|
|
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;
|
|
createNormalUser: User | Error;
|
|
findSameAccountUsers: User[] | Error;
|
|
findUserByExternalId: User | Error;
|
|
existsAuthorId: boolean | Error;
|
|
};
|
|
|
|
export type AdB2cMockValue = {
|
|
getMetaData: B2cMetadata | Error;
|
|
getSignKeySets: JwkSignKey[] | Error;
|
|
changePassword: { sub: string } | Error;
|
|
createUser: string | ConflictError | Error;
|
|
getUser: Aadb2cUser | Error;
|
|
};
|
|
|
|
export type SendGridMockValue = {
|
|
createMailContentFromEmailConfirm: {
|
|
subject: string;
|
|
text: string;
|
|
html: string;
|
|
};
|
|
createMailContentFromEmailConfirmForNormalUser:
|
|
| { subject: string; text: string; html: string }
|
|
| Error;
|
|
sendMail: undefined | Error;
|
|
};
|
|
|
|
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,
|
|
}),
|
|
],
|
|
})
|
|
.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),
|
|
};
|
|
};
|
|
|
|
export const makeSendGridServiceMock = (value: SendGridMockValue) => {
|
|
const { createMailContentFromEmailConfirm, sendMail } = value;
|
|
return {
|
|
createMailContentFromEmailConfirm:
|
|
createMailContentFromEmailConfirm instanceof Error
|
|
? jest
|
|
.fn<Promise<void>, []>()
|
|
.mockRejectedValue(createMailContentFromEmailConfirm)
|
|
: jest
|
|
.fn<Promise<{ subject: string; text: string; html: string }>, []>()
|
|
.mockResolvedValue(createMailContentFromEmailConfirm),
|
|
sendMail:
|
|
sendMail instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(sendMail)
|
|
: jest.fn<Promise<void>, []>().mockResolvedValue(sendMail),
|
|
};
|
|
};
|
|
|
|
export const makeAdB2cServiceMock = (value: AdB2cMockValue) => {
|
|
const { getMetaData, getSignKeySets, changePassword, createUser, getUser } =
|
|
value;
|
|
|
|
return {
|
|
getMetaData:
|
|
getMetaData instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(getMetaData)
|
|
: jest.fn<Promise<B2cMetadata>, []>().mockResolvedValue(getMetaData),
|
|
getSignKeySets:
|
|
getSignKeySets instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(getSignKeySets)
|
|
: jest
|
|
.fn<Promise<JwkSignKey[]>, []>()
|
|
.mockResolvedValue(getSignKeySets),
|
|
changePassword:
|
|
changePassword instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(changePassword)
|
|
: jest
|
|
.fn<Promise<{ sub: string }>, []>()
|
|
.mockResolvedValue(changePassword),
|
|
createUser:
|
|
createUser instanceof Error
|
|
? jest.fn<Promise<ConflictError>, []>().mockRejectedValue(createUser)
|
|
: jest
|
|
.fn<Promise<string | ConflictError>, []>()
|
|
.mockResolvedValue(createUser),
|
|
getUser:
|
|
getUser instanceof Error
|
|
? jest
|
|
.fn<Promise<Aadb2cUser | undefined>, []>()
|
|
.mockRejectedValue(getUser)
|
|
: jest
|
|
.fn<Promise<Aadb2cUser | undefined>, []>()
|
|
.mockResolvedValue(getUser),
|
|
};
|
|
};
|
|
|
|
export type ConfigMockValue = {
|
|
get: string | Error;
|
|
};
|
|
|
|
export const makeCryptoServiceMock = (value: CryptoMockValue) => {
|
|
const { getPublicKey } = value;
|
|
|
|
return {
|
|
getPublicKey:
|
|
getPublicKey instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(getPublicKey)
|
|
: jest.fn<Promise<string>, []>().mockResolvedValue(getPublicKey),
|
|
};
|
|
};
|
|
|
|
class authorIdError extends Error {
|
|
constructor(public code: string, e?: string) {
|
|
super(e);
|
|
}
|
|
}
|
|
|
|
export const makeUsersRepositoryMock = (value: UsersRepositoryMockValue) => {
|
|
const {
|
|
updateUserVerified,
|
|
findUserById,
|
|
createNormalUser,
|
|
findSameAccountUsers,
|
|
findUserByExternalId,
|
|
existsAuthorId,
|
|
} = value;
|
|
|
|
const aIdError = new authorIdError('ER_DUP_ENTRY');
|
|
|
|
return {
|
|
updateUserVerified:
|
|
updateUserVerified instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(updateUserVerified)
|
|
: jest.fn<Promise<void>, []>().mockResolvedValue(updateUserVerified),
|
|
findUserById:
|
|
findUserById instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(findUserById)
|
|
: jest.fn<Promise<User>, []>().mockResolvedValue(findUserById),
|
|
createNormalUser:
|
|
createNormalUser instanceof Error
|
|
? createNormalUser.name == 'ER_DUP_ENTRY'
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(aIdError)
|
|
: jest.fn<Promise<void>, []>().mockRejectedValue(createNormalUser)
|
|
: jest.fn<Promise<User>, []>().mockResolvedValue(createNormalUser),
|
|
findSameAccountUsers:
|
|
findSameAccountUsers instanceof Error
|
|
? jest
|
|
.fn<Promise<User[] | undefined>, []>()
|
|
.mockRejectedValue(findSameAccountUsers)
|
|
: jest
|
|
.fn<Promise<User[] | undefined>, []>()
|
|
.mockResolvedValue(findSameAccountUsers),
|
|
findUserByExternalId:
|
|
findUserByExternalId instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(findUserByExternalId)
|
|
: jest.fn<Promise<User>, []>().mockResolvedValue(findUserByExternalId),
|
|
existsAuthorId:
|
|
existsAuthorId instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(existsAuthorId)
|
|
: jest.fn<Promise<boolean>, []>().mockResolvedValue(existsAuthorId),
|
|
};
|
|
};
|
|
|
|
export const makeSendGridMock = (value: SendGridMockValue) => {
|
|
const { sendMail, createMailContentFromEmailConfirmForNormalUser } = value;
|
|
|
|
return {
|
|
sendMail:
|
|
sendMail instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(sendMail)
|
|
: jest.fn<Promise<void>, []>().mockResolvedValue(sendMail),
|
|
createMailContentFromEmailConfirmForNormalUser:
|
|
createMailContentFromEmailConfirmForNormalUser instanceof Error
|
|
? jest
|
|
.fn<Promise<void>, []>()
|
|
.mockRejectedValue(createMailContentFromEmailConfirmForNormalUser)
|
|
: jest
|
|
.fn<Promise<{ subject: string; text: string; html: string }>, []>()
|
|
.mockResolvedValue(createMailContentFromEmailConfirmForNormalUser),
|
|
};
|
|
};
|
|
|
|
export const makeConfigMock = (value: ConfigMockValue) => {
|
|
const { get } = value;
|
|
|
|
return {
|
|
get:
|
|
get instanceof Error
|
|
? jest.fn<Promise<void>, []>().mockRejectedValue(get)
|
|
: jest.fn<Promise<string>, []>().mockResolvedValue(get),
|
|
};
|
|
};
|
|
|
|
export const makeDefaultCryptoMockValue = (): CryptoMockValue => {
|
|
return {
|
|
getPublicKey: [
|
|
'-----BEGIN PUBLIC KEY-----',
|
|
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5IZZNgDew9eGmuFTezwd',
|
|
'HYLSaJvUPPIKYoiOeVLD1paWNI517Vkaoh0ngprcKOdv6T1N07V4igK7mOim2zY3',
|
|
'yCTR6wcWR3PfFJrl9vh5SOo79koZoJb27YiM4jtxfx2dezzp0T2GoNR5rRolPUbW',
|
|
'FJXnDe0DVXYXpJLb4LAlF2XAyYX0SYKUVUsJnzm5k4xbXtnwPwVbpm0EdswBE6qS',
|
|
'fiL9zWk9dvHoKzSnfSDzDFoFcEoVchawzYXf/MM1YR4wo5XyzECc6Q5Ah4z522//',
|
|
'mBNNaDHv83Yuw3mGShT73iJ0JQdkTturshv2Ecma38r6ftrIwNYXw4VVatJM8+GO',
|
|
'OQIDAQAB',
|
|
'-----END PUBLIC KEY-----',
|
|
].join('\n'),
|
|
};
|
|
};
|
|
|
|
export const makeDefaultSendGridlValue = (): SendGridMockValue => {
|
|
return {
|
|
sendMail: undefined,
|
|
createMailContentFromEmailConfirm: { subject: '', text: '', html: '' },
|
|
createMailContentFromEmailConfirmForNormalUser: {
|
|
subject: 'test',
|
|
text: 'test',
|
|
html: 'test',
|
|
},
|
|
};
|
|
};
|
|
|
|
export const makeDefaultConfigValue = (): ConfigMockValue => {
|
|
return {
|
|
get: `test@example.co.jp`,
|
|
};
|
|
};
|
|
|
|
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 => {
|
|
const newUser = new User();
|
|
newUser.id = 111;
|
|
|
|
const user1 = new User();
|
|
user1.id = 2;
|
|
user1.external_id = 'ede66c43-9b9d-4222-93ed-5f11c96e08e2';
|
|
user1.account_id = 1234567890123456;
|
|
user1.role = 'none';
|
|
user1.author_id = '6cce347f-0cf1-a15e-19ab-d00988b643f9';
|
|
user1.accepted_terms_version = '1.0';
|
|
user1.email_verified = true;
|
|
user1.auto_renew = false;
|
|
user1.license_alert = false;
|
|
user1.notification = false;
|
|
user1.deleted_at = null;
|
|
user1.created_by = 'test';
|
|
user1.created_at = new Date();
|
|
user1.updated_by = null;
|
|
user1.updated_at = null;
|
|
|
|
const user2 = new User();
|
|
user2.id = 3;
|
|
user2.external_id = '698176dc-4028-4638-a452-f00bf62a7781';
|
|
user2.account_id = 1234567890123456;
|
|
user2.role = 'none';
|
|
user2.author_id = '551c4077-5b55-a38c-2c55-cd1edd537aa8';
|
|
user2.accepted_terms_version = '1.0';
|
|
user2.email_verified = true;
|
|
user2.auto_renew = false;
|
|
user2.license_alert = false;
|
|
user2.notification = false;
|
|
user2.deleted_at = null;
|
|
user2.created_by = 'test';
|
|
user2.created_at = new Date();
|
|
user2.updated_by = null;
|
|
user2.updated_at = null;
|
|
|
|
return {
|
|
updateUserVerified: undefined,
|
|
findUserById: newUser,
|
|
createNormalUser: newUser,
|
|
findSameAccountUsers: [user1, user2],
|
|
findUserByExternalId: newUser,
|
|
existsAuthorId: false,
|
|
};
|
|
};
|