WebUiTest.kt (4126B)
1 /* 2 * This file is part of LibEuFin. 3 * Copyright (C) 2026 Taler Systems S.A. 4 5 * LibEuFin is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation; either version 3, or 8 * (at your option) any later version. 9 10 * LibEuFin is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Affero General Public License for more details. 14 15 * You should have received a copy of the GNU Affero General Public 16 * License along with LibEuFin; see the file COPYING. If not, see 17 * <http://www.gnu.org/licenses/> 18 */ 19 20 import io.ktor.client.request.get 21 import io.ktor.client.statement.bodyAsText 22 import io.ktor.http.HttpStatusCode 23 import io.ktor.server.testing.testApplication 24 import org.junit.Test 25 import sun.misc.Unsafe 26 import tech.libeufin.bank.BankConfig 27 import tech.libeufin.bank.bankConfig 28 import tech.libeufin.bank.corebankWebApp 29 import tech.libeufin.bank.db.Database 30 import java.nio.file.Path 31 import kotlin.io.path.createDirectories 32 import kotlin.io.path.createTempDirectory 33 import kotlin.io.path.createTempFile 34 import kotlin.io.path.readText 35 import kotlin.io.path.writeText 36 import kotlin.test.assertContains 37 import kotlin.test.assertEquals 38 import kotlin.test.assertFailsWith 39 40 class WebUiTest { 41 private fun fakeDatabase(): Database { 42 val field = Unsafe::class.java.getDeclaredField("theUnsafe") 43 field.isAccessible = true 44 val unsafe = field.get(null) as Unsafe 45 return unsafe.allocateInstance(Database::class.java) as Database 46 } 47 48 private fun config(dataDir: Path, spaPath: Path?): BankConfig { 49 val file = createTempFile(suffix = ".conf") 50 file.writeText(buildString { 51 appendLine(Path.of("conf/test_no_conversion.conf").readText()) 52 appendLine("[paths]") 53 appendLine("DATADIR = $dataDir") 54 if (spaPath != null) { 55 appendLine("[libeufin-bank]") 56 appendLine("SPA = $spaPath") 57 } 58 }) 59 return bankConfig(file) 60 } 61 62 @Test 63 fun configuredSpa() { 64 val root = createTempDirectory() 65 val spa = root.resolve("webui").createDirectories() 66 spa.resolve("index.html").writeText("configured WebUI") 67 val cfg = config(root.resolve("data"), spa) 68 69 testApplication { 70 application { corebankWebApp(fakeDatabase(), cfg) } 71 72 val noRedirectClient = createClient { followRedirects = false } 73 val redirect = noRedirectClient.get("/") 74 assertEquals(HttpStatusCode.Found, redirect.status) 75 assertEquals("/webui/", redirect.headers["Location"]) 76 77 val response = client.get("/webui/") 78 assertEquals(HttpStatusCode.OK, response.status) 79 assertEquals("configured WebUI", response.bodyAsText()) 80 } 81 } 82 83 @Test 84 fun fallbackSpa() { 85 val root = createTempDirectory() 86 val fallback = root.resolve("spa").createDirectories() 87 fallback.resolve("index.html").writeText("fallback WebUI") 88 val configuredFile = root.resolve("not-a-directory") 89 configuredFile.writeText("not a WebUI") 90 val cfg = config(root, configuredFile) 91 92 testApplication { 93 application { corebankWebApp(fakeDatabase(), cfg) } 94 95 val response = client.get("/webui/") 96 assertEquals(HttpStatusCode.OK, response.status) 97 assertEquals("fallback WebUI", response.bodyAsText()) 98 } 99 } 100 101 @Test 102 fun missingFallbackFails() { 103 val root = createTempDirectory() 104 val cfg = config(root.resolve("missing-data"), root.resolve("missing-webui")) 105 106 val error = assertFailsWith<IllegalStateException> { 107 testApplication { 108 application { corebankWebApp(fakeDatabase(), cfg) } 109 client.get("/") 110 } 111 } 112 assertContains(error.message.orEmpty(), "SPA fallback directory not found") 113 } 114 }