(defmodule lamina_m5_tests
(export all)
(include-lib "eunit/include/eunit.hrl"))
(defun org-crud-and-empty-delete-rule_test ()
(with-db
(lambda ()
(assert-ok (lamina_org_mgr:create "acme" "Acme projects"))
(let* ((row (hd (lamina_org_mgr:list-orgs)))
(id (lists:nth 1 row)))
(assert-ok (lamina_org_mgr:update-org id "team" "Renamed"))
(let ((updated (lamina_org_mgr:get id)))
(if (and (=:= #"team" (lists:nth 2 updated))
(=:= #"Renamed" (lists:nth 3 updated)))
(assert-ok (lamina_org_mgr:delete id))
(erlang:error (list "organization update was not persisted" updated))))))))
(defun nonempty-org-cannot-delete_test ()
(with-db
(lambda ()
(assert-ok (lamina_org_mgr:create "acme" ""))
(let* ((row (hd (lamina_org_mgr:list-orgs)))
(id (lists:nth 1 row)))
(lamina_db:q
"INSERT INTO repositories(name,organization_id,source,setup_username,setup_password_enc,fossil_path,created_at,updated_at) VALUES(?,?,'local',?,x'00',?,?,?);"
(list "demo" id "admin" "/tmp/m5-demo.fossil" "now" "now"))
(assert-error (lamina_org_mgr:delete id))))))
(defun organization-name-conflict_test ()
(with-db
(lambda ()
(lamina_db:q
"INSERT INTO repositories(name,organization_id,source,setup_username,setup_password_enc,fossil_path,created_at,updated_at) VALUES(?,NULL,'local',?,x'00',?,?,?);"
(list "platform" "admin" "/tmp/m5-platform.fossil" "now" "now"))
(assert-error (lamina_org_mgr:create "platform" "")))))
(defun public-index-grouping-and-order_test ()
(with-db
(lambda ()
(lamina_db:exec "INSERT INTO organizations(name,description,created_at) VALUES('first','','2026-01-01T00:00:00Z');")
(let ((first-id (lamina_db:last-rowid)))
(lamina_db:exec "INSERT INTO organizations(name,description,created_at) VALUES('second','','2026-02-01T00:00:00Z');")
(let ((second-id (lamina_db:last-rowid)))
(insert-summary "p-old" 'none "2026-01-01T00:00:00Z" "2026-01-01T00:00:00Z")
(insert-summary "p-new" 'none "2026-02-01T00:00:00Z" "2026-02-01T00:00:00Z")
(insert-summary "first-repo" first-id "2026-01-01T00:00:00Z" "2026-03-01T00:00:00Z")
(insert-summary "second-repo" second-id "2026-02-01T00:00:00Z" "2026-01-01T00:00:00Z")
(let* ((data (lamina_site_mgr:public-index))
(groups (maps:get 'groups data))
(titles (lists:map (lambda (g) (maps:get 'title g)) groups))
(project-repos (maps:get 'repos (hd groups))))
(if (and (=:= '("project" "first" "second") titles)
(=:= "p-new" (maps:get 'name (hd project-repos))))
'ok
(erlang:error (list "public index ordering is wrong" titles project-repos)))))))))
(defun assert-ok (result)
(if (=:= 'ok result)
'ok
(erlang:error (list "expected ok" result))))
(defun assert-error (result)
(if (and (is_tuple result) (=:= 'error (element 1 result)))
'ok
(erlang:error (list "expected error" result))))
(defun insert-summary (name org-id last updated)
(case org-id
('none
(lamina_db:q
"INSERT INTO repositories(name,organization_id,display_name,description,source,setup_username,setup_password_enc,fossil_path,last_timeline_at,created_at,updated_at) VALUES(?,NULL,?,?,'local',?,x'00',?,?,?,?);"
(list name name name "admin" (lists:flatten (list "/tmp/" name ".fossil")) last last updated)))
(id
(lamina_db:q
"INSERT INTO repositories(name,organization_id,display_name,description,source,setup_username,setup_password_enc,fossil_path,last_timeline_at,created_at,updated_at) VALUES(?,?,?,?, 'local',?,x'00',?,?,?,?);"
(list name id name name "admin" (lists:flatten (list "/tmp/" name ".fossil")) last last updated)))))
(defun with-db (f)
(let* ((cwd (element 2 (file:get_cwd)))
(dir (filename:join cwd "_build/tmp/m5-tests"))
(path (filename:join dir (lists:flatten (io_lib:format "db-~p.db" (list (os:system_time 'microsecond)))))))
(filelib:ensure_dir path)
(let ((open-result (lamina_db:open path)))
(if (and (is_tuple open-result) (=:= 'ok (element 1 open-result)))
(let ((result (catch (funcall f))))
(lamina_db:close)
(catch (file:delete path))
(if (=:= 'ok result) 'ok (erlang:error result)))
(erlang:error (list "database setup failed" open-result))))))