Navigate to the Follow Requests page from notification (#2757)
* Navigate to the Follow Requests page from notification Fixes #2655 * Fix lock status
This commit is contained in:
parent
c52ecc24ce
commit
b39cb06748
|
@ -146,6 +146,7 @@ dependencies {
|
||||||
testImplementation libs.mockwebserver
|
testImplementation libs.mockwebserver
|
||||||
testImplementation libs.androidx.core.testing
|
testImplementation libs.androidx.core.testing
|
||||||
testImplementation libs.kotlinx.coroutines.test
|
testImplementation libs.kotlinx.coroutines.test
|
||||||
|
testImplementation libs.androidx.work.testing
|
||||||
|
|
||||||
androidTestImplementation libs.espresso.core
|
androidTestImplementation libs.espresso.core
|
||||||
androidTestImplementation libs.androidx.room.testing
|
androidTestImplementation libs.androidx.room.testing
|
||||||
|
|
|
@ -77,6 +77,7 @@ import com.keylesspalace.tusky.components.search.SearchActivity
|
||||||
import com.keylesspalace.tusky.databinding.ActivityMainBinding
|
import com.keylesspalace.tusky.databinding.ActivityMainBinding
|
||||||
import com.keylesspalace.tusky.db.AccountEntity
|
import com.keylesspalace.tusky.db.AccountEntity
|
||||||
import com.keylesspalace.tusky.entity.Account
|
import com.keylesspalace.tusky.entity.Account
|
||||||
|
import com.keylesspalace.tusky.entity.Notification
|
||||||
import com.keylesspalace.tusky.interfaces.AccountSelectionListener
|
import com.keylesspalace.tusky.interfaces.AccountSelectionListener
|
||||||
import com.keylesspalace.tusky.interfaces.ActionButtonActivity
|
import com.keylesspalace.tusky.interfaces.ActionButtonActivity
|
||||||
import com.keylesspalace.tusky.interfaces.ReselectableFragment
|
import com.keylesspalace.tusky.interfaces.ReselectableFragment
|
||||||
|
@ -211,8 +212,14 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||||
val intent = DraftsActivity.newIntent(this)
|
val intent = DraftsActivity.newIntent(this)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
} else if (accountRequested && savedInstanceState == null) {
|
} else if (accountRequested && savedInstanceState == null) {
|
||||||
// user clicked a notification, show notification tab
|
// user clicked a notification, show follow requests for type FOLLOW_REQUEST,
|
||||||
showNotificationTab = true
|
// otherwise show notification tab
|
||||||
|
if (intent.getStringExtra(NotificationHelper.TYPE) == Notification.Type.FOLLOW_REQUEST.name) {
|
||||||
|
val intent = AccountListActivity.newIntent(this, AccountListActivity.Type.FOLLOW_REQUESTS, accountLocked = true)
|
||||||
|
startActivityWithSlideInAnimation(intent)
|
||||||
|
} else {
|
||||||
|
showNotificationTab = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.statusBarColor = Color.TRANSPARENT // don't draw a status bar, the DrawerLayout and the MaterialDrawerLayout have their own
|
window.statusBarColor = Color.TRANSPARENT // don't draw a status bar, the DrawerLayout and the MaterialDrawerLayout have their own
|
||||||
|
|
|
@ -84,6 +84,8 @@ public class NotificationHelper {
|
||||||
*/
|
*/
|
||||||
public static final String ACCOUNT_ID = "account_id";
|
public static final String ACCOUNT_ID = "account_id";
|
||||||
|
|
||||||
|
public static final String TYPE = "type";
|
||||||
|
|
||||||
private static final String TAG = "NotificationHelper";
|
private static final String TAG = "NotificationHelper";
|
||||||
|
|
||||||
public static final String REPLY_ACTION = "REPLY_ACTION";
|
public static final String REPLY_ACTION = "REPLY_ACTION";
|
||||||
|
@ -268,6 +270,7 @@ public class NotificationHelper {
|
||||||
private static NotificationCompat.Builder newNotification(Context context, Notification body, AccountEntity account, boolean summary) {
|
private static NotificationCompat.Builder newNotification(Context context, Notification body, AccountEntity account, boolean summary) {
|
||||||
Intent summaryResultIntent = new Intent(context, MainActivity.class);
|
Intent summaryResultIntent = new Intent(context, MainActivity.class);
|
||||||
summaryResultIntent.putExtra(ACCOUNT_ID, account.getId());
|
summaryResultIntent.putExtra(ACCOUNT_ID, account.getId());
|
||||||
|
summaryResultIntent.putExtra(TYPE, body.getType().name());
|
||||||
TaskStackBuilder summaryStackBuilder = TaskStackBuilder.create(context);
|
TaskStackBuilder summaryStackBuilder = TaskStackBuilder.create(context);
|
||||||
summaryStackBuilder.addParentStack(MainActivity.class);
|
summaryStackBuilder.addParentStack(MainActivity.class);
|
||||||
summaryStackBuilder.addNextIntent(summaryResultIntent);
|
summaryStackBuilder.addNextIntent(summaryResultIntent);
|
||||||
|
@ -278,6 +281,7 @@ public class NotificationHelper {
|
||||||
// we have to switch account here
|
// we have to switch account here
|
||||||
Intent eventResultIntent = new Intent(context, MainActivity.class);
|
Intent eventResultIntent = new Intent(context, MainActivity.class);
|
||||||
eventResultIntent.putExtra(ACCOUNT_ID, account.getId());
|
eventResultIntent.putExtra(ACCOUNT_ID, account.getId());
|
||||||
|
eventResultIntent.putExtra(TYPE, body.getType().name());
|
||||||
TaskStackBuilder eventStackBuilder = TaskStackBuilder.create(context);
|
TaskStackBuilder eventStackBuilder = TaskStackBuilder.create(context);
|
||||||
eventStackBuilder.addParentStack(MainActivity.class);
|
eventStackBuilder.addParentStack(MainActivity.class);
|
||||||
eventStackBuilder.addNextIntent(eventResultIntent);
|
eventStackBuilder.addNextIntent(eventResultIntent);
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
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.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 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
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
@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)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `clicking notification of type FOLLOW shows notification tab`() {
|
||||||
|
val intent = showNotification(Notification.Type.FOLLOW)
|
||||||
|
|
||||||
|
val activity = startMainActivity(intent)
|
||||||
|
val currentTab = activity.findViewById<ViewPager2>(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 {
|
||||||
|
NotificationHelper.make(
|
||||||
|
context,
|
||||||
|
Notification(
|
||||||
|
type = type,
|
||||||
|
id = "id",
|
||||||
|
account = TimelineAccount(
|
||||||
|
id = "1",
|
||||||
|
localUsername = "connyduck",
|
||||||
|
username = "connyduck@mastodon.example",
|
||||||
|
displayName = "Conny Duck",
|
||||||
|
url = "https://mastodon.example/@ConnyDuck",
|
||||||
|
avatar = "https://mastodon.example/system/accounts/avatars/000/150/486/original/ab27d7ddd18a10ea.jpg"
|
||||||
|
),
|
||||||
|
status = null
|
||||||
|
),
|
||||||
|
accountEntity,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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.mastodonApi = mock {
|
||||||
|
onBlocking { accountVerifyCredentials() } doReturn NetworkResult.success(account)
|
||||||
|
onBlocking { listAnnouncements(false) } doReturn NetworkResult.success(emptyList())
|
||||||
|
}
|
||||||
|
controller.create().start()
|
||||||
|
return activity
|
||||||
|
}
|
||||||
|
}
|
|
@ -82,6 +82,7 @@ androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefre
|
||||||
androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-junit" }
|
androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-junit" }
|
||||||
androidx-viewpager2 = { module = "androidx.viewpager2:viewpager2", version.ref = "androidx-viewpager2" }
|
androidx-viewpager2 = { module = "androidx.viewpager2:viewpager2", version.ref = "androidx-viewpager2" }
|
||||||
androidx-work-runtime = { module = "androidx.work:work-runtime", version.ref = "androidx-work" }
|
androidx-work-runtime = { module = "androidx.work:work-runtime", version.ref = "androidx-work" }
|
||||||
|
androidx-work-testing = { module = "androidx.work:work-testing", version.ref = "androidx-work" }
|
||||||
autodispose-android-lifecycle = { module = "com.uber.autodispose2:autodispose-androidx-lifecycle", version.ref = "autodispose" }
|
autodispose-android-lifecycle = { module = "com.uber.autodispose2:autodispose-androidx-lifecycle", version.ref = "autodispose" }
|
||||||
autodispose-core = { module = "com.uber.autodispose2:autodispose", version.ref = "autodispose" }
|
autodispose-core = { module = "com.uber.autodispose2:autodispose", version.ref = "autodispose" }
|
||||||
bouncycastle = { module = "org.bouncycastle:bcprov-jdk15on", version.ref = "bouncycastle" }
|
bouncycastle = { module = "org.bouncycastle:bcprov-jdk15on", version.ref = "bouncycastle" }
|
||||||
|
|
Loading…
Reference in New Issue