package com.keylesspalace.tusky import android.app.Activity import android.app.NotificationManager import android.content.ComponentName import android.content.Intent import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import androidx.viewpager2.widget.ViewPager2 import androidx.work.testing.WorkManagerTestInitHelper import at.connyduck.calladapter.networkresult.NetworkResult import com.keylesspalace.tusky.appstore.EventHub import com.keylesspalace.tusky.components.accountlist.AccountListActivity import com.keylesspalace.tusky.components.notifications.NotificationHelper import com.keylesspalace.tusky.db.AccountEntity import com.keylesspalace.tusky.entity.Account import com.keylesspalace.tusky.entity.Notification import com.keylesspalace.tusky.entity.TimelineAccount import java.util.Date import kotlinx.coroutines.test.TestScope import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.robolectric.Robolectric import org.robolectric.Shadows.shadowOf import org.robolectric.android.util.concurrent.BackgroundExecutor.runInBackground import org.robolectric.annotation.Config @Config(sdk = [28]) @RunWith(AndroidJUnit4::class) class MainActivityTest { private val context = InstrumentationRegistry.getInstrumentation().targetContext private val account = Account( id = "1", localUsername = "", username = "", displayName = "", createdAt = Date(), note = "", url = "", avatar = "", header = "" ) private val accountEntity = AccountEntity( id = 1, domain = "test.domain", accessToken = "fakeToken", clientId = "fakeId", clientSecret = "fakeSecret", isActive = true ) @Before fun setup() { WorkManagerTestInitHelper.initializeTestWorkManager(context) } @After fun teardown() { WorkManagerTestInitHelper.closeWorkDatabase() } @Test fun `clicking notification of type FOLLOW shows notification tab`() { val intent = showNotification(Notification.Type.FOLLOW) val activity = startMainActivity(intent) val currentTab = activity.findViewById(R.id.viewPager).currentItem val notificationTab = defaultTabs().indexOfFirst { it.id == NOTIFICATIONS } assertEquals(currentTab, notificationTab) } @Test fun `clicking notification of type FOLLOW_REQUEST shows follow requests`() { val intent = showNotification(Notification.Type.FOLLOW_REQUEST) val activity = startMainActivity(intent) val nextActivity = shadowOf(activity).peekNextStartedActivity() assertNotNull(nextActivity) assertEquals(ComponentName(context, AccountListActivity::class.java.name), nextActivity.component) assertEquals(AccountListActivity.Type.FOLLOW_REQUESTS, nextActivity.getSerializableExtra("type")) } private fun showNotification(type: Notification.Type): Intent { val notificationManager = context.getSystemService(NotificationManager::class.java) val shadowNotificationManager = shadowOf(notificationManager) NotificationHelper.createNotificationChannelsForAccount(accountEntity, context) runInBackground { val notification = NotificationHelper.make( context, notificationManager, Notification( type = type, id = "id", account = TimelineAccount( id = "1", localUsername = "connyduck", username = "connyduck@mastodon.example", displayName = "Conny Duck", note = "This is their bio", url = "https://mastodon.example/@ConnyDuck", avatar = "https://mastodon.example/system/accounts/avatars/000/150/486/original/ab27d7ddd18a10ea.jpg" ), status = null, report = null ), accountEntity, true ) notificationManager.notify("id", 1, notification) } val notification = shadowNotificationManager.allNotifications.first() return shadowOf(notification.contentIntent).savedIntent } private fun startMainActivity(intent: Intent): Activity { val controller = Robolectric.buildActivity(MainActivity::class.java, intent) val activity = controller.get() activity.eventHub = EventHub() activity.accountManager = mock { on { activeAccount } doReturn accountEntity } activity.draftsAlert = mock {} activity.shareShortcutHelper = mock {} activity.externalScope = TestScope() activity.mastodonApi = mock { onBlocking { accountVerifyCredentials() } doReturn NetworkResult.success(account) onBlocking { listAnnouncements(false) } doReturn NetworkResult.success(emptyList()) } controller.create().start() return activity } }