aboutsummaryrefslogtreecommitdiff
path: root/src/tests.rs
blob: 47970418e6782f8182975284a849f0f99ba78dd9 (plain)
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
104
105
106
#![cfg(test)]
use std::{future::Future, path::PathBuf, pin::Pin};

use crate::{controller::Controller, StaticContext};

use super::{
    controller::{MultiUserController, SoloController},
    origins::HttpOrigin,
};
use git2::Repository;
use hyper::{body, http::request::Builder, Body, Request, Response};
use tempdir::TempDir;

fn temp_repo() -> (PathBuf, Repository) {
    let path = TempDir::new("gitpad-test").unwrap().into_path();
    let repo = Repository::init_bare(&path).unwrap();
    (path, repo)
}

fn origin() -> HttpOrigin {
    "http://pad.example.com".parse().unwrap()
}

struct Server<C> {
    context: StaticContext,
    repo: Repository,
    controller: C,
}

impl Server<SoloController> {
    fn new() -> Self {
        let (repo_path, repo) = temp_repo();
        let origin = origin();
        Self {
            context: StaticContext { repo_path, origin },
            controller: SoloController::new(&repo),
            repo,
        }
    }
}

impl Server<MultiUserController> {
    fn new() -> Self {
        let (repo_path, repo) = temp_repo();
        let origin = origin();
        Self {
            context: StaticContext { repo_path, origin },
            controller: MultiUserController::new(&repo),
            repo,
        }
    }
}

impl<C: Controller> Server<C> {
    async fn serve(&self, req: Request<Body>) -> Response<Body> {
        super::service(&self.context, &self.controller, req).await
    }
}

trait IntoText {
    fn into_text(self) -> Pin<Box<dyn Future<Output = String>>>;
}

impl IntoText for Body {
    fn into_text(self) -> Pin<Box<dyn Future<Output = String>>> {
        Box::pin(async move {
            std::str::from_utf8(&body::to_bytes(self).await.unwrap())
                .unwrap()
                .to_string()
        })
    }
}

#[tokio::test]
async fn test_no_host_header() {
    let server = Server::<SoloController>::new();
    let res = server.serve(Builder::new().body("".into()).unwrap()).await;
    assert_eq!(res.status(), 400);
    assert!(res
        .into_body()
        .into_text()
        .await
        .contains("Host header required"));
}

#[tokio::test]
async fn test_missing_branch() {
    let server = Server::<SoloController>::new();

    let res = server
        .serve(
            Builder::new()
                .header("host", server.context.origin.host())
                .body("".into())
                .unwrap(),
        )
        .await;
    assert_eq!(res.status(), 200);
    assert!(res
        .into_body()
        .into_text()
        .await
        .contains("create files by editing the URL"));

    // TODO: create file and test that it is retrievable
}