Skip to content

Commit

Permalink
[MBL-801] Update survey response viewmodel to RX2 (#2082)
Browse files Browse the repository at this point in the history
* update survey response viewmodel to RX2

* initialize factory
  • Loading branch information
mtgriego authored Jul 30, 2024
1 parent 435976f commit 16435ed
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,28 @@ import android.content.DialogInterface
import android.net.Uri
import android.os.Bundle
import android.webkit.WebView
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import com.kickstarter.R
import com.kickstarter.databinding.SurveyResponseLayoutBinding
import com.kickstarter.libs.BaseActivity
import com.kickstarter.libs.qualifiers.RequiresActivityViewModel
import com.kickstarter.libs.rx.transformers.Transformers
import com.kickstarter.libs.utils.extensions.addToDisposable
import com.kickstarter.libs.utils.extensions.getEnvironment
import com.kickstarter.libs.utils.extensions.isProjectSurveyUri
import com.kickstarter.libs.utils.extensions.isProjectUri
import com.kickstarter.services.RequestHandler
import com.kickstarter.viewmodels.SurveyResponseViewModel
import io.reactivex.disposables.CompositeDisposable
import okhttp3.Request
import java.util.Arrays

@RequiresActivityViewModel(SurveyResponseViewModel.ViewModel::class)
class SurveyResponseActivity : BaseActivity<SurveyResponseViewModel.ViewModel>() {
class SurveyResponseActivity : ComponentActivity() {

private lateinit var binding: SurveyResponseLayoutBinding
private lateinit var factory: SurveyResponseViewModel.Factory
private val viewModel: SurveyResponseViewModel.ViewModel by viewModels { factory }
private val disposables = CompositeDisposable()

private val confirmationDialog: AlertDialog by lazy {
AlertDialog.Builder(this)
Expand All @@ -33,6 +38,9 @@ class SurveyResponseActivity : BaseActivity<SurveyResponseViewModel.ViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
getEnvironment()?.let { env ->
factory = SurveyResponseViewModel.Factory(environment = env, intent = intent)
}
binding = SurveyResponseLayoutBinding.inflate(layoutInflater)
setContentView(binding.root)

Expand All @@ -53,14 +61,14 @@ class SurveyResponseActivity : BaseActivity<SurveyResponseViewModel.ViewModel>()
)

viewModel.outputs.goBack()
.compose(bindToLifecycle())
.compose(Transformers.observeForUI())
.subscribe { back() }
.compose(Transformers.observeForUIV2())
.subscribe { onBackPressedDispatcher.onBackPressed() }
.addToDisposable(disposables)

viewModel.outputs.showConfirmationDialog()
.compose(bindToLifecycle())
.compose(Transformers.observeForUI())
.compose(Transformers.observeForUIV2())
.subscribe { confirmationDialog.show() }
.addToDisposable(disposables)
}

private fun handleProjectUriRequest(request: Request, webView: WebView): Boolean {
Expand All @@ -77,8 +85,13 @@ class SurveyResponseActivity : BaseActivity<SurveyResponseViewModel.ViewModel>()
super.onResume()
viewModel.outputs.webViewUrl()
.take(1)
.compose(bindToLifecycle())
.compose(Transformers.observeForUI())
.compose(Transformers.observeForUIV2())
.subscribe { binding.surveyResponseWebView.loadUrl(it) }
.addToDisposable(disposables)
}

override fun onDestroy() {
disposables.clear()
super.onDestroy()
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package com.kickstarter.viewmodels

import android.content.Intent
import android.util.Pair
import androidx.annotation.NonNull
import com.kickstarter.libs.ActivityViewModel
import androidx.lifecycle.ViewModelProvider
import com.kickstarter.libs.Environment
import com.kickstarter.libs.rx.transformers.Transformers
import com.kickstarter.libs.utils.extensions.addToDisposable
import com.kickstarter.models.SurveyResponse
import com.kickstarter.ui.IntentKey
import com.kickstarter.ui.activities.SurveyResponseActivity
import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.PublishSubject
import okhttp3.Request
import rx.Observable
import rx.subjects.BehaviorSubject
import rx.subjects.PublishSubject

interface SurveyResponseViewModel {
interface Inputs {
Expand All @@ -27,17 +28,17 @@ interface SurveyResponseViewModel {

interface Outputs {
/** Emits when we should navigate back. */
fun goBack(): Observable<Void>
fun goBack(): Observable<Unit>

/** Emits when we should show a confirmation dialog. */
fun showConfirmationDialog(): Observable<Void>
fun showConfirmationDialog(): Observable<Unit>

/** Emits a url to load in the web view. */
fun webViewUrl(): Observable<String?>
fun webViewUrl(): Observable<String>
}

class ViewModel(@NonNull environment: Environment) :
ActivityViewModel<SurveyResponseActivity>(environment), Inputs, Outputs {
class ViewModel(val environment: Environment, val intent: Intent) :
androidx.lifecycle.ViewModel(), Inputs, Outputs {
/**
* Returns if a project request tag's url is a survey url,
* which indicates a redirect from a successful submit.
Expand All @@ -47,29 +48,33 @@ interface SurveyResponseViewModel {
return tag == null || tag.url.toString() == projectRequestAndSurveyUrl.second
}

private val okButtonClicked = PublishSubject.create<Void>()
private val okButtonClicked = PublishSubject.create<Unit>()
private val projectUriRequest = PublishSubject.create<Request>()
private val projectSurveyUriRequest = PublishSubject.create<Request>()
private val goBack: Observable<Void>
private val showConfirmationDialog = PublishSubject.create<Void>()
private val webViewUrl = BehaviorSubject.create<String?>()
private val goBack: Observable<Unit>
private val showConfirmationDialog = PublishSubject.create<Unit>()
private val webViewUrl = BehaviorSubject.create<String>()

val inputs: Inputs = this
val outputs: Outputs = this

private fun intent() = intent.let { Observable.just(it) }

private val disposables = CompositeDisposable()

init {
val surveyResponse = intent()
.map<Any?> { it.getParcelableExtra(IntentKey.SURVEY_RESPONSE) }
.ofType(SurveyResponse::class.java)

val surveyWebUrl = surveyResponse
.map {
it.urls()?.web()?.survey()
it.urls()?.web()?.survey() ?: ""
}

surveyWebUrl
.compose(bindToLifecycle())
.subscribe(webViewUrl)
.subscribe { webViewUrl.onNext(it) }
.addToDisposable(disposables)

val projectRequestAndSurveyUrl =
Observable.combineLatest<Request, String?, Pair<Request, String>>(
Expand All @@ -83,15 +88,14 @@ interface SurveyResponseViewModel {
projectRequestAndSurveyUrl
)
}
.compose(Transformers.ignoreValues())
.compose(bindToLifecycle())
.compose(Transformers.ignoreValuesV2())
.subscribe(showConfirmationDialog)

goBack = okButtonClicked
}

override fun okButtonClicked() {
okButtonClicked.onNext(null)
okButtonClicked.onNext(Unit)
}

override fun projectUriRequest(request: Request) {
Expand All @@ -102,10 +106,21 @@ interface SurveyResponseViewModel {
projectSurveyUriRequest.onNext(request)
}

override fun goBack(): Observable<Void> = goBack
override fun goBack(): Observable<Unit> = goBack

override fun showConfirmationDialog(): Observable<Void> = showConfirmationDialog
override fun showConfirmationDialog(): Observable<Unit> = showConfirmationDialog

override fun webViewUrl(): Observable<String?> = webViewUrl
override fun webViewUrl(): Observable<String> = webViewUrl

override fun onCleared() {
disposables.clear()
super.onCleared()
}
}

class Factory(private val environment: Environment, private val intent: Intent) : ViewModelProvider.Factory {
override fun <T : androidx.lifecycle.ViewModel> create(modelClass: Class<T>): T {
return ViewModel(environment, intent) as T
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,35 @@ package com.kickstarter.viewmodels
import android.content.Intent
import com.kickstarter.KSRobolectricTestCase
import com.kickstarter.libs.Environment
import com.kickstarter.libs.utils.extensions.addToDisposable
import com.kickstarter.mock.factories.SurveyResponseFactory.surveyResponse
import com.kickstarter.models.SurveyResponse
import com.kickstarter.ui.IntentKey
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.subscribers.TestSubscriber
import okhttp3.Request
import org.junit.After
import org.junit.Test
import rx.observers.TestSubscriber

class SurveyResponseViewModelTest : KSRobolectricTestCase() {
private lateinit var vm: SurveyResponseViewModel.ViewModel
private val goBack = TestSubscriber<Void>()
private val showConfirmationDialog = TestSubscriber<Void>()
private val webViewUrl = TestSubscriber<String?>()
private val goBack = TestSubscriber<Unit>()
private val showConfirmationDialog = TestSubscriber<Unit>()
private val webViewUrl = TestSubscriber<String>()

protected fun setUpEnvironment(environment: Environment) {
vm = SurveyResponseViewModel.ViewModel(environment)
private val disposables = CompositeDisposable()

vm.outputs.goBack().subscribe(goBack)
vm.outputs.showConfirmationDialog().subscribe(showConfirmationDialog)
vm.outputs.webViewUrl().subscribe(webViewUrl)
protected fun setUpEnvironment(environment: Environment, intent: Intent) {
vm = SurveyResponseViewModel.ViewModel(environment, intent)

vm.outputs.goBack().subscribe { goBack.onNext(it) }.addToDisposable(disposables)
vm.outputs.showConfirmationDialog().subscribe { showConfirmationDialog.onNext(it) }.addToDisposable(disposables)
vm.outputs.webViewUrl().subscribe { webViewUrl.onNext(it) }.addToDisposable(disposables)
}

@Test
fun testGoBack() {
setUpEnvironment(environment())
setUpEnvironment(environment(), Intent())
vm.inputs.okButtonClicked()
goBack.assertValueCount(1)
}
Expand All @@ -53,8 +58,7 @@ class SurveyResponseViewModelTest : KSRobolectricTestCase() {
.tag(projectSurveyRequest)
.build()

setUpEnvironment(environment())
vm.intent(Intent().putExtra(IntentKey.SURVEY_RESPONSE, surveyResponse))
setUpEnvironment(environment(), Intent().putExtra(IntentKey.SURVEY_RESPONSE, surveyResponse))

// Survey loads. Successful submit redirects to project uri.
vm.inputs.projectSurveyUriRequest(projectSurveyRequest)
Expand Down Expand Up @@ -85,8 +89,7 @@ class SurveyResponseViewModelTest : KSRobolectricTestCase() {
.url("https://kck.str/projects/param/heyo")
.build()

setUpEnvironment(environment())
vm.intent(Intent().putExtra(IntentKey.SURVEY_RESPONSE, surveyResponse))
setUpEnvironment(environment(), Intent().putExtra(IntentKey.SURVEY_RESPONSE, surveyResponse))

// Survey loads. Successful submit redirects to project uri.
vm.inputs.projectSurveyUriRequest(projectSurveyRequest)
Expand All @@ -100,9 +103,13 @@ class SurveyResponseViewModelTest : KSRobolectricTestCase() {
fun testWebViewUrl() {
val surveyResponse = surveyResponse()

setUpEnvironment(environment())
vm.intent(Intent().putExtra(IntentKey.SURVEY_RESPONSE, surveyResponse))
setUpEnvironment(environment(), Intent().putExtra(IntentKey.SURVEY_RESPONSE, surveyResponse))

webViewUrl.assertValues(surveyResponse.urls()?.web()?.survey())
}

@After
fun clear() {
disposables.clear()
}
}

0 comments on commit 16435ed

Please sign in to comment.