about summary refs log tree commit diff
path: root/nixos-tests/webmention-test.nix
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2023-07-22 16:23:54 +0300
committerVika <vika@fireburn.ru>2023-07-22 16:23:54 +0300
commit22e5f4894e532203c78c140895851d3c1d6c86df (patch)
treed826eb746b7aa4e7fece60416e52e01970e0e8db /nixos-tests/webmention-test.nix
parent50c8f7d8f5f04c717ef4e72d873bf994c03efda0 (diff)
Add a NixOS test for receiving webmentions
Diffstat (limited to 'nixos-tests/webmention-test.nix')
-rw-r--r--nixos-tests/webmention-test.nix161
1 files changed, 161 insertions, 0 deletions
diff --git a/nixos-tests/webmention-test.nix b/nixos-tests/webmention-test.nix
new file mode 100644
index 0000000..2161e88
--- /dev/null
+++ b/nixos-tests/webmention-test.nix
@@ -0,0 +1,161 @@
+kittybox:
+{ lib, ... }: let
+  hosts = ''
+    192.168.2.101 kittybox.test
+    192.168.2.102 another.test
+  '';
+in {
+  name = "nixos-kittybox";
+
+  nodes = {
+    kittybox = { config, pkgs, lib, ... }: {
+      imports = [ kittybox.nixosModules.default ];
+
+      services.postgresql = {
+        enable = true;
+        ensureDatabases = ["kittybox"];
+        ensureUsers = [ {
+          name = "kittybox";
+          ensurePermissions = {
+            "DATABASE kittybox" = "ALL PRIVILEGES";
+          };
+        } ];
+      };
+
+      networking = {
+        interfaces.eth1 = {
+          ipv4.addresses = [
+            { address = "192.168.2.101"; prefixLength = 24; }
+          ];
+        };
+        extraHosts = hosts;
+        firewall.allowedTCPPorts = [ 443 ];
+        firewall.allowedUDPPorts = [ 443 ];
+      };
+
+      
+      services.kittybox = {
+        enable = true;
+        logLevel = "info,kittybox=debug,retainer::cache=warn,h2=warn,rustls=warn";
+        backendUri = "postgres://localhost?host=/run/postgresql&dbname=kittybox";
+        jobQueueUri = config.services.kittybox.backendUri;
+      };
+
+      systemd.services.kittybox.wants = [ "postgresql.service" ];
+      systemd.services.kittybox.after = [ "postgresql.service" ];
+      systemd.services.kittybox.environment = {
+        "KITTYBOX_CUSTOM_PKI_ROOTS" = ./tls/rootCA.pem;
+      };
+
+      environment.systemPackages = with pkgs; [
+        xh
+      ];
+
+      services.nginx = {
+        enable = true;
+        recommendedProxySettings = true;
+        virtualHosts = {
+          "kittybox.test" = {
+            forceSSL = true;
+            sslCertificate = ./tls/kittybox.test.pem;
+            sslCertificateKey = ./tls/kittybox.test-key.pem;
+            locations = {
+              "/" = {
+                proxyPass = "http://localhost:8080";
+              };
+            };
+          };
+        };
+      };
+
+      security.pki.certificates = [
+        (builtins.readFile ./tls/rootCA.pem)
+      ];
+    };
+
+    another = { config, pkgs, lib, ... }: {
+      networking = {
+        interfaces.eth1 = {
+          ipv4.addresses = [
+            { address = "192.168.2.102"; prefixLength = 24; }
+          ];
+        };
+        extraHosts = hosts;
+        firewall.allowedTCPPorts = [ 443 ];
+        firewall.allowedUDPPorts = [ 443 ];
+      };
+
+      services.nginx = {
+        enable = true;
+        virtualHosts = {
+          "another.test" = {
+            forceSSL = true;
+            sslCertificate = ./tls/another.test.pem;
+            sslCertificateKey = ./tls/another.test-key.pem;
+            locations = {
+              "/" = {
+                root = ./webmention-test;
+              };
+            };
+          };
+        };
+      };
+
+      environment.systemPackages = with pkgs; [
+        xh
+      ];
+
+      security.pki.certificates = [
+        (builtins.readFile ./tls/rootCA.pem)
+      ];
+    };
+  };
+
+  testScript = ''
+    import json
+    import shlex
+    import time
+
+    post_mf2 = {
+        "type": ["h-entry"],
+        "properties": {
+            "uid": ["https://kittybox.test/posts/test-post"],
+            "url": ["https://kittybox.test/posts/test-post"],
+            "published": ["2023-07-22T14:04:53+0300"],
+            "content": [{"html": "<p>Hello! This is a test post.</p>"}],
+            "author": ["https://kittybox.test/"],
+        }
+    }
+
+    start_all()
+
+    with subtest("Verify that Kittybox started correctly..."):
+        kittybox.wait_for_unit("default.target")
+        kittybox.succeed("xh --no-check-status https://kittybox.test/.kittybox/micropub")
+
+    with subtest("Onboarding should correctly work..."):
+        kittybox.copy_from_host("${./onboarding.json}", "/root/onboarding.json")
+        kittybox.succeed("xh --follow https://kittybox.test/.kittybox/onboarding -j @/root/onboarding.json")
+        # Testing for a known string is the easiest way to determine that the onboarding worked
+        kittybox.succeed("xh https://kittybox.test/ | grep 'vestige of the past long gone'")
+
+    with subtest("The other host should also be reachable..."):
+        another.wait_for_unit("default.target")
+        another.succeed("xh https://another.test/ | grep 'This is a test webmention.'")
+
+    with subtest("Kittybox accepts a webmention to a valid post..."):
+        # Note: we don't really have a way to "authenticate" here.
+        # Let's insert the post manually.
+        print(kittybox.succeed("sudo -u postgres psql kittybox -c \"INSERT INTO kittybox.mf2_json (uid, mf2, owner) VALUES ('https://kittybox.test/posts/test-post', '" + json.dumps(post_mf2).replace("\"", "\\\"").replace("'", "'" * 2) + "', 'kittybox.test') RETURNING uid\""))
+        print(kittybox.succeed("sudo -u postgres psql -A kittybox -c \"SELECT mf2 FROM kittybox.mf2_json WHERE uid = 'https://kittybox.test/posts/test-post'\""))
+        kittybox.succeed("xh --verify ${./tls/rootCA.pem} https://kittybox.test/posts/test-post")
+
+        another.succeed("xh --verify ${./tls/rootCA.pem} https://kittybox.test/.kittybox/webmention --form source=https://another.test/index.html target=https://kittybox.test/posts/test-post")
+        # Wait a while to let the async tasks settle...
+        time.sleep(2)
+        # Ensure the webmention has propagated
+        # Kittybox doesn't fully render them yet, but the counters are there
+        kittybox.succeed("xh --verify ${./tls/rootCA.pem} https://kittybox.test/posts/test-post | grep " + shlex.quote('<span class="icon" aria-label="replies">💬</span><span class="counter">1</span>'))
+        
+'';
+}