Upload via GUI (8346 Dateien)
This commit is contained in:
+36
-47
@@ -1,47 +1,36 @@
|
||||
param()
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$required = @(
|
||||
'DESKHUB_RELEASE_STORE_FILE',
|
||||
'DESKHUB_RELEASE_STORE_PASSWORD',
|
||||
'DESKHUB_RELEASE_KEY_ALIAS',
|
||||
'DESKHUB_RELEASE_KEY_PASSWORD'
|
||||
)
|
||||
|
||||
$missing = @($required | Where-Object { [string]::IsNullOrWhiteSpace([Environment]::GetEnvironmentVariable($_)) })
|
||||
if ($missing.Count -gt 0) {
|
||||
throw "Fehlende Umgebungsvariablen: $($missing -join ', ')"
|
||||
}
|
||||
|
||||
$storeFile = [Environment]::GetEnvironmentVariable('DESKHUB_RELEASE_STORE_FILE')
|
||||
if (-not (Test-Path -LiteralPath $storeFile -PathType Leaf)) {
|
||||
throw "Keystore nicht gefunden: $storeFile"
|
||||
}
|
||||
|
||||
$projectRoot = $PSScriptRoot
|
||||
$javaHome = [Environment]::GetEnvironmentVariable('JAVA_HOME')
|
||||
if ([string]::IsNullOrWhiteSpace($javaHome)) {
|
||||
throw 'JAVA_HOME muss auf ein JDK 17 zeigen.'
|
||||
}
|
||||
|
||||
Push-Location $projectRoot
|
||||
try {
|
||||
& "$projectRoot\gradlew.bat" clean assembleRelease --no-daemon --console=plain
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Release-Build fehlgeschlagen (Exitcode $LASTEXITCODE)."
|
||||
}
|
||||
|
||||
$source = "$projectRoot\build\outputs\apk\release\DeskHubMobile-release.apk"
|
||||
if (-not (Test-Path -LiteralPath $source -PathType Leaf)) {
|
||||
throw 'Signierte Release-APK wurde nicht erzeugt.'
|
||||
}
|
||||
|
||||
$artifactDirectory = "$projectRoot\artifacts"
|
||||
New-Item -ItemType Directory -Path $artifactDirectory -Force | Out-Null
|
||||
$target = "$artifactDirectory\deskhub-employee-release.apk"
|
||||
Copy-Item -LiteralPath $source -Destination $target -Force
|
||||
Get-FileHash -Algorithm SHA256 -LiteralPath $target
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Baut die signierte Release-App: AAB für den Play Store und APK für direkte Installation.
|
||||
|
||||
.DESCRIPTION
|
||||
Fragt Keystore-Datei und Passwort ab (oder nimmt DESKHUB_RELEASE_* aus der Umgebung). Das Passwort bleibt nur in diesem Prozess.
|
||||
Ergebnis: artifacts\deskhub-release.aab (Play Store) und artifacts\deskhub-employee-release.apk. Vorher versionCode in build.gradle.kts erhöhen.
|
||||
#>
|
||||
param([string]$StoreFile = (Join-Path $env:USERPROFILE 'deskhub-keys\deskhub-release.jks'), [string]$Alias = 'deskhub')
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($env:DESKHUB_RELEASE_STORE_FILE)) { $env:DESKHUB_RELEASE_STORE_FILE = $StoreFile }
|
||||
if ([string]::IsNullOrWhiteSpace($env:DESKHUB_RELEASE_KEY_ALIAS)) { $env:DESKHUB_RELEASE_KEY_ALIAS = $Alias }
|
||||
if (-not (Test-Path -LiteralPath $env:DESKHUB_RELEASE_STORE_FILE -PathType Leaf)) { throw "Keystore nicht gefunden: $($env:DESKHUB_RELEASE_STORE_FILE). Erst .\new-keystore.ps1 ausführen." }
|
||||
if ([string]::IsNullOrWhiteSpace($env:DESKHUB_RELEASE_STORE_PASSWORD)) {
|
||||
$s = Read-Host 'Keystore-Passwort' -AsSecureString
|
||||
$env:DESKHUB_RELEASE_STORE_PASSWORD = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($s))
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($env:DESKHUB_RELEASE_KEY_PASSWORD)) { $env:DESKHUB_RELEASE_KEY_PASSWORD = $env:DESKHUB_RELEASE_STORE_PASSWORD }
|
||||
if (-not (Test-Path (Join-Path $PSScriptRoot 'google-services.json'))) { throw 'google-services.json fehlt im Ordner mobile (aus der Firebase-Konsole).' }
|
||||
|
||||
Push-Location $PSScriptRoot
|
||||
try {
|
||||
& "$PSScriptRoot\gradlew.bat" clean bundleRelease assembleRelease --no-daemon --console=plain
|
||||
if ($LASTEXITCODE -ne 0) { throw "Release-Build fehlgeschlagen (Exitcode $LASTEXITCODE)." }
|
||||
New-Item -ItemType Directory -Path artifacts -Force | Out-Null
|
||||
$aab = Get-ChildItem -Recurse -Filter '*.aab' build\outputs\bundle\release | Select-Object -First 1
|
||||
$apk = "$PSScriptRoot\build\outputs\apk\release\DeskHubMobile-release.apk"
|
||||
if (-not $aab -or -not (Test-Path $apk)) { throw 'AAB oder APK wurde nicht erzeugt.' }
|
||||
Copy-Item $aab.FullName artifacts\deskhub-release.aab -Force
|
||||
Copy-Item $apk artifacts\deskhub-employee-release.apk -Force
|
||||
Get-FileHash -Algorithm SHA256 artifacts\deskhub-release.aab, artifacts\deskhub-employee-release.apk
|
||||
} finally {
|
||||
Pop-Location
|
||||
Remove-Item Env:\DESKHUB_RELEASE_STORE_PASSWORD, Env:\DESKHUB_RELEASE_KEY_PASSWORD -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
+157
-154
@@ -1,154 +1,157 @@
|
||||
plugins {
|
||||
id("com.android.application") version "8.4.2"
|
||||
id("org.jetbrains.kotlin.android") version "1.9.24"
|
||||
}
|
||||
|
||||
extra["author"] = "M_Viper"
|
||||
extra["productName"] = "deskhub"
|
||||
|
||||
val releaseStoreFile = providers.environmentVariable("DESKHUB_RELEASE_STORE_FILE").orNull
|
||||
val releaseStorePassword = providers.environmentVariable("DESKHUB_RELEASE_STORE_PASSWORD").orNull
|
||||
val releaseKeyAlias = providers.environmentVariable("DESKHUB_RELEASE_KEY_ALIAS").orNull
|
||||
val releaseKeyPassword = providers.environmentVariable("DESKHUB_RELEASE_KEY_PASSWORD").orNull
|
||||
val releaseSigningConfigured = listOf(
|
||||
releaseStoreFile,
|
||||
releaseStorePassword,
|
||||
releaseKeyAlias,
|
||||
releaseKeyPassword,
|
||||
).all { !it.isNullOrBlank() }
|
||||
|
||||
android {
|
||||
namespace = "de.deskhub.staff"
|
||||
compileSdk = 34
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "de.deskhub.staff"
|
||||
minSdk = 26
|
||||
targetSdk = 34
|
||||
// WICHTIG: Bei jedem neuen Debug-Build erhöhen. Android erkennt eine APK mit
|
||||
// unverändertem versionCode (+ gleicher Signatur) auf manchen Geräten nicht
|
||||
// zuverlässig als Update, wodurch eine Neuinstallation still fehlschlagen kann.
|
||||
versionCode = 19
|
||||
versionName = "2.1.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
compose = true
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = "1.5.14"
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
if (releaseSigningConfigured) {
|
||||
create("release") {
|
||||
storeFile = file(requireNotNull(releaseStoreFile))
|
||||
storePassword = requireNotNull(releaseStorePassword)
|
||||
keyAlias = requireNotNull(releaseKeyAlias)
|
||||
keyPassword = requireNotNull(releaseKeyPassword)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
if (releaseSigningConfigured) {
|
||||
signingConfig = signingConfigs.getByName("release")
|
||||
}
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests.isIncludeAndroidResources = true
|
||||
}
|
||||
|
||||
packaging {
|
||||
resources.excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
val composeBom = platform("androidx.compose:compose-bom:2024.09.00")
|
||||
implementation(composeBom)
|
||||
androidTestImplementation(composeBom)
|
||||
|
||||
implementation("androidx.activity:activity-compose:1.9.2")
|
||||
implementation("androidx.compose.ui:ui")
|
||||
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||
implementation("androidx.compose.material3:material3")
|
||||
implementation("androidx.compose.material:material-icons-extended")
|
||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.3")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.3")
|
||||
implementation("androidx.navigation:navigation-compose:2.7.7")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
implementation("com.google.code.gson:gson:2.11.0")
|
||||
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("org.robolectric:robolectric:4.13")
|
||||
testImplementation(composeBom)
|
||||
testImplementation("androidx.compose.ui:ui-test-junit4")
|
||||
testImplementation("androidx.test.ext:junit:1.2.1")
|
||||
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.2.1")
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
||||
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
||||
}
|
||||
|
||||
val verifyBranding by tasks.registering {
|
||||
doLast {
|
||||
val strings = layout.projectDirectory
|
||||
.file("src/main/res/values/strings.xml")
|
||||
.asFile
|
||||
.readText()
|
||||
check("<string name=\"app_name\">deskhub</string>" in strings) {
|
||||
"app_name muss exakt deskhub lauten."
|
||||
}
|
||||
val readme = layout.projectDirectory.file("README.md").asFile.readText()
|
||||
check("Ersteller: M_Viper" in readme) {
|
||||
"README.md muss das Feld Ersteller: M_Viper enthalten."
|
||||
}
|
||||
check(project.extra["author"] == "M_Viper") {
|
||||
"Gradle-Projektmetadatum author muss M_Viper sein."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val exportDebugApk by tasks.registering {
|
||||
doLast {
|
||||
val source = layout.buildDirectory.file("outputs/apk/debug/DeskHubMobile-debug.apk").get().asFile
|
||||
check(source.isFile) { "Debug-APK wurde nicht erzeugt: $source" }
|
||||
val target = layout.projectDirectory.file("artifacts/deskhub-employee-debug.apk").asFile
|
||||
target.parentFile.mkdirs()
|
||||
source.copyTo(target, overwrite = true)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.configureEach {
|
||||
if (name == "preBuild") {
|
||||
dependsOn(verifyBranding)
|
||||
}
|
||||
if (name == "assembleDebug") {
|
||||
finalizedBy(exportDebugApk)
|
||||
}
|
||||
}
|
||||
plugins {
|
||||
id("com.android.application") version "8.4.2"
|
||||
id("org.jetbrains.kotlin.android") version "1.9.24"
|
||||
id("com.google.gms.google-services") version "4.4.4"
|
||||
}
|
||||
|
||||
extra["author"] = "M_Viper"
|
||||
extra["productName"] = "deskhub"
|
||||
|
||||
val releaseStoreFile = providers.environmentVariable("DESKHUB_RELEASE_STORE_FILE").orNull
|
||||
val releaseStorePassword = providers.environmentVariable("DESKHUB_RELEASE_STORE_PASSWORD").orNull
|
||||
val releaseKeyAlias = providers.environmentVariable("DESKHUB_RELEASE_KEY_ALIAS").orNull
|
||||
val releaseKeyPassword = providers.environmentVariable("DESKHUB_RELEASE_KEY_PASSWORD").orNull
|
||||
val releaseSigningConfigured = listOf(
|
||||
releaseStoreFile,
|
||||
releaseStorePassword,
|
||||
releaseKeyAlias,
|
||||
releaseKeyPassword,
|
||||
).all { !it.isNullOrBlank() }
|
||||
|
||||
android {
|
||||
namespace = "de.deskhub.staff"
|
||||
compileSdk = 35
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "de.deskhub.staff"
|
||||
minSdk = 26
|
||||
targetSdk = 35
|
||||
// WICHTIG: Bei jedem neuen Debug-Build erhöhen. Android erkennt eine APK mit
|
||||
// unverändertem versionCode (+ gleicher Signatur) auf manchen Geräten nicht
|
||||
// zuverlässig als Update, wodurch eine Neuinstallation still fehlschlagen kann.
|
||||
versionCode = 26
|
||||
versionName = "2.5.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
compose = true
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = "1.5.14"
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
if (releaseSigningConfigured) {
|
||||
create("release") {
|
||||
storeFile = file(requireNotNull(releaseStoreFile))
|
||||
storePassword = requireNotNull(releaseStorePassword)
|
||||
keyAlias = requireNotNull(releaseKeyAlias)
|
||||
keyPassword = requireNotNull(releaseKeyPassword)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
if (releaseSigningConfigured) {
|
||||
signingConfig = signingConfigs.getByName("release")
|
||||
}
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests.isIncludeAndroidResources = true
|
||||
}
|
||||
|
||||
packaging {
|
||||
resources.excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
val composeBom = platform("androidx.compose:compose-bom:2024.09.00")
|
||||
implementation(composeBom)
|
||||
androidTestImplementation(composeBom)
|
||||
|
||||
implementation("androidx.activity:activity-compose:1.9.2")
|
||||
implementation("androidx.compose.ui:ui")
|
||||
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||
implementation("androidx.compose.material3:material3")
|
||||
implementation("androidx.compose.material:material-icons-extended")
|
||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.3")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.3")
|
||||
implementation("androidx.navigation:navigation-compose:2.7.7")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
implementation("com.google.code.gson:gson:2.11.0")
|
||||
// Push-Benachrichtigungen (Firebase Cloud Messaging)
|
||||
implementation("com.google.firebase:firebase-messaging:25.0.1")
|
||||
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("org.robolectric:robolectric:4.13")
|
||||
testImplementation(composeBom)
|
||||
testImplementation("androidx.compose.ui:ui-test-junit4")
|
||||
testImplementation("androidx.test.ext:junit:1.2.1")
|
||||
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.2.1")
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
||||
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
||||
}
|
||||
|
||||
val verifyBranding by tasks.registering {
|
||||
doLast {
|
||||
val strings = layout.projectDirectory
|
||||
.file("src/main/res/values/strings.xml")
|
||||
.asFile
|
||||
.readText()
|
||||
check("<string name=\"app_name\">deskhub</string>" in strings) {
|
||||
"app_name muss exakt deskhub lauten."
|
||||
}
|
||||
val readme = layout.projectDirectory.file("README.md").asFile.readText()
|
||||
check("Ersteller: M_Viper" in readme) {
|
||||
"README.md muss das Feld Ersteller: M_Viper enthalten."
|
||||
}
|
||||
check(project.extra["author"] == "M_Viper") {
|
||||
"Gradle-Projektmetadatum author muss M_Viper sein."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val exportDebugApk by tasks.registering {
|
||||
doLast {
|
||||
val source = layout.buildDirectory.file("outputs/apk/debug/DeskHubMobile-debug.apk").get().asFile
|
||||
check(source.isFile) { "Debug-APK wurde nicht erzeugt: $source" }
|
||||
val target = layout.projectDirectory.file("artifacts/deskhub-employee-debug.apk").asFile
|
||||
target.parentFile.mkdirs()
|
||||
source.copyTo(target, overwrite = true)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.configureEach {
|
||||
if (name == "preBuild") {
|
||||
dependsOn(verifyBranding)
|
||||
}
|
||||
if (name == "assembleDebug") {
|
||||
finalizedBy(exportDebugApk)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "436755419487",
|
||||
"project_id": "deskhub-96d3f",
|
||||
"storage_bucket": "deskhub-96d3f.firebasestorage.app"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:436755419487:android:8bad822266b61db37466ea",
|
||||
"android_client_info": {
|
||||
"package_name": "de.deskhub.staff"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyBN6ud1flyG_aFJdv25fsFQpHpxpESiDlk"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
android.useAndroidX=true
|
||||
kotlin.code.style=official
|
||||
android.suppressUnsupportedCompileSdk=35
|
||||
|
||||
@@ -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 <b> & 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user