ref: Rename package ch.parano.myice to ch.parano.myicek
Complete the MyIceK rename by updating the Kotlin package from ch.parano.myice to ch.parano.myicek across all source sets (androidMain, commonMain, desktopMain, iosMain, commonTest), the build.gradle.kts (namespace, applicationId, mainClass, desktop packageName) and the iOS Info.plist bundle URL name. The myice:// OAuth scheme is kept unchanged as it depends on the backend. Also add pull-to-refresh to ScheduleScreen using Material 3 PullToRefreshBox, replacing the manual loading overlay.
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// MyIce Kotlin Multiplatform — schedule/convocation viewer
|
||||
// Copyright (C) 2026 parano.ch
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package ch.parano.myicek.network
|
||||
|
||||
import ch.parano.myicek.models.EventDetail
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.mock.MockEngine
|
||||
import io.ktor.client.engine.mock.respond
|
||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.http.headersOf
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNull
|
||||
|
||||
class ApiServiceTest {
|
||||
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
|
||||
private fun mockClient(respondJson: String, requestUrl: String, expectedAuth: String? = "Bearer test-token"): HttpClient {
|
||||
val engine = MockEngine { request ->
|
||||
val actualUrl = if (request.url.encodedQuery.isEmpty()) {
|
||||
request.url.encodedPath
|
||||
} else {
|
||||
request.url.encodedPath + "?" + request.url.encodedQuery
|
||||
}
|
||||
assertEquals(requestUrl, actualUrl)
|
||||
if (expectedAuth != null) {
|
||||
assertEquals(expectedAuth, request.headers["Authorization"])
|
||||
}
|
||||
respond(
|
||||
content = respondJson,
|
||||
status = HttpStatusCode.OK,
|
||||
headers = headersOf(HttpHeaders.ContentType, "application/json"),
|
||||
)
|
||||
}
|
||||
return HttpClient(engine) {
|
||||
install(ContentNegotiation) { json(json) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetUserInfo() = runTest {
|
||||
AuthTokenHolder.token = "test-token"
|
||||
val client = mockClient(
|
||||
"""{"email":"rene@luria.ch","sub":"abc"}""",
|
||||
"/userinfo",
|
||||
)
|
||||
val api = ApiService(client)
|
||||
val result = api.getUserInfo()
|
||||
assertEquals("rene@luria.ch", result.email)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetAccounts() = runTest {
|
||||
AuthTokenHolder.token = "test-token"
|
||||
val client = mockClient(
|
||||
"""[{"name":"default","label":"Default"},{"name":"leonard","label":"Leonard"}]""",
|
||||
"/accounts",
|
||||
)
|
||||
val api = ApiService(client)
|
||||
val result = api.getAccounts()
|
||||
assertEquals(2, result.size)
|
||||
assertEquals("default", result[0].name)
|
||||
assertEquals("Leonard", result[1].label)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetSchedule() = runTest {
|
||||
AuthTokenHolder.token = "test-token"
|
||||
val responseJson = """
|
||||
[{"id_event":"761040","agegroup":"U13 (Elite)","name":"U13 Elite - HC Ajoie","title":"U13 (Elite)\nGame\nArena","opponent":"HC Ajoie","place":"Arena","start":"2024-11-10T14:00:00","end":"2024-11-10T16:15:00","color":"#e4222e","event":"Jeu"}]
|
||||
""".trimIndent()
|
||||
val client = mockClient(responseJson, "/schedule?account=default")
|
||||
val api = ApiService(client)
|
||||
val result = api.getSchedule("default")
|
||||
assertEquals(1, result.size)
|
||||
assertEquals("761040", result[0].idEvent)
|
||||
assertEquals("Jeu", result[0].eventType)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetGameDetail() = runTest {
|
||||
AuthTokenHolder.token = "test-token"
|
||||
val responseJson = """
|
||||
{"title":"U13 - Game","type":"games","place":"Arena","time_start":"2024-11-10T14:00:00","time_end":"2024-11-10T16:15:00","convocation":{"available":[{"position":"Gardien","number":1,"fname":"Jean","lname":"Dupont","dob":"2012-03-15"}],"staff":[{"role":"Coach","fname":"Marc","lname":"Blanc"}]}}
|
||||
""".trimIndent()
|
||||
val client = mockClient(responseJson, "/game/761040?account=default")
|
||||
val api = ApiService(client)
|
||||
val result: EventDetail = api.getGameDetail("761040", "default")
|
||||
assertEquals("U13 - Game", result.title)
|
||||
assertEquals("games", result.type)
|
||||
assertEquals(1, result.convocation.available.size)
|
||||
assertEquals("1", result.convocation.available[0].number)
|
||||
assertEquals(1, result.convocation.staff.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNoAuthTokenSendsNoAuthHeader() = runTest {
|
||||
AuthTokenHolder.token = null
|
||||
val engine = MockEngine { request ->
|
||||
assertNull(request.headers["Authorization"])
|
||||
respond(
|
||||
content = """{"email":""}""",
|
||||
status = HttpStatusCode.OK,
|
||||
headers = headersOf(HttpHeaders.ContentType, "application/json"),
|
||||
)
|
||||
}
|
||||
val client = HttpClient(engine) {
|
||||
install(ContentNegotiation) { json(json) }
|
||||
}
|
||||
val api = ApiService(client)
|
||||
val result = api.getUserInfo()
|
||||
assertEquals("", result.email)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user