-
Notifications
You must be signed in to change notification settings - Fork 47
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, 2단계 영화 극장 선택 제출합니다. #4
Merged
Merged
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
e0afc94
영화 티켓 예매 미션
woowahan-pjs 7026a40
feat(MovieListFragment): 영화 목록 화면 fragment로 변경
EmilyCh0 74deaf3
feat(MovieMainActivity): BottomNavigationView 구현
hyemdooly b2ef721
feat(ReservationListFragment): 예매 내역 레이아웃 구현
EmilyCh0 8135b14
feat(ReservationListFragment): RecyclerView 구현
hyemdooly 4f8255a
feat(ReservationListFragment): 클릭 시 예매 내역 상세 화면으로 이동 구현
EmilyCh0 add9dd3
feat(ReservationListFragment): Data 저장 구현
hyemdooly 40fcc29
refactor(MovieListAdapter): 클릭 이벤트 콜백 하나로 합치기
EmilyCh0 44bf562
feat(AlarmReceiver): 예매 후 상영 전 시간 푸시 알림 구현
hyemdooly cca69f7
feat(SettingFragment, AlarmController): 푸시 알림 수신 설정 구현
EmilyCh0 a508eaa
refactor(AlarmController): 알림 받을 시간 수정
EmilyCh0 1592c3d
refactor(AlarmController, AlarmReceiver): 코드 정리 및 메서드 분리
EmilyCh0 f5a9ef9
test(MovieMainActivityTest): 설정 프래그먼트 테스트
hyemdooly 9737d18
refactor(AndroidManifest): 필요없는 권한 삭제
hyemdooly 939d84a
refactor(layout): xml formatting
hyemdooly 76e9b00
test(SettingFragmentTest): 설정 프래그먼트 테스트
hyemdooly beb0b3a
test(MovieMainActivityTest): Fragment 선택 테스트
hyemdooly b71eb97
refactor(reservation_item.xml): isFocusable, isClickable 설정 삭제
hyemdooly 7a8b6b9
refactor(SettingFragment): property formatting
hyemdooly 070cce4
refactor(SettingFragment): if문 depth 수정
hyemdooly 8497d53
refactor(Adapter, ViewHolder): click listener 파라미터 고차함수 -> OnItemClic…
hyemdooly b2ce59d
refactor(MovieListFragment): click listener 분리
hyemdooly fcd527f
refactor(ReservationListFragment): 변수 분리 가독성 수정
hyemdooly c9df85d
refactor(ReservationCompletedActivity): 권한 유도 코드 이동
hyemdooly 8eba6d0
refactor(AlarmController): context private 수정
hyemdooly 085e9dd
refactor(AlarmReceiver, AlarmController): ALARM_REQUEST_CODE 상수 이동
hyemdooly fd3e4d3
refactor(ReservationCompletedActivity): pendingIntent를 리턴하는 함수 생성
hyemdooly 17cafbc
refactor(SeatSelectionActivity): repositoryMock에 직접 접근이 아닌 interface …
hyemdooly b634aa8
refactor(SettingFragment): defaultSharedPreferences로 변경
hyemdooly 72e7a58
refactor(Fragments): 레이아웃 id 생성자 사용
hyemdooly 00f4a8f
refactor(MovieMainActivity): Fragment 재활용
hyemdooly 923eedd
refactor(ReservationCompletedActivity): 권한 요청 코드 이동
hyemdooly 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,69 @@ | ||
# android-movie-theater | ||
# android-movie-theater | ||
|
||
## domain | ||
|
||
### Movie | ||
- [x] 제목, 상영기간, 러닝타임, 이미지를 알아야 한다. | ||
- [x] MovieDetail을 소유해야 한다. | ||
|
||
### MovieDetail | ||
- [x] 영화의 줄거리를 알아야 한다. | ||
|
||
### Reservation | ||
- [x] 영화, 예약된 좌석, 선택한 날짜와 시간, 예매 금액을 알아야 한다. | ||
- [x] 최소, 최대 예매 인원 수를 알아야 한다. | ||
|
||
### ReservationAgency | ||
- [x] 영화, 인원 수, 선택된 날짜와 시간을 알아야 한다. | ||
- [x] 예매 가능한지 판단한다. | ||
- [x] 예매한다. (Reservation을 생성한다.) | ||
- [x] 할인 정책이 적용된 총 금액을 계산한다. | ||
|
||
### DiscountPolicy | ||
- [x] 할인 조건을 가져야 한다. | ||
- [x] 할인 조건을 만족한다면 특정 금액의 할인 가격을 반환할 수 있다. | ||
|
||
### MovieDayDiscountPolicy | ||
- [x] 할인 조건을 만족하면 10% 할인한다. | ||
- [x] 10, 20, 30일에 할인 조건을 만족한다는 할인 조건을 가지고 있다. | ||
|
||
### ScreeningTimeDiscountPolicy | ||
- [x] 할인 조건을 만족하면 2000원 할인한다. | ||
- [x] 조조, 야간 할인 조건을 가지고 있다. | ||
|
||
### DiscountCondition | ||
- [x] 영화 예매에 대해 할인할 수 있는지 판단할 수 있다. | ||
|
||
### DayDiscountCondition | ||
- [x] 상영 날짜로 할인할 수 있는지 판단한다. | ||
|
||
### ScreeningTimeDiscountCondition | ||
- [x] 상영 시간으로 할인할 수 있는지 판단한다. | ||
|
||
### Seat | ||
- [x] 좌석의 행과 열을 알아야 한다. | ||
- [x] 행은 1~4, 열은 1~5를 만족한다. | ||
- [x] 좌석에 해당하는 금액을 구한다. | ||
|
||
### SeatType | ||
- [x] 좌석타입에 해당하는 금액을 가지고 있다. | ||
|
||
## View | ||
|
||
### MovieListActivity | ||
- [x] 모든 영화의 제목, 상영 기간, 러닝타임, 이미지를 보여준다. | ||
- [x] 영화마다 예매할 수 있는 버튼이 존재한다. | ||
|
||
### ReservationActivity | ||
- [x] 영화의 이미지, 제목, 상영 기간, 상영 시간, 러닝타임, 상세정보를 보여준다. | ||
- [x] 상영 기간과 상영 시간은 스피너로 선택할 수 있다. | ||
- [x] 예매 인원을 조절할 수 있는 버튼이 존재한다. | ||
- [x] 클릭하면 예매 정보를 보여주는 화면을 띄우는 예매 완료 버튼이 존재한다. | ||
|
||
### ReservationCompletedActivity | ||
- [x] 영화 제목, 상영일, 상영 시간, 예매 인원, 예매 금액을 보여준다. | ||
|
||
## Repository | ||
|
||
### MovieRepository | ||
- [x] 영화 데이터들을 조회할 수 있다. |
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
Empty file.
38 changes: 38 additions & 0 deletions
38
app/src/androidTest/java/woowacourse/movie/view/MovieMainActivityTest.kt
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,38 @@ | ||
package woowacourse.movie.view | ||
|
||
import androidx.test.espresso.Espresso.onView | ||
import androidx.test.espresso.action.ViewActions.click | ||
import androidx.test.espresso.assertion.ViewAssertions.matches | ||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed | ||
import androidx.test.espresso.matcher.ViewMatchers.withId | ||
import androidx.test.ext.junit.rules.ActivityScenarioRule | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import woowacourse.movie.R | ||
import woowacourse.movie.view.moviemain.MovieMainActivity | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class MovieMainActivityTest { | ||
@get:Rule | ||
val mActivityTestRule = ActivityScenarioRule(MovieMainActivity::class.java) | ||
|
||
@Test | ||
fun 예매내역_버튼을_누르면_예매내역_Fragment로_바뀐다() { | ||
onView(withId(R.id.action_reservation_list)).perform(click()) | ||
onView(withId(R.id.recyclerview)).check(matches(isDisplayed())) | ||
} | ||
|
||
@Test | ||
fun 홈_버튼을_누르면_홈_Fragment로_바뀐다() { | ||
onView(withId(R.id.action_home)).perform(click()) | ||
onView(withId(R.id.movie_recyclerview)).check(matches(isDisplayed())) | ||
} | ||
|
||
@Test | ||
fun 설정_버튼을_누르면_설정_Fragment로_바뀐다() { | ||
onView(withId(R.id.action_setting)).perform(click()) | ||
onView(withId(R.id.setting_toggle)).check(matches(isDisplayed())) | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
app/src/androidTest/java/woowacourse/movie/view/ReservationActivityTest.kt
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,59 @@ | ||
package woowacourse.movie.view | ||
|
||
import androidx.test.core.app.ApplicationProvider | ||
import androidx.test.espresso.Espresso.onView | ||
import androidx.test.espresso.action.ViewActions.click | ||
import androidx.test.espresso.assertion.ViewAssertions.matches | ||
import androidx.test.espresso.matcher.ViewMatchers.withId | ||
import androidx.test.espresso.matcher.ViewMatchers.withText | ||
import androidx.test.ext.junit.rules.ActivityScenarioRule | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import woowacourse.movie.R | ||
import woowacourse.movie.view.model.MovieListModel | ||
import java.time.LocalDate | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class ReservationActivityTest { | ||
|
||
private val movie = MovieListModel.MovieUiModel( | ||
"해리 포터와 마법사의 돌", | ||
LocalDate.of(2024, 3, 1), | ||
LocalDate.of(2024, 3, 31), | ||
152, | ||
R.drawable.harry_potter1_poster, | ||
"《해리 포터와 마법사의 돌》은 2001년 J. K. 롤링의 동명 소설을 원작으로 하여 만든, 영국과 미국 합작, 판타지 영화이다. 해리포터 시리즈 영화 8부작 중 첫 번째에 해당하는 작품이다. 크리스 콜럼버스가 감독을 맡았다." | ||
) | ||
|
||
private val intent = ReservationActivity.newIntent( | ||
ApplicationProvider.getApplicationContext(), | ||
movie | ||
) | ||
|
||
@get:Rule | ||
val activityRule = ActivityScenarioRule<ReservationActivity>(intent) | ||
|
||
@Test | ||
fun 영화_제목을_표시한다() { | ||
onView(withId(R.id.movie_title)).check(matches(withText("해리 포터와 마법사의 돌"))) | ||
} | ||
|
||
@Test | ||
fun 처음_표시되는_인원수는_1이다() { | ||
onView(withId(R.id.people_count)).check(matches(withText("1"))) | ||
} | ||
|
||
@Test | ||
fun 플러스_버튼을_한_번_클릭하면_인원수는_2이다() { | ||
onView(withId(R.id.plus_button)).perform(click()) | ||
onView(withId(R.id.people_count)).check(matches(withText("2"))) | ||
} | ||
|
||
@Test | ||
fun 초기_인원_1인_경우_마이너스_버튼을_눌러도_인원수는_1이다() { | ||
onView(withId(R.id.minus_button)).perform(click()) | ||
onView(withId(R.id.people_count)).check(matches(withText("1"))) | ||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
app/src/androidTest/java/woowacourse/movie/view/SeatSelectionActivityTest.kt
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,103 @@ | ||
package woowacourse.movie.view | ||
|
||
import androidx.test.core.app.ApplicationProvider | ||
import androidx.test.espresso.Espresso.onView | ||
import androidx.test.espresso.action.ViewActions.click | ||
import androidx.test.espresso.assertion.ViewAssertions.matches | ||
import androidx.test.espresso.matcher.ViewMatchers.isEnabled | ||
import androidx.test.espresso.matcher.ViewMatchers.isNotEnabled | ||
import androidx.test.espresso.matcher.ViewMatchers.isNotSelected | ||
import androidx.test.espresso.matcher.ViewMatchers.isSelected | ||
import androidx.test.espresso.matcher.ViewMatchers.withId | ||
import androidx.test.espresso.matcher.ViewMatchers.withText | ||
import androidx.test.ext.junit.rules.ActivityScenarioRule | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import androidx.test.filters.LargeTest | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import woowacourse.movie.R | ||
import woowacourse.movie.domain.Minute | ||
import woowacourse.movie.domain.Movie | ||
import woowacourse.movie.view.mapper.toUiModel | ||
import woowacourse.movie.view.model.ReservationOptions | ||
import woowacourse.movie.view.seatselection.SeatSelectionActivity | ||
import java.time.LocalDate | ||
import java.time.LocalDateTime | ||
import java.time.LocalTime | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
@LargeTest | ||
class SeatSelectionActivityTest { | ||
|
||
private val reservationOptions = ReservationOptions( | ||
"해리 포터와 마법사의 돌", | ||
LocalDateTime.of(LocalDate.of(2024, 3, 1), LocalTime.of(13, 0)), | ||
2 | ||
) | ||
|
||
private val movie = Movie( | ||
"해리 포터와 마법사의 돌", | ||
LocalDate.of(2024, 3, 1), | ||
LocalDate.of(2024, 3, 31), | ||
Minute(152), | ||
R.drawable.harry_potter1_poster, | ||
"《해리 포터와 마법사의 돌》은 2001년 J. K. 롤링의 동명 소설을 원작으로 하여 만든, 영국과 미국 합작, 판타지 영화이다. 해리포터 시리즈 영화 8부작 중 첫 번째에 해당하는 작품이다. 크리스 콜럼버스가 감독을 맡았다." | ||
) | ||
|
||
private val intent = SeatSelectionActivity.newIntent( | ||
ApplicationProvider.getApplicationContext(), | ||
reservationOptions, | ||
movie.toUiModel() | ||
) | ||
|
||
@get:Rule | ||
val activityRule = ActivityScenarioRule<SeatSelectionActivity>(intent) | ||
|
||
@Test | ||
fun 영화_제목을_표시한다() { | ||
onView(withId(R.id.movie_title_textview)) | ||
.check(matches(withText("해리 포터와 마법사의 돌"))) | ||
} | ||
|
||
@Test | ||
fun 한_번_클릭하면_좌석이_선택된다() { | ||
onView(withText("A1")).perform(click()).check(matches(isSelected())) | ||
} | ||
|
||
@Test | ||
fun 두_번_클릭하면_좌석_선택이_해제된다() { | ||
onView(withText("A1")).perform(click()) | ||
onView(withText("A1")).perform(click()).check(matches(isNotSelected())) | ||
} | ||
|
||
@Test | ||
fun 인원수에_해당하는_좌석이_모두_선택되지_않았다면_확인_버튼은_비활성화_상태다() { | ||
onView(withText("A1")).perform(click()) | ||
onView(withId(R.id.confirm_reservation_button)) | ||
.check(matches(isNotEnabled())) | ||
} | ||
|
||
@Test | ||
fun 인원수에_해당하는_좌석이_모두_선택되었다면_확인_버튼은_활성화_상태다() { | ||
onView(withText("A1")).perform(click()) | ||
onView(withText("A2")).perform(click()) | ||
onView(withId(R.id.confirm_reservation_button)) | ||
.check(matches(isEnabled())) | ||
} | ||
|
||
@Test | ||
fun 인원수에_해당하는_좌석이_모두_선택되었다면_최종_금액이_표시된다() { | ||
onView(withText("A1")).perform(click()) | ||
onView(withText("A2")).perform(click()) | ||
onView(withId(R.id.reservation_fee_textview)).check(matches(withText("20,000원"))) | ||
} | ||
|
||
@Test | ||
fun 좌석_선택을_해제하여_인원수에_해당하는_좌석이_모두_선택되지_않았다면_최종_금액은_0원으로_표시된다() { | ||
onView(withText("A1")).perform(click()) | ||
onView(withText("A2")).perform(click()) | ||
onView(withText("A1")).perform(click()) | ||
onView(withId(R.id.reservation_fee_textview)).check(matches(withText("0원"))) | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
app/src/androidTest/java/woowacourse/movie/view/SettingFragmentTest.kt
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,61 @@ | ||
package woowacourse.movie.view | ||
|
||
import android.content.Context | ||
import android.content.SharedPreferences | ||
import androidx.fragment.app.commit | ||
import androidx.preference.PreferenceManager | ||
import androidx.test.core.app.ActivityScenario | ||
import androidx.test.espresso.Espresso.onView | ||
import androidx.test.espresso.action.ViewActions | ||
import androidx.test.espresso.assertion.ViewAssertions | ||
import androidx.test.espresso.matcher.ViewMatchers | ||
import androidx.test.ext.junit.rules.ActivityScenarioRule | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import androidx.test.platform.app.InstrumentationRegistry | ||
import org.junit.Before | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import woowacourse.movie.R | ||
import woowacourse.movie.view.moviemain.MovieMainActivity | ||
import woowacourse.movie.view.moviemain.setting.SettingFragment | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class SettingFragmentTest { | ||
@get:Rule | ||
val mActivityTestRule = ActivityScenarioRule(MovieMainActivity::class.java) | ||
|
||
@Before | ||
fun setup() { | ||
ActivityScenario.launch(MovieMainActivity::class.java).onActivity { | ||
it.supportFragmentManager.commit { | ||
replace(R.id.fragment_container_view, SettingFragment()) | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
fun 설정_Fragment에서_저장된_세팅값이_false면_토글도_꺼져있다() { | ||
setSharedPreferences(false) | ||
onView(ViewMatchers.withId(R.id.action_setting)).perform(ViewActions.click()) | ||
onView(ViewMatchers.withId(R.id.setting_toggle)) | ||
.check(ViewAssertions.matches(ViewMatchers.isNotChecked())) | ||
} | ||
|
||
@Test | ||
fun 설정_Fragment에서_저장된_세팅값이_true면_토글도_켜져있다() { | ||
setSharedPreferences(true) | ||
onView(ViewMatchers.withId(R.id.action_setting)).perform(ViewActions.click()) | ||
onView(ViewMatchers.withId(R.id.setting_toggle)) | ||
.check(ViewAssertions.matches(ViewMatchers.isChecked())) | ||
} | ||
|
||
private fun setSharedPreferences(isAlarmOn: Boolean) { | ||
val targetContext: Context = InstrumentationRegistry.getInstrumentation().targetContext | ||
|
||
val preferencesEditor: SharedPreferences.Editor = PreferenceManager.getDefaultSharedPreferences(targetContext).edit() | ||
preferencesEditor.clear() | ||
preferencesEditor.putBoolean(SettingFragment.IS_ALARM_ON, isAlarmOn) | ||
preferencesEditor.commit() | ||
} | ||
Comment on lines
+53
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아래 내용은 꼭 반영하지 않으셔도 됩니다. 세팅 화면에서 UI 테스트를 하기 위해 프리퍼런스가 잘 동작하는지를 체크하는게 맞을까? 라는 의문이 들었어요. 만약 프리퍼런스가 아닌 데이터베이스로 바뀌면 UI 테스트가 같이 실패하게 됩니다. |
||
} |
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.
프래그먼트가 보인다를 테스트해야 하는데, 실제로 해당 프래그먼트의 컨텐츠를 확인하는게 아쉽네요..
저도 프래그먼트 테스트는 자주 해보지 않아서, 어떤 방식이 최적의 방식인지는 추천드리기 어려운데
프래그먼트 매니저를 이용해서 프래그먼트의 인스턴스가 해당 타입이 맞는지 확인하는게 가능할까 싶네요!?
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.
TAG로 프래그먼트를 가져와서 그 프래그먼트가 visible인지 검사했습니다! :)