Skip to content

Commit

Permalink
[BE#486] 팔로우 관련 api (#492)
Browse files Browse the repository at this point in the history
* fix: test코드에서 입력값 변경

- 인자를 (2023-11-29, 09:00) --> (2023-11-29T16:00:00, +09:00) 으로 변경

* refactor: mates.service의 db접근 부분 private으로 변경

- private으로 변경하면서 test코드도 같이 usersRepository 모킹하도록 변경

* feat: 본인 정보 조회시 팔로워 팔로잉 수도 응답

- usersService에 getFollowsCount 함수 작성 후 authController에서 호출

* feat: follower, following 조회 api 구현

- 이너조인 하고, 이름 순으로 정렬

---------

Co-authored-by: victolee0 <[email protected]>
  • Loading branch information
yeongbinim and victolee0 authored Jan 12, 2024
1 parent a601139 commit 638aaf3
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 9 deletions.
3 changes: 3 additions & 0 deletions BE/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ export class AuthController {
@ApiBearerAuth()
async getUser(@User('id') user_id: number): Promise<any> {
const user = await this.usersService.findUserById(user_id);
const followsCount = await this.usersService.getFollowsCount(user_id);
return {
follower_count: followsCount.follower_count,
following_count: followsCount.following_count,
nickname: user.nickname,
email: user.email,
image_url: getImageUrl(
Expand Down
16 changes: 16 additions & 0 deletions BE/src/mates/mates.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ export class MatesController {
return this.matesService.getMates(user_id, datetime, timezone);
}

@Get('/followers')
@UseGuards(AccessTokenGuard)
@ApiBearerAuth()
@ApiOperation({ summary: '나를 팔로우 하는 사람들 조회하기' })
getFollowers(@User('id') user_id: number): Promise<object> {
return this.matesService.getFollowersInfo(user_id);
}

@Get('/followings')
@UseGuards(AccessTokenGuard)
@ApiBearerAuth()
@ApiOperation({ summary: '내가 팔로우 하는 사람들 조회하기' })
getFollowings(@User('id') user_id: number): Promise<object> {
return this.matesService.getFollowingsInfo(user_id);
}

@Get('/status')
@UseGuards(AccessTokenGuard)
@ApiBearerAuth()
Expand Down
8 changes: 4 additions & 4 deletions BE/src/mates/mates.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,14 @@ describe('MatesService', () => {
describe('.getMates()', () => {
it('유효한 데이터가 주어지면 성공적으로 친구들을 가져온다.', async () => {
jest
.spyOn(service, 'getMatesStudyTime')
.spyOn(usersRepository, 'query')
.mockResolvedValueOnce([
{ id: 2, nickname: '어린콩2', total_time: 825 },
]);
jest
.spyOn(redisService, 'hget')
.mockResolvedValueOnce('2023-11-29 16:00:00');
const result = await service.getMates(1, '2023-11-29 00:00:00', ' 09:00');
const result = await service.getMates(1, '2023-11-29T16:00:00', '+09:00');
expect(result).toStrictEqual([
{
id: 2,
Expand All @@ -214,8 +214,8 @@ describe('MatesService', () => {
]);
});
it('친구가 없는 유저는 빈 배열을 가져온다.', async () => {
jest.spyOn(service, 'getMatesStudyTime').mockResolvedValueOnce([]);
const result = await service.getMates(3, '2023-11-29 00:00:00', '09:00');
jest.spyOn(usersRepository, 'query').mockResolvedValueOnce([]);
const result = await service.getMates(3, '2023-11-29T16:00:00', '+09:00');
expect(result).toStrictEqual([]);
});
});
Expand Down
33 changes: 28 additions & 5 deletions BE/src/mates/mates.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,28 @@ export class MatesService {
};
}

getFollowersInfo(user_id: number) {
return this.matesRepository.query(
`SELECT u.id, u.nickname, u.image_url
FROM mates
INNER JOIN users_model as u ON u.id = mates.follower_id
WHERE mates.following_id = ?
ORDER BY u.nickname`,
[user_id],
);
}

getFollowingsInfo(user_id: number) {
return this.matesRepository.query(
`SELECT u.id, u.nickname, u.image_url
FROM mates
INNER JOIN users_model as u ON u.id = mates.following_id
WHERE mates.follower_id = ?
ORDER BY u.nickname`,
[user_id],
);
}

async getMates(
user_id: number,
datetime: string,
Expand All @@ -69,7 +91,6 @@ export class MatesService {
throw new BadRequestException('인자의 형식이 잘못되었습니다.');
}
const offset = timezone[0] === ' ' ? `+${timezone.trim()}` : timezone;

const nowUserTime = moment(`${datetime}${offset}`)
.utcOffset(offset)
.format('YYYY-MM-DD HH:mm:ss');
Expand Down Expand Up @@ -98,8 +119,12 @@ export class MatesService {
);
}

async getMatesStudyTime(followerDate, followerTimezone, followerId) {
const result = await this.userRepository.query(
private getMatesStudyTime(
followerDate: string,
followerTimezone: string,
followerId: number,
) {
return this.userRepository.query(
`
SELECT u.id, u.nickname, u.image_url, COALESCE(SUM(s.learning_time), 0) AS total_time
FROM users_model u
Expand All @@ -111,8 +136,6 @@ export class MatesService {
`,
[followerDate, followerTimezone, followerId],
);

return result;
}

async getMatesStatus(user_id: number): Promise<object[]> {
Expand Down
13 changes: 13 additions & 0 deletions BE/src/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ export class UsersService {
private config: ConfigService,
) {}

async getFollowsCount(user_id: number) {
const [followsCount] = await this.usersRepository.query(
`SELECT
(SELECT COUNT(*) FROM mates WHERE following_id = ?) AS follower_count,
(SELECT COUNT(*) FROM mates WHERE follower_id = ?) AS following_count`,
[user_id, user_id],
);
return {
follower_count: +followsCount.follower_count,
following_count: +followsCount.following_count,
};
}

async createUser(user: UsersModel): Promise<UsersModel> {
try {
const userObject = this.usersRepository.create({
Expand Down

0 comments on commit 638aaf3

Please sign in to comment.