Merged PR 167: タイピストユーザー取得API実装
## 概要 [Task1931: タイピストユーザー取得API実装](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/1931) - アカウント内のタイピストユーザーを取得する処理を実装しました。 ## レビューポイント - ADB2Cからのユーザー取得、マージは適切か ## UIの変更 なし ## 動作確認状況 - ローカルで確認
This commit is contained in:
parent
8c75f7a1b1
commit
ef17e4ff0b
@ -193,18 +193,13 @@ export class AccountsController {
|
||||
@Get('typists')
|
||||
async getTypists(@Req() req: Request): Promise<GetTypistsResponse> {
|
||||
console.log(req.header('Authorization'));
|
||||
return {
|
||||
typists: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'AAA',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'BBB',
|
||||
},
|
||||
],
|
||||
};
|
||||
// アクセストークン取得
|
||||
const accessToken = retrieveAuthorizationToken(req);
|
||||
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
||||
|
||||
const typists = await this.accountService.getTypists(payload.userId);
|
||||
|
||||
return { typists };
|
||||
}
|
||||
|
||||
@ApiResponse({
|
||||
|
||||
@ -26,26 +26,90 @@ describe('AccountsService', () => {
|
||||
expectedAccountLisenceCounts,
|
||||
);
|
||||
});
|
||||
});
|
||||
it('ライセンス情報が取得できない場合、エラーとなる', async () => {
|
||||
const accountId = 1;
|
||||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const accountsRepositoryMockValue = makeDefaultAccountsRepositoryMockValue();
|
||||
accountsRepositoryMockValue.getLicenseSummaryInfo = null;
|
||||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||||
const service = await makeAccountsServiceMock(
|
||||
accountsRepositoryMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendGridMockValue,
|
||||
);
|
||||
await expect(service.getLicenseSummary(accountId)).rejects.toEqual(
|
||||
new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
),
|
||||
);
|
||||
|
||||
it('ライセンス情報が取得できない場合、エラーとなる', async () => {
|
||||
const accountId = 1;
|
||||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const accountsRepositoryMockValue =
|
||||
makeDefaultAccountsRepositoryMockValue();
|
||||
accountsRepositoryMockValue.getLicenseSummaryInfo = null;
|
||||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||||
const service = await makeAccountsServiceMock(
|
||||
accountsRepositoryMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendGridMockValue,
|
||||
);
|
||||
await expect(service.getLicenseSummary(accountId)).rejects.toEqual(
|
||||
new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('アカウントに紐づくタイピストユーザーを取得できる', async () => {
|
||||
const externalId = 'externalId';
|
||||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const accountsRepositoryMockValue =
|
||||
makeDefaultAccountsRepositoryMockValue();
|
||||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||||
const service = await makeAccountsServiceMock(
|
||||
accountsRepositoryMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendGridMockValue,
|
||||
);
|
||||
expect(await service.getTypists(externalId)).toEqual([
|
||||
{ id: 1, name: 'Typist1' },
|
||||
{ id: 2, name: 'Typist2' },
|
||||
{ id: 3, name: 'Typist3' },
|
||||
]);
|
||||
});
|
||||
it('ユーザー取得に失敗した場合、エラーとなる', async () => {
|
||||
const externalId = 'externalId';
|
||||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||||
usersRepositoryMockValue.findTypistUsers = new Error();
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
const accountsRepositoryMockValue =
|
||||
makeDefaultAccountsRepositoryMockValue();
|
||||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||||
const service = await makeAccountsServiceMock(
|
||||
accountsRepositoryMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendGridMockValue,
|
||||
);
|
||||
await expect(service.getTypists(externalId)).rejects.toEqual(
|
||||
new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
),
|
||||
);
|
||||
});
|
||||
it('ADB2Cからのユーザーの取得に失敗した場合、エラーとなる', async () => {
|
||||
const externalId = 'externalId';
|
||||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||||
adb2cParam.getUsers = new Error();
|
||||
const accountsRepositoryMockValue =
|
||||
makeDefaultAccountsRepositoryMockValue();
|
||||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||||
const service = await makeAccountsServiceMock(
|
||||
accountsRepositoryMockValue,
|
||||
usersRepositoryMockValue,
|
||||
adb2cParam,
|
||||
sendGridMockValue,
|
||||
);
|
||||
await expect(service.getTypists(externalId)).rejects.toEqual(
|
||||
new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const expectedAccountLisenceCounts = {
|
||||
|
||||
@ -15,7 +15,7 @@ import { Account } from '../../repositories/accounts/entity/account.entity';
|
||||
import { User } from '../../repositories/users/entity/user.entity';
|
||||
import { LICENSE_EXPIRATION_THRESHOLD_DAYS, TIER_5 } from '../../constants';
|
||||
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
|
||||
import { GetLicenseSummaryResponse } from './types/types';
|
||||
import { GetLicenseSummaryResponse, Typist } from './types/types';
|
||||
import { AccessToken } from '../../common/token';
|
||||
|
||||
@Injectable()
|
||||
@ -227,4 +227,42 @@ export class AccountsService {
|
||||
this.logger.log(`[OUT] ${this.getMyAccountInfo.name}`);
|
||||
return userInfo.account_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets typists
|
||||
* @param externalId
|
||||
* @returns typists
|
||||
*/
|
||||
async getTypists(externalId: string): Promise<Typist[]> {
|
||||
this.logger.log(`[IN] ${this.getTypists.name}`);
|
||||
|
||||
// Typist取得
|
||||
try {
|
||||
const typistUsers = await this.usersRepository.findTypistUsers(
|
||||
externalId,
|
||||
);
|
||||
const externalIds = typistUsers.map((x) => x.external_id);
|
||||
|
||||
// B2Cからユーザー名を取得する
|
||||
const adb2cUsers = await this.adB2cService.getUsers(externalIds);
|
||||
|
||||
const typists = typistUsers.map((x) => {
|
||||
const user = adb2cUsers.find((adb2c) => adb2c.id === x.external_id);
|
||||
return {
|
||||
id: x.id,
|
||||
name: user.displayName,
|
||||
};
|
||||
});
|
||||
|
||||
return typists;
|
||||
} catch (e) {
|
||||
this.logger.error(e);
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
} finally {
|
||||
this.logger.log(`[OUT] ${this.getTypists.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,12 +10,15 @@ import {
|
||||
} from '../../../gateways/adb2c/adb2c.service';
|
||||
import { SendGridService } from '../../../gateways/sendgrid/sendgrid.service';
|
||||
import { LicenseSummaryInfo } from '../types/types';
|
||||
import { AdB2cUser } from '../../../gateways/adb2c/types/types';
|
||||
export type UsersRepositoryMockValue = {
|
||||
findUserById: User | Error;
|
||||
findUserByExternalId: User | Error;
|
||||
findTypistUsers: User[] | Error;
|
||||
};
|
||||
export type AdB2cMockValue = {
|
||||
createUser: string | ConflictError | Error;
|
||||
getUsers: AdB2cUser[] | Error;
|
||||
};
|
||||
export type SendGridMockValue = {
|
||||
createMailContentFromEmailConfirm: {
|
||||
@ -83,17 +86,21 @@ export const makeAccountsRepositoryMock = (
|
||||
};
|
||||
};
|
||||
export const makeUsersRepositoryMock = (value: UsersRepositoryMockValue) => {
|
||||
const { findUserById } = value;
|
||||
const { findUserById, findTypistUsers } = value;
|
||||
|
||||
return {
|
||||
findUserById:
|
||||
findUserById instanceof Error
|
||||
? jest.fn<Promise<void>, []>().mockRejectedValue(findUserById)
|
||||
: jest.fn<Promise<User>, []>().mockResolvedValue(findUserById),
|
||||
findTypistUsers:
|
||||
findTypistUsers instanceof Error
|
||||
? jest.fn<Promise<void>, []>().mockRejectedValue(findTypistUsers)
|
||||
: jest.fn<Promise<User[]>, []>().mockResolvedValue(findTypistUsers),
|
||||
};
|
||||
};
|
||||
export const makeAdB2cServiceMock = (value: AdB2cMockValue) => {
|
||||
const { createUser } = value;
|
||||
const { createUser, getUsers } = value;
|
||||
|
||||
return {
|
||||
createUser:
|
||||
@ -102,6 +109,10 @@ export const makeAdB2cServiceMock = (value: AdB2cMockValue) => {
|
||||
: jest
|
||||
.fn<Promise<string | ConflictError>, []>()
|
||||
.mockResolvedValue(createUser),
|
||||
getUsers:
|
||||
getUsers instanceof Error
|
||||
? jest.fn<Promise<void>, []>().mockRejectedValue(getUsers)
|
||||
: jest.fn<Promise<AdB2cUser[]>, []>().mockResolvedValue(getUsers),
|
||||
};
|
||||
};
|
||||
export const makeSendGridServiceMock = (value: SendGridMockValue) => {
|
||||
@ -161,14 +172,51 @@ export const makeDefaultUsersRepositoryMockValue =
|
||||
user.updated_by = null;
|
||||
user.updated_at = null;
|
||||
|
||||
const typists: User[] = [];
|
||||
typists.push(
|
||||
{
|
||||
...user,
|
||||
id: 1,
|
||||
external_id: 'typist1',
|
||||
role: 'typist',
|
||||
},
|
||||
{
|
||||
...user,
|
||||
id: 2,
|
||||
external_id: 'typist2',
|
||||
role: 'typist',
|
||||
},
|
||||
{
|
||||
...user,
|
||||
id: 3,
|
||||
external_id: 'typist3',
|
||||
role: 'typist',
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
findUserById: user,
|
||||
findUserByExternalId: user,
|
||||
findTypistUsers: typists,
|
||||
};
|
||||
};
|
||||
export const makeDefaultAdB2cMockValue = (): AdB2cMockValue => {
|
||||
return {
|
||||
createUser: '001',
|
||||
getUsers: [
|
||||
{
|
||||
id: 'typist1',
|
||||
displayName: 'Typist1',
|
||||
},
|
||||
{
|
||||
id: 'typist2',
|
||||
displayName: 'Typist2',
|
||||
},
|
||||
{
|
||||
id: 'typist3',
|
||||
displayName: 'Typist3',
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
export const makeDefaultSendGridlValue = (): SendGridMockValue => {
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { DataSource, UpdateResult } from 'typeorm';
|
||||
import { DataSource, IsNull, 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';
|
||||
import { USER_ROLES } from '../../constants';
|
||||
|
||||
// UsersRepositoryServiceで発生するエラーを定義
|
||||
export class EmailAlreadyVerifiedError extends Error {}
|
||||
@ -222,4 +223,31 @@ export class UsersRepositoryService {
|
||||
|
||||
return dbUsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* アカウント内のタイピストユーザーを取得する
|
||||
* @param sub
|
||||
* @returns typist users
|
||||
*/
|
||||
async findTypistUsers(sub: string): Promise<User[]> {
|
||||
return await this.dataSource.transaction(async (entityManager) => {
|
||||
const repo = entityManager.getRepository(User);
|
||||
|
||||
const user = await repo.findOne({
|
||||
where: {
|
||||
external_id: sub,
|
||||
},
|
||||
});
|
||||
|
||||
const typists = await repo.find({
|
||||
where: {
|
||||
account_id: user.account_id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
deleted_at: IsNull(),
|
||||
},
|
||||
});
|
||||
|
||||
return typists;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user