-
Notifications
You must be signed in to change notification settings - Fork 88
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
[1단계 - 영화 목록 불러오기] 야미(이다인) 미션 제출합니다. #5
Merged
Merged
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
5db1c55
docs: 기능 목록과 요구 사항 작성
feb-dain 281a479
chore: 폴더 정리 및 프리티어 적용
feb-dain fbc7b98
fix: 이미지 업로드 문제 해결
feb-dain 82760c2
feat: 헤더 컴포넌트화
feb-dain 904e6c0
feat: 영화 목록 컴포넌트화
feb-dain 509f9f0
style: export 방법 변경
feb-dain cbd6e3d
feat: 영화 아이템 컴포넌트화
feb-dain 440d6fe
feat: API 요청 및 API 키 은닉화
feb-dain c866b88
feat: API에서 가져온 정보 렌더링
feb-dain 3947f75
feat: 더보기 클릭시 영화 목록 추가 및 렌더링
feb-dain f77159e
refactor: 영화 목록 관련 함수 분리
feb-dain 8cec080
feat: 인기순으로 영화 정렬
feb-dain c936bdd
fix: 이미지 불러오기 문제 해결
feb-dain 7197252
feat: 검색 기능 구현 및 정렬 기능 삭제
feb-dain cfa5193
feat: 목록 이름 대신 검색 결과 표시하는 기능 추가
feb-dain 658cc76
feat: 별점을 소수점 1자리까지만 표시는
feb-dain b362bed
feat: 로고 클릭시 처음 화면으로 돌아가는 기능 구현
feb-dain ae6383e
feat: 요청한 API 상태 코드에 따라 오류 메시지 출력
feb-dain 17a4af6
feat: 검색 결과가 없을 경우 결과 없음 안내 페이지 렌더링
feb-dain eb55b7c
fix: 페이지 초기화 문제 해결
feb-dain 1efa111
refactor: any 타입 제거
feb-dain e0a59bb
refactor: movie API와 movieStore 분리
feb-dain 95c26c3
feat: 스켈레톤 로딩 기능 추가 및 빈 이미지일 경우 대체 이미지 추가
feb-dain beea5fc
test: e2e 테스트 진행
feb-dain f639cfd
docs: README 작성
feb-dain 2e96a14
chore: 필요 없는 파일 삭제
feb-dain 3bc416d
comment: 불필요한 주석 삭제
feb-dain d85a393
refactor: `I- prefix` 삭제 및 타입 선언 방식 변경
feb-dain cf49660
style: css 수정 및 a 태그 삭제
feb-dain ae1e790
remove: 이벤트 리스너 유틸 삭제"
feb-dain 58c0c35
refactor: movieApi 필드 `camelCase`로 변경
feb-dain 46d29a8
refactor: `new URL`, `new URLSearchParams` 사용 및 상수화
feb-dain 4834c40
refactor: 함수명 변경
feb-dain 623f7d6
refactor: 역할 분리 및 에러 핸들러 개선
feb-dain cd080ed
test: 테스트 코드 수정 및 추가
feb-dain File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
node_modules | ||
.env | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,106 @@ | ||
# javascript-movie-review | ||
# 🎬 | ||
|
||
FE 5기 레벨1 영화관 미션 | ||
## FE 5기 레벨1 영화관 미션 | ||
|
||
![스크린샷(91)](https://user-images.githubusercontent.com/108778921/225553741-43297097-5333-4167-8364-e336aed2e832.png) | ||
|
||
<br> | ||
|
||
### 🧑🤝🧑 페어 (페어 프로그래밍으로 개발) | ||
|
||
<table> | ||
<tr> | ||
<td align="center" width="120px"> | ||
<a href="https://github.com/feb-dain" target="_blank"> | ||
<img src="https://avatars.githubusercontent.com/u/108778921?v=4" alt="야미(이다인) 프로필" /> | ||
</a> | ||
</td> | ||
<td align="center" width="120px"> | ||
<a href="https://github.com/gabrielyoon7" target="_blank"> | ||
<img src="https://avatars.githubusercontent.com/u/69189073?v=4" alt="가브리엘(윤주현) 프로필" /> | ||
</a> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td align="center"> | ||
<a href="https://github.com/feb-dain" target="_blank"> | ||
야미(이다인) | ||
</a> | ||
</td> | ||
<td align="center"> | ||
<a href="https://github.com/gabrielyoon7" target="_blank"> | ||
가브리엘(윤주현) | ||
</a> | ||
</td> | ||
</tr> | ||
</table> | ||
|
||
<br> | ||
|
||
### 📍 학습 목표 | ||
|
||
- 이번 미션의 주요 목표는 웹 프론트엔드에서의 비동기에 대해 이해하고, | ||
- API 통신을 처리할 때 고려해야 하는 다양한 문제를 직접 경험해보면서 해결 방법을 고민해보는 것입니다 | ||
- API 연동을 위한 테스트 환경 경험 | ||
- 실제 동작하는 API를 통한 비동기 통신 | ||
- UX 경험 개선을 위한 더 보기(페이징) 구현 | ||
- 역할과 책임에 따라 관심사를 분리할 수 있는 마지막 기회 | ||
|
||
<br> | ||
|
||
### 📝 실행 방법 | ||
|
||
- <a href="https://feb-dain.github.io/javascript-/javascript-movie-review">앱 바로 실행하기</a> | ||
|
||
- 터미널에서 npm 설치(`npm install`) 후 `npm run start` 커맨드로 앱을 실행할 수 있다. | ||
|
||
<br> | ||
<br> | ||
|
||
### 🎯 기능 목록 | ||
|
||
- 🎬 영화 목록 조회 (인기순) | ||
- 영화 목록의 1페이지를 불러오며 더보기 버튼을 누르면 그 다음의 영화 목록을 불러 올 수 있다. | ||
- 단, 페이지 끝에 도달한 경우에는 더보기 버튼을 화면에 출력하지 않는다. | ||
- ⚠️ 인기순은 TMDB에서 제공하는 API의 속성 이름을 나타내는 것이므로 별도로 받은 데이터를 정렬하지 않습니다. | ||
- figma 시안과는 달리 20개씩 영화 목록을 보여주면 됩니다. | ||
- 영화 목록 아이템에 대한 Skeleton UI를 구현한다. | ||
- Skeleton UI는 템플릿으로 제공되는 파일 이외로 자유롭게 구현할 수 있다. | ||
|
||
<br> | ||
|
||
- 🔎 검색 | ||
- 영화 검색 API를 이용하여 내가 보고 싶은 영화를 검색할 수 있다. | ||
- 엔터키를 눌러 검색할 수 있다 | ||
- 검색 버튼을 클릭하여 검색할 수 있다 | ||
- 영화 목록 조회와 같이 검색한 결과에 한해 정보를 보여주는 화면의 요구사항은 동일하다 | ||
|
||
<br> | ||
|
||
- ⚠️ 오류 | ||
- 오류가 발생하는 경우에는 사용자를 위한 오류 메시지를 띄워 준다. | ||
- 어떤 오류를 대응해야 하고, 어떤 UI로 보여줄 것인지는 자율적으로 결정한다. | ||
|
||
<br> | ||
<br> | ||
|
||
### ✅ 프로그래밍 요구 사항 | ||
|
||
**이전 미션의 프로그래밍 요구 사항은 기본으로 포함한다.** | ||
|
||
- API key를 공개된 저장소에 포함하지 않는다. | ||
- 비동기 통신에서 실패할 경우를 대비한다. | ||
- 비동기 통신에서 일어날 수 있는 다양한 상황을 고려해 본다. | ||
- 비동기 호출을 포함한 사용자 기능 플로우를 선정하고 기능을 포함하여 E2E 테스트를 작성한다. | ||
- 특정한 패턴에 사고를 끼워 맞추지 않고 단지 역할과 책임에 따라 관심사를 분리한다. | ||
- 어떠한 관점에서 역할과 책임에 따라 관심사를 분리하였는지 리뷰어에게 설명할 수 있어야 한다. | ||
- 도메인 영역을 TypeScript를 사용해 구현한다. (UI 영역은 선택) | ||
- any를 사용하지 않는다. | ||
- API에서 응답한 데이터의 규격을 문자열 그대로 활용하지 않고 도메인 객체를 만들어 활용한다. | ||
|
||
<br> | ||
<br> | ||
|
||
--- | ||
|
||
<a href="https://github.com/woowacourse">@woowacourse</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
module.exports = { | ||
presets: [["@babel/preset-env", { targets: { node: "current" } }], "@babel/preset-typescript"], | ||
presets: [ | ||
["@babel/preset-env", { targets: { node: "current" } }], | ||
"@babel/preset-typescript", | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { defineConfig } from "cypress"; | ||
|
||
export default defineConfig({ | ||
e2e: { | ||
setupNodeEvents(on, config) { | ||
// implement node event listeners here | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { API, PATH } from "../../src/constants"; | ||
const { URL: API_URL } = API; | ||
const { POPULAR_MOVIE } = PATH; | ||
|
||
describe("영화관 앱 테스트.", () => { | ||
const buildMovieUrl = (endpoint: string) => { | ||
const url = new URL(endpoint, API_URL); | ||
|
||
return new RegExp(`^${url}`); | ||
}; | ||
|
||
const interceptor = (url: () => RegExp, fixture: string) => { | ||
return [ | ||
{ | ||
method: "GET", | ||
url: url(), | ||
}, | ||
{ | ||
fixture: fixture, | ||
}, | ||
]; | ||
}; | ||
|
||
beforeEach(() => { | ||
const [movieUrl, popularMovies] = interceptor( | ||
() => buildMovieUrl(POPULAR_MOVIE), | ||
"popular-movies.json" | ||
); | ||
|
||
cy.intercept(movieUrl, popularMovies).as("getPopularMovies"); | ||
|
||
const [page2, popularMoviesIn2Page] = interceptor( | ||
() => /&page=2/, | ||
"popular-movie-page2.json" | ||
); | ||
|
||
cy.intercept(page2, popularMoviesIn2Page).as("getPopularMoviePage2"); | ||
|
||
const [MovieSearchUrl, searchedMovies] = interceptor( | ||
() => buildMovieUrl("search/movie"), | ||
"searched-movies.json" | ||
); | ||
|
||
cy.intercept(MovieSearchUrl, searchedMovies).as("getSearchedMovies"); | ||
|
||
cy.visit("http://localhost:8080/"); | ||
}); | ||
|
||
it("API 요청시 성공적으로 응답한다.", () => { | ||
cy.wait("@getPopularMovies").then((interception) => { | ||
const state = interception.response?.statusCode; | ||
const movieItems = interception.response?.body.results; | ||
|
||
expect(state).to.equal(200); | ||
expect(movieItems.length).to.equal(20); | ||
}); | ||
}); | ||
|
||
it("더보기를 클릭하면 영화 목록이 20개씩 추가된다.", () => { | ||
cy.wait("@getPopularMovies"); | ||
|
||
cy.get("#more-button").click(); | ||
|
||
cy.wait("@getPopularMoviePage2"); | ||
|
||
cy.get(".item-list").children().should("have.length", "40"); | ||
|
||
cy.fixture("popular-movie-page2.json").then((movieInfo) => { | ||
movieInfo.results.forEach((movie) => { | ||
cy.get(".item-list > li").should("contain.text", movie.title); | ||
}); | ||
}); | ||
}); | ||
|
||
it("키워드를 검색하면 해당 키워드가 포함된 영화 목록을 보여준다.", () => { | ||
cy.get("input[name='search-bar']").type("강아지"); | ||
cy.get("#search-bar").submit(); | ||
|
||
cy.wait("@getSearchedMovies"); | ||
|
||
cy.get(".item-list > li").each((li: HTMLElement) => { | ||
expect(li).to.contain.text("강아지"); | ||
}); | ||
|
||
cy.fixture("searched-movies.json").then((movieInfo) => { | ||
movieInfo.results.forEach((movie) => { | ||
cy.get(".item-list > li").should("contain.text", movie.title); | ||
}); | ||
}); | ||
}); | ||
|
||
it("로고를 클릭하면 처음 화면으로 이동한다.", () => { | ||
cy.get("#logo").click(); | ||
|
||
cy.wait("@getPopularMovies"); | ||
|
||
cy.get(".item-view > h2").should("contain.text", "지금 인기 있는 영화"); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍