Commit 4b2b7573 authored by Christian Sadilek's avatar Christian Sadilek
Browse files

Issue #2364: Make sure suggestions are removed before new ones are added

parent 4647628b
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ class BrowserAwesomeBar @JvmOverloads constructor(
    defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr), AwesomeBar {
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    internal val jobDispatcher = Executors.newFixedThreadPool(PROVIDER_QUERY_THREADS).asCoroutineDispatcher()
    internal var jobDispatcher = Executors.newFixedThreadPool(PROVIDER_QUERY_THREADS).asCoroutineDispatcher()
    private val providers: MutableList<AwesomeBar.SuggestionProvider> = mutableListOf()
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    internal val uniqueSuggestionIds = LruCache<String, Long>(INITIAL_NUMBER_OF_PROVIDERS * PROVIDER_MAX_SUGGESTIONS)
@@ -137,6 +137,8 @@ class BrowserAwesomeBar @JvmOverloads constructor(
        job?.cancel()

        job = scope.launch {
            suggestionsAdapter.optionallyClearSuggestions()

            providers.forEach { provider ->
                launch {
                    val suggestions = withContext(jobDispatcher) { provider.block() }
@@ -148,8 +150,6 @@ class BrowserAwesomeBar @JvmOverloads constructor(
                }
            }
        }

        suggestionsAdapter.optionallyClearSuggestions()
    }

    internal fun processProviderSuggestions(suggestions: List<AwesomeBar.Suggestion>): List<AwesomeBar.Suggestion> {
+40 −0
Original line number Diff line number Diff line
@@ -4,7 +4,10 @@

package mozilla.components.browser.awesomebar

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExecutorCoroutineDispatcher
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import mozilla.components.browser.awesomebar.transform.SuggestionTransformer
@@ -27,6 +30,8 @@ import org.mockito.Mockito.verify
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
import java.util.UUID
import org.mockito.Mockito.inOrder
import java.util.concurrent.Executor

@ExperimentalCoroutinesApi
@RunWith(RobolectricTestRunner::class)
@@ -420,6 +425,41 @@ class BrowserAwesomeBarTest {
        awesomeBar.addProviders(provider2, provider3)
    }

    @Test
    fun `clears suggestions before new ones are produced`() {
        val provider = mockProvider()

        var mainRunnable: Runnable? = null
        val fakeMainDispatcher = Executor {
            if (mainRunnable == null) {
                mainRunnable = it
            } else {
                it.run()
            }
        }.asCoroutineDispatcher()

        val fakeJobDispatcher = Executor {
            it.run()
        }.asCoroutineDispatcher() as ExecutorCoroutineDispatcher

        val adapter: SuggestionsAdapter = mock()
        val awesomeBar = BrowserAwesomeBar(testContext)
        awesomeBar.scope = CoroutineScope(fakeMainDispatcher)
        awesomeBar.jobDispatcher = fakeJobDispatcher
        awesomeBar.suggestionsAdapter = adapter
        awesomeBar.addProviders(provider)

        runBlocking {
            val inOrder = inOrder(adapter, provider)
            awesomeBar.onInputChanged("Hello!")
            verify(adapter, never()).optionallyClearSuggestions()
            mainRunnable?.run()

            inOrder.verify(adapter).optionallyClearSuggestions()
            inOrder.verify(provider).onInputChanged("Hello!")
        }
    }

    private fun mockProvider(): AwesomeBar.SuggestionProvider = spy(object : AwesomeBar.SuggestionProvider {
        override val id: String = UUID.randomUUID().toString()