AtlatestRepositorysigil-wise

sigil-wise / tree / testwise-test.sgl

1;;; Tests for (wise)
2
3(import (sigil core)
4 (sigil dict)
5 (sigil string)
6 (sigil struct)
7 (sigil json)
8 (sigil test)
9 (wise))
11;; ---------------------------------------------------------------
12;; Test fixtures — JSON response samples
13;; ---------------------------------------------------------------
15(define profiles-json
16 (json-decode
17 (string-append
18 "[{\"id\": 12345, \"type\": \"PERSONAL\","
19 " \"fullName\": \"Alice Smith\","
20 " \"details\": {\"firstName\": \"Alice\","
21 " \"lastName\": \"Smith\"}},"
22 " {\"id\": 67890, \"type\": \"BUSINESS\","
23 " \"fullName\": \"Acme Corp\","
24 " \"details\": {\"firstName\": \"Acme\","
25 " \"lastName\": \"Corp\"}}]")))
27(define balances-json
28 (json-decode
29 (string-append
30 "[{\"id\": 100, \"type\": \"STANDARD\","
31 " \"amount\": {\"value\": 1500.42, \"currency\": \"EUR\"},"
32 " \"reservedAmount\": {\"value\": 10.00,"
33 " \"currency\": \"EUR\"}},"
34 " {\"id\": 200, \"type\": \"STANDARD\","
35 " \"amount\": {\"value\": 3200.00, \"currency\": \"USD\"},"
36 " \"reservedAmount\": {\"value\": 0,"
37 " \"currency\": \"USD\"}}]")))
39(define statement-json
40 (json-decode
41 (string-append
42 "{\"accountHolder\": {\"type\": \"PERSONAL\"},"
43 " \"transactions\": ["
44 " {\"type\": \"CREDIT\","
45 " \"date\": \"2026-03-01T10:30:00Z\","
46 " \"amount\": {\"value\": 500.00,"
47 " \"currency\": \"EUR\"},"
48 " \"details\": {\"description\": \"Salary\"},"
49 " \"referenceNumber\": \"TXN-001\","
50 " \"runningBalance\": {\"value\": 1500.00,"
51 " \"currency\": \"EUR\"}},"
52 " {\"type\": \"DEBIT\","
53 " \"date\": \"2026-03-05T14:00:00Z\","
54 " \"amount\": {\"value\": -42.50,"
55 " \"currency\": \"EUR\"},"
56 " \"details\": {\"description\": \"Coffee shop\","
57 " \"merchant\": \"Bean Co\"},"
58 " \"referenceNumber\": \"TXN-002\","
59 " \"runningBalance\": {\"value\": 1457.50,"
60 " \"currency\": \"EUR\"}}"
61 " ],"
62 " \"endOfStatementBalance\":"
63 " {\"value\": 1457.50, \"currency\": \"EUR\"}}")))
65;; ---------------------------------------------------------------
66;; Profile parsing tests
67;; ---------------------------------------------------------------
69(test-group "profile parsing"
71 (test "parse personal profile"
72 (let ((data (array-ref profiles-json 0)))
73 (let ((p (parse-profile data)))
74 (assert-true (wise-profile? p))
75 (assert-equal 12345 (wise-profile-id p))
76 (assert-equal "PERSONAL" (wise-profile-type p))
77 (assert-equal "Alice Smith" (wise-profile-name p)))))
79 (test "parse business profile"
80 (let ((data (array-ref profiles-json 1)))
81 (let ((p (parse-profile data)))
82 (assert-true (wise-profile? p))
83 (assert-equal 67890 (wise-profile-id p))
84 (assert-equal "BUSINESS" (wise-profile-type p))
85 (assert-equal "Acme Corp" (wise-profile-name p))))))
87;; ---------------------------------------------------------------
88;; Balance parsing tests
89;; ---------------------------------------------------------------
91(test-group "balance parsing"
93 (test "parse EUR balance"
94 (let ((data (array-ref balances-json 0)))
95 (let ((b (parse-balance data)))
96 (assert-true (wise-balance? b))
97 (assert-equal 100 (wise-balance-id b))
98 (assert-equal "EUR" (wise-balance-currency b))
99 (assert-equal "STANDARD" (wise-balance-type b))
100 (assert-equal 1500.42 (wise-balance-amount b))
101 (assert-equal 10.00 (wise-balance-reserved-amount b)))))
103 (test "parse USD balance"
104 (let ((data (array-ref balances-json 1)))
105 (let ((b (parse-balance data)))
106 (assert-equal 200 (wise-balance-id b))
107 (assert-equal "USD" (wise-balance-currency b))
108 (assert-equal 3200.00 (wise-balance-amount b))
109 (assert-equal 0 (wise-balance-reserved-amount b))))))
111;; ---------------------------------------------------------------
112;; Transaction parsing tests
113;; ---------------------------------------------------------------
115(test-group "transaction parsing"
117 (test "parse credit transaction"
118 (let ((txns (dict-ref statement-json transactions:)))
119 (let ((t (parse-transaction (array-ref txns 0))))
120 (assert-true (wise-transaction? t))
121 (assert-equal "CREDIT" (wise-transaction-type t))
122 (assert-equal "2026-03-01T10:30:00Z" (wise-transaction-date t))
123 (assert-equal 500.00 (wise-transaction-amount t))
124 (assert-equal "EUR" (wise-transaction-currency t))
125 (assert-equal "TXN-001" (wise-transaction-reference-number t))
126 (assert-equal 1500.00 (wise-transaction-running-balance t)))))
128 (test "parse debit transaction"
129 (let ((txns (dict-ref statement-json transactions:)))
130 (let ((t (parse-transaction (array-ref txns 1))))
131 (assert-equal "DEBIT" (wise-transaction-type t))
132 (assert-equal -42.50 (wise-transaction-amount t))
133 (assert-equal "TXN-002" (wise-transaction-reference-number t))
134 (assert-equal 1457.50 (wise-transaction-running-balance t)))))
136 (test "parse transaction details"
137 (let ((txns (dict-ref statement-json transactions:)))
138 (let ((t (parse-transaction (array-ref txns 1))))
139 (let ((details (wise-transaction-details t)))
140 (assert-true (dict? details))
141 (assert-equal "Coffee shop" (dict-ref details description:))
142 (assert-equal "Bean Co" (dict-ref details merchant:)))))))
144;; ---------------------------------------------------------------
145;; Date windowing tests
146;; ---------------------------------------------------------------
148(test-group "date windowing"
150 (test "single window for short range"
151 (let ((windows (wise-date-windows
152 "2026-01-01T00:00:00Z"
153 "2026-03-01T00:00:00Z")))
154 (assert-equal 1 (length windows))
155 (assert-equal "2026-01-01T00:00:00Z" (car (car windows)))
156 (assert-equal "2026-03-01T00:00:00Z" (cdr (car windows)))))
158 (test "single window for exactly 469 days"
159 (let ((windows (wise-date-windows
160 "2025-01-01T00:00:00Z"
161 "2026-04-15T00:00:00Z")))
162 ;; 469 days from 2025-01-01 = 2026-04-15
163 (assert-equal 1 (length windows))))
165 (test "two windows for range > 469 days"
166 (let ((windows (wise-date-windows
167 "2024-01-01T00:00:00Z"
168 "2026-03-25T00:00:00Z")))
169 ;; ~815 days, needs 2 windows
170 (assert-true (>= (length windows) 2))
171 ;; First window starts at the start date
172 (assert-equal "2024-01-01T00:00:00Z" (car (car windows)))
173 ;; Last window ends at the end date
174 (assert-equal "2026-03-25T00:00:00Z"
175 (cdr (list-ref windows (- (length windows) 1))))))
177 (test "three windows for very long range"
178 (let ((windows (wise-date-windows
179 "2023-01-01T00:00:00Z"
180 "2026-03-25T00:00:00Z")))
181 ;; ~1179 days, needs 3 windows
182 (assert-true (>= (length windows) 3))
183 ;; Windows are contiguous
184 (assert-equal (cdr (car windows))
185 (car (list-ref windows 1)))))
187 (test "empty range returns empty"
188 (let ((windows (wise-date-windows
189 "2026-03-01T00:00:00Z"
190 "2026-03-01T00:00:00Z")))
191 (assert-equal 0 (length windows))))
193 (test "preserves time components"
194 (let ((windows (wise-date-windows
195 "2026-01-15T08:30:45Z"
196 "2026-06-20T16:00:00Z")))
197 (assert-equal 1 (length windows))
198 (assert-equal "2026-01-15T08:30:45Z" (car (car windows)))
199 (assert-equal "2026-06-20T16:00:00Z" (cdr (car windows))))))
201;; ---------------------------------------------------------------
202;; Client construction tests
203;; ---------------------------------------------------------------
205(test-group "client construction"
207 (test "default base URL"
208 (let ((c (wise-client token: "test-token")))
209 (assert-true (wise-client? c))
210 (assert-equal "test-token" (wise-client-token c))
211 (assert-equal "https://api.wise.com" (wise-client-base-url c))))
213 (test "custom base URL for sandbox"
214 (let ((c (wise-client token: "sandbox-token"
215 base-url: "https://api.wise-sandbox.com")))
216 (assert-equal "https://api.wise-sandbox.com"
217 (wise-client-base-url c)))))
219;; ---------------------------------------------------------------
220;; Record construction tests
221;; ---------------------------------------------------------------
223(test-group "record construction"
225 (test "wise-profile fields"
226 (let ((p (wise-profile id: 1 type: "PERSONAL" name: "Test")))
227 (assert-equal 1 (wise-profile-id p))
228 (assert-equal "PERSONAL" (wise-profile-type p))
229 (assert-equal "Test" (wise-profile-name p))))
231 (test "wise-balance fields"
232 (let ((b (wise-balance id: 10 currency: "GBP" type: "STANDARD"
233 amount: 999.99 reserved-amount: 5.00)))
234 (assert-equal 10 (wise-balance-id b))
235 (assert-equal "GBP" (wise-balance-currency b))
236 (assert-equal 999.99 (wise-balance-amount b))
237 (assert-equal 5.00 (wise-balance-reserved-amount b))))
239 (test "wise-transaction fields"
240 (let ((t (wise-transaction type: "CREDIT" date: "2026-01-01T00:00:00Z"
241 amount: 100.00 currency: "EUR"
242 details: #{} reference-number: "REF-1"
243 running-balance: 500.00)))
244 (assert-equal "CREDIT" (wise-transaction-type t))
245 (assert-equal 100.00 (wise-transaction-amount t))
246 (assert-equal "REF-1" (wise-transaction-reference-number t)))))
248(run-tests)