atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
bf5f8cb6f60f6e974991335cdfec63b7874a37bf
1
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git
src/tests/methods.rsRust158 lines5.9 KB
1
use super::*;
2
3
#[tokio::test]
4
async fn creating_a_run_returns_location_and_etag() {
5
    let response = send(&app(), "POST", "/runs?seed=1", &[], "").await;
6
    assert_eq!(response.status(), StatusCode::CREATED);
7
    assert!(header(&response, "location").starts_with("/runs/"));
8
    assert!(response.headers().contains_key(header::ETAG));
9
    assert_eq!(header(&response, "server"), "jelqd/0.6.9");
10
}
11
12
#[tokio::test]
13
async fn bodies_do_not_repeat_the_headers() {
14
    let Harness { app, .. } = harness(Floor::Bedroom, SEED, |_| {});
15
    let response = send(&app, "GET", "/runs/cafebabe", &[], "").await;
16
    assert!(response.headers().contains_key("x-eq"));
17
    let body = json(response).await;
18
    for stat in [
19
        "eq",
20
        "girth",
21
        "foreskin",
22
        "stamina",
23
        "cash",
24
        "self_reported_length",
25
    ] {
26
        assert!(body.get(stat).is_none(), "{stat} is already a header");
27
    }
28
}
29
30
#[tokio::test]
31
async fn jelqing_cold_goes_through_at_a_price() {
32
    let friction = async |warm: bool| {
33
        let app = seeded_with(Floor::Bedroom, |run| {
34
            run.body.eq = if warm { 40 } else { 20 };
35
            run.body.foreskin = Some(1.0);
36
        });
37
        let response = send(&app, "JELQ", "/runs/cafebabe?technique=stretch", &[], "").await;
38
        let noted = warnings(&response).iter().any(|w| w.contains("Cold start"));
39
        assert_eq!(noted, !warm);
40
        header(&response, "x-friction").to_owned()
41
    };
42
    assert_eq!(friction(true).await, "1/10");
43
    assert_eq!(friction(false).await, "3/10");
44
}
45
46
#[tokio::test]
47
async fn wet_without_lube_is_unsupported_media() {
48
    let Harness { app, .. } = harness(Floor::Bedroom, SEED, |_| {});
49
    send(&app, "JELQ", "/runs/cafebabe?technique=warmup", &[], "").await;
50
    let response = send(&app, "JELQ", "/runs/cafebabe?technique=wet", &[], "").await;
51
    assert_eq!(response.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE);
52
    let images = send(
53
        &app,
54
        "JELQ",
55
        "/runs/cafebabe?technique=wet",
56
        &[("content-type", "image/jpeg")],
57
        "",
58
    )
59
    .await;
60
    assert_eq!(json(images).await["detail"], "No.");
61
}
62
63
#[tokio::test]
64
async fn unknown_methods_are_not_implemented() {
65
    let Harness { app, .. } = harness(Floor::Bedroom, SEED, |_| {});
66
    let response = send(&app, "MILK", "/runs/cafebabe", &[], "").await;
67
    assert_eq!(response.status(), StatusCode::NOT_IMPLEMENTED);
68
    let teapot = send(&app, "BREW", "/runs/cafebabe", &[], "").await;
69
    assert_eq!(teapot.status(), StatusCode::IM_A_TEAPOT);
70
}
71
72
#[tokio::test]
73
async fn the_clinic_does_not_advertise_jelq() {
74
    let Harness { app, .. } = harness(Floor::Clinic, SEED, |_| {});
75
    let options = send(&app, "OPTIONS", "/runs/cafebabe", &[], "").await;
76
    assert!(!header(&options, "allow").contains("JELQ"));
77
    let jelq = send(&app, "JELQ", "/runs/cafebabe?technique=wet", &[], "").await;
78
    assert_eq!(jelq.status(), StatusCode::METHOD_NOT_ALLOWED);
79
    assert!(!header(&jelq, "allow").contains("JELQ"));
80
    let Harness { app: bedroom, .. } = harness(Floor::Bedroom, SEED, |_| {});
81
    let options = send(&bedroom, "OPTIONS", "/runs/cafebabe", &[], "").await;
82
    assert!(header(&options, "allow").contains("JELQ"));
83
}
84
85
#[tokio::test]
86
async fn patch_only_accepts_the_truth() {
87
    let Harness { app, .. } = harness(Floor::Bedroom, SEED, |_| {});
88
    let patch = [("content-type", "application/json-patch+json")];
89
    let replace = send(
90
        &app,
91
        "PATCH",
92
        "/runs/cafebabe",
93
        &patch,
94
        r#"[{"op":"replace","path":"/length","value":12}]"#,
95
    )
96
    .await;
97
    assert_eq!(replace.status(), StatusCode::UNPROCESSABLE_ENTITY);
98
    let lie = send(
99
        &app,
100
        "PATCH",
101
        "/runs/cafebabe",
102
        &patch,
103
        r#"[{"op":"test","path":"/length","value":40}]"#,
104
    )
105
    .await;
106
    assert_eq!(
107
        json(lie).await["type"],
108
        "https://jelq.dev/problems/exaggeration"
109
    );
110
}
111
112
#[tokio::test]
113
async fn http_1_0_gets_the_pdf_treatment() {
114
    let request = Request::builder()
115
        .uri("/graveyard")
116
        .version(Version::HTTP_10)
117
        .body(Body::empty())
118
        .unwrap();
119
    let response = app().oneshot(request).await.unwrap();
120
    assert_eq!(response.status(), StatusCode::HTTP_VERSION_NOT_SUPPORTED);
121
}
122
123
#[tokio::test]
124
async fn links_offer_only_usable_techniques() {
125
    let app = seeded_with(Floor::Bedroom, |run| run.body.foreskin = Some(1.0));
126
    let cold = send(&app, "GET", "/runs/cafebabe", &[], "").await;
127
    assert!(
128
        advertised(&cold).contains(&"stretch".to_owned()),
129
        "a cold jelq is allowed"
130
    );
131
    let warm = send(&app, "JELQ", "/runs/cafebabe?technique=warmup", &[], "").await;
132
    let usable = advertised(&warm);
133
    assert!(usable.contains(&"wet".to_owned()) && usable.contains(&"dry".to_owned()));
134
    assert!(!usable.contains(&"uli".to_owned()), "uli needs the forum");
135
    assert!(!usable.contains(&"pump".to_owned()), "pump needs a pump");
136
    assert!(
137
        header(&warm, "link").contains("title=\"wet\"; allow=\"JELQ\"; lubricant=\"required\"")
138
    );
139
140
    let Harness { app: forum, .. } = harness(Floor::Forum, SEED, |_| {});
141
    let response = send(&forum, "GET", "/runs/cafebabe", &[], "").await;
142
    assert!(advertised(&response).is_empty());
143
}
144
145
#[tokio::test]
146
async fn links_hide_resources_that_would_do_nothing() {
147
    let Harness { app: bedroom, .. } = harness(Floor::Bedroom, SEED, |_| {});
148
    let before = linked_rels(&send(&bedroom, "GET", "/runs/cafebabe", &[], "").await);
149
    assert!(before.contains(&"drawer".to_owned()));
150
    assert!(!before.contains(&"diagnosis".to_owned()));
151
    assert!(!before.contains(&"thread".to_owned()));
152
    let searched = send(&bedroom, "POST", "/runs/cafebabe/drawer", &[], "").await;
153
    assert!(!linked_rels(&searched).contains(&"drawer".to_owned()));
154
155
    let Harness { app: clinic, .. } = harness(Floor::Clinic, SEED, |_| {});
156
    let rels = linked_rels(&send(&clinic, "GET", "/runs/cafebabe", &[], "").await);
157
    assert!(rels.contains(&"diagnosis".to_owned()) && rels.contains(&"thread".to_owned()));
158
}