feat(flake): Add unit testing

Change-Id: Idc9bbca0e752b21a5293e2ad4819da9af42ca8ca
Reviewed-on: https://git.clicks.codes/c/Infra/NixFiles/+/782
Tested-by: Skyler Grey <minion@clicks.codes>
Reviewed-by: Samuel Shuert <coded@clicks.codes>
diff --git a/flake.nix b/flake.nix
index da9ce5a..00c6592 100644
--- a/flake.nix
+++ b/flake.nix
@@ -10,16 +10,17 @@
     nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
     unstable.url = "github:nixos/nixpkgs/nixos-unstable";
 
-    snowfall-lib = {
-      url = "github:snowfallorg/lib/dev";
-      inputs.nixpkgs.follows = "nixpkgs";
-    };
 
     deploy-rs = {
       url = "github:serokell/deploy-rs";
       inputs.nixpkgs.follows = "nixpkgs";
     };
 
+    snowfall-lib = {
+      url = "github:snowfallorg/lib";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
+
     sops-nix = {
       url = "github:Mic92/sops-nix";
       inputs = {
@@ -34,7 +35,7 @@
   outputs =
     inputs:
     let
-      lib = inputs.snowfall-lib.mkLib {
+      lib = (inputs.snowfall-lib.mkLib {
         inherit inputs;
 
         src = ./.;
@@ -42,7 +43,7 @@
         snowfall = {
           namespace = "clicks";
         };
-      };
+      }).snowfall.internal.system-lib;
     in
     lib.mkFlake {
       overlays = with inputs; [ ];
@@ -52,17 +53,42 @@
         inputs.sops-nix.nixosModules.sops
       ];
 
-      deploy = lib.deploy.mkDeploy {
+      deploy = lib.clicks.deploy.mkDeploy {
         inherit (inputs) self;
         overrides = {
           teal.hostname = "teal.alpha.clicks.domains";
         };
       };
 
-      checks = builtins.mapAttrs (
-        system: deploy-lib: deploy-lib.deployChecks inputs.self.deploy
-      ) inputs.deploy-rs.lib;
+      outputs-builder = channels: {
+        specs = let
+          nixFiles = lib.snowfall.fs.get-nix-files-recursive ./.;
+          specFiles = builtins.filter (lib.clicks.strings.endsWith ".spec.nix") nixFiles;
+          importedSpecs = lib.forEach specFiles (file: {
+            name = builtins.unsafeDiscardStringContext (builtins.baseNameOf file);
+            value = import file {
+              inherit channels lib;
+            };
+          });
+        in builtins.listToAttrs importedSpecs;
 
-      outputs-builder = channels: { formatter = channels.nixpkgs.nixfmt-rfc-style; };
+        formatter = channels.nixpkgs.nixfmt-rfc-style;
+
+        checks = let
+          allChecks = {
+            deploy-rs = lib.deploy-rs.${channels.nixpkgs.system}.deployChecks inputs.self.deploy;
+            clicks = lib.clicks.checks channels.nixpkgs;
+          };
+
+          mergedChecks = lib.trivial.pipe allChecks [
+            (lib.attrsets.mapAttrsToList (sourceName: (lib.attrsets.mapAttrsToList (checkName: value: {
+              name = "${sourceName}:${checkName}";
+              inherit value;
+            }))))
+            lib.lists.flatten
+            builtins.listToAttrs
+          ];
+        in mergedChecks;
+      };
     };
 }