feat(tests): implement integration and unit tests for auth, company, and ledger behaviors
- Auth: 30 tests (97 assertions) covering OAuth, sessions, JWT, impersonation, roles - Company: 35 tests (92 assertions) covering profile, 1099, expense reports, permissions - Ledger: 113 tests (148 assertions) covering grid, journal entries, import, reports - Fix existing test failures in running_balance, insights, tx, plaid, graphql - Fix InMemSolrClient to handle Solr query syntax properly - Update behavior docs: auth (42 done), company (32 done), ledger (120 done) - All 478 tests pass with 0 failures, 0 errors
This commit is contained in:
93
test/clj/auto_ap/auth/jwt_test.clj
Normal file
93
test/clj/auto_ap/auth/jwt_test.clj
Normal file
@@ -0,0 +1,93 @@
|
||||
(ns auto-ap.auth.jwt-test
|
||||
(:require
|
||||
[auto-ap.integration.util :refer [wrap-setup]]
|
||||
[auto-ap.routes.auth :as auth]
|
||||
[buddy.sign.jwt :as jwt]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clj-time.core :as time]
|
||||
[clojure.test :refer [deftest is testing use-fixtures]]
|
||||
[config.core :refer [env]]))
|
||||
|
||||
(use-fixtures :each wrap-setup)
|
||||
|
||||
(deftest test-user->jwt-generates-token
|
||||
(testing "Behavior 7.1: It should generate a JWT containing the user's role and client access on login"
|
||||
(let [user {:db/id 123
|
||||
:user/name "Test User"
|
||||
:user/role :user-role/user
|
||||
:user/clients [{:db/id 1 :client/code "A" :client/locations ["DT"]}
|
||||
{:db/id 2 :client/code "B" :client/locations ["MH"]}]}
|
||||
token (auth/user->jwt user "fake-oauth-token")]
|
||||
(is (= "Test User" (:user token)))
|
||||
(is (= "user" (:user/role token)))
|
||||
(is (= 123 (:db/id token)))
|
||||
(is (= "Test User" (:user/name token)))
|
||||
(is (some? (:exp token))))))
|
||||
|
||||
(deftest test-admin-jwt-compresses-clients
|
||||
(testing "Behavior 7.2: It should compress the client list for admin users to fit in the JWT"
|
||||
(let [user {:db/id 1
|
||||
:user/name "Admin"
|
||||
:user/role :user-role/admin
|
||||
:user/clients [{:db/id 10 :client/code "A" :client/locations ["DT"]}
|
||||
{:db/id 20 :client/code "B" :client/locations ["MH"]}]}
|
||||
token (auth/user->jwt user "fake-oauth-token")]
|
||||
(is (= "admin" (:user/role token)))
|
||||
(is (some? (:gz-clients token)))
|
||||
(is (string? (:gz-clients token)))
|
||||
(is (nil? (:user/clients token)))
|
||||
;; Verify the compressed data can be decompressed
|
||||
(let [decompressed (auth/gunzip (:gz-clients token))]
|
||||
(is (= [{:db/id 10 :client/code "A" :client/locations ["DT"]}
|
||||
{:db/id 20 :client/code "B" :client/locations ["MH"]}]
|
||||
decompressed))))))
|
||||
|
||||
(deftest test-readonly-jwt-compresses-clients
|
||||
(testing "Behavior 7.3: It should compress the client list for read-only users to fit in the JWT"
|
||||
(let [user {:db/id 2
|
||||
:user/name "Read Only"
|
||||
:user/role :user-role/read-only
|
||||
:user/clients [{:db/id 30 :client/code "C" :client/locations ["DT"]}]}
|
||||
token (auth/user->jwt user "fake-oauth-token")]
|
||||
(is (= "read-only" (:user/role token)))
|
||||
(is (some? (:gz-clients token)))
|
||||
(is (string? (:gz-clients token)))
|
||||
(is (nil? (:user/clients token)))
|
||||
(let [decompressed (auth/gunzip (:gz-clients token))]
|
||||
(is (= [{:db/id 30 :client/code "C" :client/locations ["DT"]}]
|
||||
decompressed))))))
|
||||
|
||||
(deftest test-regular-user-jwt-plain-clients
|
||||
(testing "Behavior 7.4: It should include a plain client list for regular users in the JWT"
|
||||
(let [user {:db/id 3
|
||||
:user/name "Regular"
|
||||
:user/role :user-role/user
|
||||
:user/clients [{:db/id 40 :client/code "D" :client/locations ["DT"]}]}
|
||||
token (auth/user->jwt user "fake-oauth-token")]
|
||||
(is (= "user" (:user/role token)))
|
||||
(is (some? (:user/clients token)))
|
||||
(is (sequential? (:user/clients token)))
|
||||
(is (nil? (:gz-clients token)))
|
||||
(is (= [{:db/id 40 :client/code "D" :client/locations ["DT"]}]
|
||||
(:user/clients token))))))
|
||||
|
||||
(deftest test-api-token
|
||||
(testing "Behavior 7.5: It should create API tokens with admin role and 1000-day expiration"
|
||||
(let [token-str (auth/make-api-token)
|
||||
claims (jwt/unsign token-str (:jwt-secret env) {:alg :hs512})
|
||||
exp-dt (coerce/from-long (* 1000 (long (:exp claims))))
|
||||
now (time/now)]
|
||||
(is (= "API" (:user claims)))
|
||||
(is (= "admin" (:user/role claims)))
|
||||
(is (= "API" (:user/name claims)))
|
||||
(is (some? (:exp claims)))
|
||||
;; Verify expiration is approximately 1000 days from now
|
||||
(is (time/after? exp-dt now))
|
||||
(is (time/before? exp-dt (time/plus now (time/days 1001)))))))
|
||||
|
||||
(deftest test-gzip-roundtrip
|
||||
(testing "gzip and gunzip are inverse operations"
|
||||
(let [data [{:db/id 1 :client/code "A"} {:db/id 2 :client/code "B"}]
|
||||
compressed (auth/gzip data)
|
||||
decompressed (auth/gunzip compressed)]
|
||||
(is (= data decompressed)))))
|
||||
Reference in New Issue
Block a user