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

[AN/USER] feat: 학생 인증 화면 구현 (#370) #429

Merged
merged 35 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c6dedda
feat: 학생 인증 레포지토리 정의
SeongHoonC Aug 24, 2023
f64f815
feat: 학교 레포지토리 임시 정의
SeongHoonC Aug 24, 2023
90ca80f
feat: 학교 인증 화면 뷰모델 구현
SeongHoonC Aug 24, 2023
306b1dc
test: 학생 인증 화면 뷰모델 테스트 작성
SeongHoonC Aug 25, 2023
fa3831d
refactor: LiveData stateFlow 로 리팩터링
SeongHoonC Sep 5, 2023
a36f8e1
feat: StudentVerificationActivity 생성
SeongHoonC Sep 5, 2023
b3a81da
feat: 학생 인증 화면 xml 그리기
SeongHoonC Sep 5, 2023
9b84313
feat: 재사용 가능한 문장 검증 로직 생성 및 테스트
SeongHoonC Sep 7, 2023
5b42940
feat: 학생 인증 검증 로직 생성 및 테스트
SeongHoonC Sep 7, 2023
024c3d2
feat: SchoolId Long 으로 변경
SeongHoonC Sep 7, 2023
1600176
feat: 인증 코드 확인 요청 기능 작성
SeongHoonC Sep 7, 2023
ee4175b
feat: 코드 형식 확인 인증
SeongHoonC Sep 7, 2023
cb765d4
feat: 임시 학교 인증 화면 이동
SeongHoonC Sep 7, 2023
5b853fc
refator: ktlint check
SeongHoonC Sep 7, 2023
4c50f49
refator: 클래스 및 변수 명 변경
SeongHoonC Sep 8, 2023
12faf1a
fix: 화면 회전 시 학교 이메일을 재요청하지 않음
SeongHoonC Sep 8, 2023
e8bd130
refactor: 사용하지않는 코드 주석 제거
SeongHoonC Sep 11, 2023
3b896e4
refactor: repeatOnStartedState util 추가
SeongHoonC Sep 11, 2023
9165d3b
refactor: StudentVerificationActivity 전체 리팩터링
SeongHoonC Sep 11, 2023
981fdfe
refactor: Students 를 Student 로 통일
SeongHoonC Sep 11, 2023
56056f4
refactor: State 성공 시 처리 함수 분리 및 네이밍 변경
SeongHoonC Sep 11, 2023
b4eface
refactor: 글자 30개까지 입력으로 변경
SeongHoonC Sep 11, 2023
56d7ca2
feat: sealed interface 학생 인증 이벤트 추가
SeongHoonC Sep 11, 2023
3743d5b
refactor: 학생 인증 ViewModel 리팩터링
SeongHoonC Sep 11, 2023
4dcf7c3
test: 학생 인증 이벤트 테스트 추가
SeongHoonC Sep 11, 2023
da5a951
refactor: 사용하지 않는 뷰 제거
SeongHoonC Sep 11, 2023
2c09605
test: 학생 인증 코드 예외 테스트 추가
SeongHoonC Sep 11, 2023
738f96e
feat: Event observing 추가
SeongHoonC Sep 11, 2023
e522752
refactor: 테스트 리팩터링
SeongHoonC Sep 12, 2023
917d18a
refactor: 테스트 네이밍 리팩터링
SeongHoonC Sep 12, 2023
c25372f
refactor: turbine 추가 및 sharedFlow 테스트 리팩터링
SeongHoonC Sep 13, 2023
f135fcd
refactor: Text 검증 테스트 네이밍 및 구조 리팩터링
SeongHoonC Sep 14, 2023
c2615df
refactor: TextValidator 생성 로직 통일
SeongHoonC Sep 14, 2023
84e963e
refactor: given when 함수 분리 및 테스트 리팩터링
SeongHoonC Sep 14, 2023
6e6ce87
refactor: seal interface 는 isExactlyInstanceOf 로 테스트
SeongHoonC Sep 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions android/festago/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ dependencies {
// Encrypted SharedPreference
implementation("androidx.security:security-crypto-ktx:1.1.0-alpha06")

// turbine
testImplementation("app.cash.turbine:turbine:1.0.0")

// domain
implementation(project(":domain"))
}
Expand Down
4 changes: 2 additions & 2 deletions android/festago/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".presentation.ui.studentsverification.StudentVerificationActivity"
android:name=".presentation.ui.studentverification.StudentVerificationActivity"
android:exported="false" />
<activity
android:name=".presentation.ui.signin.SignInActivity"
Expand Down Expand Up @@ -58,7 +58,7 @@
</activity>
<activity
android:name=".presentation.ui.tickethistory.TicketHistoryActivity"
android:exported="false"></activity>
android:exported="false" />
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.festago.festago.data.repository

import com.festago.festago.data.service.StudentVerificationRetrofitService
import com.festago.festago.model.StudentVerificationCode
import com.festago.festago.repository.StudentVerificationRepository

class StudentVerificationDefaultRepository(
private val studentVerificationRetrofitService: StudentVerificationRetrofitService,
) : StudentVerificationRepository {

override suspend fun sendVerificationCode(userName: String, schoolId: Long): Result<Unit> {
// TODO: API 연동 작업 필요
return Result.success(Unit)
}

override suspend fun requestVerificationCodeConfirm(code: StudentVerificationCode): Result<Unit> {
// TODO: API 연동 작업 필요
return Result.success(Unit)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.POST

interface StudentsVerificationRetrofitService {
interface StudentVerificationRetrofitService {
@POST("/students/send-verification")
suspend fun sendVerificationCode(
@Body sendVerificationRequest: SendVerificationRequest,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.festago.festago.di

import com.festago.festago.data.retrofit.AuthInterceptor
import com.festago.festago.data.service.StudentsVerificationRetrofitService
import com.festago.festago.data.service.StudentVerificationRetrofitService
import com.festago.festago.data.service.TicketRetrofitService
import com.festago.festago.data.service.UserRetrofitService
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
Expand Down Expand Up @@ -31,7 +31,7 @@ class AuthServiceContainer(baseUrl: String, tokenContainer: TokenContainer) {
authRetrofit.create(UserRetrofitService::class.java)
}

val studentsVerificationRetrofitService: StudentsVerificationRetrofitService by lazy {
authRetrofit.create(StudentsVerificationRetrofitService::class.java)
val studentVerificationRetrofitService: StudentVerificationRetrofitService by lazy {
authRetrofit.create(StudentVerificationRetrofitService::class.java)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import com.festago.festago.data.repository.AuthDefaultRepository
import com.festago.festago.data.repository.FestivalDefaultRepository
import com.festago.festago.data.repository.ReservationTicketDefaultRepository
import com.festago.festago.data.repository.SchoolDefaultRepository
import com.festago.festago.data.repository.StudentsVerificationDefaultRepository
import com.festago.festago.data.repository.StudentVerificationDefaultRepository
import com.festago.festago.data.repository.TicketDefaultRepository
import com.festago.festago.data.repository.UserDefaultRepository
import com.festago.festago.repository.AuthRepository
import com.festago.festago.repository.FestivalRepository
import com.festago.festago.repository.ReservationTicketRepository
import com.festago.festago.repository.SchoolRepository
import com.festago.festago.repository.StudentsVerificationRepository
import com.festago.festago.repository.StudentVerificationRepository
import com.festago.festago.repository.TicketRepository
import com.festago.festago.repository.UserRepository

Expand Down Expand Up @@ -45,9 +45,9 @@ class RepositoryContainer(
reservationTicketRetrofitService = normalServiceContainer.reservationTicketRetrofitService,
)

val studentsVerificationRepository: StudentsVerificationRepository
get() = StudentsVerificationDefaultRepository(
studentsVerificationRetrofitService = authServiceContainer.studentsVerificationRetrofitService,
val studentVerificationRepository: StudentVerificationRepository
get() = StudentVerificationDefaultRepository(
studentVerificationRetrofitService = authServiceContainer.studentVerificationRetrofitService,
)

val schoolRepository: SchoolRepository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.festago.festago.presentation.ui.home.festivallist.FestivalListViewMod
import com.festago.festago.presentation.ui.home.mypage.MyPageViewModel
import com.festago.festago.presentation.ui.home.ticketlist.TicketListViewModel
import com.festago.festago.presentation.ui.signin.SignInViewModel
import com.festago.festago.presentation.ui.studentsverification.StudentsVerificationViewModel
import com.festago.festago.presentation.ui.studentverification.StudentVerificationViewModel
import com.festago.festago.presentation.ui.ticketentry.TicketEntryViewModel
import com.festago.festago.presentation.ui.tickethistory.TicketHistoryViewModel
import com.festago.festago.presentation.ui.ticketreserve.TicketReserveViewModel
Expand Down Expand Up @@ -64,9 +64,9 @@ val FestagoViewModelFactory: ViewModelProvider.Factory = object : ViewModelProvi
analyticsHelper = analysisContainer.analyticsHelper,
)

modelClass.isAssignableFrom(StudentsVerificationViewModel::class.java) -> StudentsVerificationViewModel(
modelClass.isAssignableFrom(StudentVerificationViewModel::class.java) -> StudentVerificationViewModel(
schoolRepository = repositoryContainer.schoolRepository,
studentsVerificationRepository = repositoryContainer.studentsVerificationRepository,
studentVerificationRepository = repositoryContainer.studentVerificationRepository,
analyticsHelper = analysisContainer.analyticsHelper,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.festago.festago.databinding.FragmentMyPageBinding
import com.festago.festago.presentation.ui.FestagoViewModelFactory
import com.festago.festago.presentation.ui.home.HomeActivity
import com.festago.festago.presentation.ui.signin.SignInActivity
import com.festago.festago.presentation.ui.studentsverification.StudentVerificationActivity
import com.festago.festago.presentation.ui.studentverification.StudentVerificationActivity
import com.festago.festago.presentation.ui.tickethistory.TicketHistoryActivity

class MyPageFragment : Fragment(R.layout.fragment_my_page) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@
package com.festago.festago.presentation.ui.studentsverification
package com.festago.festago.presentation.ui.studentverification

import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.festago.festago.R
import com.festago.festago.databinding.ActivityStudentVerificationBinding
import com.festago.festago.presentation.ui.FestagoViewModelFactory
import kotlinx.coroutines.launch
import com.festago.festago.presentation.util.repeatOnStarted
import java.time.LocalTime
import java.time.format.DateTimeFormatter

class StudentVerificationActivity : AppCompatActivity() {

private lateinit var binding: ActivityStudentVerificationBinding
private val binding: ActivityStudentVerificationBinding by lazy {
ActivityStudentVerificationBinding.inflate(layoutInflater)
}

private val vm: StudentsVerificationViewModel by viewModels { FestagoViewModelFactory }
private val vm: StudentVerificationViewModel by viewModels { FestagoViewModelFactory }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initBinding()
initObserving()
initView()
initObserve()
}

private fun initBinding() {
binding = ActivityStudentVerificationBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.lifecycleOwner = this
binding.vm = vm
Expand All @@ -47,20 +45,27 @@ class StudentVerificationActivity : AppCompatActivity() {
}
}

private fun initObserving() {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
vm.uiState.collect { uiState ->
binding.uiState = uiState
when (uiState) {
is StudentVerificationUiState.Success -> handleSuccess(uiState)
is StudentVerificationUiState.Loading, StudentVerificationUiState.Error -> {}
}
}
private fun initObserve() {
repeatOnStarted {
vm.uiState.collect { uiState ->
handleUiState(uiState)
}
}
repeatOnStarted {
vm.event.collect { event ->
handleEvent(event)
}
}
}

private fun handleUiState(uiState: StudentVerificationUiState) {
binding.uiState = uiState
when (uiState) {
is StudentVerificationUiState.Success -> handleSuccess(uiState)
is StudentVerificationUiState.Loading, StudentVerificationUiState.Error -> Unit
}
}

private fun handleSuccess(uiState: StudentVerificationUiState.Success) {
binding.tvSchoolEmail.text =
getString(R.string.student_verification_tv_email_format, uiState.schoolEmail)
Expand All @@ -73,9 +78,18 @@ class StudentVerificationActivity : AppCompatActivity() {
binding.btnVerificationConfirm.isEnabled = uiState.isValidateCode
}

private fun handleEvent(event: StudentVerificationEvent) {
when (event) {
is StudentVerificationEvent.VerificationSuccess -> Unit
is StudentVerificationEvent.VerificationFailure -> Unit
is StudentVerificationEvent.CodeTimeOut -> Unit
}
}

companion object {

private const val KEY_SCHOOL_ID = "KEY_SCHOOL_ID"

fun getIntent(context: Context, schoolId: Long): Intent {
return Intent(context, StudentVerificationActivity::class.java).apply {
putExtra(KEY_SCHOOL_ID, schoolId)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.festago.festago.presentation.ui.studentverification

sealed interface StudentVerificationEvent {
object CodeTimeOut : StudentVerificationEvent
object VerificationFailure : StudentVerificationEvent
object VerificationSuccess : StudentVerificationEvent
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.festago.festago.presentation.ui.studentsverification
package com.festago.festago.presentation.ui.studentverification

sealed interface StudentVerificationUiState {
object Loading : StudentVerificationUiState
Expand Down
Loading