cljs / test / ird / coverage_test.cljs
1,741 words
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
(ns ird.coverage-test
  "Executable full-coverage inventory: one row per API operation. Each row
  invokes the client fn against a capturing transport and asserts the exact
  HTTP method and URL, and the set of rows is compared with every operation
  the vendored spec declares — so a renamed path, a missing fn, or an
  endpoint the API gained fails loudly."
  (:require [cljs.test :refer [deftest is]]
            [cljs.core.async :refer [<!]]
            [clojure.set :as set]
            [ird.auth :as auth]
            [ird.client :as ird]
            [ird.credits :as credits]
            [ird.dns :as dns]
            [ird.domains :as domains]
            [ird.ipfs :as ipfs]
            [ird.jobs :as jobs]
            [ird.p2p :as p2p]
            [ird.pins :as pins]
            [ird.registrations :as reg]
            [ird.sharing :as sharing]
            [ird.support :as support]
            [ird.test-util :as tu :refer [deftest-async]]
            [ird.transfers :as transfers]
            [ird.tunnels :as tunnels]
            [ird.vps :as vps]))

(def B "https://api.ird.ro")

(def operations
  "[description fn method expected-url args...] — one row per operation,
  grouped by namespace. Descriptions are the spec's own \"METHOD /path\"
  keys, template placeholders included."
  [;; auth + api-keys (6)
   ["POST /auth/device/start" auth/device-start :post (str B "/auth/device/start")]
   ["POST /auth/device/poll" auth/device-poll :post (str B "/auth/device/poll") "dc"]
   ["POST /auth/device/complete" auth/device-complete :post (str B "/auth/device/complete") "dc" "cc"]
   ["GET /auth/api-keys" auth/list-api-keys :get (str B "/auth/api-keys")]
   ["POST /auth/api-keys" auth/create-api-key :post (str B "/auth/api-keys") {:name "ci"}]
   ["POST /auth/api-keys/{id}/revoke" auth/revoke-api-key :post (str B "/auth/api-keys/ak1/revoke") "ak1"]

   ;; credits (3)
   ["GET /credits/balance" credits/balance :get (str B "/credits/balance")]
   ["GET /credits/ledger" credits/ledger :get (str B "/credits/ledger")]
   ["GET /credits/prices" credits/prices :get (str B "/credits/prices")]

   ;; support (4)
   ["GET /contact/threads" support/list-threads :get (str B "/contact/threads")]
   ["POST /contact/threads" support/create-thread :post (str B "/contact/threads") {:title "t" :service "general" :message "m"}]
   ["GET /contact/threads/{id}" support/get-thread :get (str B "/contact/threads/t1") "t1"]
   ["POST /contact/threads/{id}/messages" support/reply :post (str B "/contact/threads/t1/messages") "t1" {:message "m"}]

   ;; domains + directory (9)
   ["GET /domains/check" domains/check :get (str B "/domains/check?domain=x.ro") "x.ro"]
   ["GET /domains/info" domains/info :get (str B "/domains/info?domain=x.ro") "x.ro"]
   ["GET /domains/preflight" domains/preflight :get (str B "/domains/preflight?domain=x.ro") "x.ro"]
   ["GET /domains/dns-snapshot" domains/dns-snapshot :get (str B "/domains/dns-snapshot?domain=x.ro") "x.ro"]
   ["GET /domains/search" domains/search :get (str B "/domains/search?q=shop") "shop"]
   ["POST /domains/search" domains/search-descriptions :post (str B "/domains/search") {:q "an online shop"}]
   ["GET /domains/example" domains/example :get (str B "/domains/example")]
   ["GET /domains/directory" domains/directory :get (str B "/domains/directory")]
   ["GET /domains/directory/{domain}" domains/directory-entry :get (str B "/domains/directory/x.ro") "x.ro"]

   ;; registrations (27)
   ["GET /domains/registrations" reg/list-registrations :get (str B "/domains/registrations")]
   ["POST /domains/registrations" reg/register :post (str B "/domains/registrations") {:domain "x.ro"}]
   ["GET /domains/registrations/{id}" reg/get-registration :get (str B "/domains/registrations/r1") "r1"]
   ["POST /domains/registrations/{id}/renew" reg/renew :post (str B "/domains/registrations/r1/renew") "r1"]
   ["PUT /domains/registrations/{id}/auto-renew" reg/set-auto-renew :put (str B "/domains/registrations/r1/auto-renew") "r1" {:enabled true}]
   ["PUT /domains/registrations/{id}/sensitive" reg/set-sensitive :put (str B "/domains/registrations/r1/sensitive") "r1" {:enabled true}]
   ["PUT /domains/registrations/{id}/nameservers" reg/set-nameservers :put (str B "/domains/registrations/r1/nameservers") "r1" {:nameservers ["ns1.x.ro"]}]
   ["GET /domains/registrations/{id}/hosts" reg/list-hosts :get (str B "/domains/registrations/r1/hosts") "r1"]
   ["POST /domains/registrations/{id}/hosts" reg/create-host :post (str B "/domains/registrations/r1/hosts") "r1" {:host "ns1" :ips ["1.2.3.4"]}]
   ["PUT /domains/registrations/{id}/hosts/{host}" reg/set-host-ips :put (str B "/domains/registrations/r1/hosts/ns1.x.ro") "r1" "ns1.x.ro" {:ips ["1.2.3.4"]}]
   ["DELETE /domains/registrations/{id}/hosts/{host}" reg/delete-host :delete (str B "/domains/registrations/r1/hosts/ns1.x.ro") "r1" "ns1.x.ro"]
   ["GET /domains/registrations/{id}/dsdata" reg/list-dsdata :get (str B "/domains/registrations/r1/dsdata") "r1"]
   ["POST /domains/registrations/{id}/dsdata" reg/publish-dsdata :post (str B "/domains/registrations/r1/dsdata") "r1" {:keytag 1 :alg 13 :digest_type 2 :digest "ab"}]
   ["DELETE /domains/registrations/{id}/dsdata" reg/withdraw-dsdata :delete (str B "/domains/registrations/r1/dsdata") "r1" {:keytag 1 :alg 13 :digest_type 2 :digest "ab"}]
   ["POST /domains/registrations/{id}/transfer-out" reg/transfer-out :post (str B "/domains/registrations/r1/transfer-out") "r1"]
   ["PUT /domains/registrations/{id}/registrant" reg/update-registrant :put (str B "/domains/registrations/r1/registrant") "r1" {:email "a@b.ro"}]
   ["POST /domains/registrations/{id}/registrant-email/start" reg/start-registrant-email-verification :post (str B "/domains/registrations/r1/registrant-email/start") "r1"]
   ["POST /domains/registrations/{id}/registrant-email/confirm" reg/confirm-registrant-email :post (str B "/domains/registrations/r1/registrant-email/confirm") "r1" {:token "t" :code "c"}]
   ["POST /domains/registrations/{id}/registrant-email/adopt" reg/adopt-registrant-email :post (str B "/domains/registrations/r1/registrant-email/adopt") "r1" {:email "a@b.ro"}]
   ["GET /domains/registrations/{id}/trade" reg/quote-trade :get (str B "/domains/registrations/r1/trade") "r1"]
   ["POST /domains/registrations/{id}/trade" reg/trade :post (str B "/domains/registrations/r1/trade") "r1" {:auth_key "k"}]
   ["POST /domains/transfers-in" reg/transfer-in :post (str B "/domains/transfers-in") {:domain "x.ro" :auth_key "k"}]
   ["POST /domains/trades-in" reg/trade-in :post (str B "/domains/trades-in") {:domain "x.ro" :auth_key "k"}]
   ["POST /domains/adoptions" reg/adopt :post (str B "/domains/adoptions") {:domain "x.ro"}]
   ["GET /domains/actions" reg/list-actions :get (str B "/domains/actions")]
   ["GET /domains/actions/{id}" reg/get-action :get (str B "/domains/actions/a1") "a1"]
   ["POST /domains/actions/{id}/cancel" reg/cancel-action :post (str B "/domains/actions/a1/cancel") "a1"]

   ;; dns (18)
   ["POST /domains/registrations/{id}/dns" dns/enable-hosting :post (str B "/domains/registrations/r1/dns") "r1"]
   ["DELETE /domains/registrations/{id}/dns" dns/disable-hosting :delete (str B "/domains/registrations/r1/dns") "r1"]
   ["GET /domains/registrations/{id}/dns/dnssec" dns/get-dnssec :get (str B "/domains/registrations/r1/dns/dnssec") "r1"]
   ["POST /domains/registrations/{id}/dns/dnssec" dns/enable-dnssec :post (str B "/domains/registrations/r1/dns/dnssec") "r1"]
   ["DELETE /domains/registrations/{id}/dns/dnssec" dns/disable-dnssec :delete (str B "/domains/registrations/r1/dns/dnssec") "r1"]
   ["GET /domains/registrations/{id}/dns/nameservers" dns/hosted-nameservers :get (str B "/domains/registrations/r1/dns/nameservers") "r1"]
   ["POST /domains/registrations/{id}/dns/nameservers" dns/set-hosted-nameservers :post (str B "/domains/registrations/r1/dns/nameservers") "r1" {:mode "labels"}]
   ["GET /dns/domains" dns/list-zones :get (str B "/dns/domains")]
   ["GET /dns/domains/{domain}" dns/get-zone :get (str B "/dns/domains/x.ro") "x.ro"]
   ["PUT /dns/domains/{domain}/records" dns/set-record :put (str B "/dns/domains/x.ro/records") "x.ro" {:record {:name "www" :type "A" :value "1.2.3.4"}}]
   ["DELETE /dns/domains/{domain}/records" dns/delete-record :delete (str B "/dns/domains/x.ro/records") "x.ro" {:name "www" :type "A"}]
   ["GET /dns/claims" dns/list-claims :get (str B "/dns/claims")]
   ["POST /dns/claims" dns/create-claim :post (str B "/dns/claims") {:domain "example.com"}]
   ["GET /dns/claims/{id}" dns/get-claim :get (str B "/dns/claims/c1") "c1"]
   ["DELETE /dns/claims/{id}" dns/release-claim :delete (str B "/dns/claims/c1") "c1"]
   ["PUT /dns/claims/{id}/seed" dns/seed-claim :put (str B "/dns/claims/c1/seed") "c1" {:snapshot_id "s1"}]
   ["DELETE /dns/claims/{id}/seed" dns/unseed-claim :delete (str B "/dns/claims/c1/seed") "c1"]
   ["POST /dns/claims/{id}/verify" dns/verify-claim :post (str B "/dns/claims/c1/verify") "c1"]

   ;; sharing (7)
   ["GET /domains/registrations/{id}/grants" sharing/list-domain-grants :get (str B "/domains/registrations/r1/grants") "r1"]
   ["POST /domains/registrations/{id}/grants" sharing/invite :post (str B "/domains/registrations/r1/grants") "r1" {:email "a@b.ro" :scopes ["dns"]}]
   ["DELETE /domains/registrations/{id}/grants/{grant-id}" sharing/revoke-grant :delete (str B "/domains/registrations/r1/grants/g1") "r1" "g1"]
   ["GET /grants" sharing/list-grants :get (str B "/grants")]
   ["POST /grants/{id}/accept" sharing/accept-grant :post (str B "/grants/g1/accept") "g1"]
   ["POST /grants/{id}/decline" sharing/decline-grant :post (str B "/grants/g1/decline") "g1"]
   ["POST /grants/{id}/leave" sharing/leave-grant :post (str B "/grants/g1/leave") "g1"]

   ;; vps (34)
   ["GET /vps/tiers" vps/list-tiers :get (str B "/vps/tiers")]
   ["GET /vps/system-images" vps/list-system-images :get (str B "/vps/system-images")]
   ["GET /vps/ssh-keys" vps/list-ssh-keys :get (str B "/vps/ssh-keys")]
   ["POST /vps/ssh-keys" vps/add-ssh-key :post (str B "/vps/ssh-keys") {:name "k" :public_key "ssh-ed25519 AAA"}]
   ["DELETE /vps/ssh-keys/{id}" vps/delete-ssh-key :delete (str B "/vps/ssh-keys/k1") "k1"]
   ["GET /vps/availability" vps/availability :get (str B "/vps/availability")]
   ["GET /vps/instances" vps/list-instances :get (str B "/vps/instances")]
   ["POST /vps/instances" vps/create-instance :post (str B "/vps/instances") {:tier_id "t1" :image_ref "ubuntu"}]
   ["GET /vps/apps" vps/app-catalog :get (str B "/vps/apps")]
   ["GET /vps/apps/deployments" vps/list-app-deployments :get (str B "/vps/apps/deployments")]
   ["POST /vps/apps/deployments" vps/deploy-app :post (str B "/vps/apps/deployments") {:app_id "a1" :tier_id "t1"}]
   ["GET /vps/apps/deployments/{id}" vps/get-app-deployment :get (str B "/vps/apps/deployments/d1") "d1"]
   ["POST /vps/apps/deployments/{id}/reveal-password" vps/reveal-app-password :post (str B "/vps/apps/deployments/d1/reveal-password") "d1"]
   ["GET /vps/instances/{id}" vps/get-instance :get (str B "/vps/instances/i1") "i1"]
   ["DELETE /vps/instances/{id}" vps/destroy-instance :delete (str B "/vps/instances/i1") "i1"]
   ["GET /vps/instances/{id}/metrics" vps/get-metrics :get (str B "/vps/instances/i1/metrics") "i1"]
   ["POST /vps/instances/{id}/queue-notify" vps/set-queue-notify :post (str B "/vps/instances/i1/queue-notify") "i1" {:enabled true}]
   ["POST /vps/instances/{id}/images" vps/create-snapshot :post (str B "/vps/instances/i1/images") "i1"]
   ["POST /vps/instances/{id}/restart" vps/restart :post (str B "/vps/instances/i1/restart") "i1"]
   ["POST /vps/instances/{id}/reset" vps/reset :post (str B "/vps/instances/i1/reset") "i1"]
   ["POST /vps/instances/{id}/shutdown" vps/shutdown :post (str B "/vps/instances/i1/shutdown") "i1"]
   ["POST /vps/instances/{id}/power-off" vps/power-off :post (str B "/vps/instances/i1/power-off") "i1"]
   ["POST /vps/instances/{id}/power-on" vps/power-on :post (str B "/vps/instances/i1/power-on") "i1"]
   ["PUT /vps/instances/{id}/rdns" vps/set-rdns :put (str B "/vps/instances/i1/rdns") "i1" {:hostname "srv.x.ro"}]
   ["GET /vps/instances/{id}/domains" vps/list-instance-domains :get (str B "/vps/instances/i1/domains") "i1"]
   ["POST /vps/instances/{id}/domains" vps/connect-domain :post (str B "/vps/instances/i1/domains") "i1" {:zone "x.ro" :subdomain "www"}]
   ["DELETE /vps/instances/{id}/domains/{connection-id}" vps/disconnect-domain :delete (str B "/vps/instances/i1/domains/c1") "i1" "c1"]
   ["GET /vps/volumes" vps/list-volumes :get (str B "/vps/volumes")]
   ["POST /vps/volumes" vps/create-volume :post (str B "/vps/volumes") {:name "v" :size_gb 10}]
   ["DELETE /vps/volumes/{id}" vps/delete-volume :delete (str B "/vps/volumes/v1") "v1"]
   ["GET /vps/images" vps/list-images :get (str B "/vps/images")]
   ["DELETE /vps/images/{id}" vps/delete-image :delete (str B "/vps/images/img1") "img1"]
   ["GET /vps/actions/{id}" vps/get-action :get (str B "/vps/actions/a1") "a1"]
   ["GET /vps/activity" vps/list-activity :get (str B "/vps/activity")]

   ;; transfers (9)
   ["POST /vps/instances/{id}/transfer" transfers/offer-instance :post (str B "/vps/instances/i1/transfer") "i1" {:email "a@b.ro"}]
   ["DELETE /vps/instances/{id}/transfer" transfers/withdraw-instance-offer :delete (str B "/vps/instances/i1/transfer") "i1"]
   ["POST /vps/volumes/{id}/transfer" transfers/offer-volume :post (str B "/vps/volumes/v1/transfer") "v1" {:email "a@b.ro"}]
   ["DELETE /vps/volumes/{id}/transfer" transfers/withdraw-volume-offer :delete (str B "/vps/volumes/v1/transfer") "v1"]
   ["POST /vps/images/{id}/transfer" transfers/offer-image :post (str B "/vps/images/img1/transfer") "img1" {:email "a@b.ro"}]
   ["DELETE /vps/images/{id}/transfer" transfers/withdraw-image-offer :delete (str B "/vps/images/img1/transfer") "img1"]
   ["GET /vps/transfers" transfers/list-transfers :get (str B "/vps/transfers")]
   ["POST /vps/transfers/{id}/accept" transfers/accept-transfer :post (str B "/vps/transfers/tr1/accept") "tr1"]
   ["POST /vps/transfers/{id}/decline" transfers/decline-transfer :post (str B "/vps/transfers/tr1/decline") "tr1"]

   ;; tunnels (6)
   ["GET /tunnels" tunnels/list-tunnels :get (str B "/tunnels")]
   ["POST /tunnels" tunnels/create-tunnel :post (str B "/tunnels") {:hostname "dev.x.ro"}]
   ["GET /tunnels/{id}" tunnels/get-tunnel :get (str B "/tunnels/tn1") "tn1"]
   ["DELETE /tunnels/{id}" tunnels/delete-tunnel :delete (str B "/tunnels/tn1") "tn1"]
   ["PATCH /tunnels/{id}" tunnels/update-tunnel :patch (str B "/tunnels/tn1") "tn1" {:settings {}}]
   ["POST /tunnels/{id}/verify-dns" tunnels/verify-dns :post (str B "/tunnels/tn1/verify-dns") "tn1"]

   ;; ipfs (18)
   ["GET /ipfs/pins" ipfs/list-pins :get (str B "/ipfs/pins")]
   ["POST /ipfs/pins" ipfs/pin :post (str B "/ipfs/pins") {:cid "bafy1"}]
   ["GET /ipfs/pins/{id}" ipfs/get-pin :get (str B "/ipfs/pins/p1") "p1"]
   ["DELETE /ipfs/pins/{id}" ipfs/unpin :delete (str B "/ipfs/pins/p1") "p1"]
   ["POST /ipfs/uploads" ipfs/start-upload :post (str B "/ipfs/uploads")]
   ["GET /ipfs/uploads/{id}" ipfs/get-upload :get (str B "/ipfs/uploads/u1") "u1"]
   ["GET /ipfs/names" ipfs/list-names :get (str B "/ipfs/names")]
   ["POST /ipfs/names" ipfs/create-name :post (str B "/ipfs/names")]
   ["GET /ipfs/names/{id}" ipfs/get-name :get (str B "/ipfs/names/n1") "n1"]
   ["DELETE /ipfs/names/{id}" ipfs/delete-name :delete (str B "/ipfs/names/n1") "n1"]
   ["PUT /ipfs/names/{id}/target" ipfs/publish-target :put (str B "/ipfs/names/n1/target") "n1" {:cid "bafy1"}]
   ["GET /ipfs/domains" ipfs/list-domains :get (str B "/ipfs/domains")]
   ["POST /ipfs/domains" ipfs/attach-domain :post (str B "/ipfs/domains") {:domain "gw.x.ro"}]
   ["GET /ipfs/domains/{id}" ipfs/get-domain :get (str B "/ipfs/domains/d1") "d1"]
   ["GET /ipfs/domains/{id}/pins" ipfs/list-domain-pins :get (str B "/ipfs/domains/d1/pins") "d1"]
   ["POST /ipfs/domains/{id}/pins" ipfs/update-domain-pins :post (str B "/ipfs/domains/d1/pins") "d1" {:add ["p1"]}]
   ["DELETE /ipfs/domains/{id}" ipfs/detach-domain :delete (str B "/ipfs/domains/d1") "d1"]
   ["GET /ipfs/usage" ipfs/usage :get (str B "/ipfs/usage")]

   ;; pins — Pinning Service API (5)
   ["GET /pins" pins/list-pins :get (str B "/pins")]
   ["POST /pins" pins/add-pin :post (str B "/pins") {:cid "bafy1"}]
   ["GET /pins/{requestid}" pins/get-pin :get (str B "/pins/rq1") "rq1"]
   ["POST /pins/{requestid}" pins/replace-pin :post (str B "/pins/rq1") "rq1" {:cid "bafy2"}]
   ["DELETE /pins/{requestid}" pins/remove-pin :delete (str B "/pins/rq1") "rq1"]

   ;; p2p (12)
   ["GET /p2p/apps" p2p/list-apps :get (str B "/p2p/apps")]
   ["POST /p2p/apps" p2p/create-app :post (str B "/p2p/apps") {:name "app"}]
   ["GET /p2p/apps/{id}" p2p/get-app :get (str B "/p2p/apps/a1") "a1"]
   ["DELETE /p2p/apps/{id}" p2p/delete-app :delete (str B "/p2p/apps/a1") "a1"]
   ["PATCH /p2p/apps/{id}" p2p/update-app :patch (str B "/p2p/apps/a1") "a1" {:origins ["https://x.ro"]}]
   ["POST /p2p/apps/{id}/turn-credentials" p2p/mint-turn-credentials :post (str B "/p2p/apps/a1/turn-credentials") "a1"]
   ["POST /p2p/apps/{id}/mailbox-credentials" p2p/mint-mailbox-credentials :post (str B "/p2p/apps/a1/mailbox-credentials") "a1"]
   ["GET /p2p/apps/{id}/domains" p2p/list-app-domains :get (str B "/p2p/apps/a1/domains") "a1"]
   ["POST /p2p/apps/{id}/domains" p2p/attach-domain :post (str B "/p2p/apps/a1/domains") "a1" {:hostname "p2p.x.ro"}]
   ["DELETE /p2p/apps/{id}/domains/{domain-id}" p2p/detach-domain :delete (str B "/p2p/apps/a1/domains/d1") "a1" "d1"]
   ["POST /p2p/apps/{id}/domains/{domain-id}/verify-dns" p2p/verify-domain-dns :post (str B "/p2p/apps/a1/domains/d1/verify-dns") "a1" "d1"]
   ["GET /p2p/usage" p2p/usage :get (str B "/p2p/usage")]

   ;; jobs (3)
   ["POST /jobs" jobs/enqueue :post (str B "/jobs") {:type "embedding" :input "x"}]
   ["GET /jobs/{id}" jobs/get-job :get (str B "/jobs/j1") "j1"]
   ["GET /jobs/{id}/result" jobs/get-result :get (str B "/jobs/j1/result") "j1"]])

(deftest inventory-equals-the-spec
  (let [described (set (map first operations))
        declared (tu/spec-operations)]
    (is (= (count operations) (count described)) "no duplicate rows")
    (is (= 161 (count declared)) "spec operation count (update README and site when this moves)")
    (is (= declared described)
        (str "\n  in spec but not in table: " (pr-str (sort (set/difference declared described)))
             "\n  in table but not in spec: " (pr-str (sort (set/difference described declared)))))))

(deftest-async every-operation-hits-the-exact-method-and-url
  (loop [rows operations]
    (when-let [[description f method url & args] (first rows)]
      (let [captured (atom [])
            client (ird/make-client {:api-key "ird_k" :http-fn (tu/capturing captured)})
            result (<! (apply f client args))]
        (is (not (tu/error? result)) (str description " delivered an error: " (some-> result ex-message)))
        (is (= 1 (count @captured)) (str description " made exactly one request"))
        (is (= method (:method (first @captured))) (str description " method"))
        (is (= url (:url (first @captured))) (str description " url"))
        (is (= "Bearer ird_k" (get-in (first @captured) [:headers "Authorization"])) (str description " auth")))
      (recur (rest rows)))))

static mirror of HEAD · about · clone: git clone https://ird.cod-sursa.ro/cljs.git