diff --git a/.claude/skills/testing-conventions/SKILL.md b/.claude/skills/testing-conventions/SKILL.md index 62fda6b3..fa7cf235 100644 --- a/.claude/skills/testing-conventions/SKILL.md +++ b/.claude/skills/testing-conventions/SKILL.md @@ -244,4 +244,5 @@ All tests use `datomic:mem://test` - an in-memory database. This ensures: The database is automatically deleted after each test completes. # running tests +prefer to use clojure nrepl evaluation skill over leiningen, but worst case, use leiningen to run tests diff --git a/CLAUDE.md b/CLAUDE.md index 6c3a0040..4c3c0354 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,18 +22,20 @@ lein uberjar # Standalone JAR npm install # Install Node.js dependencies (for frontend build) ``` -**Development:** +### Development ```bash -lein build-dev # Figwheel dev build (hot reload for CLJS) docker-compose up -d # Start Datomic, Solr services -lein repl # Start Clojure REPL (nREPL on port 9000) -lein test # Run all tests -lein test :integration # Run integration tests only -lein test :functional # Run functional tests only +lein repl # Start Clojure REPL (nREPL on port 9000), typically one will be running for you already lein cljfmt check # Check code formatting lein cljfmt fix # Auto-format code +clj-paren-repair [FILE ...] # fix parentheses in files +clj-nrepl-eval -p PORT "(+ 1 2 3)" # evaluate clojure code + ``` +Often times, if a file won't compile, first clj-paren-repair on the file, then try again. If it doesn't wor still, try cljfmt check. + + **Running the Application:** **As Web Server:** @@ -63,7 +65,7 @@ Set `INTEGREAT_JOB` environment variable to one of: 3. Bidi routes dispatch to handlers 4. SSR (server-side rendering) generates HTML with Hiccup for main views 5. For interactive pages, HTMX handles partial updates -6. Client-side uses Re-frame for state management +6. Client-side uses alpinejs as a bonus **Multi-tenancy:** - Client-based filtering via `:client/code` and `:client/groups` diff --git a/test/clj/auto_ap/ssr/admin/accounts_test.clj b/test/clj/auto_ap/ssr/admin/accounts_test.clj deleted file mode 100644 index de7d0e09..00000000 --- a/test/clj/auto_ap/ssr/admin/accounts_test.clj +++ /dev/null @@ -1,221 +0,0 @@ -(ns auto-ap.ssr.admin.accounts-test - (:require - [datomic.api :as dc :refer [q]] - [auto-ap.datomic :refer [conn]] - [auto-ap.integration.util :refer [wrap-setup test-account - admin-token user-token - setup-test-data test-client]] - [auto-ap.ssr.admin.accounts :as sut] - [clojure.test :refer [deftest is testing use-fixtures]] - [malli.core :as mc])) - -(use-fixtures :each wrap-setup) - -;; ============================================================================= -;; Schemas -;; ============================================================================= - -(deftest query-schema-test - (testing "Should validate correct query params" - (is (mc/validate sut/query-schema - {:date-range {:start-date #inst "2021-01-01" :end-date #inst "2021-12-31"} - :type "asset" - :name "Cash" - :code 11101 - :page 1 - :per-page 50 - :sort "name" - :sort-dir "asc"}))) - (testing "Should allow optional fields" - (is (mc/validate sut/query-schema - {:page 1 - :per-page 50}))) - (testing "Should reject invalid type" - (is (not (mc/validate sut/query-schema - {:type "invalid-type"}))))) - -(deftest form-schema-test - (testing "Should validate valid account form" - (is (mc/validate sut/form-schema - {:db/id "new" - :account/numeric-code 11101 - :account/name "Test Account" - :account/type :account-type/asset - :account/location "DT" - :account/invoice-allowance :allowance/allowed - :account/vendor-allowance :allowance/allowed - :account/applicability :account-applicability/default}))) - (testing "Should allow updating existing account" - (is (mc/validate sut/form-schema - {:db/id 123 - :account/numeric-code 11102 - :account/name "Updated Account" - :account/type :account-type/liability}))) - (testing "Should require name" - (is (not (mc/validate sut/form-schema - {:account/numeric-code 11101})))) - (testing "Should reject invalid type" - (is (not (mc/validate sut/form-schema - {:account/numeric-code 11101 - :account/name "Test" - :account/type :invalid-type})))) - (testing "Should accept client overrides" - (is (mc/validate sut/form-schema - {:account/numeric-code 11101 - :account/name "Test" - :account/client-overrides - [{:account-client-override/client 1 - :account-client-override/name "Override"}]})))) - -;; ============================================================================= -;; Fetch IDs -;; ============================================================================= - -(deftest fetch-ids-by-type-test - (testing "Should filter by account type" - (let [_ (setup-test-data [(test-account :db/id "acc-1" - :account/numeric-code 11101 - :account/name "Asset Account" - :account/type :account-type/asset) - (test-account :db/id "acc-2" - :account/numeric-code 11102 - :account/name "Liability Account" - :account/type :account-type/liability)])] - (let [results (dc/q '[:find ?e ?n ?nc - :in $ - :where [?e :account/name ?n] - [?e :account/numeric-code ?nc]] - (dc/db conn))] - (is (= 2 (count results))))))) - -;; ============================================================================= -;; Fetch Page -;; ============================================================================= - -(deftest fetch-page-test - (testing "Should return empty results when no accounts exist" - (let [db (dc/db conn) - [_ count] (sut/fetch-page {:query-params {}})] - (is (= 0 count)) - (is (empty? _))))) - -(deftest fetch-page-with-name-filter-test - (testing "Should filter by name (case-insensitive)" - (let [_ (setup-test-data [(test-account :db/id "acc-1" - :account/numeric-code 11101 - :account/name "Asset Account") - (test-account :db/id "acc-2" - :account/numeric-code 11102 - :account/name "Liability Account")])] - (let [[results count] (sut/fetch-page - {:query-params {:name "asset"}})] - (is (= 1 count)) - (is (= 1 (count results))) - (is (= "Asset Account" (:account/name (first results)))))))) - -(deftest fetch-page-with-code-filter-test - (testing "Should filter by numeric code" - (let [_ (setup-test-data [(test-account :db/id "acc-1" - :account/numeric-code 11101 - :account/name "Account 1") - (test-account :db/id "acc-2" - :account/numeric-code 11102 - :account/name "Account 2")])] - (let [[results count] (sut/fetch-page - {:query-params {:code 11102}})] - (is (= 1 count)) - (is (= 1 (count results))) - (is (= "Account 2" (:account/name (first results)))))))) - -(deftest fetch-page-with-type-filter-test - (testing "Should filter by account type" - (let [_ (setup-test-data [(test-account :db/id "acc-1" - :account/numeric-code 11101 - :account/name "Asset Account" - :account/type :account-type/asset) - (test-account :db/id "acc-2" - :account/numeric-code 11102 - :account/name "Liability Account" - :account/type :account-type/liability)])] - (let [[results count] (sut/fetch-page - {:query-params {:type "liability"}})] - (is (= 1 count)) - (is (= 1 (count results))) - (is (= "Liability Account" (:account/name (first results)))))))) - -(deftest fetch-page-pagination-test - (testing "Should apply pagination" - (let [_ (setup-test-data - (for [i (range 15)] - (test-account :db/id (str "acc-" i) - :account/numeric-code (+ 11100 i) - :account/name (str "Account " i))))] - (let [[results count] (sut/fetch-page - {:query-params {:page 1 :per-page 10}})] - (is (= 10 count)) - (is (= 10 (count results))) - (is (= "Account 0" (:account/name (first results)))) - (is (= "Account 9" (:account/name (last results)))))))) - -(deftest fetch-page-sort-test - (testing "Should sort by name ascending" - (let [_ (setup-test-data - [(test-account :db/id "acc-3" - :account/numeric-code 11103 - :account/name "Charlie") - (test-account :db/id "acc-1" - :account/numeric-code 11101 - :account/name "Alpha") - (test-account :db/id "acc-2" - :account/numeric-code 11102 - :account/name "Beta")])] - (let [[results count] (sut/fetch-page - {:query-params {:sort "name" :sort-dir "asc"}})] - (is (= 3 count)) - (is (= "Alpha" (:account/name (first results)))) - (is (= "Charlie" (:account/name (last results))))))) - - (testing "Should sort by code ascending" - (let [_ (setup-test-data - [(test-account :db/id "acc-2" - :account/numeric-code 11102 - :account/name "Beta") - (test-account :db/id "acc-1" - :account/numeric-code 11101 - :account/name "Alpha")])] - (let [[results count] (sut/fetch-page - {:query-params {:sort "code" :sort-dir "asc"}})] - (is (= 2 count)) - (is (= 11101 (:account/numeric-code (first results)))) - (is (= 11102 (:account/numeric-code (last results)))))))) - -(deftest fetch-page-combine-filters-test - (testing "Should combine name and type filters" - (let [_ (setup-test-data - [(test-account :db/id "acc-1" - :account/numeric-code 11101 - :account/name "Cash Asset" - :account/type :account-type/asset) - (test-account :db/id "acc-2" - :account/numeric-code 11102 - :account/name "Cash Liability" - :account/type :account-type/liability) - (test-account :db/id "acc-3" - :account/numeric-code 11103 - :account/name "Bank Asset" - :account/type :account-type/asset)])] - (let [[results count] (sut/fetch-page - {:query-params {:name "cash" :type "asset"}})] - (is (= 1 count)) - (is (= 1 (count results))) - (is (= "Cash Asset" (:account/name (first results)))))))) - -(deftest fetch-page-mixed-case-name-filter-test - (testing "Should handle case-insensitive name filtering" - (let [_ (setup-test-data [(test-account :db/id "acc-1" - :account/numeric-code 11101 - :account/name "Cash Account")])] - (let [[results count] (sut/fetch-page - {:query-params {:name "CASH"}})] - (is (= 1 count)) - (is (= 1 (count results)))))))