## 概要 [Task3210: 画面修正(Terms画面)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3210) [Task3211:API修正(バージョン取得API)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/OMDSDictation/_sprints/taskboard/OMDSDictation%20%E3%83%81%E3%83%BC%E3%83%A0/OMDSDictation/%E3%82%B9%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88%2023-1?workitem=3211) [Task3212:API修正(バージョン更新API))](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/OMDSDictation/_sprints/taskboard/OMDSDictation%20%E3%83%81%E3%83%BC%E3%83%A0/OMDSDictation/%E3%82%B9%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88%2023-1?workitem=3212) - このPull Requestでの対象/対象外 Click here to read the terms of use.の文言は多言語対応の対象のため、現在一律同じ文言がでます。 第一~第四階層は 上からEULA,PrivacyNotice,DPAが表示されています 第五階層は、 上から、PrivacyNotice,DPAが表示されています - 影響範囲(他の機能にも影響があるか) ユーザアーカイブテーブルにPrivacyNoticeのバージョンを追加 ## レビューポイント 同意済みプライバシーポリシーはユーザーアーカイブの対象だと認識しているが正しいか。 termsテーブルのdocument_typeの値をPrivacyNoticeにしているが、PRIVACY_NOTICEにしたほうがよいか。 ユニットテストに不足はないか。 ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 https://ndstokyo.sharepoint.com/sites/Piranha/Shared%20Documents/Forms/AllItems.aspx?csf=1&web=1&e=hzPw9b&cid=7737ed1b%2D0eb4%2D4331%2Da238%2D14dd35b27e18&FolderCTID=0x012000C0DCEE65AC2177479C3C761CD137C9C9&id=%2Fsites%2FPiranha%2FShared%20Documents%2FGeneral%2FOMDS%2F%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%2FTask3210&viewid=786a81cf%2Dd15f%2D4dc2%2D9e55%2Dc7a729fbc72f ## 動作確認状況 - ローカルで確認 ## 補足 - 相談、参考資料などがあれば
410 lines
12 KiB
TypeScript
410 lines
12 KiB
TypeScript
import { v4 as uuidv4 } from 'uuid';
|
||
import { DataSource } from 'typeorm';
|
||
import { User, UserArchive } from '../../repositories/users/entity/user.entity';
|
||
import { Account } from '../../repositories/accounts/entity/account.entity';
|
||
import { ADMIN_ROLES, USER_ROLES } from '../../constants';
|
||
import { License } from '../../repositories/licenses/entity/license.entity';
|
||
|
||
type InitialTestDBState = {
|
||
tier1Accounts: { account: Account; users: User[] }[];
|
||
tier2Accounts: { account: Account; users: User[] }[];
|
||
tier3Accounts: { account: Account; users: User[] }[];
|
||
tier4Accounts: { account: Account; users: User[] }[];
|
||
tier5Accounts: { account: Account; users: User[] }[];
|
||
};
|
||
|
||
// 上書きされたら困る項目を除外したAccount型
|
||
type OverrideAccount = Omit<
|
||
Account,
|
||
'id' | 'primary_admin_user_id' | 'secondary_admin_user_id' | 'user'
|
||
>;
|
||
|
||
// 上書きされたら困る項目を除外したUser型
|
||
type OverrideUser = Omit<
|
||
User,
|
||
'id' | 'account' | 'license' | 'userGroupMembers'
|
||
>;
|
||
|
||
type AccountDefault = { [K in keyof OverrideAccount]?: OverrideAccount[K] };
|
||
type UserDefault = { [K in keyof OverrideUser]?: OverrideUser[K] };
|
||
|
||
/**
|
||
* テスト ユーティリティ: 1~4階層のアカウントとその管理者ユーザーを作成します
|
||
* @param dataSource データソース
|
||
* @returns 作成されたデータセット
|
||
*/
|
||
export const makeHierarchicalAccounts = async (
|
||
datasource: DataSource,
|
||
): Promise<InitialTestDBState> => {
|
||
const state: InitialTestDBState = {
|
||
tier1Accounts: [],
|
||
tier2Accounts: [],
|
||
tier3Accounts: [],
|
||
tier4Accounts: [],
|
||
tier5Accounts: [],
|
||
};
|
||
|
||
// 第1階層を作成
|
||
{
|
||
const { account, admin } = await makeTestAccount(datasource, {
|
||
tier: 1,
|
||
company_name: 'OMDS',
|
||
});
|
||
|
||
state.tier1Accounts.push({
|
||
account: account,
|
||
users: [admin],
|
||
});
|
||
}
|
||
// 第2階層を作成
|
||
{
|
||
const tier1 = state.tier1Accounts.slice().shift();
|
||
{
|
||
const { account, admin } = await makeTestAccount(datasource, {
|
||
tier: 2,
|
||
parent_account_id: tier1?.account.id,
|
||
company_name: 'OMDS_US',
|
||
});
|
||
state.tier2Accounts.push({
|
||
account: account,
|
||
users: [admin],
|
||
});
|
||
}
|
||
{
|
||
const { account, admin } = await makeTestAccount(datasource, {
|
||
tier: 2,
|
||
parent_account_id: tier1?.account.id,
|
||
company_name: 'OMDS_EU',
|
||
});
|
||
state.tier2Accounts.push({
|
||
account: account,
|
||
users: [admin],
|
||
});
|
||
}
|
||
}
|
||
|
||
// 第3階層を作成
|
||
{
|
||
for (const v of state.tier2Accounts) {
|
||
{
|
||
const { account, admin } = await makeTestAccount(datasource, {
|
||
tier: 3,
|
||
parent_account_id: v.account.id,
|
||
company_name: `Agency_${v.account.id}_01`,
|
||
});
|
||
state.tier3Accounts.push({
|
||
account: account,
|
||
users: [admin],
|
||
});
|
||
}
|
||
{
|
||
const { account, admin } = await makeTestAccount(datasource, {
|
||
tier: 3,
|
||
parent_account_id: v.account.id,
|
||
company_name: `Agency_${v.account.id}_02`,
|
||
});
|
||
state.tier3Accounts.push({
|
||
account: account,
|
||
users: [admin],
|
||
});
|
||
}
|
||
}
|
||
// 第4階層を作成
|
||
for (const v of state.tier3Accounts) {
|
||
{
|
||
const { account, admin } = await makeTestAccount(datasource, {
|
||
tier: 4,
|
||
parent_account_id: v.account.id,
|
||
company_name: `Distributor_${v.account.id}_01`,
|
||
});
|
||
state.tier4Accounts.push({
|
||
account: account,
|
||
users: [admin],
|
||
});
|
||
}
|
||
{
|
||
const { account, admin } = await makeTestAccount(datasource, {
|
||
tier: 4,
|
||
parent_account_id: v.account.id,
|
||
company_name: `Distributor_${v.account.id}_02`,
|
||
});
|
||
state.tier4Accounts.push({
|
||
account: account,
|
||
users: [admin],
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
return state;
|
||
};
|
||
|
||
/**
|
||
* テスト ユーティリティ: 指定したプロパティを上書きしたアカウントとその管理者ユーザーを作成する
|
||
* @param dataSource データソース
|
||
* @param defaultUserValue Account型と同等かつoptionalなプロパティを持つ上書き箇所指定用オブジェクト
|
||
* @param defaultAdminUserValue User型と同等かつoptionalなプロパティを持つ上書き箇所指定用オブジェクト(account_id等の所属関係が破壊される上書きは無視する)
|
||
* @returns 作成したアカウント
|
||
*/
|
||
export const makeTestAccount = async (
|
||
datasource: DataSource,
|
||
defaultAccountValue?: AccountDefault,
|
||
defaultAdminUserValue?: UserDefault,
|
||
isPrimaryAdminNotExist?: boolean,
|
||
isSecondaryAdminNotExist?: boolean,
|
||
): Promise<{ account: Account; admin: User }> => {
|
||
let accountId: number;
|
||
let userId: number;
|
||
{
|
||
const d = defaultAccountValue;
|
||
const { identifiers } = await datasource.getRepository(Account).insert({
|
||
tier: d?.tier ?? 1,
|
||
parent_account_id: d?.parent_account_id ?? undefined,
|
||
country: d?.country ?? 'US',
|
||
delegation_permission: d?.delegation_permission ?? false,
|
||
locked: d?.locked ?? false,
|
||
company_name: d?.company_name ?? 'test inc.',
|
||
verified: d?.verified ?? true,
|
||
deleted_at: d?.deleted_at ?? '',
|
||
created_by: d?.created_by ?? 'test_runner',
|
||
created_at: d?.created_at ?? new Date(),
|
||
updated_by: d?.updated_by ?? 'updater',
|
||
updated_at: d?.updated_at ?? new Date(),
|
||
});
|
||
const result = identifiers.pop() as Account;
|
||
accountId = result.id;
|
||
}
|
||
{
|
||
const d = defaultAdminUserValue;
|
||
const { identifiers } = await datasource.getRepository(User).insert({
|
||
external_id: d?.external_id ?? uuidv4(),
|
||
account_id: accountId,
|
||
role: d?.role ?? 'admin none',
|
||
author_id: d?.author_id ?? undefined,
|
||
accepted_eula_version: d?.accepted_eula_version ?? '1.0',
|
||
accepted_privacy_notice_version:
|
||
d?.accepted_privacy_notice_version ?? '1.0',
|
||
accepted_dpa_version: d?.accepted_dpa_version ?? '1.0',
|
||
email_verified: d?.email_verified ?? true,
|
||
auto_renew: d?.auto_renew ?? true,
|
||
license_alert: d?.license_alert ?? true,
|
||
notification: d?.notification ?? true,
|
||
encryption: d?.encryption ?? true,
|
||
encryption_password: d?.encryption_password ?? 'password',
|
||
prompt: d?.prompt ?? true,
|
||
deleted_at: d?.deleted_at ?? '',
|
||
created_by: d?.created_by ?? 'test_runner',
|
||
created_at: d?.created_at ?? new Date(),
|
||
updated_by: d?.updated_by ?? 'updater',
|
||
updated_at: d?.updated_at ?? new Date(),
|
||
});
|
||
|
||
const result = identifiers.pop() as User;
|
||
userId = result.id;
|
||
}
|
||
|
||
// Accountの管理者を設定する
|
||
let secondaryAdminUserId: number | null = null;
|
||
if (isPrimaryAdminNotExist && !isSecondaryAdminNotExist) {
|
||
secondaryAdminUserId = userId;
|
||
}
|
||
await datasource.getRepository(Account).update(
|
||
{ id: accountId },
|
||
{
|
||
primary_admin_user_id: isPrimaryAdminNotExist ? null : userId,
|
||
secondary_admin_user_id: secondaryAdminUserId,
|
||
},
|
||
);
|
||
|
||
const account = await datasource.getRepository(Account).findOne({
|
||
where: {
|
||
id: accountId,
|
||
},
|
||
});
|
||
|
||
const admin = await datasource.getRepository(User).findOne({
|
||
where: {
|
||
id: userId,
|
||
},
|
||
});
|
||
if (!account || !admin) {
|
||
throw new Error('Unexpected null');
|
||
}
|
||
|
||
return {
|
||
account: account,
|
||
admin: admin,
|
||
};
|
||
};
|
||
|
||
/**
|
||
* テスト ユーティリティ: 指定したプロパティを上書きした管理者ユーザーの存在しないアカウントを作成する
|
||
* @param dataSource データソース
|
||
* @param defaultUserValue Account型と同等かつoptionalなプロパティを持つ上書き箇所指定用オブジェクト
|
||
* @returns 作成したアカウント
|
||
*/
|
||
export const makeTestSimpleAccount = async (
|
||
datasource: DataSource,
|
||
defaultAccountValue?: AccountDefault,
|
||
): Promise<Account> => {
|
||
const d = defaultAccountValue;
|
||
const { identifiers } = await datasource.getRepository(Account).insert({
|
||
tier: d?.tier ?? 1,
|
||
parent_account_id: d?.parent_account_id ?? undefined,
|
||
country: d?.country ?? 'US',
|
||
delegation_permission: d?.delegation_permission ?? false,
|
||
locked: d?.locked ?? false,
|
||
company_name: d?.company_name ?? 'test inc.',
|
||
verified: d?.verified ?? true,
|
||
deleted_at: d?.deleted_at ?? '',
|
||
created_by: d?.created_by ?? 'test_runner',
|
||
created_at: d?.created_at ?? new Date(),
|
||
updated_by: d?.updated_by ?? 'updater',
|
||
updated_at: d?.updated_at ?? new Date(),
|
||
});
|
||
const result = identifiers.pop() as Account;
|
||
|
||
const account = await datasource.getRepository(Account).findOne({
|
||
where: {
|
||
id: result.id,
|
||
},
|
||
});
|
||
if (!account) {
|
||
throw new Error('Unexpected null');
|
||
}
|
||
return account;
|
||
};
|
||
|
||
/**
|
||
* テスト ユーティリティ: 指定したプロパティを上書きしたユーザーを作成する
|
||
* @param dataSource データソース
|
||
* @param defaultUserValue User型と同等かつoptionalなプロパティを持つ上書き箇所指定用オブジェクト
|
||
* @returns 作成したユーザー
|
||
*/
|
||
export const makeTestUser = async (
|
||
datasource: DataSource,
|
||
defaultUserValue?: UserDefault,
|
||
): Promise<User> => {
|
||
const d = defaultUserValue;
|
||
const { identifiers } = await datasource.getRepository(User).insert({
|
||
account_id: d?.account_id ?? -1,
|
||
external_id: d?.external_id ?? uuidv4(),
|
||
role: d?.role ?? `${ADMIN_ROLES.STANDARD} ${USER_ROLES.NONE}`,
|
||
author_id: d?.author_id,
|
||
accepted_eula_version: d?.accepted_eula_version ?? '1.0',
|
||
accepted_dpa_version: d?.accepted_dpa_version ?? '1.0',
|
||
email_verified: d?.email_verified ?? true,
|
||
auto_renew: d?.auto_renew ?? true,
|
||
license_alert: d?.license_alert ?? true,
|
||
notification: d?.notification ?? true,
|
||
encryption: d?.encryption ?? true,
|
||
encryption_password: d?.encryption_password,
|
||
prompt: d?.prompt ?? true,
|
||
created_by: d?.created_by ?? 'test_runner',
|
||
created_at: d?.created_at ?? new Date(),
|
||
updated_by: d?.updated_by ?? 'updater',
|
||
updated_at: d?.updated_at ?? new Date(),
|
||
});
|
||
const result = identifiers.pop() as User;
|
||
|
||
const user = await datasource.getRepository(User).findOne({
|
||
where: {
|
||
id: result.id,
|
||
},
|
||
});
|
||
if (!user) {
|
||
throw new Error('Unexpected null');
|
||
}
|
||
return user;
|
||
};
|
||
|
||
/**
|
||
* テスト ユーティリティ: 指定IDのアカウントを取得する
|
||
* @param dataSource データソース
|
||
* @param id アカウントID
|
||
* @returns 該当アカウント
|
||
*/
|
||
export const getAccount = async (
|
||
dataSource: DataSource,
|
||
id: number,
|
||
): Promise<Account | null> => {
|
||
return await dataSource.getRepository(Account).findOne({
|
||
where: { id: id },
|
||
});
|
||
};
|
||
|
||
/**
|
||
* テスト ユーティリティ: すべてのアカウントを取得する
|
||
* @param dataSource データソース
|
||
* @returns 該当アカウント一覧
|
||
*/
|
||
export const getAccounts = async (
|
||
dataSource: DataSource,
|
||
): Promise<Account[]> => {
|
||
return await dataSource.getRepository(Account).find();
|
||
};
|
||
|
||
/**
|
||
* テスト ユーティリティ: 指定ExternalIdのユーザーを取得する
|
||
* @param dataSource データソース
|
||
* @param externalId 外部ID
|
||
* @returns 該当ユーザー
|
||
*/
|
||
export const getUserFromExternalId = async (
|
||
dataSource: DataSource,
|
||
externalId: string,
|
||
) => {
|
||
return await dataSource.getRepository(User).findOne({
|
||
where: { external_id: externalId },
|
||
});
|
||
};
|
||
|
||
/**
|
||
* テスト ユーティリティ: 指定Idのユーザーを取得する
|
||
* @param dataSource データソース
|
||
* @param externalId 外部ID
|
||
* @returns 該当ユーザー
|
||
*/
|
||
export const getUser = async (
|
||
datasource: DataSource,
|
||
id: number,
|
||
): Promise<User | null> => {
|
||
const user = await datasource.getRepository(User).findOne({
|
||
where: {
|
||
id: id,
|
||
},
|
||
});
|
||
return user;
|
||
};
|
||
|
||
/**
|
||
* テスト ユーティリティ: すべてのユーザーを取得する
|
||
* @param dataSource データソース
|
||
* @returns 該当ユーザー一覧
|
||
*/
|
||
export const getUsers = async (dataSource: DataSource): Promise<User[]> => {
|
||
return await dataSource.getRepository(User).find();
|
||
};
|
||
|
||
/**
|
||
* テスト ユーティリティ: ユーザー退避テーブルの内容を取得する
|
||
* @param dataSource データソース
|
||
* @returns ユーザー退避テーブルの内容
|
||
*/
|
||
export const getUserArchive = async (
|
||
dataSource: DataSource,
|
||
): Promise<UserArchive[]> => {
|
||
return await dataSource.getRepository(UserArchive).find();
|
||
};
|
||
export const getLicenses = async (
|
||
datasource: DataSource,
|
||
account_id: number,
|
||
): Promise<License[]> => {
|
||
const licenses = await datasource.getRepository(License).find({
|
||
where: {
|
||
account_id: account_id,
|
||
},
|
||
});
|
||
return licenses;
|
||
};
|