Skip to content

Commit

Permalink
refactor: 그룹 로거를 사용하도록 수정 (#51)
Browse files Browse the repository at this point in the history
  • Loading branch information
Coalery authored Jan 14, 2024
1 parent 2c4dd8b commit 267a9d1
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ import { ChangeGroupStateCommand } from '@sight/app/application/group/command/ch
import { ChangeGroupStateCommandHandler } from '@sight/app/application/group/command/changeGroupState/ChangeGroupStateCommandHandler';
import { ChangeGroupStateCommandResult } from '@sight/app/application/group/command/changeGroupState/ChangeGroupStateCommandResult';

import { GroupLogFactory } from '@sight/app/domain/group/GroupLogFactory';
import { GroupState } from '@sight/app/domain/group/model/constant';
import { Group } from '@sight/app/domain/group/model/Group';
import {
GroupLogRepository,
IGroupLogRepository,
} from '@sight/app/domain/group/IGroupLogRepository';
GroupLogger,
IGroupLogger,
} from '@sight/app/domain/group/IGroupLogger';
import {
GroupRepository,
IGroupRepository,
Expand All @@ -24,27 +23,21 @@ import { Message } from '@sight/constant/message';
describe('ChangeGroupStateCommandHandler', () => {
let handler: ChangeGroupStateCommandHandler;
let groupRepository: jest.Mocked<IGroupRepository>;
let groupLogFactory: jest.Mocked<GroupLogFactory>;
let groupLogRepository: jest.Mocked<IGroupLogRepository>;
let groupLogger: jest.Mocked<IGroupLogger>;

beforeAll(async () => {
advanceTo(new Date());

const testModule = await Test.createTestingModule({
providers: [
ChangeGroupStateCommandHandler,
...generateEmptyProviders(
GroupRepository,
GroupLogFactory,
GroupLogRepository,
),
...generateEmptyProviders(GroupRepository, GroupLogger),
],
}).compile();

handler = testModule.get(ChangeGroupStateCommandHandler);
groupRepository = testModule.get(GroupRepository);
groupLogFactory = testModule.get(GroupLogFactory);
groupLogRepository = testModule.get(GroupLogRepository);
groupLogger = testModule.get(GroupLogger);
});

afterAll(() => {
Expand All @@ -62,17 +55,14 @@ describe('ChangeGroupStateCommandHandler', () => {
group = DomainFixture.generateGroup({
adminUserId: requesterUserId,
});
const log = DomainFixture.generateGroupLog();

group.isCustomerServiceGroup = jest.fn().mockReturnValue(false);
group.isPracticeGroup = jest.fn().mockReturnValue(false);
groupLogFactory.create = jest.fn().mockReturnValue(log);
groupRepository.findById = jest.fn().mockResolvedValue(group);
groupLogRepository.nextId = jest.fn().mockReturnValue('some-id');

group.changeState = jest.fn();
groupRepository.save = jest.fn();
groupLogRepository.save = jest.fn();
groupLogger.log = jest.fn();
});

test('그룹이 존재하지 않으면 예외를 발생시켜야 한다', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ import { Transactional } from '@sight/core/persistence/transaction/Transactional
import { ChangeGroupStateCommand } from '@sight/app/application/group/command/changeGroupState/ChangeGroupStateCommand';
import { ChangeGroupStateCommandResult } from '@sight/app/application/group/command/changeGroupState/ChangeGroupStateCommandResult';

import { GroupLogFactory } from '@sight/app/domain/group/GroupLogFactory';
import { GroupState } from '@sight/app/domain/group/model/constant';
import {
GroupLogRepository,
IGroupLogRepository,
} from '@sight/app/domain/group/IGroupLogRepository';
GroupLogger,
IGroupLogger,
} from '@sight/app/domain/group/IGroupLogger';
import {
GroupRepository,
IGroupRepository,
Expand All @@ -32,10 +31,8 @@ export class ChangeGroupStateCommandHandler
constructor(
@Inject(GroupRepository)
private readonly groupRepository: IGroupRepository,
@Inject(GroupLogFactory)
private readonly groupLogFactory: GroupLogFactory,
@Inject(GroupLogRepository)
private readonly groupLogRepository: IGroupLogRepository,
@Inject(GroupLogger)
private readonly groupLogger: IGroupLogger,
) {}

@Transactional()
Expand Down Expand Up @@ -65,13 +62,7 @@ export class ChangeGroupStateCommandHandler
group.wake();
await this.groupRepository.save(group);

const newGroupLog = this.groupLogFactory.create({
id: this.groupLogRepository.nextId(),
groupId,
userId: requester.userId,
message: this.buildMessage(nextState),
});
await this.groupLogRepository.save(newGroupLog);
await this.groupLogger.log(groupId, this.buildMessage(nextState));

return new ChangeGroupStateCommandResult(nextState);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { Transactional } from '@sight/core/persistence/transaction/Transactional';

import { GroupPortfolioEnabled } from '@sight/app/domain/group/event/GroupPortfolioEnabled';
import { GroupLogFactory } from '@sight/app/domain/group/GroupLogFactory';
import { SlackMessageCategory } from '@sight/app/domain/message/model/constant';
import {
ISlackSender,
SlackSender,
} from '@sight/app/domain/adapter/ISlackSender';
import {
GroupLogRepository,
IGroupLogRepository,
} from '@sight/app/domain/group/IGroupLogRepository';
GroupLogger,
IGroupLogger,
} from '@sight/app/domain/group/IGroupLogger';
import {
GroupMemberRepository,
IGroupMemberRepository,
Expand All @@ -28,6 +27,8 @@ import {
} from '@sight/app/domain/user/IUserRepository';

import { Point } from '@sight/constant/point';
import { ClsService } from 'nestjs-cls';
import { IRequester } from '@sight/core/auth/IRequester';

@EventsHandler(GroupPortfolioEnabled)
export class GroupPortfolioEnabledHandler
Expand All @@ -38,14 +39,13 @@ export class GroupPortfolioEnabledHandler
private readonly groupRepository: IGroupRepository,
@Inject(GroupMemberRepository)
private readonly groupMemberRepository: IGroupMemberRepository,
@Inject(GroupLogFactory)
private readonly groupLogFactory: GroupLogFactory,
@Inject(GroupLogRepository)
private readonly groupLogRepository: IGroupLogRepository,
@Inject(GroupLogger)
private readonly groupLogger: IGroupLogger,
@Inject(UserRepository)
private readonly userRepository: IUserRepository,
@Inject(SlackSender)
private readonly slackSender: ISlackSender,
private readonly clsService: ClsService,
) {}

@Transactional()
Expand All @@ -70,20 +70,14 @@ export class GroupPortfolioEnabledHandler
);
await this.userRepository.save(...users);

// TODO: 그룹 로거를 만들어서 사용하도록 수정
const groupLog = this.groupLogFactory.create({
id: this.groupLogRepository.nextId(),
groupId,
userId: '', // TODO: 요청자 정보에 접근할 수 있을 때 수정
message: '포트폴리오가 발행 중입니다.',
});
await this.groupLogRepository.save(groupLog);
await this.groupLogger.log(groupId, '포트폴리오가 발행 중입니다.');

const requester: IRequester = this.clsService.get('requester');
this.slackSender.send({
category: SlackMessageCategory.GROUP_ACTIVITY,
message: `<a href="/group/'${groupId}'"><u>${group.title}</u></a> 그룹의 <a href="/folio/'${groupId}'" target="_blank">포트폴리오</a>가 발행 중입니다.`,
sourceUserId: null,
targetUserId: '', // TODO: 요청자 정보에 접근할 수 있을 때 수정
targetUserId: requester.userId, // TODO: 요청자 정보에 접근할 수 있을 때 수정
});
}
}
28 changes: 10 additions & 18 deletions src/app/application/group/eventHandler/GroupUpdatedHandler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@ import { advanceTo, clear } from 'jest-date-mock';

import { GroupUpdatedHandler } from '@sight/app/application/group/eventHandler/GroupUpdatedHandler';

import { GroupLogFactory } from '@sight/app/domain/group/GroupLogFactory';
import {
ISlackSender,
SlackSender,
} from '@sight/app/domain/adapter/ISlackSender';
import {
GroupLogRepository,
IGroupLogRepository,
} from '@sight/app/domain/group/IGroupLogRepository';
import {
GroupMemberRepository,
IGroupMemberRepository,
Expand All @@ -32,11 +27,14 @@ import {
} from '@sight/app/domain/group/event/GroupUpdated';
import { DomainFixture } from '@sight/__test__/fixtures';
import { GroupMember } from '@sight/app/domain/group/model/GroupMember';
import {
GroupLogger,
IGroupLogger,
} from '@sight/app/domain/group/IGroupLogger';

describe('GroupUpdatedHandler', () => {
let handler: GroupUpdatedHandler;
let groupLogFactory: jest.Mocked<GroupLogFactory>;
let groupLogRepository: jest.Mocked<IGroupLogRepository>;
let groupLogger: jest.Mocked<IGroupLogger>;
let groupRepository: jest.Mocked<IGroupRepository>;
let groupMemberRepository: jest.Mocked<IGroupMemberRepository>;
let messageBuilder: jest.Mocked<IGroupUpdatedMessageBuilder>;
Expand All @@ -49,8 +47,7 @@ describe('GroupUpdatedHandler', () => {
providers: [
GroupUpdatedHandler,
...generateEmptyProviders(
GroupLogFactory,
GroupLogRepository,
GroupLogger,
GroupRepository,
GroupMemberRepository,
GroupUpdatedMessageBuilder,
Expand All @@ -60,8 +57,7 @@ describe('GroupUpdatedHandler', () => {
}).compile();

handler = testModule.get(GroupUpdatedHandler);
groupLogFactory = testModule.get(GroupLogFactory);
groupLogRepository = testModule.get(GroupLogRepository);
groupLogger = testModule.get(GroupLogger);
groupRepository = testModule.get(GroupRepository);
groupMemberRepository = testModule.get(GroupMemberRepository);
messageBuilder = testModule.get(GroupUpdatedMessageBuilder);
Expand Down Expand Up @@ -91,17 +87,14 @@ describe('GroupUpdatedHandler', () => {
id: groupId,
adminUserId: groupAdminUserId,
});
const groupLog = DomainFixture.generateGroupLog({ groupId });

groupRepository.findById = jest.fn().mockResolvedValue(group);
messageBuilder.build = jest.fn().mockReturnValue(message);
groupLogFactory.create = jest.fn().mockReturnValue(groupLog);
groupLogRepository.nextId = jest.fn().mockReturnValue(groupLog.id);
groupMemberRepository.findByGroupId = jest
.fn()
.mockResolvedValue(groupMembers);

groupLogRepository.save = jest.fn();
groupLogger.log = jest.fn();
slackSender.send = jest.fn();
});

Expand All @@ -110,14 +103,13 @@ describe('GroupUpdatedHandler', () => {

await handler.handle(event);

expect(groupLogRepository.save).not.toBeCalled();
expect(groupLogger.log).not.toBeCalled();
});

test('로그를 생성하여 저장해야 한다', async () => {
await handler.handle(event);

expect(groupLogFactory.create).toBeCalledTimes(1);
expect(groupLogRepository.save).toBeCalledTimes(1);
expect(groupLogger.log).toBeCalledTimes(1);
});

test('모든 그룹 멤버들에게 메시지를 보내야 한다', async () => {
Expand Down
22 changes: 6 additions & 16 deletions src/app/application/group/eventHandler/GroupUpdatedHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { Transactional } from '@sight/core/persistence/transaction/Transactional';

import { GroupUpdated } from '@sight/app/domain/group/event/GroupUpdated';
import { GroupLogFactory } from '@sight/app/domain/group/GroupLogFactory';
import { SlackMessageCategory } from '@sight/app/domain/message/model/constant';
import {
ISlackSender,
SlackSender,
} from '@sight/app/domain/adapter/ISlackSender';
import {
GroupLogRepository,
IGroupLogRepository,
} from '@sight/app/domain/group/IGroupLogRepository';
GroupLogger,
IGroupLogger,
} from '@sight/app/domain/group/IGroupLogger';
import {
GroupMemberRepository,
IGroupMemberRepository,
Expand All @@ -30,10 +29,8 @@ import {
@EventsHandler(GroupUpdated)
export class GroupUpdatedHandler implements IEventHandler<GroupUpdated> {
constructor(
@Inject(GroupLogFactory)
private readonly groupLogFactory: GroupLogFactory,
@Inject(GroupLogRepository)
private readonly groupLogRepository: IGroupLogRepository,
@Inject(GroupLogger)
private readonly groupLogger: IGroupLogger,
@Inject(GroupRepository)
private readonly groupRepository: IGroupRepository,
@Inject(GroupMemberRepository)
Expand All @@ -54,14 +51,7 @@ export class GroupUpdatedHandler implements IEventHandler<GroupUpdated> {
}

const message = this.messageBuilder.build(updatedItem);

const newGroupLog = this.groupLogFactory.create({
id: this.groupLogRepository.nextId(),
groupId,
userId: group.adminUserId,
message,
});
await this.groupLogRepository.save(newGroupLog);
await this.groupLogger.log(groupId, message);

const members = await this.groupMemberRepository.findByGroupId(groupId);
members.forEach((member) =>
Expand Down
8 changes: 4 additions & 4 deletions src/app/infra/logger/GroupLogger.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ClsService } from 'nestjs-cls';
import { IRequester } from '@sight/core/auth/IRequester';
import { UserRole } from '@sight/core/auth/UserRole';

import { GroupLogger } from '@sight/app/infra/logger/GroupLogger';
import { GroupLoggerImpl } from '@sight/app/infra/logger/GroupLogger';

import { GroupLogFactory } from '@sight/app/domain/group/GroupLogFactory';
import {
Expand All @@ -16,7 +16,7 @@ import {
import { generateEmptyProviders } from '@sight/__test__/util';

describe('GroupLogger', () => {
let groupLogger: GroupLogger;
let groupLogger: GroupLoggerImpl;
let groupLogFactory: GroupLogFactory;
let groupLogRepository: jest.Mocked<IGroupLogRepository>;
let clsService: jest.Mocked<ClsService>;
Expand All @@ -26,13 +26,13 @@ describe('GroupLogger', () => {

const testModule = await Test.createTestingModule({
providers: [
GroupLogger,
GroupLoggerImpl,
GroupLogFactory,
...generateEmptyProviders(ClsService, GroupLogRepository),
],
}).compile();

groupLogger = testModule.get(GroupLogger);
groupLogger = testModule.get(GroupLoggerImpl);
groupLogFactory = testModule.get(GroupLogFactory);
groupLogRepository = testModule.get(GroupLogRepository);
clsService = testModule.get(ClsService);
Expand Down
2 changes: 1 addition & 1 deletion src/app/infra/logger/GroupLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '@sight/app/domain/group/IGroupLogRepository';

@Injectable()
export class GroupLogger implements IGroupLogger {
export class GroupLoggerImpl implements IGroupLogger {
constructor(
private readonly clsService: ClsService,
private readonly groupLogFactory: GroupLogFactory,
Expand Down

0 comments on commit 267a9d1

Please sign in to comment.