Back
swap! (clj)
(source)function
(swap! at f & args)
swap! on atomic clock 'at'
Examples
borgeby/jarl
(ns jarl.builtins.http-test
(:require [jarl.builtins.http :refer [builtin-http-send content-type create-request parse-timeout]]
[jarl.exceptions :as errors]
[jarl.types :refer [rego-equal?]]
[jarl.http-client :as http-client]
[jarl.time :as time]
#?(:clj [clojure.test :refer [deftest is testing]]
:cljs [cljs.test :refer [deftest is testing]])
[tick.core :as t]))
(testing "force cache"
(let [counter (atom 0)
req {"method" "get" "url" "http://borge.by" "force_cache" true "force_cache_duration_seconds" 30}]
(with-redefs [http-client/send-request
(fn [_]
(swap! counter inc)
{:status 200 :headers {"content-type" "application/json"} :body "{\"foo\":\"bar\"}"})]
(let [res {"body" {"foo" "bar"} "headers" {"content-type" "application/json"}
"raw_body" "{\"foo\":\"bar\"}" "status" "200 OK" "status_code" 200}]
(is (= (builtin-http-send {:args [req] :builtin-context {:time-now-ns 1}}) res))
(is (= (builtin-http-send {:args [req] :builtin-context {:time-now-ns 1}}) res))
(is (= (builtin-http-send {:args [req] :builtin-context {:time-now-ns 1}}) res))
(is (= @counter 1)))))))
(deftest http-send-caching-test
(testing "force cache"
(let [counter (atom 0)
req {"method" "get" "url" "http://borge.by/foo" "force_cache" true "force_cache_duration_seconds" 30}]
(with-redefs [http-client/send-request
(fn [_]
(swap! counter inc)
{:status 200 :headers {"content-type" "application/json"} :body "{\"foo\":\"bar\"}"})]
(let [res {"body" {"foo" "bar"} "headers" {"content-type" "application/json"}
"raw_body" "{\"foo\":\"bar\"}" "status" "200 OK" "status_code" 200}]
(is (= (builtin-http-send {:args [req] :builtin-context {:time-now-ns 1}}) res))
(is (= (builtin-http-send {:args [req] :builtin-context {:time-now-ns 1}}) res))
(is (= @counter 1))))))
(testing "force cache duration"
(let [counter (atom 0)
req {"method" "get" "url" "http://borge.by/bar" "force_cache" true "force_cache_duration_seconds" 30}]
(with-redefs [http-client/send-request
(fn [_]
(swap! counter inc)
{:status 200 :headers {"content-type" "application/json"} :body "{\"foo\":\"bar\"}"})]
(let [res {"body" {"foo" "bar"} "headers" {"content-type" "application/json"}
"raw_body" "{\"foo\":\"bar\"}" "status" "200 OK" "status_code" 200}
now (time/now-ns)
exp (time/instant->ns (t/>> (t/now) (t/new-duration 60 :seconds)))
bctx {:time-now-ns now}]
(is (= (builtin-http-send {:args [req] :builtin-context bctx}) res))
(is (= @counter 1))
(is (= (builtin-http-send {:args [req] :builtin-context bctx}) res))
(is (= @counter 1))
(is (= (builtin-http-send {:args [req] :builtin-context {:time-now-ns exp}}) res)) ; fast-forward 1 minute
(is (= @counter 2))))))
(testing "cache from response headers, cache-control"
(let [counter (atom 0)
req {"method" "get" "url" "http://borge.by" "cache" true}]
(with-redefs [http-client/send-request
(fn [_]
(swap! counter inc)
{:status 200
; note upper-case keys
:headers {"Content-Type" "application/json"
"Cache-Control" "ignored, max-age=30, also=ignored"
"Date" "Sat, 01 Jan 2022 15:10:05 GMT"}
:body "{\"foo\":\"bar\"}"})]
(let [res {"body" {"foo" "bar"}
"headers" {"content-type" "application/json"
"cache-control" "ignored, max-age=30, also=ignored"
"date" "Sat, 01 Jan 2022 15:10:05 GMT"}
"raw_body" "{\"foo\":\"bar\"}" "status" "200 OK" "status_code" 200}
now (t/instant (t/zoned-date-time "2022-01-01T15:10:05Z"))
exp (time/instant->ns (t/>> now (t/new-duration 60 :seconds)))
bctx {:time-now-ns (time/instant->ns now)}]
(is (= (builtin-http-send {:args [req] :builtin-context bctx}) res))
(is (= @counter 1))
(is (= (builtin-http-send {:args [req] :builtin-context bctx}) res))
(is (= @counter 1))
(is (= (builtin-http-send {:args [req] :builtin-context {:time-now-ns exp}}) res)) ; fast-forward 1 minute
(is (= @counter 2))))))
(testing "cache from response headers, expires"
(let [counter (atom 0)
req {"method" "get" "url" "http://borge.by/jarl" "cache" true}]
(with-redefs [http-client/send-request
(fn [_]
(swap! counter inc)
{:status 200
:headers {"content-type" "application/json"
"date" "Sat, 01 Jan 2022 15:10:05 GMT"
"expires" "Sat, 01 Jan 2022 15:40:05 GMT"}
:body "{\"foo\":\"bar\"}"})]
(let [res {"body" {"foo" "bar"}
"headers" {"content-type" "application/json"
"date" "Sat, 01 Jan 2022 15:10:05 GMT"
"expires" "Sat, 01 Jan 2022 15:40:05 GMT"}
"raw_body" "{\"foo\":\"bar\"}" "status" "200 OK" "status_code" 200}
now (t/instant (t/zoned-date-time "2022-01-01T15:10:05Z"))
exp (time/instant->ns (t/>> now (t/new-duration 60 :minutes)))
bctx {:time-now-ns (time/instant->ns now)}]
(is (= (builtin-http-send {:args [req] :builtin-context bctx}) res))
(is (= @counter 1))
(is (= (builtin-http-send {:args [req] :builtin-context bctx}) res))
(is (= @counter 1))
(is (= (builtin-http-send {:args [req] :builtin-context {:time-now-ns exp}}) res)) ; fast-forward 1 hour
(is (= @counter 2)))))))