libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

http.kt (2391B)


      1 /*
      2  * This file is part of LibEuFin.
      3  * Copyright (C) 2024-2025 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 MERCHANTABILITY
     12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
     13  * 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 package tech.libeufin.ebics
     21 
     22 import io.ktor.http.*
     23 import io.ktor.http.content.*
     24 import io.ktor.client.*
     25 import io.ktor.client.request.*
     26 import io.ktor.client.plugins.*
     27 import io.ktor.client.engine.mock.*
     28 import java.time.Instant
     29 import java.time.ZoneId
     30 import java.time.format.DateTimeFormatter
     31 
     32 /** Use for unit testing */
     33 var MOCK_ENGINE: MockEngine? = null
     34 
     35 /** Create an HTTP client for EBICS requests */
     36 fun httpClient(): HttpClient = MOCK_ENGINE?.let { 
     37     HttpClient(it)
     38 } ?: HttpClient {
     39     install(HttpTimeout) {
     40         // It can take a lot of time for the bank to generate documents
     41         socketTimeoutMillis = 5 * 60 * 1000
     42     }
     43 }
     44 
     45 /** Gets an HTTP client whose requests are going to be served by 'handler' */
     46 fun getMockedClient(
     47     handler: MockRequestHandleScope.(HttpRequestData) -> HttpResponseData
     48 ): HttpClient = HttpClient(MockEngine) {
     49     followRedirects = false
     50     engine {
     51         addHandler {
     52             request -> handler(request)
     53         }
     54     }
     55 }
     56 
     57 private lateinit var steps: Iterator<(String) -> ByteArray>
     58 
     59 object BadRequest: Exception()
     60 
     61 fun setMock(sequences: Sequence<(String) -> ByteArray>) {
     62     steps = sequences.iterator()
     63     if (MOCK_ENGINE == null) {
     64         val cfg: MockEngineConfig = MockEngineConfig()
     65         cfg.addHandler { req ->
     66             val body = String((req.body as OutgoingContent.ByteArrayContent).bytes())
     67             val handler = steps.next()
     68             try {
     69                 val res = handler(body)
     70                 respond(res)
     71             } catch (e: BadRequest) {
     72                 respondBadRequest()
     73             }
     74         }
     75         MOCK_ENGINE = MockEngine(cfg)
     76     }
     77 }