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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
mod fixtures;
mod utils;
use fixtures::{server, Error, TestServer, DEEPLY_NESTED_FILE, DIRECTORIES};
use pretty_assertions::{assert_eq, assert_ne};
use rstest::rstest;
use select::document::Document;
use std::process::{Command, Stdio};
use utils::get_link_from_text;
#[rstest(
input,
expected,
case("", "/"),
case("/dira", "/dira/"),
case("/dirb/", "/dirb/"),
case("/very/deeply/nested", "/very/deeply/nested/")
)]
/// Directories get a trailing slash.
fn index_gets_trailing_slash(server: TestServer, input: &str, expected: &str) -> Result<(), Error> {
let resp = reqwest::blocking::get(server.url().join(input)?)?;
assert!(resp.url().as_str().ends_with(expected));
Ok(())
}
#[rstest]
/// Can't navigate up the root.
fn cant_navigate_up_the_root(server: TestServer) -> Result<(), Error> {
// We're using curl for this as it has the option `--path-as-is` which doesn't normalize
// invalid urls. A useful feature in this particular case.
let base_url = server.url();
let curl_successful = Command::new("curl")
.arg("-s")
.arg("--fail")
.arg("--path-as-is")
.arg(format!("{base_url}/../"))
.stdout(Stdio::null())
.status()?
.success();
assert!(curl_successful);
Ok(())
}
#[rstest]
/// We can navigate into directories and back using shown links.
fn can_navigate_into_dirs_and_back(server: TestServer) -> Result<(), Error> {
let base_url = server.url();
let initial_body = reqwest::blocking::get(base_url.as_str())?.error_for_status()?;
let initial_parsed = Document::from_read(initial_body)?;
for &directory in DIRECTORIES {
let dir_elem = get_link_from_text(&initial_parsed, directory).expect("Dir not found.");
let body =
reqwest::blocking::get(&format!("{base_url}{dir_elem}"))?.error_for_status()?;
let parsed = Document::from_read(body)?;
let back_link =
get_link_from_text(&parsed, "Parent directory").expect("Back link not found.");
let resp = reqwest::blocking::get(&format!("{base_url}{back_link}"))?;
// Now check that we can actually get back to the original location we came from using the
// link.
assert_eq!(resp.url().as_str(), base_url.as_str());
}
Ok(())
}
#[rstest]
/// We can navigate deep into the file tree and back using shown links.
fn can_navigate_deep_into_dirs_and_back(server: TestServer) -> Result<(), Error> {
// Create a vector of directory names. We don't need to fetch the file and so we'll
// remove that part.
let dir_names = {
let mut comps = DEEPLY_NESTED_FILE
.split('/')
.map(|d| format!("{d}/"))
.collect::<Vec<String>>();
comps.pop();
comps
};
let base_url = server.url();
// First we'll go forwards through the directory tree and then we'll go backwards.
// In the end, we'll have to end up where we came from.
let mut next_url = base_url.clone();
for dir_name in dir_names.iter() {
let resp = reqwest::blocking::get(next_url.as_str())?;
let body = resp.error_for_status()?;
let parsed = Document::from_read(body)?;
let dir_elem = get_link_from_text(&parsed, dir_name).expect("Dir not found.");
next_url = next_url.join(&dir_elem)?;
}
assert_ne!(base_url, next_url);
// Now try to get out the tree again using links only.
while next_url != base_url {
let resp = reqwest::blocking::get(next_url.as_str())?;
let body = resp.error_for_status()?;
let parsed = Document::from_read(body)?;
let dir_elem =
get_link_from_text(&parsed, "Parent directory").expect("Back link not found.");
next_url = next_url.join(&dir_elem)?;
}
assert_eq!(base_url, next_url);
Ok(())
}
#[rstest]
#[case(server(&["--title", "some title"]), "some title")]
#[case(server(None::<&str>), format!("localhost:{}", server.port()))]
/// We can use breadcrumbs to navigate.
fn can_navigate_using_breadcrumbs(
#[case] server: TestServer,
#[case] title_name: String,
) -> Result<(), Error> {
// Create a vector of directory names. We don't need to fetch the file and so we'll
// remove that part.
let dir: String = {
let mut comps = DEEPLY_NESTED_FILE
.split('/')
.map(|d| format!("{d}/"))
.collect::<Vec<String>>();
comps.pop();
comps.join("")
};
let base_url = server.url();
let nested_url = base_url.join(&dir)?;
let resp = reqwest::blocking::get(nested_url.as_str())?;
let body = resp.error_for_status()?;
let parsed = Document::from_read(body)?;
// can go back to root dir by clicking title
let title_link = get_link_from_text(&parsed, &title_name).expect("Root dir link not found.");
assert_eq!("/", title_link);
// can go to intermediate dir
let intermediate_dir_link =
get_link_from_text(&parsed, "very").expect("Intermediate dir link not found.");
assert_eq!("/very/", intermediate_dir_link);
// current dir is not linked
let current_dir_link = get_link_from_text(&parsed, "nested");
assert_eq!(None, current_dir_link);
Ok(())
}
|