1{ pkgs, lib, ... }:
2{
3 name = "tandoor-recipes-script-name";
4
5 nodes.machine =
6 { pkgs, nodes, ... }:
7 {
8 services.tandoor-recipes = {
9 enable = true;
10 extraConfig = {
11 SCRIPT_NAME = "/any/path";
12 STATIC_URL = "${nodes.machine.services.tandoor-recipes.extraConfig.SCRIPT_NAME}/static/";
13 };
14 };
15 };
16
17 testScript =
18 { nodes, ... }:
19 let
20 inherit (nodes.machine.services.tandoor-recipes) address port;
21 inherit (nodes.machine.services.tandoor-recipes.extraConfig) SCRIPT_NAME;
22 in
23 ''
24 from html.parser import HTMLParser
25
26 origin_url = "http://${address}:${toString port}"
27 base_url = f"{origin_url}${SCRIPT_NAME}"
28 login_path = "/admin/login/"
29 login_url = f"{base_url}{login_path}"
30
31 cookie_jar_path = "/tmp/cookies.txt"
32 curl = f"curl --cookie {cookie_jar_path} --cookie-jar {cookie_jar_path} --fail --header 'Origin: {origin_url}' --show-error --silent"
33
34 print("Wait for the service to respond")
35 machine.wait_for_unit("tandoor-recipes.service")
36 machine.wait_until_succeeds(f"{curl} {login_url}")
37
38 username = "username"
39 password = "password"
40
41 print("Create admin user")
42 machine.succeed(
43 f"DJANGO_SUPERUSER_PASSWORD='{password}' /var/lib/tandoor-recipes/tandoor-recipes-manage createsuperuser --no-input --username='{username}' --email=nobody@example.com"
44 )
45
46 print("Get CSRF token for later requests")
47 csrf_token = machine.succeed(f"grep csrftoken {cookie_jar_path} | cut --fields=7").rstrip()
48
49 print("Log in as admin user")
50 machine.succeed(
51 f"{curl} --data 'csrfmiddlewaretoken={csrf_token}' --data 'username={username}' --data 'password={password}' {login_url}"
52 )
53
54 print("Get the contents of the logged in main page")
55 logged_in_page = machine.succeed(f"{curl} --location {base_url}")
56
57 class UrlParser(HTMLParser):
58 def __init__(self):
59 super().__init__()
60
61 self.urls: list[str] = []
62
63 def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
64 if tag == "form":
65 for name, value in attrs:
66 if name == "action" and value is not None:
67 assert not value.endswith(login_path)
68 break
69
70 if tag != "a":
71 return
72
73 for name, value in attrs:
74 if name == "href" and value is not None:
75 if value.startswith(base_url):
76 self.urls.append(value)
77 elif value.startswith("/"):
78 self.urls.append(f"{origin_url}{value}")
79 else:
80 print(f"Ignoring non-path URL: {value}")
81
82 break
83
84 parser = UrlParser()
85 parser.feed(logged_in_page)
86
87 for url in parser.urls:
88 with subtest(f"Verify that {url} can be reached"):
89 machine.succeed(f"{curl} {url}")
90 '';
91
92 meta.maintainers = with lib.maintainers; [ l0b0 ];
93}