AtlatestRepositorysigil-twitch

sigil-twitch / tree / testtwitch-test.sgl

1;;; Tests for (twitch) — core module
2;;;
3;;; Tests record construction, JSON response parsing, URL building,
4;;; and query string encoding using fixture data (no real API calls).
5
6(import (sigil core)
7 (sigil dict)
8 (sigil string)
9 (sigil struct)
10 (sigil json)
11 (sigil test)
12 (only (sigil http) url-encode-value build-query-string)
13 (twitch))
15;; ---------------------------------------------------------------
16;; Test fixtures — JSON response samples
17;; ---------------------------------------------------------------
19(define channel-resource-json
20 (json-decode
21 (string-append
22 "{\"broadcaster_id\": \"141981764\","
23 " \"broadcaster_login\": \"twitchdev\","
24 " \"broadcaster_name\": \"TwitchDev\","
25 " \"game_name\": \"Science & Technology\","
26 " \"game_id\": \"509670\","
27 " \"title\": \"Building cool stuff\","
28 " \"tags\": [\"English\", \"Coding\"]}")))
30(define channel-minimal-json
31 (json-decode
32 (string-append
33 "{\"broadcaster_id\": \"12345\","
34 " \"broadcaster_name\": \"MinimalUser\"}")))
36(define stream-resource-json
37 (json-decode
38 (string-append
39 "{\"id\": \"40944942733\","
40 " \"user_id\": \"141981764\","
41 " \"user_name\": \"TwitchDev\","
42 " \"game_name\": \"Science & Technology\","
43 " \"title\": \"Live coding session\","
44 " \"viewer_count\": 1234,"
45 " \"started_at\": \"2026-03-25T14:00:00Z\"}")))
47(define stream-minimal-json
48 (json-decode
49 (string-append
50 "{\"id\": \"99999\","
51 " \"user_id\": \"11111\"}")))
53(define user-resource-json
54 (json-decode
55 (string-append
56 "{\"id\": \"141981764\","
57 " \"login\": \"twitchdev\","
58 " \"display_name\": \"TwitchDev\","
59 " \"type\": \"\","
60 " \"broadcaster_type\": \"partner\","
61 " \"description\": \"Supporting devs\","
62 " \"profile_image_url\": \"https://example.com/pic.png\","
63 " \"created_at\": \"2016-12-14T20:32:28Z\"}")))
65(define user-minimal-json
66 (json-decode
67 (string-append
68 "{\"id\": \"54321\","
69 " \"login\": \"testuser\"}")))
71;; ---------------------------------------------------------------
72;; Client construction tests
73;; ---------------------------------------------------------------
75(test-group "client construction"
77 (test "client with credentials"
78 (let ((c (twitch-client client-id: "abc123"
79 access-token: "oauth-token")))
80 (assert-true (twitch-client? c))
81 (assert-equal "abc123" (twitch-client-client-id c))
82 (assert-equal "oauth-token" (twitch-client-access-token c))
83 (assert-equal "https://api.twitch.tv/helix"
84 (twitch-client-base-url c))))
86 (test "custom base url"
87 (let ((c (twitch-client client-id: "id"
88 access-token: "tok"
89 base-url: "http://localhost:8080/mock")))
90 (assert-equal "http://localhost:8080/mock"
91 (twitch-client-base-url c)))))
93;; ---------------------------------------------------------------
94;; Auth headers tests
95;; ---------------------------------------------------------------
97(test-group "auth headers"
99 (test "headers include both client-id and bearer token"
100 (let* ((c (twitch-client client-id: "my-client-id"
101 access-token: "my-token"))
102 (headers (twitch-auth-headers c)))
103 (assert-equal "Bearer my-token"
104 (dict-ref headers authorization:))
105 (assert-equal "my-client-id"
106 (dict-ref headers client-id:)))))
108;; ---------------------------------------------------------------
109;; Channel record tests
110;; ---------------------------------------------------------------
112(test-group "channel records"
114 (test "channel record construction"
115 (let ((ch (twitch-channel id: "12345" name: "TestChannel"
116 game-name: "Just Chatting"
117 game-id: "509658"
118 title: "Hello!"
119 tags: '("English" "Coding"))))
120 (assert-true (twitch-channel? ch))
121 (assert-equal "12345" (twitch-channel-id ch))
122 (assert-equal "TestChannel" (twitch-channel-name ch))
123 (assert-equal "Just Chatting" (twitch-channel-game-name ch))
124 (assert-equal "509658" (twitch-channel-game-id ch))
125 (assert-equal "Hello!" (twitch-channel-title ch))
126 (assert-equal '("English" "Coding") (twitch-channel-tags ch))))
128 (test "channel record defaults"
129 (let ((ch (twitch-channel id: "99")))
130 (assert-equal "" (twitch-channel-name ch))
131 (assert-equal "" (twitch-channel-game-name ch))
132 (assert-equal "" (twitch-channel-game-id ch))
133 (assert-equal "" (twitch-channel-title ch))
134 (assert-equal '() (twitch-channel-tags ch)))))
136;; ---------------------------------------------------------------
137;; Stream record tests
138;; ---------------------------------------------------------------
140(test-group "stream records"
142 (test "stream record construction"
143 (let ((s (twitch-stream id: "40944942733"
144 user-id: "141981764"
145 user-name: "TwitchDev"
146 game-name: "Science & Technology"
147 title: "Live coding"
148 viewer-count: 500
149 started-at: "2026-03-25T14:00:00Z")))
150 (assert-true (twitch-stream? s))
151 (assert-equal "40944942733" (twitch-stream-id s))
152 (assert-equal "141981764" (twitch-stream-user-id s))
153 (assert-equal 500 (twitch-stream-viewer-count s))))
155 (test "stream record defaults"
156 (let ((s (twitch-stream id: "1")))
157 (assert-equal "" (twitch-stream-user-id s))
158 (assert-equal 0 (twitch-stream-viewer-count s))
159 (assert-equal #f (twitch-stream-started-at s)))))
161;; ---------------------------------------------------------------
162;; User record tests
163;; ---------------------------------------------------------------
165(test-group "user records"
167 (test "user record construction"
168 (let ((u (twitch-user id: "141981764"
169 login: "twitchdev"
170 display-name: "TwitchDev"
171 broadcaster-type: "partner")))
172 (assert-true (twitch-user? u))
173 (assert-equal "141981764" (twitch-user-id u))
174 (assert-equal "twitchdev" (twitch-user-login u))
175 (assert-equal "partner" (twitch-user-broadcaster-type u))))
177 (test "user record defaults"
178 (let ((u (twitch-user id: "1")))
179 (assert-equal "" (twitch-user-login u))
180 (assert-equal "" (twitch-user-display-name u))
181 (assert-equal "" (twitch-user-type u))
182 (assert-equal #f (twitch-user-created-at u)))))
184;; ---------------------------------------------------------------
185;; Channel parsing tests
186;; ---------------------------------------------------------------
188(test-group "channel parsing"
190 (test "parse full channel resource"
191 (let ((ch (parse-channel channel-resource-json)))
192 (assert-true (twitch-channel? ch))
193 (assert-equal "141981764" (twitch-channel-id ch))
194 (assert-equal "TwitchDev" (twitch-channel-name ch))
195 (assert-equal "Science & Technology" (twitch-channel-game-name ch))
196 (assert-equal "509670" (twitch-channel-game-id ch))
197 (assert-equal "Building cool stuff" (twitch-channel-title ch))
198 (assert-equal '("English" "Coding") (twitch-channel-tags ch))))
200 (test "parse minimal channel resource"
201 (let ((ch (parse-channel channel-minimal-json)))
202 (assert-equal "12345" (twitch-channel-id ch))
203 (assert-equal "MinimalUser" (twitch-channel-name ch))
204 (assert-equal "" (twitch-channel-game-name ch))
205 (assert-equal '() (twitch-channel-tags ch)))))
207;; ---------------------------------------------------------------
208;; Stream parsing tests
209;; ---------------------------------------------------------------
211(test-group "stream parsing"
213 (test "parse full stream resource"
214 (let ((s (parse-stream stream-resource-json)))
215 (assert-true (twitch-stream? s))
216 (assert-equal "40944942733" (twitch-stream-id s))
217 (assert-equal "141981764" (twitch-stream-user-id s))
218 (assert-equal "TwitchDev" (twitch-stream-user-name s))
219 (assert-equal "Science & Technology" (twitch-stream-game-name s))
220 (assert-equal "Live coding session" (twitch-stream-title s))
221 (assert-equal 1234 (twitch-stream-viewer-count s))
222 (assert-equal "2026-03-25T14:00:00Z" (twitch-stream-started-at s))))
224 (test "parse minimal stream resource"
225 (let ((s (parse-stream stream-minimal-json)))
226 (assert-equal "99999" (twitch-stream-id s))
227 (assert-equal "11111" (twitch-stream-user-id s))
228 (assert-equal "" (twitch-stream-user-name s))
229 (assert-equal 0 (twitch-stream-viewer-count s)))))
231;; ---------------------------------------------------------------
232;; User parsing tests
233;; ---------------------------------------------------------------
235(test-group "user parsing"
237 (test "parse full user resource"
238 (let ((u (parse-user user-resource-json)))
239 (assert-true (twitch-user? u))
240 (assert-equal "141981764" (twitch-user-id u))
241 (assert-equal "twitchdev" (twitch-user-login u))
242 (assert-equal "TwitchDev" (twitch-user-display-name u))
243 (assert-equal "partner" (twitch-user-broadcaster-type u))
244 (assert-equal "Supporting devs" (twitch-user-description u))
245 (assert-equal "2016-12-14T20:32:28Z" (twitch-user-created-at u))))
247 (test "parse minimal user resource"
248 (let ((u (parse-user user-minimal-json)))
249 (assert-equal "54321" (twitch-user-id u))
250 (assert-equal "testuser" (twitch-user-login u))
251 (assert-equal "" (twitch-user-display-name u))
252 (assert-equal #f (twitch-user-created-at u)))))
254;; ---------------------------------------------------------------
255;; URL encoding tests
256;; ---------------------------------------------------------------
258(test-group "URL encoding"
260 (test "encode simple string"
261 (assert-equal "hello" (url-encode-value "hello")))
263 (test "encode spaces"
264 (assert-equal "hello+world" (url-encode-value "hello world")))
266 (test "encode special characters"
267 (assert-equal "foo%26bar" (url-encode-value "foo&bar")))
269 (test "encode equals sign"
270 (assert-equal "key%3Dvalue" (url-encode-value "key=value")))
272 (test "preserve unreserved characters"
273 (assert-equal "a-b_c.d~e" (url-encode-value "a-b_c.d~e"))))
275;; ---------------------------------------------------------------
276;; Query string building tests
277;; ---------------------------------------------------------------
279(test-group "query string building"
281 (test "build simple query string"
282 (assert-equal "?broadcaster_id=12345"
283 (build-query-string
284 (list (cons "broadcaster_id" "12345")))))
286 (test "build multi-param query string"
287 (assert-equal "?part=snippet&id=abc123"
288 (build-query-string
289 (list (cons "part" "snippet")
290 (cons "id" "abc123")))))
292 (test "omit false values"
293 (assert-equal "?broadcaster_id=12345"
294 (build-query-string
295 (list (cons "broadcaster_id" "12345")
296 (cons "after" #f)))))
298 (test "empty params"
299 (assert-equal ""
300 (build-query-string '())))
302 (test "encode values in query string"
303 (assert-equal "?q=hello+world"
304 (build-query-string
305 (list (cons "q" "hello world"))))))
307;; ---------------------------------------------------------------
308;; Pagination parsing tests
309;; ---------------------------------------------------------------
311(test-group "pagination parsing"
313 (test "parse pagination with cursor"
314 (let ((data #{ pagination: #{ cursor: "eyJiI123" } }))
315 (assert-equal "eyJiI123" (parse-pagination data))))
317 (test "parse pagination without cursor"
318 (let ((data #{ pagination: #{} }))
319 (assert-equal #f (parse-pagination data))))
321 (test "parse pagination with missing pagination key"
322 (let ((data #{}))
323 (assert-equal #f (parse-pagination data)))))
325(run-tests)