aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/test/java
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-11-03 18:36:42 +0100
committerDanilo M. <danix@danix.xyz>2026-11-03 18:36:42 +0100
commitcc880cf62ea8391f693f034858578cd4b693043b (patch)
tree767a1ebb24b6c4e94bd0c3073a2cb5e98d406c0a /app/src/test/java
parent9dba2efd0b8d9d117956d671468361acac060482 (diff)
downloadHardenedPass-cc880cf62ea8391f693f034858578cd4b693043b.tar.gz
HardenedPass-cc880cf62ea8391f693f034858578cd4b693043b.zip
feat(app): drop two sort orders, fix the proxy user name
The Compose list shows folders and entries in separate groups, so the files first and type independent sort orders did nothing visible. They are removed; a stored one migrates to folders first, and any unknown value reads as folders first instead of throwing. The OpenKeychain SSH key ID, which nothing reads any more, is removed once. GitSettings wrote the proxy user name to the proxy preferences but read it from the main settings, so ProxyUtils never authenticated. Adds the pure parts of the settings port: proxy port parsing, HEAD status and the commit log. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'app/src/test/java')
-rw-r--r--app/src/test/java/app/passwordstore/ui/settings/SettingsModelTest.kt90
-rw-r--r--app/src/test/java/app/passwordstore/util/settings/GitSettingsTest.kt27
-rw-r--r--app/src/test/java/app/passwordstore/util/settings/MigrationsTest.kt25
-rw-r--r--app/src/test/java/app/passwordstore/util/settings/PasswordSortOrderTest.kt26
4 files changed, 168 insertions, 0 deletions
diff --git a/app/src/test/java/app/passwordstore/ui/settings/SettingsModelTest.kt b/app/src/test/java/app/passwordstore/ui/settings/SettingsModelTest.kt
new file mode 100644
index 00000000..693e07dd
--- /dev/null
+++ b/app/src/test/java/app/passwordstore/ui/settings/SettingsModelTest.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+package app.passwordstore.ui.settings
+
+import app.passwordstore.util.git.GitCommit
+import java.io.File
+import java.nio.file.Files
+import kotlin.test.AfterTest
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertNull
+import org.eclipse.jgit.api.Git
+import org.eclipse.jgit.lib.PersonIdent
+import org.eclipse.jgit.revwalk.RevCommit
+import org.eclipse.jgit.util.FS
+
+class SettingsModelTest {
+
+ private val root = Files.createTempDirectory("aps-settings").toFile()
+ private val identity = PersonIdent("test", "test@example.org")
+
+ init {
+ // Ignore the developer's ~/.gitconfig (default branch, commit signing).
+ FS.DETECTED.setUserHome(root)
+ }
+
+ @AfterTest fun cleanUp() = root.deleteRecursively().let {}
+
+ private fun repo(): Git =
+ Git.init().setInitialBranch("master").setDirectory(File(root, "store")).call()
+
+ private fun Git.commitFile(name: String, message: String): RevCommit {
+ File(repository.workTree, name).writeText(message)
+ add().addFilepattern(name).call()
+ return commit()
+ .setMessage(message)
+ .setAuthor(identity)
+ .setCommitter(identity)
+ .setSign(false)
+ .call()
+ }
+
+ @Test
+ fun proxyPorts() {
+ assertEquals(-1, proxyPort(""))
+ assertEquals(-1, proxyPort(" "))
+ assertEquals(8080, proxyPort("8080"))
+ assertEquals(8080, proxyPort(" 8080 "))
+ assertEquals(1, proxyPort("1"))
+ assertEquals(65535, proxyPort("65535"))
+ assertNull(proxyPort("0"))
+ assertNull(proxyPort("65536"))
+ assertNull(proxyPort("99999999999"))
+ assertNull(proxyPort("-1"))
+ assertNull(proxyPort("80a"))
+ }
+
+ @Test
+ fun headStatusFollowsHead() {
+ repo().use { git ->
+ // A new repository: HEAD names a branch that has no commit yet.
+ assertEquals(HeadStatus.Branch("master"), headStatus(git.repository))
+ val first = git.commitFile("a.gpg", "Add a")
+ git.commitFile("b.gpg", "Add b")
+ assertEquals(HeadStatus.Branch("master"), headStatus(git.repository))
+ assertFalse(needsAbort(git.repository))
+ git.checkout().setName(first.name).call()
+ assertEquals(HeadStatus.Detached(first.name.take(8)), headStatus(git.repository))
+ }
+ }
+
+ @Test
+ fun gitLogIsNewestFirst() {
+ assertEquals(emptyList<GitCommit>(), gitLog(null))
+ repo().use { git ->
+ // No commit yet: JGit's NoHeadException is an empty log, not a crash.
+ assertEquals(emptyList<GitCommit>(), gitLog(git.repository))
+ val first = git.commitFile("a.gpg", "Add a")
+ val second = git.commitFile("b.gpg", "Add b")
+ val log = gitLog(git.repository)
+ assertEquals(listOf("Add b", "Add a"), log.map(GitCommit::shortMessage))
+ assertEquals(listOf(second.name, first.name), log.map(GitCommit::hash))
+ assertEquals("test", log[0].authorName)
+ }
+ }
+}
diff --git a/app/src/test/java/app/passwordstore/util/settings/GitSettingsTest.kt b/app/src/test/java/app/passwordstore/util/settings/GitSettingsTest.kt
new file mode 100644
index 00000000..6b30c248
--- /dev/null
+++ b/app/src/test/java/app/passwordstore/util/settings/GitSettingsTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+package app.passwordstore.util.settings
+
+import app.passwordstore.util.extensions.getString
+import com.github.ivanshafran.sharedpreferencesmock.SPMockBuilder
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertNull
+
+class GitSettingsTest {
+
+ @Test
+ fun proxyUsernameIsReadWhereItIsWritten() {
+ val settings = SPMockBuilder().createSharedPreferences()
+ val proxy = SPMockBuilder().createSharedPreferences()
+ val gitSettings =
+ GitSettings(settings, SPMockBuilder().createSharedPreferences(), proxy, "/nonexistent")
+ gitSettings.proxyUsername = "proxy-user"
+ assertEquals("proxy-user", gitSettings.proxyUsername)
+ assertEquals("proxy-user", proxy.getString(PreferenceKeys.PROXY_USERNAME))
+ assertNull(settings.getString(PreferenceKeys.PROXY_USERNAME))
+ }
+}
diff --git a/app/src/test/java/app/passwordstore/util/settings/MigrationsTest.kt b/app/src/test/java/app/passwordstore/util/settings/MigrationsTest.kt
index 62109563..44bd12ba 100644
--- a/app/src/test/java/app/passwordstore/util/settings/MigrationsTest.kt
+++ b/app/src/test/java/app/passwordstore/util/settings/MigrationsTest.kt
@@ -184,4 +184,29 @@ class MigrationsTest {
assertFalse { sharedPrefs.contains(PreferenceKeys.GIT_EXTERNAL_REPO) }
assertTrue { sharedPrefs.getBoolean(PreferenceKeys.GIT_EXTERNAL_MIGRATED, false) }
}
+
+ @Test
+ fun removedSortOrdersFallBackToFoldersFirst() {
+ val gitSettings =
+ GitSettings(sharedPrefs, encryptedSharedPreferences, proxySharedPreferences, filesDir)
+ for (removed in listOf("FILE_FIRST", "INDEPENDENT")) {
+ sharedPrefs.edit { putString(PreferenceKeys.SORT_ORDER, removed) }
+ runMigrations(filesDir, sharedPrefs, gitSettings)
+ assertEquals("FOLDER_FIRST", sharedPrefs.getString(PreferenceKeys.SORT_ORDER))
+ }
+ sharedPrefs.edit { putString(PreferenceKeys.SORT_ORDER, "RECENTLY_USED") }
+ runMigrations(filesDir, sharedPrefs, gitSettings)
+ assertEquals("RECENTLY_USED", sharedPrefs.getString(PreferenceKeys.SORT_ORDER))
+ }
+
+ @Test
+ fun staleOpenKeystoreKeyIdIsRemoved() {
+ sharedPrefs.edit { putString(PreferenceKeys.SSH_OPENKEYSTORE_KEYID, "0123456789ABCDEF") }
+ runMigrations(
+ filesDir,
+ sharedPrefs,
+ GitSettings(sharedPrefs, encryptedSharedPreferences, proxySharedPreferences, filesDir),
+ )
+ assertFalse(sharedPrefs.contains(PreferenceKeys.SSH_OPENKEYSTORE_KEYID))
+ }
}
diff --git a/app/src/test/java/app/passwordstore/util/settings/PasswordSortOrderTest.kt b/app/src/test/java/app/passwordstore/util/settings/PasswordSortOrderTest.kt
new file mode 100644
index 00000000..34348692
--- /dev/null
+++ b/app/src/test/java/app/passwordstore/util/settings/PasswordSortOrderTest.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+package app.passwordstore.util.settings
+
+import androidx.core.content.edit
+import com.github.ivanshafran.sharedpreferencesmock.SPMockBuilder
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class PasswordSortOrderTest {
+
+ @Test
+ fun unknownAndRemovedValuesReadAsFoldersFirst() {
+ val prefs = SPMockBuilder().createSharedPreferences()
+ assertEquals(PasswordSortOrder.FOLDER_FIRST, PasswordSortOrder.getSortOrder(prefs))
+ for (value in listOf("FILE_FIRST", "INDEPENDENT", "bogus")) {
+ prefs.edit { putString(PreferenceKeys.SORT_ORDER, value) }
+ assertEquals(PasswordSortOrder.FOLDER_FIRST, PasswordSortOrder.getSortOrder(prefs))
+ }
+ prefs.edit { putString(PreferenceKeys.SORT_ORDER, "RECENTLY_USED") }
+ assertEquals(PasswordSortOrder.RECENTLY_USED, PasswordSortOrder.getSortOrder(prefs))
+ }
+}