Android: portless fixture URLs after D-124

D-124 serves Kvitt at https://<host> on 443. The README, the AppBuildInfo and
AboutRepositoryImpl comments, the S-21/S-22 fake scenarios and the :data test
fixtures drop the :8443 port. S-21's invite-created goldens and every S-22
golden re-recorded (link and server row now portless). The release-URL
normaliser test checks a portless URL and keeps one explicit-port case (a
typed port survives), on example.org instead of the owner's old host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
2026-10-19 20:33:15 +02:00
parent 038c6036fe
commit ad3523116f
38 changed files with 13 additions and 11 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ compile, unit tests (including every vector of `contracts/test-vectors/`), lint
**Public host (D-121).** The release server's host name is the build property `kvitt.publicHost`, never a literal in
the code: `:app` exposes it as `BuildConfig.PUBLIC_HOST`, as the manifest placeholder `publicHost` (the host of the
`https://<host>:8443/i/<CODE>` invite links, AC-2.6) and as `RELEASE_SERVER_URL` = `https://<host>:8443`, which S-1
`https://<host>/i/<CODE>` invite links, AC-2.6) and as `RELEASE_SERVER_URL` = `https://<host>`, which S-1
prefills (AC-2.7). Gradle takes `-Pkvitt.publicHost=…` first (`infra/publish-apk.sh` passes it), else the key
`kvitt.publicHost` in `android/local.properties`, where the owner sets it (git-ignored, never committed), else the
placeholder `kvitt.example.invalid`, so a release built without it cannot talk to a real host. Debug builds pair with
@@ -71,7 +71,7 @@ object FakeScenarios {
clockSkew = false,
syncRunning = false,
update = UpdateState.None,
about = AboutState("dev", 1, "https://kvitt.example.org:8443", null, null),
about = AboutState("dev", 1, "https://kvitt.example.org", null, null),
online = true,
today = "2026-10-17",
now = "2026-10-17T06:00:00.000Z",
@@ -116,7 +116,7 @@ object SettingsScenarios {
devices = devices,
invites = listOf(pendingDeviceInvite),
lastSuccessAt = "2026-10-17T11:59:00.000Z",
about = AboutState("1.1", 11, "https://kvitt.example.org:8443", "1.1.0", 3),
about = AboutState("1.1", 11, "https://kvitt.example.org", "1.1.0", 3),
today = "2026-10-17",
now = "2026-10-17T12:02:00.000Z",
defaultAccountId = huset.id,
@@ -88,7 +88,7 @@ import javax.inject.Qualifier
import javax.inject.Singleton
/**
* What `:app` provides: its version (§10.6), build type (AC-2.8, AC-16.5) and release server `https://<host>:8443`
* What `:app` provides: its version (§10.6), build type (AC-2.8, AC-16.5) and release server `https://<host>`
* (`RELEASE_SERVER_URL`, from the Gradle property `kvitt.publicHost`, D-121), which S-22 shows before pairing (D-122).
*/
data class AppBuildInfo(val versionCode: Int, val versionName: String, val debug: Boolean, val releaseServerUrl: String)
@@ -388,7 +388,7 @@ class AboutRepositoryImpl(
private val gate: OnlineGate,
private val versionName: String,
private val versionCode: Int,
/** Shown while no server is paired: `AppBuildInfo.releaseServerUrl`, `https://<kvitt.publicHost>:8443` (D-122). */
/** Shown while no server is paired: `AppBuildInfo.releaseServerUrl`, `https://<kvitt.publicHost>` (D-122, D-124). */
private val releaseServerUrl: String,
) : AboutRepository {
override fun about(): Flow<AboutState> {
@@ -188,7 +188,7 @@ class Harness {
companion object {
const val APP_VERSION = 41
const val APP_VERSION_NAME = "1.1"
const val BASE_URL = "https://kvitt.test:8443"
const val BASE_URL = "https://kvitt.test"
const val TOKEN = "kvt_testtoken0000000000000000000000000000000000"
const val ME = "0192a000-0000-7000-8000-000000000001"
const val PARTNER = "0192a000-0000-7000-8000-000000000002"
@@ -528,6 +528,6 @@ class RepositoriesTest {
private companion object {
const val OLDER = "0192a003-0000-7000-8000-000000000002"
/** `AppBuildInfo.releaseServerUrl` of the tests: a fixed host, not `:app`'s `kvitt.publicHost` (D-122). */
const val RELEASE_SERVER_URL = "https://kvitt.example.org:8443"
const val RELEASE_SERVER_URL = "https://kvitt.example.org"
}
}
@@ -60,14 +60,14 @@ class SessionRepositoryTest {
@Test
fun pair_storesCredentials_writesTheHousehold_andStartsAFullSync() = runSync {
acceptAs(ME)
val result = repo().pair("https://kvitt.test:8443/ ", "7k3m-qx9d-2hpa", "Jacob", "Galaxy S26")
val result = repo().pair("https://kvitt.test/ ", "7k3m-qx9d-2hpa", "Jacob", "Galaxy S26")
assertEquals(ME, (result as OnlineResult.Ok).value.user.id.value)
assertEquals(InviteKind.ADMIN_SETUP, result.value.inviteKind)
val request = h.requests.single()
assertEquals("https://kvitt.test:8443/invites/accept", request.url.toString())
assertEquals("https://kvitt.test/invites/accept", request.url.toString())
val credentials = h.credentials.credentials()
assertEquals("kvt_new", credentials?.token)
assertEquals("https://kvitt.test:8443", credentials?.baseUrl)
assertEquals("https://kvitt.test", credentials?.baseUrl)
assertEquals("d2", credentials?.deviceId)
val session = repo().session.first()
assertTrue(session is SessionState.Paired)
@@ -98,7 +98,9 @@ class SessionRepositoryTest {
@Test
fun serverUrls_releaseHttpsOnly_debugAlsoLocalHttp() {
assertEquals("https://icehack.asuscomm.com:8443", SessionRepositoryImpl.normaliseServerUrl("https://icehack.asuscomm.com:8443/", debugBuild = false))
assertEquals("https://kvitt.example.org", SessionRepositoryImpl.normaliseServerUrl("https://kvitt.example.org/", debugBuild = false))
// An explicit port survives normalisation (D-124 serves on 443, but a typed port is the owner's choice).
assertEquals("https://kvitt.example.org:8443", SessionRepositoryImpl.normaliseServerUrl("https://kvitt.example.org:8443/", debugBuild = false))
assertNull(SessionRepositoryImpl.normaliseServerUrl("http://192.168.1.10:8080", debugBuild = false))
for (ok in listOf("http://localhost:8080", "http://10.0.2.2:8080", "http://10.1.2.3", "http://172.16.0.1", "http://172.31.255.1", "http://192.168.1.10:8080")) {
assertEquals(ok, SessionRepositoryImpl.normaliseServerUrl(ok, debugBuild = true))
Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 24 KiB