This commit is contained in:
parent
0228cec056
commit
d17f9cf7a4
25
.gitea/workflows/action.yml
Normal file
25
.gitea/workflows/action.yml
Normal file
@ -0,0 +1,25 @@
|
||||
name: CI/CD Pipeline
|
||||
|
||||
on: push
|
||||
|
||||
env:
|
||||
CARGO_TARGET: x86_64-unknown-linux-musl
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
container: git.hofer.link/philipp/ci-images:rust-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run Test DB Script
|
||||
run: ./test_db.sh
|
||||
|
||||
- name: Cache Cargo dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cargo build
|
||||
|
||||
- name: Backend tests
|
||||
run: cargo test --verbose
|
173
Cargo.lock
generated
173
Cargo.lock
generated
@ -47,12 +47,28 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
|
||||
|
||||
[[package]]
|
||||
name = "assert-json-diff"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.88"
|
||||
@ -73,6 +89,12 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "auto-future"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
@ -133,6 +155,36 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-test"
|
||||
version = "17.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eb1dfb84bd48bad8e4aa1acb82ed24c2bb5e855b659959b4e03b4dca118fcac"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert-json-diff",
|
||||
"auto-future",
|
||||
"axum",
|
||||
"bytes",
|
||||
"bytesize",
|
||||
"cookie",
|
||||
"http",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"mime",
|
||||
"pretty_assertions",
|
||||
"reserve-port",
|
||||
"rust-multipart-rfc7578_2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"smallvec",
|
||||
"tokio",
|
||||
"tower",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.74"
|
||||
@ -221,6 +273,12 @@ version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "bytesize"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3c8f83209414aacf0eeae3cf730b18d6981697fba62f200fcfb92b9f082acba"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.18"
|
||||
@ -372,6 +430,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
@ -781,6 +845,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"smallvec",
|
||||
"tokio",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -790,13 +855,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"libc",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1167,7 +1236,7 @@ dependencies = [
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-traits",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"smallvec",
|
||||
"zeroize",
|
||||
]
|
||||
@ -1321,6 +1390,16 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
|
||||
dependencies = [
|
||||
"diff",
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.94"
|
||||
@ -1364,8 +1443,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||
dependencies = [
|
||||
"rand_chacha 0.9.0",
|
||||
"rand_core 0.9.3",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1375,7 +1465,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1387,6 +1487,15 @@ dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||
dependencies = [
|
||||
"getrandom 0.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.11"
|
||||
@ -1425,6 +1534,15 @@ version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "reserve-port"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3747658ee2585ecf5607fa9887c92eff61b362ff5253dbf797dfeb73d33d78"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.14"
|
||||
@ -1452,7 +1570,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"pkcs1",
|
||||
"pkcs8",
|
||||
"rand_core",
|
||||
"rand_core 0.6.4",
|
||||
"signature",
|
||||
"spki",
|
||||
"subtle",
|
||||
@ -1513,6 +1631,21 @@ dependencies = [
|
||||
"triomphe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-multipart-rfc7578_2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c839d037155ebc06a571e305af66ff9fd9063a6e662447051737e1ac75beea41"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http",
|
||||
"mime",
|
||||
"rand 0.9.0",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
@ -1710,7 +1843,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"rand_core",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1885,7 +2018,7 @@ dependencies = [
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"rsa",
|
||||
"serde",
|
||||
"sha1",
|
||||
@ -1924,7 +2057,7 @@ dependencies = [
|
||||
"md-5",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
@ -1971,6 +2104,7 @@ name = "stationslauf"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"axum-test",
|
||||
"chrono",
|
||||
"dotenv",
|
||||
"maud",
|
||||
@ -2262,7 +2396,7 @@ dependencies = [
|
||||
"futures",
|
||||
"http",
|
||||
"parking_lot",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@ -2326,6 +2460,12 @@ dependencies = [
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.18.0"
|
||||
@ -2416,6 +2556,15 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
|
||||
dependencies = [
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
@ -2760,6 +2909,12 @@ version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.7.5"
|
||||
|
@ -14,3 +14,6 @@ tokio = { version = "1.44", features = ["macros", "rt-multi-thread"] }
|
||||
tower-sessions = "0.14"
|
||||
tracing = "0.1"
|
||||
rust-i18n = "3"
|
||||
|
||||
[dev-dependencies]
|
||||
axum-test = "17.3"
|
||||
|
@ -1,4 +1,4 @@
|
||||
CREATE TABLE station (
|
||||
CREATE TABLE IF NOT EXISTS station (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
notes TEXT,
|
||||
@ -9,12 +9,12 @@ CREATE TABLE station (
|
||||
lng REAL
|
||||
);
|
||||
|
||||
CREATE TABLE route (
|
||||
CREATE TABLE IF NOT EXISTS route (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE -- e.g. 'wiwö'
|
||||
);
|
||||
|
||||
CREATE TABLE route_station (
|
||||
CREATE TABLE IF NOT EXISTS route_station (
|
||||
route_id INTEGER NOT NULL,
|
||||
station_id INTEGER NOT NULL,
|
||||
pos INTEGER NOT NULL,
|
||||
@ -23,7 +23,7 @@ CREATE TABLE route_station (
|
||||
FOREIGN KEY (station_id) REFERENCES station(id)
|
||||
);
|
||||
|
||||
CREATE TABLE team (
|
||||
CREATE TABLE IF NOT EXISTS team (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
notes TEXT,
|
||||
@ -34,7 +34,7 @@ CREATE TABLE team (
|
||||
FOREIGN KEY (route_id) REFERENCES route(id)
|
||||
);
|
||||
|
||||
CREATE TABLE rating (
|
||||
CREATE TABLE IF NOT EXISTS rating (
|
||||
team_id INTEGER NOT NULL,
|
||||
station_id INTEGER NOT NULL,
|
||||
points INTEGER,
|
||||
|
@ -65,7 +65,7 @@ impl Station {
|
||||
Some(station)
|
||||
}
|
||||
|
||||
async fn create(db: &SqlitePool, name: &str) -> Result<(), String> {
|
||||
pub(crate) async fn create(db: &SqlitePool, name: &str) -> Result<(), String> {
|
||||
sqlx::query!("INSERT INTO station(name) VALUES (?)", name)
|
||||
.execute(db)
|
||||
.await
|
||||
|
25
src/lib.rs
25
src/lib.rs
@ -1,6 +1,19 @@
|
||||
#[macro_use]
|
||||
extern crate rust_i18n;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_export]
|
||||
macro_rules! testdb {
|
||||
() => {{
|
||||
let pool = SqlitePool::connect(":memory:").await.unwrap();
|
||||
sqlx::query_file!("./migration.sql")
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
pool
|
||||
}};
|
||||
}
|
||||
|
||||
i18n!("locales", fallback = "de-AT");
|
||||
|
||||
use admin::station::Station;
|
||||
@ -114,14 +127,13 @@ impl FromRef<AppState> for Arc<SqlitePool> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Starts the main application.
|
||||
pub async fn start(listener: TcpListener, db: SqlitePool) {
|
||||
fn router(db: SqlitePool) -> Router {
|
||||
let session_store = MemoryStore::default();
|
||||
let session_layer = SessionManagerLayer::new(session_store);
|
||||
|
||||
let state = AppState { db: Arc::new(db) };
|
||||
|
||||
let app = Router::new()
|
||||
Router::new()
|
||||
.nest("/s/{id}/{code}", station::routes()) // TODO: maybe switch to "/"
|
||||
.nest("/admin", admin::routes())
|
||||
.route("/pico.css", get(serve_pico_css))
|
||||
@ -130,7 +142,12 @@ pub async fn start(listener: TcpListener, db: SqlitePool) {
|
||||
.route("/leaflet.js", get(serve_leaflet_js))
|
||||
.route("/marker.png", get(serve_marker_png))
|
||||
.with_state(state)
|
||||
.layer(session_layer);
|
||||
.layer(session_layer)
|
||||
}
|
||||
|
||||
/// Starts the main application.
|
||||
pub async fn start(listener: TcpListener, db: SqlitePool) {
|
||||
let app = router(db);
|
||||
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
@ -304,3 +304,42 @@ pub(super) fn routes() -> Router<AppState> {
|
||||
.route("/team-finished/{team_id}", get(team_finished))
|
||||
.route("/remove-left/{team_id}", get(remove_left))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{router, testdb, Station};
|
||||
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
use axum_test::TestServer;
|
||||
|
||||
#[sqlx::test]
|
||||
async fn test_wrong_station() {
|
||||
let pool = testdb!();
|
||||
|
||||
Station::create(&pool, "Teststation").await.unwrap();
|
||||
|
||||
let server = TestServer::new(router(pool)).unwrap();
|
||||
|
||||
let response = server.get("/s/1/wrong-pw").await;
|
||||
|
||||
response.assert_text_contains(
|
||||
"Falscher Quick-Einlogg-Link. Bitte nochmal scannen oder neu eingeben.",
|
||||
);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
async fn test_correct_station() {
|
||||
let pool = testdb!();
|
||||
|
||||
Station::create(&pool, "42-Station").await.unwrap();
|
||||
let stations = Station::all(&pool).await;
|
||||
let station = stations.last().unwrap();
|
||||
|
||||
let server = TestServer::new(router(pool)).unwrap();
|
||||
|
||||
let response = server.get(&format!("/s/1/{}", station.pw)).await;
|
||||
|
||||
response.assert_text_contains("42-Station");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user