Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: 식물 카드 상세 조회 API #33

Merged
merged 11 commits into from Nov 4, 2023
Merged

Feat: 식물 카드 상세 조회 API #33

merged 11 commits into from Nov 4, 2023

Conversation

jokj624
Copy link
Member

@jokj624 jokj624 commented Aug 13, 2023

📚 PR 요약 / Linked Issue

해당 PR에서 작업한 내용을 한 줄로 요약해주세요.

💡 변경 사항

디테일한 작업 내역을 적어주세요.
주의할 사항이 있다면 적어주세요.
변경사항 (모듈 설치 등)이 있다면 적어주세요.

plants conflict 가 많을 것 같아 develop 으로 바로 병합하지 않고 각자 작업하던 PR은 feature/34 브랜치로 병합하고 develop 올리는 게 좋을 것 같습니다.

  • 식물 카드 상세 조회 API 구현
  • src/plants/utils/plants.ts 에 loveGague 로 식물 레벨을 구하는 calculatePlantLevel,
    다음 물 줄 날짜를 구하는 calculateNextWateringDate,
    물 주기 D-Day 를 통해 식물 상태를 구하는 calculatePlantStatus 를 구현해두었습니다.
    src/utils 내부에 넣을까 고민 했는데 plants 에만 종속되는 유틸 함수라 생각해 plants 폴더 내부 유틸 함수로 넣었습니다.
  • swagger constants 를 작성하고 기존에 작성한 object 이름에 action 에 해당하는 접미사를 붙여 가독성을 높였습니다.
  • 별건 아니고 PR 템플릿에 swagger 캡쳐와 테스트 코드 작성 체크 리스트를 추가했습니다.
  • e2e 테스트 시 docker 를 사용해 격리된 MySQL 컨테이너를 생성해 사용하도록 환경을 구성했습니다.

📖 Swagger

API Swagger 를 추가했다면 캡쳐해주세요.
image
image

✅ PR check list

  • 커밋 컨벤션, 제목 등을 확인했나요?
  • 알맞은 라벨을 달았나요?
  • 셀프 코드리뷰를 작성했나요?

@jokj624 jokj624 changed the base branch from develop to feature/34 August 13, 2023 14:41
Copy link
Member

@junjuning junjuning left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

{ statusMessage: string; statusGague: number }
> = {
healthy: {
statusMessage: '힘이 솟아요',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[] <- 요거 머죠!?!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 왜 모바일에선 너가 말한것처럼 이상한 기호 보이고 pc 에선 안보임 ㄷ ㄷ
image

Comment on lines +1 to +20
# Set the version of docker compose to use
version: '3.9'

# The containers that compose the project
services:
db:
image: mysql:8.0
restart: always
container_name: e2e-test-prisma
ports:
- '3306:3306'
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test
volumes:
- /var/lib/mysql
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --skip-character-set-client-handshake
Copy link
Member Author

@jokj624 jokj624 Aug 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e2e 테스트 시 현재 사용중인 DB 에 영향이 가지 않도록 docker-compose 를 사용해 MySQL 로컬 DB 를 띄우고 격리된 환경으로 진행하기 위한 compose file 입니다.

Comment on lines +21 to +28
"test:e2e": "yarn docker:up && sleep 6.5 && yarn migrate:test && yarn seed:test && dotenv -e .env.test -- jest --config ./test/jest-e2e.json && yarn docker:down",
"migrate:test": "dotenv -e .env.test -- npx prisma migrate deploy",
"seed:test": "dotenv -e .env.test -- npx prisma db seed",
"docker:up": "docker-compose -f docker-compose.test.yml up -d",
"docker:down": "docker-compose -f docker-compose.test.yml down -v"
},
"prisma": {
"seed": "cross-env NODE_ENV=test ts-node prisma/seed.ts"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yarn test:e2e 진행 시 다음과 같은 순서로 진행됩니다.

  1. docker-compose 로 MySQL 컨테이너 Up
  2. 컨테이너 환경 구축 동안 잠시 sleep
  3. env.test 파일을 환경 변수로 하여 prisma migrate 진행
  4. 만들어져 있는 seed 파일을 실행시켜 DB에 더미 데이터 삽입
  5. env.test 파일을 환경 변수로 하여 jest e2e 테스트 진행
  6. 테스트 성공적 종료 시 MySQL 컨테이너 down

참고)
dotenv -e .env.test 의 경우 prisma 문서에서 prisma 를 multi 환경에서 사용하기 위해 dotenv-cli 라는 패키지를 사용해 진행하면 된다고 명시되어 있어 사용했습니다. 가이드

const prisma = new PrismaClient();

async function main() {
const user = await prisma.user.create({
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 환경을 위해 만들어진 DB 에 더미데이터 삽입을 위한 seed 파일

앞으로 테스트 로직이 추가 될 때 필요한 더미 데이터가 있다면 seed 파일을 통해 삽입하면 됩니다.

},
],
});
process.env.NODE_ENV !== 'test' &&
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 환경에서는 webhook interceptor 가 동작하지 않도록 바꿨습니다.

Comment on lines +27 to +34
export const PLANT_D_DAY: Record<number, number[]> = {
1: [0, 3, 7],
2: [0, 4, 13],
3: [0, 6, 13],
4: [0, 3, 7],
5: [0, 3, 7],
6: [0, 3, 7],
};
Copy link
Member Author

@jokj624 jokj624 Aug 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plant health status 가 바뀌는 기준 데이입니다.
key : plantId

Comment on lines +48 to +55
beforeAll(() => {
jest.useFakeTimers();
jest.setSystemTime(new Date('2023-08-13 18:00'));
});

afterAll(() => {
jest.useRealTimers();
});
Copy link
Member Author

@jokj624 jokj624 Aug 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 하는 시간 자체를 mocking 하는 코드입니다.
체리쉬에 경우 시간으로 계산하는 로직이 많아 시간을 mocking 하지 않으면 다음날 테스트 했을 때 잘못된 결과가 나오니
테스트 로직을 작성하는 날을 기준으로 mocking 해주면 됩니다.


@Injectable()
export class PlantsService {
constructor(private prisma: PrismaService) {}

async getUserPlantDetail(id: number): Promise<ResponsePlantDetailData> {
const userPlant = await this.prisma.userPlant.findUnique({
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이이 ... 긴 prisma find 코드 때문에 극혐인데 repository 계층을 따로 나눠서 분리하는 것도 가독성에 좋아보입니다.. 좋은 의견.. 주세요

);

const dDay: number = utilDay.calculateDday(new Date(), nextWateringDate);
const duration: number = -utilDay.calculateDday(new Date(), createdAt);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duration (지금까지 함께한 일 수) 의 경우 d-day 와 달리 + (양수) 로만 나와야하기 때문에 강제로 부호를 바꿔줍니다.

Comment on lines +32 to +48
if (dDay < PLANT_D_DAY[plantId][0]) {
plantStatus = 'healthy';
} else if (dDay === PLANT_D_DAY[plantId][0]) {
plantStatus = 'waterDay';
} else if (
dDay > PLANT_D_DAY[plantId][0] &&
dDay <= PLANT_D_DAY[plantId][1]
) {
plantStatus = 'happy';
} else if (
dDay > PLANT_D_DAY[plantId][1] &&
dDay <= PLANT_D_DAY[plantId][2]
) {
plantStatus = 'thirsty';
} else if (dDay > PLANT_D_DAY[plantId][2]) {
plantStatus = 'veryThirsty';
}
Copy link
Member Author

@jokj624 jokj624 Aug 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

물 주기까지 남은 날을 기준으로 식물 상태를 결정하는 util 함수 입니다.. if/else 가 최선일까요?..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PLANT_D_DAY[plantId][n]처럼 반복적으로 if문에 들어가는 값은 변수로 빼면 더 가독성이 좋아질 것 같습니다 >>> 라고 클린코드 수업에서 배웠어요

Comment on lines +43 to +49
jest.useFakeTimers({ doNotFake: ['nextTick', 'setImmediate'] });
jest.setSystemTime(new Date('2023-08-13 18:00'));
});

afterAll(() => {
jest.useRealTimers();
});
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

마찬가지로 time mocking 처리입니다. 다만, 서비스 로직은 prisma 를 mocking 해서 상관이 없었는데 e2e 에서는 그냥 사용하니 timeout 에러가 발생했습니다.
관련된 에러를 찾아보다가 jest 고질적으로 발생하는 문제여서 해당 issue 를 참고하여 mocking 시 doNotFake 옵션을 추가했습니다.

@jokj624
Copy link
Member Author

jokj624 commented Aug 22, 2023

e2e 관련 환경 설정 및 자세한 방법은 제 블로그에 올려뒀으니 세팅할 때 참고해주세여

@jokj624 jokj624 merged commit f10f672 into feature/34 Nov 4, 2023
@jokj624 jokj624 deleted the feature/20 branch November 4, 2023 06:18
seohyun-106 added a commit that referenced this pull request Dec 17, 2023
* Feat: 식물 카드 상세 조회 API (#33)

* Docs: update PR template (add swagger)

* Refactor: file name kebab-case 적용

* Feat: plant util 함수

* Feat: plant 상세 조회 API

* Docs: update PR template (add checklist)

* Feat: plant 상세 조회 service 로직 unit test

* Feat: plant 상세 조회 controller unit test

* Fix: plants service 로직 time mocking

* Feat: env test 환경 설정

* Feat: e2e test 격리된 docker 환경 구축

* Feat: plants e2e test

* Feat: 식물 카드 수정 api (#39)

* Feat: 식물 카드 수정 api

* Feat: 식물 카드 수정 api 상수 파일

* Feat: global exception 에 prisma 에러 처리 추가

* Feat: 식물 카드 수정 테스트 코드

* Feat: 메인 식물 리스트 조회 API (#40)

* Feat: 메인 식물 리스트 조회 응닶값 세팅

* Update issue templates

* Feat: 메인 화면 랜덤 description 함수 추가

* Chore: Gauge로 통일

* Feat: 메인 식물 리스트 전체 조회 API

* Chore: getUserPlants로 함수 이름 변경

* Chore: class 대문자로 변경

* Chore: 프리티어 적용

---------

Co-authored-by: 장서현 <jangseohyun@jangseohyeon-ui-MacBookAir.local>

---------

Co-authored-by: Chae Jeong Ah <jokj624@gmail.com>
Co-authored-by: 장서현 <jangseohyun@jangseohyeon-ui-MacBookAir.local>
seohyun-106 added a commit that referenced this pull request Dec 17, 2023
* Feat: 식물 카드 상세 조회 API (#33)

* Docs: update PR template (add swagger)

* Refactor: file name kebab-case 적용

* Feat: plant util 함수

* Feat: plant 상세 조회 API

* Docs: update PR template (add checklist)

* Feat: plant 상세 조회 service 로직 unit test

* Feat: plant 상세 조회 controller unit test

* Fix: plants service 로직 time mocking

* Feat: env test 환경 설정

* Feat: e2e test 격리된 docker 환경 구축

* Feat: plants e2e test

* Feat: 메인 식물 리스트 조회 응닶값 세팅

* Feat: 메인 화면 랜덤 description 함수 추가

* Chore: Gauge로 통일

* Feat: 메인 식물 리스트 전체 조회 API

* Chore: getUserPlants로 함수 이름 변경

* Chore: class 대문자로 변경

* Chore: 프리티어 적용

---------

Co-authored-by: Chae Jeong Ah <jokj624@gmail.com>
Co-authored-by: 장서현 <jangseohyun@jangseohyeon-ui-MacBookAir.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feat: 식물 카드 상세조회 api
3 participants