Registry / RepositoryTypeScriptRustPython
Rollpie
ReadmeFiles
Versions
Info
Download
0.1.280.1 KB2026-09-140.1.167.6 KB2026-09-140.1.064.9 KB2026-09-14
Version
0.1.1
Copyright
Rollpie, Irohabook
Publisher
math
Published
2026-09-14
Size
67.6 KB
Downloads
3
Checksum
1394ade0d23f53c562acdce1e27a9c4c559f73c22d104e84c7c03c6b2fcc47b0
Dependencies
None

collision.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! mon がパスを 1 つも取らないことを確かめる。
//!
//! 病院が `/health` を診療案内に使う、`/static` を別の意味で使う、自前の 404 を出す。
//! どれも通らなければならない。取ってしまうと、そのパスがそのアプリでは使えなくなる。

use axum::Router;
use axum::body::{Body, to_bytes};
use axum::http::{Request, StatusCode};
use axum::routing::get;
use mon::state::AppState;
use mon::{Conf, database, relay, route, session};
use std::sync::Arc;
use tower::ServiceExt;


async fn app(routes: Router<AppState>) -> Router {
    let conf = Conf::default();
    let database = database::connect("sqlite::memory:").await.unwrap();
    let store = session::store(&conf, &database);
    session::prepare(&store).await.unwrap();

    route::wrap(
        routes,
        AppState {
            database,
            client: relay::client(&conf).unwrap(),
            session: store,
            conf: Arc::new(conf),
        },
    )
}


async fn read(uri: &str, routes: Router<AppState>) -> (StatusCode, String) {
    let request = Request::builder().uri(uri).body(Body::empty()).unwrap();
    let response = app(routes).await.oneshot(request).await.unwrap();
    let status = response.status();
    let content = to_bytes(response.into_body(), 65536).await.unwrap();

    (status, String::from_utf8_lossy(&content).into_owned())
}


/// 病院が `/health` を診療案内のページに使う
#[tokio::test]
async fn health_can_be_a_page() {
    let routes = Router::new().route("/health", get(|| async { "健康について" }));
    let (status, body) = read("/health", routes).await;

    assert_eq!(status, StatusCode::OK);
    assert_eq!(body, "健康について");
}


/// 自前の 404 を出す
#[tokio::test]
async fn the_fallback_is_theirs() {
    let routes = Router::new().fallback(|| async { "こちらの 404" });
    let (_, body) = read("/nowhere", routes).await;

    assert_eq!(body, "こちらの 404");
}


/// `/static` を静的ファイルではない意味で使う
#[tokio::test]
async fn static_can_mean_something_else() {
    let routes = Router::new().route("/static", get(|| async { "静的な話" }));
    let (status, body) = read("/static", routes).await;

    assert_eq!(status, StatusCode::OK);
    assert_eq!(body, "静的な話");
}


/// `/api/session` を自分の用途に使う
#[tokio::test]
async fn the_session_path_is_theirs() {
    let routes = Router::new().route("/api/session", get(|| async { "こちらのセッション" }));
    let (status, body) = read("/api/session", routes).await;

    assert_eq!(status, StatusCode::OK);
    assert_eq!(body, "こちらのセッション");
}


/// mon の部品は好きな名前に置ける
#[tokio::test]
async fn the_parts_go_where_they_are_put() {
    let routes = Router::new().route("/_alive", get(route::health));
    let (status, body) = read("/_alive", routes).await;

    assert_eq!(status, StatusCode::OK);
    assert!(body.contains("ok"), "{body}");
}


/// 何も置かなければ、何も答えない
#[tokio::test]
async fn an_empty_router_answers_nothing() {
    let (status, _) = read("/health", Router::new()).await;
    assert_eq!(status, StatusCode::NOT_FOUND);
}