Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Issue #2985: Support loading reader view ext. page in new session #6906

Merged
merged 1 commit into from
May 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.mapNotNull
import mozilla.components.browser.state.action.ReaderAction
import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.state.store.BrowserStore
Expand Down Expand Up @@ -120,7 +119,7 @@ class ReaderViewFeature(
connectReaderViewContentScript(tab)
}
if (tab.readerState.checkRequired) {
checkReaderable(tab)
checkReaderState(tab)
}

if (tab.id == store.state.selectedTabId) {
Expand Down Expand Up @@ -196,10 +195,10 @@ class ReaderViewFeature(
}

@VisibleForTesting
internal fun checkReaderable(session: TabSessionState? = store.state.selectedTab) {
internal fun checkReaderState(session: TabSessionState? = store.state.selectedTab) {
session?.engineState?.engineSession?.let { engineSession ->
if (extensionController.portConnected(engineSession)) {
extensionController.sendContentMessage(createCheckReaderableMessage(), engineSession)
extensionController.sendContentMessage(createCheckReaderStateMessage(), engineSession)
}
store.dispatch(ReaderAction.UpdateReaderableCheckRequiredAction(session.id, false))
}
Expand Down Expand Up @@ -250,12 +249,7 @@ class ReaderViewFeature(
private val config: WeakReference<Config>
) : MessageHandler {
override fun onPortConnected(port: Port) {
val config = config.get() ?: return

port.postMessage(createCheckReaderableMessage())
if (store.state.findTab(sessionId)?.readerState?.active == true) {
port.postMessage(createShowReaderMessage(config))
}
port.postMessage(createCheckReaderStateMessage())
}

override fun onPortMessage(message: Any, port: Port) {
Expand All @@ -267,6 +261,9 @@ class ReaderViewFeature(
store.dispatch(ReaderAction.UpdateReaderableAction(sessionId, readerable))

if (message.has(ACTIVE_URL_RESPONSE_MESSAGE_KEY)) {
config.get()?.let { config ->
port.postMessage(createShowReaderMessage(config))
}
val activeUrl = message.getString(ACTIVE_URL_RESPONSE_MESSAGE_KEY)
store.dispatch(ReaderAction.UpdateReaderActiveUrlAction(sessionId, activeUrl))
}
Expand Down Expand Up @@ -304,7 +301,7 @@ class ReaderViewFeature(
internal const val FONT_SIZE_KEY = "mozac-readerview-fontsize"
internal const val FONT_SIZE_DEFAULT = 3

private fun createCheckReaderableMessage(): JSONObject {
private fun createCheckReaderStateMessage(): JSONObject {
return JSONObject().put(ACTION_MESSAGE_KEY, ACTION_CHECK_READER_STATE)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class ReaderViewFeatureTest {

testDispatcher.advanceUntilIdle()
val tabCaptor = argumentCaptor<TabSessionState>()
verify(readerViewFeature).checkReaderable(tabCaptor.capture())
verify(readerViewFeature).checkReaderState(tabCaptor.capture())
assertEquals(tab.id, tabCaptor.value.id)
}

Expand Down Expand Up @@ -337,12 +337,12 @@ class ReaderViewFeatureTest {
}

@Test
fun `readerable check sends message to web extension`() {
fun `reader state check sends message to web extension`() {
val port = mock<Port>()
val message = argumentCaptor<JSONObject>()
val readerViewFeature = prepareFeatureForTest(port)

readerViewFeature.checkReaderable()
readerViewFeature.checkReaderState()
verify(port, times(1)).postMessage(message.capture())
assertEquals(ReaderViewFeature.ACTION_CHECK_READER_STATE, message.value[ReaderViewFeature.ACTION_MESSAGE_KEY])
}
Expand Down Expand Up @@ -437,37 +437,49 @@ class ReaderViewFeatureTest {
}

@Test
fun `reader mode is activated when port connects`() {
fun `state is updated when reader state arrives`() {
val engine: Engine = mock()
val view: ReaderViewControlsView = mock()
val engineSession: EngineSession = mock()
val ext: WebExtension = mock()
val controller: WebExtensionController = mock()

val tab = createTab("https://www.mozilla.org", id = "test-tab")
val store = BrowserStore(BrowserState(tabs = listOf(tab)))
val store = spy(BrowserStore(initialState = BrowserState(tabs = listOf(tab))))
store.dispatch(EngineAction.LinkEngineSessionAction(tab.id, engineSession)).joinBlocking()
store.dispatch(TabListAction.SelectTabAction(tab.id)).joinBlocking()
store.dispatch(ReaderAction.UpdateReaderActiveAction(tab.id, true)).joinBlocking()

val ext: WebExtension = mock()
val messageHandler = argumentCaptor<MessageHandler>()
val message = argumentCaptor<JSONObject>()

WebExtensionController.installedExtensions[ReaderViewFeature.READER_VIEW_EXTENSION_ID] = ext

val readerViewFeature = spy(ReaderViewFeature(testContext, engine, store, mock()))
readerViewFeature.start()
verify(ext).registerContentMessageHandler(eq(engineSession), eq(ReaderViewFeature.READER_VIEW_EXTENSION_ID), messageHandler.capture())

val port: Port = mock()
whenever(port.engineSession).thenReturn(engineSession)
whenever(ext.getConnectedPort(any(), any())).thenReturn(port)

whenever(controller.portConnected(any(), any())).thenReturn(true)
val readerViewFeature = spy(ReaderViewFeature(testContext, engine, store, view))
readerViewFeature.extensionController = controller

val messageHandler = argumentCaptor<MessageHandler>()
val message = argumentCaptor<JSONObject>()
readerViewFeature.start()
verify(controller).registerContentMessageHandler(eq(engineSession), messageHandler.capture(), any())

messageHandler.value.onPortConnected(port)
verify(port, times(2)).postMessage(message.capture())
assertEquals(ReaderViewFeature.ACTION_CHECK_READER_STATE, message.allValues[0][ReaderViewFeature.ACTION_MESSAGE_KEY])
assertEquals(ReaderViewFeature.ACTION_SHOW, message.allValues[1][ReaderViewFeature.ACTION_MESSAGE_KEY])
verify(port).postMessage(message.capture())
assertEquals(ReaderViewFeature.ACTION_CHECK_READER_STATE, message.value[ReaderViewFeature.ACTION_MESSAGE_KEY])

val readerStateMessage = JSONObject()
.put("readerable", true)
.put("baseUrl", "moz-extension://")
.put("activeUrl", "http://mozilla.org/article")
messageHandler.value.onPortMessage(readerStateMessage, port)
verify(store).dispatch(ReaderAction.UpdateReaderableAction(tab.id, true))
verify(store).dispatch(ReaderAction.UpdateReaderBaseUrlAction(tab.id, "moz-extension://"))
verify(store).dispatch(ReaderAction.UpdateReaderActiveUrlAction(tab.id, "http://mozilla.org/article"))
}

@Test
fun `state is updated when reader state arrives`() {
fun `reader is shown when state arrives from reader page`() {
val engine: Engine = mock()
val view: ReaderViewControlsView = mock()
val engineSession: EngineSession = mock()
Expand Down Expand Up @@ -495,17 +507,15 @@ class ReaderViewFeatureTest {
verify(controller).registerContentMessageHandler(eq(engineSession), messageHandler.capture(), any())

messageHandler.value.onPortConnected(port)
verify(port).postMessage(message.capture())
assertEquals(ReaderViewFeature.ACTION_CHECK_READER_STATE, message.value[ReaderViewFeature.ACTION_MESSAGE_KEY])

val readerableMessage = JSONObject()
val readerStateMessage = JSONObject()
.put("readerable", true)
.put("baseUrl", "moz-extension://")
.put("activeUrl", "http://mozilla.org/article")
messageHandler.value.onPortMessage(readerableMessage, port)
verify(store).dispatch(ReaderAction.UpdateReaderableAction(tab.id, true))
verify(store).dispatch(ReaderAction.UpdateReaderBaseUrlAction(tab.id, "moz-extension://"))
verify(store).dispatch(ReaderAction.UpdateReaderActiveUrlAction(tab.id, "http://mozilla.org/article"))
messageHandler.value.onPortMessage(readerStateMessage, port)
verify(port, times(2)).postMessage(message.capture())
assertEquals(ReaderViewFeature.ACTION_CHECK_READER_STATE, message.allValues[0][ReaderViewFeature.ACTION_MESSAGE_KEY])
assertEquals(ReaderViewFeature.ACTION_SHOW, message.allValues[1][ReaderViewFeature.ACTION_MESSAGE_KEY])
}

private fun prepareFeatureForTest(
Expand Down