mirror of
https://github.com/afollestad/nock-nock.git
synced 2025-04-20 03:25:14 +00:00
Fix StatusUpdateIntentReceiverTest
This commit is contained in:
parent
1e92644904
commit
98327c8c5b
8 changed files with 72 additions and 27 deletions
|
@ -15,11 +15,10 @@
|
|||
*/
|
||||
package com.afollestad.nocknock.broadcasts
|
||||
|
||||
import android.app.Application
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import androidx.lifecycle.Lifecycle.Event.ON_DESTROY
|
||||
import androidx.lifecycle.Lifecycle.Event.ON_PAUSE
|
||||
import androidx.lifecycle.Lifecycle.Event.ON_RESUME
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
|
@ -27,13 +26,15 @@ import androidx.lifecycle.OnLifecycleEvent
|
|||
import com.afollestad.nocknock.data.model.Site
|
||||
import com.afollestad.nocknock.engine.validation.ValidationJob.Companion.ACTION_STATUS_UPDATE
|
||||
import com.afollestad.nocknock.engine.validation.ValidationJob.Companion.KEY_UPDATE_MODEL
|
||||
import com.afollestad.nocknock.utilities.providers.IntentProvider
|
||||
|
||||
typealias SiteCallback = (Site) -> Unit
|
||||
|
||||
/** @author Aidan Follestad (@afollestad) */
|
||||
class StatusUpdateIntentReceiver(
|
||||
private val app: Application,
|
||||
private val callback: SiteCallback
|
||||
private val context: Context,
|
||||
private val intentProvider: IntentProvider,
|
||||
private var callback: SiteCallback?
|
||||
) : LifecycleObserver {
|
||||
|
||||
internal val intentReceiver = object : BroadcastReceiver() {
|
||||
|
@ -44,19 +45,24 @@ class StatusUpdateIntentReceiver(
|
|||
if (intent.action == ACTION_STATUS_UPDATE) {
|
||||
val model = intent.getSerializableExtra(KEY_UPDATE_MODEL) as? Site
|
||||
?: return
|
||||
callback(model)
|
||||
callback?.invoke(model)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(ON_RESUME)
|
||||
fun onResume() {
|
||||
val filter = IntentFilter().apply {
|
||||
addAction(ACTION_STATUS_UPDATE)
|
||||
}
|
||||
app.registerReceiver(intentReceiver, filter)
|
||||
val filter = intentProvider.createFilter(ACTION_STATUS_UPDATE)
|
||||
context.registerReceiver(intentReceiver, filter)
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(ON_PAUSE)
|
||||
fun onPause() = app.unregisterReceiver(intentReceiver)
|
||||
fun onPause() {
|
||||
context.unregisterReceiver(intentReceiver)
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(ON_DESTROY)
|
||||
fun onDestroy() {
|
||||
callback = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.afollestad.nocknock.broadcasts.StatusUpdateIntentReceiver
|
|||
import com.afollestad.nocknock.data.model.Site
|
||||
import com.afollestad.nocknock.dialogs.AboutDialog
|
||||
import com.afollestad.nocknock.notifications.NockNotificationManager
|
||||
import com.afollestad.nocknock.utilities.providers.IntentProvider
|
||||
import com.afollestad.nocknock.viewcomponents.ext.showOrHide
|
||||
import kotlinx.android.synthetic.main.activity_main.fab
|
||||
import kotlinx.android.synthetic.main.activity_main.list
|
||||
|
@ -43,12 +44,14 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
|
|||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
private val notificationManager by inject<NockNotificationManager>()
|
||||
private val intentProvider by inject<IntentProvider>()
|
||||
|
||||
internal val viewModel by viewModel<MainViewModel>()
|
||||
|
||||
private lateinit var adapter: ServerAdapter
|
||||
|
||||
private val statusUpdateReceiver =
|
||||
StatusUpdateIntentReceiver(application) {
|
||||
StatusUpdateIntentReceiver(application, intentProvider) {
|
||||
viewModel.postSiteUpdate(it)
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.afollestad.nocknock.R
|
|||
import com.afollestad.nocknock.broadcasts.StatusUpdateIntentReceiver
|
||||
import com.afollestad.nocknock.data.model.Site
|
||||
import com.afollestad.nocknock.data.model.ValidationMode
|
||||
import com.afollestad.nocknock.utilities.providers.IntentProvider
|
||||
import com.afollestad.nocknock.viewcomponents.ext.attachLiveData
|
||||
import com.afollestad.nocknock.viewcomponents.ext.dimenFloat
|
||||
import com.afollestad.nocknock.viewcomponents.ext.onScroll
|
||||
|
@ -48,6 +49,7 @@ import kotlinx.android.synthetic.main.activity_viewsite.textNextCheck
|
|||
import kotlinx.android.synthetic.main.activity_viewsite.textUrlWarning
|
||||
import kotlinx.android.synthetic.main.activity_viewsite.toolbar
|
||||
import kotlinx.android.synthetic.main.activity_viewsite.validationModeDescription
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
/** @author Aidan Follestad (@afollestad) */
|
||||
|
@ -55,8 +57,9 @@ class ViewSiteActivity : AppCompatActivity() {
|
|||
|
||||
internal val viewModel by viewModel<ViewSiteViewModel>()
|
||||
|
||||
private val intentProvider by inject<IntentProvider>()
|
||||
private val statusUpdateReceiver =
|
||||
StatusUpdateIntentReceiver(application) {
|
||||
StatusUpdateIntentReceiver(application, intentProvider) {
|
||||
viewModel.setModel(it)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
*/
|
||||
package com.afollestad.nocknock
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import com.afollestad.nocknock.data.AppDatabase
|
||||
import com.afollestad.nocknock.data.SiteDao
|
||||
import com.afollestad.nocknock.data.SiteSettingsDao
|
||||
|
@ -27,6 +29,9 @@ import com.afollestad.nocknock.data.model.Status.OK
|
|||
import com.afollestad.nocknock.data.model.ValidationMode
|
||||
import com.afollestad.nocknock.data.model.ValidationMode.STATUS_CODE
|
||||
import com.afollestad.nocknock.data.model.ValidationResult
|
||||
import com.afollestad.nocknock.utilities.providers.CanNotifyModel
|
||||
import com.afollestad.nocknock.utilities.providers.IntentProvider
|
||||
import com.nhaarman.mockitokotlin2.any
|
||||
import com.nhaarman.mockitokotlin2.doAnswer
|
||||
import com.nhaarman.mockitokotlin2.doReturn
|
||||
import com.nhaarman.mockitokotlin2.isA
|
||||
|
@ -130,3 +135,21 @@ fun mockDatabase(): AppDatabase {
|
|||
on { validationResultsDao() } doReturn resultsDao
|
||||
}
|
||||
}
|
||||
|
||||
fun mockIntentProvider() = object : IntentProvider {
|
||||
override fun createFilter(vararg actions: String): IntentFilter {
|
||||
return mock {
|
||||
on { this.getAction(any()) } doAnswer { inv ->
|
||||
val index = inv.getArgument<Int>(0)
|
||||
return@doAnswer actions[index]
|
||||
}
|
||||
on { this.actionsIterator() } doReturn actions.iterator()
|
||||
on { this.countActions() } doReturn actions.size
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPendingIntentForViewSite(model: CanNotifyModel): PendingIntent {
|
||||
// basically no-op right now
|
||||
return mock()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,11 @@ import com.afollestad.nocknock.MOCK_MODEL_2
|
|||
import com.afollestad.nocknock.engine.validation.ValidationJob.Companion.ACTION_STATUS_UPDATE
|
||||
import com.afollestad.nocknock.engine.validation.ValidationJob.Companion.KEY_UPDATE_MODEL
|
||||
import com.afollestad.nocknock.fakeIntent
|
||||
import com.afollestad.nocknock.mockIntentProvider
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.nhaarman.mockitokotlin2.argumentCaptor
|
||||
import com.nhaarman.mockitokotlin2.doReturn
|
||||
import com.nhaarman.mockitokotlin2.eq
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.times
|
||||
import com.nhaarman.mockitokotlin2.verify
|
||||
|
@ -34,9 +36,10 @@ import org.junit.Test
|
|||
class StatusUpdateIntentReceiverTest {
|
||||
|
||||
private val app = mock<Application>()
|
||||
private val intentProvider = mockIntentProvider()
|
||||
private val callback = mock<SiteCallback>()
|
||||
|
||||
private val receiver = StatusUpdateIntentReceiver(app, callback)
|
||||
private val receiver = StatusUpdateIntentReceiver(app, intentProvider, callback)
|
||||
|
||||
@Test fun onReceive() {
|
||||
val badIntent = fakeIntent("Hello World")
|
||||
|
@ -54,7 +57,7 @@ class StatusUpdateIntentReceiverTest {
|
|||
receiver.onResume()
|
||||
|
||||
val filterCaptor = argumentCaptor<IntentFilter>()
|
||||
verify(app).registerReceiver(receiver.intentReceiver, filterCaptor.capture())
|
||||
verify(app).registerReceiver(eq(receiver.intentReceiver), filterCaptor.capture())
|
||||
|
||||
val actionIterator = filterCaptor.firstValue.actionsIterator()
|
||||
assertThat(actionIterator.hasNext()).isTrue()
|
||||
|
|
|
@ -19,21 +19,24 @@ import android.app.PendingIntent
|
|||
import android.app.PendingIntent.FLAG_CANCEL_CURRENT
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import java.io.Serializable
|
||||
|
||||
/** @author Aidan Follestad (@afollestad) */
|
||||
interface CanNotifyModel : Serializable {
|
||||
|
||||
fun notiId(): Int
|
||||
fun notifyId(): Int
|
||||
|
||||
fun notiName(): String
|
||||
fun notifyName(): String
|
||||
|
||||
fun notiTag(): String
|
||||
fun notifyTag(): String
|
||||
}
|
||||
|
||||
/** @author Aidan Follestad (@afollestad) */
|
||||
interface IntentProvider {
|
||||
|
||||
fun createFilter(vararg actions: String): IntentFilter
|
||||
|
||||
fun getPendingIntentForViewSite(
|
||||
model: CanNotifyModel
|
||||
): PendingIntent
|
||||
|
@ -50,11 +53,15 @@ class RealIntentProvider(
|
|||
const val KEY_VIEW_NOTIFICATION_MODEL = "model"
|
||||
}
|
||||
|
||||
override fun createFilter(vararg actions: String) = IntentFilter().apply {
|
||||
actions.forEach { addAction(it) }
|
||||
}
|
||||
|
||||
override fun getPendingIntentForViewSite(model: CanNotifyModel): PendingIntent {
|
||||
val openIntent = getIntentForViewSite(model)
|
||||
return PendingIntent.getActivity(
|
||||
context,
|
||||
BASE_NOTIFICATION_REQUEST_CODE + model.notiId(),
|
||||
BASE_NOTIFICATION_REQUEST_CODE + model.notifyId(),
|
||||
openIntent,
|
||||
FLAG_CANCEL_CURRENT
|
||||
)
|
||||
|
|
|
@ -41,11 +41,11 @@ data class Site(
|
|||
|
||||
constructor() : this(0, "", "", null, null)
|
||||
|
||||
override fun notiId(): Int = id.toInt()
|
||||
override fun notifyId(): Int = id.toInt()
|
||||
|
||||
override fun notiName(): String = name
|
||||
override fun notifyName(): String = name
|
||||
|
||||
override fun notiTag(): String = url
|
||||
override fun notifyTag(): String = url
|
||||
|
||||
fun intervalText(): String {
|
||||
requireNotNull(settings) { "Settings not queried." }
|
||||
|
|
|
@ -66,29 +66,29 @@ class RealNockNotificationManager(
|
|||
override fun postStatusNotification(model: CanNotifyModel) {
|
||||
if (isAppOpen) {
|
||||
// Don't show notifications while the app is open
|
||||
log("App is open, status notification for site ${model.notiId()} won't be posted.")
|
||||
log("App is open, status notification for site ${model.notifyId()} won't be posted.")
|
||||
return
|
||||
}
|
||||
|
||||
log("Posting status notification for site ${model.notiId()}...")
|
||||
log("Posting status notification for site ${model.notifyId()}...")
|
||||
val intent = intentProvider.getPendingIntentForViewSite(model)
|
||||
|
||||
val newNotification = notificationProvider.create(
|
||||
channelId = CheckFailures.id,
|
||||
title = model.notiName(),
|
||||
title = model.notifyName(),
|
||||
content = stringProvider.get(R.string.something_wrong),
|
||||
intent = intent,
|
||||
smallIcon = R.drawable.ic_notification,
|
||||
largeIcon = bitmapProvider.get(appIconRes)
|
||||
)
|
||||
|
||||
stockManager.notify(model.notiTag(), model.notificationId(), newNotification)
|
||||
stockManager.notify(model.notifyTag(), model.notificationId(), newNotification)
|
||||
log("Posted status notification for site ${model.notificationId()}.")
|
||||
}
|
||||
|
||||
override fun cancelStatusNotification(model: CanNotifyModel) {
|
||||
stockManager.cancel(model.notificationId())
|
||||
log("Cancelled status notification for site ${model.notiId()}.")
|
||||
log("Cancelled status notification for site ${model.notifyId()}.")
|
||||
}
|
||||
|
||||
override fun cancelStatusNotifications() = stockManager.cancelAll()
|
||||
|
@ -105,5 +105,5 @@ class RealNockNotificationManager(
|
|||
log("Created notification channel ${channel.id}")
|
||||
}
|
||||
|
||||
private fun CanNotifyModel.notificationId() = BASE_NOTIFICATION_REQUEST_CODE + this.notiId()
|
||||
private fun CanNotifyModel.notificationId() = BASE_NOTIFICATION_REQUEST_CODE + this.notifyId()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue