Upload via GUI (8346 Dateien)

This commit is contained in:
2026-10-21 16:54:40 +00:00
parent bb8ffee10d
commit 7fb620e7ca
5 changed files with 348 additions and 201 deletions
@@ -0,0 +1,125 @@
package de.deskhub.staff.push
import android.app.Application
import android.app.NotificationManager
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
import org.robolectric.annotation.Config
/** Benachrichtigungen der Push-Nachrichten (auf der JVM mit Robolectric). */
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [34])
class DeskHubPushTest {
private val context: Application get() = ApplicationProvider.getApplicationContext()
private fun grantPermission() = shadowOf(context).grantPermissions(android.Manifest.permission.POST_NOTIFICATIONS)
private fun manager() = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
@Test
fun createsHighImportanceChannel() {
DeskHubPush.ensureChannel(context)
val channel = manager().getNotificationChannel(DeskHubPush.CHANNEL_TICKETS)
assertNotNull(channel)
assertEquals(NotificationManager.IMPORTANCE_HIGH, channel.importance)
}
@Test
fun showsNotificationWithTitleTextAndOpensTicket() {
grantPermission()
val shown = DeskHubPush.show(context, mapOf("type" to "ticket_new", "ticket" to "T-123", "title" to "Neues Ticket", "body" to "#T-123"))
assertTrue(shown)
val posted = shadowOf(manager()).allNotifications
assertEquals(1, posted.size)
val n = posted[0]
assertEquals("Neues Ticket", n.extras.getCharSequence("android.title").toString())
assertEquals("#T-123", n.extras.getCharSequence("android.text").toString())
// Tipp öffnet die App mit der Ticketnummer
val intent = shadowOf(n.contentIntent).savedIntent
assertEquals("T-123", intent.getStringExtra(DeskHubPush.EXTRA_TICKET))
}
@Test
fun sameTicketReplacesEarlierNotification() {
grantPermission()
val data = mapOf("type" to "ticket_reply", "ticket" to "T-7", "title" to "Neue Antwort", "body" to "#T-7")
DeskHubPush.show(context, data)
DeskHubPush.show(context, data)
assertEquals(1, shadowOf(manager()).allNotifications.size)
DeskHubPush.show(context, data + ("ticket" to "T-8"))
assertEquals(2, shadowOf(manager()).allNotifications.size)
}
@Test
fun ignoresUnknownOrEmptyMessages() {
grantPermission()
assertFalse(DeskHubPush.show(context, mapOf("type" to "irgendwas", "title" to "x")))
assertFalse(DeskHubPush.show(context, mapOf("type" to "ticket_new", "title" to " ")))
assertFalse(DeskHubPush.show(context, emptyMap()))
assertEquals(0, shadowOf(manager()).allNotifications.size)
}
@Test
fun showsNothingWithoutPermission() {
shadowOf(context).denyPermissions(android.Manifest.permission.POST_NOTIFICATIONS)
assertFalse(DeskHubPush.canNotify(context))
assertFalse(DeskHubPush.show(context, mapOf("type" to "ticket_new", "ticket" to "T-1", "title" to "Neues Ticket")))
assertEquals(0, shadowOf(manager()).allNotifications.size)
}
@Test
fun customerReplyHasQuickReplyActionOthersDoNot() {
grantPermission()
DeskHubPush.show(context, mapOf("type" to "ticket_reply", "ticket" to "T-5", "title" to "Neue Antwort", "body" to "#T-5"))
DeskHubPush.show(context, mapOf("type" to "ticket_new", "ticket" to "T-6", "title" to "Neues Ticket", "body" to "#T-6"))
val all = shadowOf(manager()).allNotifications
val reply = all.first { it.extras.getCharSequence("android.text").toString() == "#T-5" }
val other = all.first { it.extras.getCharSequence("android.text").toString() == "#T-6" }
assertEquals(1, reply.actions.size)
assertEquals("Antworten", reply.actions[0].title.toString())
assertNotNull(reply.actions[0].remoteInputs)
assertEquals(PushReplyReceiver.KEY_REPLY, reply.actions[0].remoteInputs[0].resultKey)
assertTrue(other.actions == null || other.actions.isEmpty())
}
@Test
fun newEventTypesAreShown() {
grantPermission()
assertTrue(DeskHubPush.show(context, mapOf("type" to "ticket_sla", "ticket" to "T-9", "title" to "SLA überschritten", "body" to "#T-9")))
assertTrue(DeskHubPush.show(context, mapOf("type" to "ticket_mention", "ticket" to "T-9", "title" to "Erwähnung", "body" to "#T-9")))
assertEquals(2, shadowOf(manager()).allNotifications.size)
}
@Test
fun brandNameShowsNextToAppName() {
grantPermission()
DeskHubPush.show(context, mapOf("type" to "ticket_new", "ticket" to "T-20", "title" to "Neues Ticket", "body" to "#T-20", "brand" to "Windel Support"))
DeskHubPush.show(context, mapOf("type" to "ticket_new", "ticket" to "T-21", "title" to "Neues Ticket", "body" to "#T-21"))
val all = shadowOf(manager()).allNotifications
val withBrand = all.first { it.extras.getCharSequence("android.text").toString() == "#T-20" }
val without = all.first { it.extras.getCharSequence("android.text").toString() == "#T-21" }
assertEquals("Windel Support", withBrand.extras.getCharSequence("android.subText").toString())
assertTrue(without.extras.getCharSequence("android.subText") == null)
}
@Test
fun quickReplyTextIsEscapedForHtml() {
assertEquals("a &lt;b&gt; &amp; c<br>d", PushReplyReceiver.toHtml("a <b> & c\nd"))
}
@Test
fun notificationIdsDifferPerTicketAndType() {
assertTrue(DeskHubPush.notificationId("ticket_new", "T-1") != DeskHubPush.notificationId("ticket_new", "T-2"))
assertTrue(DeskHubPush.notificationId("ticket_new", "T-1") != DeskHubPush.notificationId("ticket_reply", "T-1"))
assertEquals(DeskHubPush.notificationId("ticket_new", "T-1"), DeskHubPush.notificationId("ticket_new", "T-1"))
assertTrue(DeskHubPush.notificationId("ticket_new", "T-1") >= 0)
}
}