Skip to content

Commit

Permalink
More fragment store tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Laimiux committed Sep 17, 2024
1 parent fcfb123 commit f4e4e33
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,8 @@ internal class FragmentStoreFormula<in Component>(
feature = feature,
)
action.onEvent {
if (state.activeIds.contains(fragmentId)) {
val keyState = FragmentOutput(fragmentId.key, it)
transition(state.copy(outputs = state.outputs.plus(fragmentId to keyState)))
} else {
none()
}
val keyState = FragmentOutput(fragmentId.key, it)
transition(state.copy(outputs = state.outputs.plus(fragmentId to keyState)))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.instacart.formula.android.fakes.FakeComponent
import com.instacart.formula.android.fakes.MainKey
import com.instacart.formula.android.events.FragmentLifecycleEvent
import com.instacart.formula.android.fakes.NoOpViewFactory
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.observers.TestObserver
import io.reactivex.rxjava3.subjects.PublishSubject
import org.junit.Test
Expand Down Expand Up @@ -204,6 +205,45 @@ class FragmentStoreTest {
)
}

@Test fun `fragment store ignores events after key is removed`() {
val stateSubject = PublishSubject.create<Any>()

val store = FragmentStore.init {
val featureFactory = object : FeatureFactory<Any, MainKey> {
override fun initialize(dependencies: Any, key: MainKey): Feature {
return Feature(
state = stateSubject,
viewFactory = NoOpViewFactory(),
)
}
}
bind(featureFactory)
}

val observer = store.state(FragmentEnvironment()).test()
val fragmentId = FragmentId("", MainKey(1))
store.onLifecycleEffect(
FragmentLifecycleEvent.Added(fragmentId = fragmentId)
)
stateSubject.onNext("value")

// Check that first event was shown
val firstModel = observer.values().last().outputs[fragmentId]?.renderModel
assertThat(firstModel).isEqualTo("value")

// Remove fragment
store.onLifecycleEffect(
FragmentLifecycleEvent.Removed(fragmentId = fragmentId)
)

// Check that new events are ignored
stateSubject.onNext("new-value")

// Output should not exist
val secondModel = observer.values().last().outputs[fragmentId]
assertThat(secondModel).isNull()
}

@Test fun `feature observable error emits on screen error and finishes`() {
val stateSubject = PublishSubject.create<Any>()

Expand Down Expand Up @@ -251,6 +291,44 @@ class FragmentStoreTest {
)
}

@Test fun `fragment store visible output`() {
val store = FragmentStore.init {
val featureFactory = object : FeatureFactory<Any, MainKey> {
override fun initialize(dependencies: Any, key: MainKey): Feature {
return Feature(
state = Observable.just("value"),
viewFactory = NoOpViewFactory(),
)
}
}
bind(featureFactory)
}

val observer = store.state(FragmentEnvironment()).test()
val fragmentId = FragmentId("", MainKey(1))
store.onLifecycleEffect(
FragmentLifecycleEvent.Added(fragmentId = fragmentId)
)

// No visible output yet
val firstModel = observer.values().last().visibleOutput()
assertThat(firstModel).isNull()

// Toggle visibility
store.onVisibilityChanged(fragmentId, true)

// Check that visible output is now present
val secondModel = observer.values().last().visibleOutput()
assertThat(secondModel).isNotNull()

// Toggle visibility again
store.onVisibilityChanged(fragmentId, false)

// Check that visible output is null again
val third = observer.values().last().visibleOutput()
assertThat(third).isNull()
}

private fun FragmentStore.toStates(): TestObserver<Map<FragmentKey, FragmentOutput>> {
return state(FragmentEnvironment())
.map { it.outputs.mapKeys { entry -> entry.key.key } }
Expand Down

0 comments on commit f4e4e33

Please sign in to comment.