NotificationsViewModelTestBase.kt 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Copyright 2023 Tusky Contributors
  3. *
  4. * This file is a part of Tusky.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it under the terms of the
  7. * GNU General Public License as published by the Free Software Foundation; either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
  11. * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  12. * Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with Tusky; if not,
  15. * see <http://www.gnu.org/licenses>.
  16. */
  17. package com.keylesspalace.tusky.components.notifications
  18. import android.content.SharedPreferences
  19. import android.os.Looper
  20. import androidx.test.ext.junit.runners.AndroidJUnit4
  21. import com.keylesspalace.tusky.appstore.EventHub
  22. import com.keylesspalace.tusky.db.AccountEntity
  23. import com.keylesspalace.tusky.db.AccountManager
  24. import com.keylesspalace.tusky.settings.PrefKeys
  25. import com.keylesspalace.tusky.usecase.TimelineCases
  26. import kotlinx.coroutines.Dispatchers
  27. import kotlinx.coroutines.ExperimentalCoroutinesApi
  28. import kotlinx.coroutines.test.TestDispatcher
  29. import kotlinx.coroutines.test.UnconfinedTestDispatcher
  30. import kotlinx.coroutines.test.resetMain
  31. import kotlinx.coroutines.test.setMain
  32. import okhttp3.ResponseBody
  33. import okhttp3.ResponseBody.Companion.toResponseBody
  34. import org.junit.Before
  35. import org.junit.Rule
  36. import org.junit.rules.TestWatcher
  37. import org.junit.runner.Description
  38. import org.junit.runner.RunWith
  39. import org.mockito.kotlin.any
  40. import org.mockito.kotlin.doAnswer
  41. import org.mockito.kotlin.doReturn
  42. import org.mockito.kotlin.mock
  43. import org.robolectric.Shadows.shadowOf
  44. import org.robolectric.annotation.Config
  45. import retrofit2.HttpException
  46. import retrofit2.Response
  47. @OptIn(ExperimentalCoroutinesApi::class)
  48. class MainCoroutineRule constructor(private val dispatcher: TestDispatcher = UnconfinedTestDispatcher()) : TestWatcher() {
  49. override fun starting(description: Description) {
  50. super.starting(description)
  51. Dispatchers.setMain(dispatcher)
  52. }
  53. override fun finished(description: Description) {
  54. super.finished(description)
  55. Dispatchers.resetMain()
  56. }
  57. }
  58. @Config(sdk = [28])
  59. @RunWith(AndroidJUnit4::class)
  60. @OptIn(ExperimentalCoroutinesApi::class)
  61. abstract class NotificationsViewModelTestBase {
  62. protected lateinit var notificationsRepository: NotificationsRepository
  63. protected lateinit var sharedPreferencesMap: MutableMap<String, Boolean>
  64. protected lateinit var sharedPreferences: SharedPreferences
  65. protected lateinit var accountManager: AccountManager
  66. protected lateinit var timelineCases: TimelineCases
  67. protected lateinit var eventHub: EventHub
  68. protected lateinit var viewModel: NotificationsViewModel
  69. /** Empty success response, for API calls that return one */
  70. protected var emptySuccess = Response.success("".toResponseBody())
  71. /** Empty error response, for API calls that return one */
  72. protected var emptyError: Response<ResponseBody> = Response.error(404, "".toResponseBody())
  73. /** Exception to throw when testing errors */
  74. protected val httpException = HttpException(emptyError)
  75. @get:Rule
  76. val mainCoroutineRule = MainCoroutineRule()
  77. @Before
  78. fun setup() {
  79. shadowOf(Looper.getMainLooper()).idle()
  80. notificationsRepository = mock()
  81. // Backing store for sharedPreferences, to allow mutation in tests
  82. sharedPreferencesMap = mutableMapOf(
  83. PrefKeys.ANIMATE_GIF_AVATARS to false,
  84. PrefKeys.ANIMATE_CUSTOM_EMOJIS to false,
  85. PrefKeys.ABSOLUTE_TIME_VIEW to false,
  86. PrefKeys.SHOW_BOT_OVERLAY to true,
  87. PrefKeys.USE_BLURHASH to true,
  88. PrefKeys.CONFIRM_REBLOGS to true,
  89. PrefKeys.CONFIRM_FAVOURITES to false,
  90. PrefKeys.WELLBEING_HIDE_STATS_POSTS to false,
  91. PrefKeys.SHOW_NOTIFICATIONS_FILTER to true,
  92. PrefKeys.FAB_HIDE to false
  93. )
  94. // Any getBoolean() call looks for the result in sharedPreferencesMap
  95. sharedPreferences = mock {
  96. on { getBoolean(any(), any()) } doAnswer { sharedPreferencesMap[it.arguments[0]] }
  97. }
  98. accountManager = mock {
  99. on { activeAccount } doReturn AccountEntity(
  100. id = 1,
  101. domain = "mastodon.test",
  102. accessToken = "fakeToken",
  103. clientId = "fakeId",
  104. clientSecret = "fakeSecret",
  105. isActive = true,
  106. notificationsFilter = "['follow']",
  107. mediaPreviewEnabled = true,
  108. alwaysShowSensitiveMedia = true,
  109. alwaysOpenSpoiler = true
  110. )
  111. }
  112. eventHub = EventHub()
  113. timelineCases = mock()
  114. viewModel = NotificationsViewModel(
  115. notificationsRepository,
  116. sharedPreferences,
  117. accountManager,
  118. timelineCases,
  119. eventHub
  120. )
  121. }
  122. }