{ lib, pkgs }:
let
  # TODO: specify project/service name globally
  name = "panel";
  defaults = {
    services.${name} = {
      enable = true;
      production = false;
      restart = "no";
      domain = "example.com";
      secrets = {
        SECRET_KEY = pkgs.writeText "SECRET_KEY" "secret";
      };
    };

    virtualisation = {
      memorySize = 2048;
      cores = 2;
    };
  };
in
lib.mapAttrs (name: test: pkgs.testers.runNixOSTest (test // { inherit name; })) {
  application-tests = {
    inherit defaults;
    nodes.server = _: { imports = [ ./configuration.nix ]; };
    # run all application-level tests managed by Django
    # https://docs.djangoproject.com/en/5.0/topics/testing/overview/
    testScript = ''
      server.succeed("manage test ${name}")
    '';
  };
  admin = {
    inherit defaults;
    nodes.server = _: { imports = [ ./configuration.nix ]; };
    # check that the admin interface is served
    testScript = ''
      server.wait_for_unit("multi-user.target")
      server.wait_for_unit("${name}.service")
      server.wait_for_open_port(8000)
      server.succeed("curl --fail -L -H 'Host: example.org' http://localhost/admin")
    '';
  };

  sass-processing = {
    inherit defaults;
    nodes.server = _: { imports = [ ./configuration.nix ]; };
    extraPythonPackages = ps: with ps; [ beautifulsoup4 ];
    skipTypeCheck = true;
    # check that stylesheets are pre-processed and served
    testScript = ''
      from bs4 import BeautifulSoup
      server.wait_for_unit("multi-user.target")
      server.wait_for_unit("${name}.service")
      server.wait_for_open_port(8000)
      stdout = server.succeed("curl --fail -H 'Host: example.org' http://localhost")
      # the CSS is auto-generated with a hash in the file name
      html = BeautifulSoup(stdout, 'html.parser')
      css = html.find('link', type="text/css")['href']
      server.succeed(f"curl --fail -H 'Host: example.org' http://localhost/{css}")
    '';
  };
}