taler-rust

GNU Taler code in Rust. Largely core banking integrations.
Log | Files | Refs | Submodules | README | LICENSE

commit 614d4763dcf81c22d28812a0a294c011320be872
parent 29b5207e9f46e9d91cce0002cb206c7af79ece35
Author: Antoine A <>
Date:   Sat, 28 Jun 2025 17:28:23 +0200

common: clean code and improve shared logic

Diffstat:
MCargo.lock | 107++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
MMakefile | 2+-
Mcommon/taler-api/src/error.rs | 10++++++++++
Mcommon/taler-api/src/json.rs | 2+-
Mcommon/taler-api/tests/common/mod.rs | 4++--
Mcommon/taler-common/src/cli.rs | 2+-
Mcommon/taler-common/src/config.rs | 8+++++++-
Mcommon/taler-common/src/lib.rs | 3++-
Mcommon/taler-common/src/types/payto.rs | 18++++++------------
Mcommon/taler-test-utils/src/lib.rs | 32+++++++++++++++++++-------------
Mcommon/taler-test-utils/src/routine.rs | 90++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mcommon/taler-test-utils/src/server.rs | 16++++++++++++++++
Rtaler-magnet-bank/src/adapter.rs -> taler-magnet-bank/src/api.rs | 0
Mtaler-magnet-bank/src/config.rs | 1+
Mtaler-magnet-bank/src/db.rs | 3++-
Mtaler-magnet-bank/src/lib.rs | 13+++++++++----
Mtaler-magnet-bank/src/main.rs | 17++++++-----------
Mtaler-magnet-bank/tests/api.rs | 21++++++++++++++++++---
18 files changed, 241 insertions(+), 108 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.18.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byteorder" @@ -416,9 +416,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" @@ -629,12 +629,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -979,7 +979,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.0", + "webpki-roots 1.0.1", ] [[package]] @@ -1121,9 +1121,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown 0.15.4", @@ -1725,7 +1725,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 1.0.0", + "webpki-roots 1.0.1", ] [[package]] @@ -2187,9 +2187,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.103" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -2774,14 +2774,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.0", + "webpki-roots 1.0.1", ] [[package]] name = "webpki-roots" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb" +checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" dependencies = [ "rustls-pki-types", ] @@ -2855,6 +2855,15 @@ dependencies = [ ] [[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + +[[package]] name = "windows-targets" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2878,7 +2887,7 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", @@ -2886,6 +2895,22 @@ dependencies = [ ] [[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2898,6 +2923,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2910,6 +2941,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2922,12 +2959,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2940,6 +2989,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2952,6 +3007,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2964,6 +3025,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2976,6 +3043,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] name = "wit-bindgen-rt" version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Makefile b/Makefile @@ -30,7 +30,7 @@ install-nobuild: install: build install-nobuild .PHONY: check -check: +check: install-nobuild cargo test .PHONY: doc diff --git a/common/taler-api/src/error.rs b/common/taler-api/src/error.rs @@ -157,3 +157,13 @@ pub fn failure_status(code: ErrorCode, hint: impl Into<Box<str>>, status: Status path: None, } } + +pub fn not_implemented(hint: impl Into<Box<str>>) -> ApiError { + ApiError { + code: ErrorCode::END, + hint: Some(hint.into()), + log: None, + status: Some(StatusCode::NOT_IMPLEMENTED), + path: None, + } +} diff --git a/common/taler-api/src/json.rs b/common/taler-api/src/json.rs @@ -108,7 +108,7 @@ where Err(err) => { return Err(failure( ErrorCode::GENERIC_UNEXPECTED_REQUEST_ERROR, - format!("Failed to read body: {}", err), + format!("Failed to read body: {err}"), )); } }, diff --git a/common/taler-api/tests/common/mod.rs b/common/taler-api/tests/common/mod.rs @@ -35,7 +35,7 @@ use taler_common::{ error_code::ErrorCode, types::{payto::payto, timestamp::Timestamp}, }; -use taler_test_utils::db_test_setup; +use taler_test_utils::db_test_setup_manual; use tokio::sync::watch::Sender; pub mod db; @@ -199,7 +199,7 @@ pub async fn test_api(pool: PgPool, currency: String) -> Router { } pub async fn setup() -> (Router, PgPool) { - let pool = db_test_setup("taler-api").await; + let pool = db_test_setup_manual("../../database-versioning".as_ref(), "taler-api").await; let api = test_api(pool.clone(), "EUR".to_string()).await; (api.finalize(), pool) diff --git a/common/taler-common/src/cli.rs b/common/taler-common/src/cli.rs @@ -63,7 +63,7 @@ impl ConfigCmd { ConfigCmd::Pathsub { path_expr } => cfg.pathsub(path_expr, 0)?, ConfigCmd::Dump => cfg.to_string(), }; - println!("{}", out); + println!("{out}"); Ok(()) } } diff --git a/common/taler-common/src/config.rs b/common/taler-common/src/config.rs @@ -264,7 +264,7 @@ pub mod parser { .or_default() .extend(secret_section); } else { - warn!(target: "config", "{}", line_err(format!("Configuration file at '{}' loaded with @inline-secret@ does not contain section '{section_up}' ", secret_file), src, num)); + warn!(target: "config", "{}", line_err(format!("Configuration file at '{secret_file}' loaded with @inline-secret@ does not contain section '{section_up}'"), src, num)); } } unknown => { @@ -330,6 +330,7 @@ pub mod parser { } impl ConfigSource { + /// Create a new config source pub const fn new( project_name: &'static str, component_name: &'static str, @@ -342,6 +343,11 @@ pub mod parser { } } + /// Create a config source where the project, component and exec names are the same + pub const fn simple(name: &'static str) -> Self { + Self::new(name, name, name) + } + /** * Search the default configuration file path * diff --git a/common/taler-common/src/lib.rs b/common/taler-common/src/lib.rs @@ -14,7 +14,7 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -use std::{future::Future, path::PathBuf}; +use std::{future::Future, io::IsTerminal, path::PathBuf}; use config::{Config, parser::ConfigSource}; use log::TalerTime; @@ -57,6 +57,7 @@ pub fn taler_main<F: Future<Output = Result<(), anyhow::Error>>>( .with_timer(TalerTime::new()) .with_max_level(level) .with_writer(std::io::stderr) + .with_ansi(std::io::stderr().is_terminal()) .finish() .init(); diff --git a/common/taler-common/src/types/payto.rs b/common/taler-common/src/types/payto.rs @@ -25,7 +25,7 @@ use url::Url; use super::{ amount::Amount, - iban::{BIC, IBAN, ParseBicError, ParseIbanError}, + iban::{BIC, IBAN}, }; /// Parse a payto URI, panic if malformed @@ -156,14 +156,8 @@ pub struct BankID { const IBAN: &str = "iban"; #[derive(Debug, thiserror::Error)] -pub enum BankIDErr { - #[error("missing IBAN in path")] - MissingIban, - #[error(transparent)] - IBAN(#[from] ParseIbanError), - #[error(transparent)] - BIC(#[from] ParseBicError), -} +#[error("missing IBAN in path")] +pub struct MissingIban; impl PaytoImpl for BankID { fn as_payto(&self) -> PaytoURI { @@ -179,10 +173,10 @@ impl PaytoImpl for BankID { )); } let Some(mut segments) = url.path_segments() else { - return Err(PaytoErr::custom(BankIDErr::MissingIban)); + return Err(PaytoErr::custom(MissingIban)); }; let Some(first) = segments.next() else { - return Err(PaytoErr::custom(BankIDErr::MissingIban)); + return Err(PaytoErr::custom(MissingIban)); }; let (iban, bic) = match segments.next() { Some(second) => ( @@ -198,7 +192,7 @@ impl PaytoImpl for BankID { impl PaytoImpl for IBAN { fn as_payto(&self) -> PaytoURI { - PaytoURI::from_parts(IBAN, format_args!("/{}", self)) + PaytoURI::from_parts(IBAN, format_args!("/{self}")) } fn parse(raw: &PaytoURI) -> Result<Self, PaytoErr> { diff --git a/common/taler-test-utils/src/lib.rs b/common/taler-test-utils/src/lib.rs @@ -28,7 +28,11 @@ use sqlx::{ postgres::{PgConnectOptions, PgPoolOptions}, }; -use taler_common::db::{dbinit, pool}; +use taler_api::config::DbCfg; +use taler_common::{ + config::{Config, parser::ConfigSource}, + db::{dbinit, pool}, +}; use tracing::Level; use tracing_subscriber::{FmtSubscriber, util::SubscriberInitExt}; @@ -37,22 +41,24 @@ pub mod json; pub mod routine; pub mod server; -pub async fn db_test_setup(prefix: &str) -> PgPool { - let schema = prefix.replace("-", "_"); +pub async fn db_test_setup(src: ConfigSource) -> PgPool { + let cfg = Config::from_file(src, None::<&str>).unwrap(); + let name = format!("{}db-postgres", src.component_name); + let sect = cfg.section(&name); + let db_cfg = DbCfg::parse(sect).unwrap(); + db_test_setup_manual(db_cfg.sql_dir.as_ref(), src.component_name).await +} + +pub async fn db_test_setup_manual(sql_dir: &Path, component_name: &str) -> PgPool { + println!("{sql_dir:?} {component_name}"); setup_tracing(); let cfg = test_db().await; - let pool = pool(cfg, &schema).await.unwrap(); + let pool = pool(cfg, &component_name.replace("-", "_")).await.unwrap(); let mut conn = pool.acquire().await.unwrap(); - let path: &Path = env!("CARGO_MANIFEST_DIR").as_ref(); - dbinit( - &mut conn, - &path.join("../../database-versioning"), - prefix, - true, - ) - .await - .unwrap(); + dbinit(&mut conn, sql_dir, component_name, true) + .await + .unwrap(); pool } diff --git a/common/taler-test-utils/src/routine.rs b/common/taler-test-utils/src/routine.rs @@ -48,6 +48,11 @@ pub async fn routine_pagination<'a, T: DeserializeOwned, F: Future<Output = ()>> ids: fn(T) -> Vec<i64>, mut register: impl FnMut(&'a Router, usize) -> F, ) { + // Check supported + if !server.get(&format!("{url}")).await.is_implemented() { + return; + } + // Check history is following specs let assert_history = |args: Cow<'static, str>, size: usize| async move { let resp = server.get(&format!("{url}?{args}")).await; @@ -282,17 +287,20 @@ pub async fn transfer_routine( }); // Check empty db - server - .get("/taler-wire-gateway/transfers") - .await - .assert_no_content(); - server - .get(&format!( - "/taler-wire-gateway/transfers?status={}", - default_status.as_ref() - )) - .await - .assert_no_content(); + { + let res = server.get("/taler-wire-gateway/transfers").await; + if res.is_implemented() { + res.assert_no_content(); + + server + .get(&format!( + "/taler-wire-gateway/transfers?status={}", + default_status.as_ref() + )) + .await + .assert_no_content(); + } + } // Check create transfer { @@ -351,21 +359,23 @@ pub async fn transfer_routine( .assert_ok_json::<TransferResponse>(); // Check OK - let tx = server + let res = server .get(&format!("/taler-wire-gateway/transfers/{}", resp.row_id)) - .await - .assert_ok_json::<TransferStatus>(); - assert_eq!(default_status, tx.status); - assert_eq!(default_amount, tx.amount); - assert_eq!("http://exchange.taler/", tx.origin_exchange_url); - assert_eq!(wtid, tx.wtid); - assert_eq!(resp.timestamp, tx.timestamp); - - // Check unknown transaction - server - .get("/taler-wire-gateway/transfers/42") - .await - .assert_error(ErrorCode::BANK_TRANSACTION_NOT_FOUND); + .await; + if res.is_implemented() { + let tx = res.assert_ok_json::<TransferStatus>(); + assert_eq!(default_status, tx.status); + assert_eq!(default_amount, tx.amount); + assert_eq!("http://exchange.taler/", tx.origin_exchange_url); + assert_eq!(wtid, tx.wtid); + assert_eq!(resp.timestamp, tx.timestamp); + + // Check unknown transaction + server + .get("/taler-wire-gateway/transfers/42") + .await + .assert_error(ErrorCode::BANK_TRANSACTION_NOT_FOUND); + } } // Check transfer page @@ -381,21 +391,21 @@ pub async fn transfer_routine( .assert_ok_json::<TransferResponse>(); } { - let list = server - .get("/taler-wire-gateway/transfers") - .await - .assert_ok_json::<TransferList>(); - assert_eq!(list.transfers.len(), 6); - assert_eq!( - list, - server - .get(&format!( - "/taler-wire-gateway/transfers?status={}", - default_status.as_ref() - )) - .await - .assert_ok_json::<TransferList>() - ); + let res = server.get("/taler-wire-gateway/transfers").await; + if res.is_implemented() { + let list = res.assert_ok_json::<TransferList>(); + assert_eq!(list.transfers.len(), 6); + assert_eq!( + list, + server + .get(&format!( + "/taler-wire-gateway/transfers?status={}", + default_status.as_ref() + )) + .await + .assert_ok_json::<TransferList>() + ); + } } // Pagination test diff --git a/common/taler-test-utils/src/server.rs b/common/taler-test-utils/src/server.rs @@ -30,6 +30,7 @@ use libdeflater::CompressionLvl; use serde::{Deserialize, Serialize, de::DeserializeOwned}; use taler_common::{api_common::ErrorDetail, error_code::ErrorCode}; use tower::ServiceExt as _; +use tracing::warn; use url::Url; pub trait TestServer { @@ -167,6 +168,21 @@ pub struct TestResponse { impl TestResponse { #[track_caller] + pub fn is_implemented(&self) -> bool { + if self.status == StatusCode::NOT_IMPLEMENTED { + let err: ErrorDetail = self.json_parse(); + warn!( + "{} is not implemented: {}", + self.uri.path(), + err.hint.unwrap_or_default() + ); + false + } else { + true + } + } + + #[track_caller] pub fn json_parse<'de, T: Deserialize<'de>>(&'de self) -> T { let TestResponse { status, diff --git a/taler-magnet-bank/src/adapter.rs b/taler-magnet-bank/src/api.rs diff --git a/taler-magnet-bank/src/config.rs b/taler-magnet-bank/src/config.rs @@ -29,6 +29,7 @@ use crate::{FullHuPayto, HuIban, magnet::Token}; pub fn parse_db_cfg(cfg: &Config) -> Result<DbCfg, ValueErr> { DbCfg::parse(cfg.section("magnet-bankdb-postgres")) } + pub fn parse_account_payto(cfg: &Config) -> Result<FullHuPayto, ValueErr> { let sect = cfg.section("magnet-bank"); let iban: HuIban = sect.parse("iban", "IBAN").require()?; diff --git a/taler-magnet-bank/src/db.rs b/taler-magnet-bank/src/db.rs @@ -629,6 +629,7 @@ mod test { use tokio::sync::watch::Receiver; use crate::{ + CONFIG_SOURCE, constant::CURRENCY, db::{ self, AddIncomingResult, AddOutgoingResult, BounceResult, Initiated, TransferResult, @@ -645,7 +646,7 @@ mod test { } async fn setup() -> (PgConnection, PgPool) { - let pool = taler_test_utils::db_test_setup("magnet-bank").await; + let pool = taler_test_utils::db_test_setup(CONFIG_SOURCE).await; let conn = pool.acquire().await.unwrap().leak(); (conn, pool) } diff --git a/taler-magnet-bank/src/lib.rs b/taler-magnet-bank/src/lib.rs @@ -16,12 +16,15 @@ use std::{borrow::Cow, str::FromStr}; -use taler_common::types::{ - iban::{Country, IBAN, IbanErrorKind, ParseIbanError}, - payto::{FullPayto, IbanPayto, Payto, PaytoErr, PaytoImpl, PaytoURI, TransferPayto}, +use taler_common::{ + config::parser::ConfigSource, + types::{ + iban::{Country, IBAN, IbanErrorKind, ParseIbanError}, + payto::{FullPayto, IbanPayto, Payto, PaytoErr, PaytoImpl, PaytoURI, TransferPayto}, + }, }; -pub mod adapter; +pub mod api; pub mod config; pub mod constant; pub mod db; @@ -36,6 +39,8 @@ pub mod failure_injection { } pub const MAX_MAGNET_BBAN_SIZE: usize = 24; +pub const CONFIG_SOURCE: ConfigSource = + ConfigSource::new("taler-magnet-bank", "magnet-bank", "taler-magnet-bank"); #[derive(Debug, Clone, PartialEq, Eq)] pub struct HuIban(IBAN); diff --git a/taler-magnet-bank/src/main.rs b/taler-magnet-bank/src/main.rs @@ -21,12 +21,13 @@ use taler_api::api::{Router, TalerRouter as _}; use taler_common::{ CommonArgs, cli::{ConfigCmd, long_version}, - config::{Config, parser::ConfigSource}, + config::Config, db::{dbinit, pool}, taler_main, }; use taler_magnet_bank::{ - adapter::MagnetApi, + CONFIG_SOURCE, + api::MagnetApi, config::{ServeCfg, WorkerCfg, parse_db_cfg}, dev::{self, DevCmd}, magnet::AuthClient, @@ -139,13 +140,7 @@ async fn app(args: Args, cfg: Config) -> anyhow::Result<()> { fn main() { let args = Args::parse(); - taler_main( - ConfigSource::new( - "taler-magnet-bank", - "taler-magnet-bank", - "taler-magnet-bank", - ), - args.common.clone(), - |cfg| async move { app(args, cfg).await }, - ); + taler_main(CONFIG_SOURCE, args.common.clone(), |cfg| async move { + app(args, cfg).await + }); } diff --git a/taler-magnet-bank/tests/api.rs b/taler-magnet-bank/tests/api.rs @@ -20,17 +20,19 @@ use sqlx::PgPool; use taler_api::{api::TalerRouter as _, auth::AuthMethod, subject::OutgoingSubject}; use taler_common::{ api_common::ShortHashCode, - api_wire::{OutgoingHistory, TransferState}, + api_revenue::RevenueConfig, + api_wire::{OutgoingHistory, TransferState, WireConfig}, types::{amount::amount, payto::payto, timestamp::Timestamp, url}, }; -use taler_magnet_bank::{adapter::MagnetApi, db, magnet_payto}; +use taler_magnet_bank::{CONFIG_SOURCE, api::MagnetApi, db, magnet_payto}; use taler_test_utils::{ Router, db_test_setup, routine::{admin_add_incoming_routine, revenue_routine, routine_pagination, transfer_routine}, + server::TestServer, }; async fn setup() -> (Router, PgPool) { - let pool = db_test_setup("magnet-bank").await; + let pool = db_test_setup(CONFIG_SOURCE).await; let api = Arc::new( MagnetApi::start( pool.clone(), @@ -47,6 +49,19 @@ async fn setup() -> (Router, PgPool) { } #[tokio::test] +async fn config() { + let (server, _) = setup().await; + server + .get("/taler-wire-gateway/config") + .await + .assert_ok_json::<WireConfig>(); + server + .get("/taler-revenue/config") + .await + .assert_ok_json::<RevenueConfig>(); +} + +#[tokio::test] async fn transfer() { let (server, _) = setup().await; transfer_routine(