| 39 |
39 |
|
//! against six others by hand.
|
| 40 |
40 |
|
|
| 41 |
41 |
|
use makeover_layout as layout;
|
| 42 |
|
- |
use quasi_router::screen::{Act, Row};
|
| 43 |
|
- |
use quasi_router::{
|
| 44 |
|
- |
Action, Document, Node, RegionKind, Request, Response, RouteError, Screen as Described, Slot,
|
| 45 |
|
- |
};
|
|
42 |
+ |
use quasi_declare::declare;
|
|
43 |
+ |
use quasi_router::{Document, Request, Response, RouteError};
|
| 46 |
44 |
|
use quasi_webview::Webview;
|
| 47 |
45 |
|
|
| 48 |
46 |
|
/// The address, registered whole. See [`super::public_document_mount`].
|
| 120 |
118 |
|
},
|
| 121 |
119 |
|
];
|
| 122 |
120 |
|
|
|
121 |
+ |
/// One of the other policy documents.
|
|
122 |
+ |
///
|
|
123 |
+ |
/// Named members rather than a tuple, for the reason [`Section`] has them: a
|
|
124 |
+ |
/// description names what it draws, and `.1` is not a name.
|
|
125 |
+ |
struct Other {
|
|
126 |
+ |
title: &'static str,
|
|
127 |
+ |
covers: &'static str,
|
|
128 |
+ |
route: &'static str,
|
|
129 |
+ |
}
|
|
130 |
+ |
|
| 123 |
131 |
|
/// The other policy documents: a title, what it covers, and where it lives.
|
| 124 |
|
- |
const OTHER: &[(&str, &str, &str)] = &[
|
| 125 |
|
- |
(
|
| 126 |
|
- |
"Terms of Service",
|
| 127 |
|
- |
"What you agree to by using Makenotwork",
|
| 128 |
|
- |
"/docs/terms-of-service",
|
| 129 |
|
- |
),
|
| 130 |
|
- |
(
|
| 131 |
|
- |
"Privacy Policy",
|
| 132 |
|
- |
"What we collect, why, and how to exercise your rights",
|
| 133 |
|
- |
"/docs/privacy-policy",
|
| 134 |
|
- |
),
|
| 135 |
|
- |
(
|
| 136 |
|
- |
"Payments & Refunds",
|
| 137 |
|
- |
"Merchant-of-record model, refunds, chargebacks",
|
| 138 |
|
- |
"/docs/payments",
|
| 139 |
|
- |
),
|
| 140 |
|
- |
(
|
| 141 |
|
- |
"Acceptable Use",
|
| 142 |
|
- |
"Specific behaviour that gets accounts suspended",
|
| 143 |
|
- |
"/docs/acceptable-use",
|
| 144 |
|
- |
),
|
| 145 |
|
- |
(
|
| 146 |
|
- |
"Copyright & DMCA",
|
| 147 |
|
- |
"How takedowns and counter-notifications work",
|
| 148 |
|
- |
"/docs/copyright",
|
| 149 |
|
- |
),
|
| 150 |
|
- |
(
|
| 151 |
|
- |
"Appeals",
|
| 152 |
|
- |
"How to challenge a moderation decision",
|
| 153 |
|
- |
"/docs/appeals",
|
| 154 |
|
- |
),
|
| 155 |
|
- |
(
|
| 156 |
|
- |
"Mailing List Data Processing",
|
| 157 |
|
- |
"Who answers a subscriber's request about a project mailing list",
|
| 158 |
|
- |
"/docs/mailing-list-data-processing",
|
| 159 |
|
- |
),
|
|
132 |
+ |
const OTHER: &[Other] = &[
|
|
133 |
+ |
Other {
|
|
134 |
+ |
title: "Terms of Service",
|
|
135 |
+ |
covers: "What you agree to by using Makenotwork",
|
|
136 |
+ |
route: "/docs/terms-of-service",
|
|
137 |
+ |
},
|
|
138 |
+ |
Other {
|
|
139 |
+ |
title: "Privacy Policy",
|
|
140 |
+ |
covers: "What we collect, why, and how to exercise your rights",
|
|
141 |
+ |
route: "/docs/privacy-policy",
|
|
142 |
+ |
},
|
|
143 |
+ |
Other {
|
|
144 |
+ |
title: "Payments & Refunds",
|
|
145 |
+ |
covers: "Merchant-of-record model, refunds, chargebacks",
|
|
146 |
+ |
route: "/docs/payments",
|
|
147 |
+ |
},
|
|
148 |
+ |
Other {
|
|
149 |
+ |
title: "Acceptable Use",
|
|
150 |
+ |
covers: "Specific behaviour that gets accounts suspended",
|
|
151 |
+ |
route: "/docs/acceptable-use",
|
|
152 |
+ |
},
|
|
153 |
+ |
Other {
|
|
154 |
+ |
title: "Copyright & DMCA",
|
|
155 |
+ |
covers: "How takedowns and counter-notifications work",
|
|
156 |
+ |
route: "/docs/copyright",
|
|
157 |
+ |
},
|
|
158 |
+ |
Other {
|
|
159 |
+ |
title: "Appeals",
|
|
160 |
+ |
covers: "How to challenge a moderation decision",
|
|
161 |
+ |
route: "/docs/appeals",
|
|
162 |
+ |
},
|
|
163 |
+ |
Other {
|
|
164 |
+ |
title: "Mailing List Data Processing",
|
|
165 |
+ |
covers: "Who answers a subscriber's request about a project mailing list",
|
|
166 |
+ |
route: "/docs/mailing-list-data-processing",
|
|
167 |
+ |
},
|
| 160 |
168 |
|
];
|
| 161 |
169 |
|
|
| 162 |
170 |
|
/// The page. Reads nothing.
|
| 164 |
172 |
|
Ok(page_screen().into())
|
| 165 |
173 |
|
}
|
| 166 |
174 |
|
|
| 167 |
|
- |
/// The whole document: the title, the measure, the body.
|
| 168 |
|
- |
fn page_screen() -> Described {
|
| 169 |
|
- |
let mut page = Slot::new(PAGE_REGION, RegionKind::Pane)
|
| 170 |
|
- |
.with(Node::page("Content Policy"))
|
| 171 |
|
- |
.with(Node::text(
|
| 172 |
|
- |
"Makenotwork exists so creators can sell their work on fair terms. This policy \
|
| 173 |
|
- |
describes what belongs here, what doesn't, and how we handle problems.",
|
| 174 |
|
- |
));
|
|
175 |
+ |
declare! {
|
|
176 |
+ |
/// The whole document: the title, the measure, the body.
|
|
177 |
+ |
shape page_screen() -> Screen;
|
| 175 |
178 |
|
|
| 176 |
|
- |
for section in SECTIONS {
|
| 177 |
|
- |
page = page
|
| 178 |
|
- |
.with(Node::section(section.heading))
|
| 179 |
|
- |
.with(super::own_prose(section.body));
|
|
179 |
+ |
screen single "Content Policy - Makenotwork" {
|
|
180 |
+ |
measured MEASURE;
|
|
181 |
+ |
documented Document::default().classed(crate::shell::body_class(MEASURE, &["policy-page"]));
|
|
182 |
+ |
summarised "What belongs on Makenotwork, what doesn't, and how problems are handled.";
|
|
183 |
+ |
|
|
184 |
+ |
region PAGE_REGION as Pane {
|
|
185 |
+ |
page "Content Policy";
|
|
186 |
+ |
text "Makenotwork exists so creators can sell their work on fair terms. This policy \
|
|
187 |
+ |
describes what belongs here, what doesn't, and how we handle problems.";
|
|
188 |
+ |
|
|
189 |
+ |
for part in SECTIONS {
|
|
190 |
+ |
section part.heading;
|
|
191 |
+ |
include super::own_prose(part.body);
|
|
192 |
+ |
}
|
|
193 |
+ |
|
|
194 |
+ |
section "Other Policies";
|
|
195 |
+ |
list {
|
|
196 |
+ |
for other in OTHER {
|
|
197 |
+ |
row other.title {
|
|
198 |
+ |
secondary other.covers;
|
|
199 |
+ |
act "Read" to get other.route navigating;
|
|
200 |
+ |
}
|
|
201 |
+ |
}
|
|
202 |
+ |
}
|
|
203 |
+ |
|
|
204 |
+ |
section "Questions";
|
|
205 |
+ |
include super::own_prose(QUESTIONS);
|
|
206 |
+ |
}
|
| 180 |
207 |
|
}
|
| 181 |
|
- |
|
| 182 |
|
- |
page = page
|
| 183 |
|
- |
.with(Node::section("Other Policies"))
|
| 184 |
|
- |
.with(Node::list(OTHER.iter().map(|(title, covers, route)| {
|
| 185 |
|
- |
Row::new(*title)
|
| 186 |
|
- |
.secondary(*covers)
|
| 187 |
|
- |
.act(Act::new("Read", Action::get(*route).navigating()))
|
| 188 |
|
- |
})));
|
| 189 |
|
- |
|
| 190 |
|
- |
page = page.with(Node::section("Questions")).with(super::own_prose(
|
| 191 |
|
- |
"If something's unclear or you want to check before posting, reach out at \
|
| 192 |
|
- |
**policy@makenot.work**.",
|
| 193 |
|
- |
));
|
| 194 |
|
- |
|
| 195 |
|
- |
Described::single("Content Policy - Makenotwork")
|
| 196 |
|
- |
.measured(MEASURE)
|
| 197 |
|
- |
.documented(
|
| 198 |
|
- |
Document::default().classed(crate::shell::body_class(MEASURE, &["policy-page"])),
|
| 199 |
|
- |
)
|
| 200 |
|
- |
.summarised("What belongs on Makenotwork, what doesn't, and how problems are handled.")
|
| 201 |
|
- |
.with(page)
|
| 202 |
208 |
|
}
|
| 203 |
209 |
|
|
|
210 |
+ |
/// The closing paragraph, a const so the declaration reads as one sentence
|
|
211 |
+ |
/// rather than as a paragraph in an argument.
|
|
212 |
+ |
const QUESTIONS: &str = "If something's unclear or you want to check before posting, reach out \
|
|
213 |
+ |
at **policy@makenot.work**.";
|
|
214 |
+ |
|
| 204 |
215 |
|
/// The document this screen is drawn in. Same shape as the other public
|
| 205 |
216 |
|
/// documents: the skip link and the site header, whose user is optional here.
|
| 206 |
217 |
|
#[must_use]
|
| 273 |
284 |
|
fn every_other_policy_keeps_its_row_and_its_route() {
|
| 274 |
285 |
|
let html = html();
|
| 275 |
286 |
|
|
| 276 |
|
- |
for (title, _, route) in OTHER {
|
| 277 |
|
- |
let escaped = crate::helpers::escape_html(title);
|
| 278 |
|
- |
assert!(html.contains(&escaped), "{title} missing");
|
| 279 |
|
- |
assert!(html.contains(route), "{route} missing");
|
|
287 |
+ |
for other in OTHER {
|
|
288 |
+ |
let escaped = crate::helpers::escape_html(other.title);
|
|
289 |
+ |
assert!(html.contains(&escaped), "{} missing", other.title);
|
|
290 |
+ |
assert!(html.contains(other.route), "{} missing", other.route);
|
| 280 |
291 |
|
}
|
| 281 |
292 |
|
}
|
| 282 |
293 |
|
|