(ns auto-ap.company.plaid-yodlee-test (:require [auto-ap.datomic :refer [conn]] [auto-ap.integration.util :refer [admin-token setup-test-data test-client user-token wrap-setup]] [auto-ap.permissions :as permissions] [auto-ap.ssr.company.plaid :as company-plaid] [auto-ap.ssr.company.yodlee :as company-yodlee] [auto-ap.ssr.components.aside :as aside] [clj-time.core :as time] [clj-time.coerce :as coerce] [clojure.string :as str] [clojure.test :refer [deftest is testing use-fixtures]] [datomic.api :as dc])) (use-fixtures :each wrap-setup) ;; ============================================================================ ;; Reconciliation Reports - Access Behaviors ;; ============================================================================ (deftest test-reconciliation-nav-link-permission (testing "Behavior 8.1: It should show the reconciliation navigation link only when the user has reconciliation report permission" (let [{:strs [test-client-id]} (setup-test-data [])] ;; Admin user should see reconciliation nav link (testing "Admin user sees reconciliation nav link" (let [nav (aside/company-aside-nav- {:identity (admin-token) :matched-route :company :client {:db/id test-client-id} :clients [{:db/id test-client-id}]})] (is (re-find #"Bank Sync Report" (str nav))))) ;; Regular user should NOT see reconciliation nav link (testing "Regular user does not see reconciliation nav link" (let [nav (aside/company-aside-nav- {:identity (user-token test-client-id) :matched-route :company :client {:db/id test-client-id} :clients [{:db/id test-client-id}]})] (is (not (re-find #"Bank Sync Report" (str nav)))))) ;; Read-only user should NOT see reconciliation nav link (testing "Read-only user does not see reconciliation nav link" (let [nav (aside/company-aside-nav- {:identity {:user "READONLY" :exp (time/plus (time/now) (time/days 1)) :user/role "read-only" :user/name "READONLY" :user/clients [{:db/id test-client-id}]} :matched-route :company :client {:db/id test-client-id} :clients [{:db/id test-client-id}]})] (is (not (re-find #"Bank Sync Report" (str nav))))))))) ;; ============================================================================ ;; Plaid Bank Linking - Account Grid Behaviors ;; ============================================================================ (deftest test-plaid-sort-by-external-id-and-status (testing "Behavior 9.5: It should support sorting by external ID and Plaid bank status" (let [tempids (setup-test-data [(test-client :db/id "client-a" :client/code "AAA")]) client-a-id (get tempids "client-a")] ;; Create Plaid items with different external IDs and statuses @(dc/transact conn [{:db/id "plaid-item-1" :plaid-item/client client-a-id :plaid-item/external-id "external-002" :plaid-item/status "ERROR" :plaid-item/access-token "token-1" :plaid-item/last-updated (coerce/to-date (time/now))} {:db/id "plaid-item-2" :plaid-item/client client-a-id :plaid-item/external-id "external-001" :plaid-item/status "SUCCESS" :plaid-item/access-token "token-2" :plaid-item/last-updated (coerce/to-date (time/now))}]) ;; Sort by external-id ascending (let [[results _] (company-plaid/fetch-page {:trimmed-clients #{client-a-id} :query-params {:sort [{:sort-key "external-id" :asc true}]}})] (is (= 2 (count results))) (is (= ["external-001" "external-002"] (map :plaid-item/external-id results)))) ;; Sort by plaid-bank-status ascending (let [[results _] (company-plaid/fetch-page {:trimmed-clients #{client-a-id} :query-params {:sort [{:sort-key "plaid-bank-status" :asc true}]}})] (is (= 2 (count results))) (is (= ["ERROR" "SUCCESS"] (map :plaid-item/status results))))))) ;; ============================================================================ ;; Yodlee Bank Linking - Account Grid Behaviors ;; ============================================================================ (deftest test-yodlee-sort-by-status-client-provider-last-updated (testing "Behavior 12.5: It should support sorting by status, client, provider account, and last updated" (let [tempids (setup-test-data [(test-client :db/id "client-a" :client/code "AAA") (test-client :db/id "client-b" :client/code "BBB")]) client-a-id (get tempids "client-a") client-b-id (get tempids "client-b")] ;; Create Yodlee provider accounts with different attributes @(dc/transact conn [{:db/id "yodlee-1" :yodlee-provider-account/client client-b-id :yodlee-provider-account/status "SUCCESS" :yodlee-provider-account/id 200 :yodlee-provider-account/detailed-status "OK" :yodlee-provider-account/last-updated (coerce/to-date (time/now))} {:db/id "yodlee-2" :yodlee-provider-account/client client-a-id :yodlee-provider-account/status "FAILED" :yodlee-provider-account/id 100 :yodlee-provider-account/detailed-status "ERROR" :yodlee-provider-account/last-updated (coerce/to-date (time/minus (time/now) (time/days 1)))}]) ;; Sort by status ascending (let [[results _] (company-yodlee/fetch-page {:trimmed-clients #{client-a-id client-b-id} :query-params {:sort [{:sort-key "status" :asc true}]}})] (is (= 2 (count results))) (is (= ["FAILED" "SUCCESS"] (map :yodlee-provider-account/status results)))) ;; Sort by provider-account ascending (let [[results _] (company-yodlee/fetch-page {:trimmed-clients #{client-a-id client-b-id} :query-params {:sort [{:sort-key "provider-account" :asc true}]}})] (is (= 2 (count results))) (is (= [100 200] (map :yodlee-provider-account/id results)))) ;; Sort by client ascending (let [[results _] (company-yodlee/fetch-page {:trimmed-clients #{client-a-id client-b-id} :query-params {:sort [{:sort-key "client" :asc true}]}})] (is (= 2 (count results))))))) ;; Note: client sort uses client/code, not client id ;; We verify results are returned without checking specific order ;; since client code is not in the pull pattern