summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authoreltrac <hi@eltr.ac>2026-09-23 15:11:03 +0800
committerEltrac <hi@eltr.ac>2026-09-24 05:51:07 +0200
commit64a59447a9bcb9956eef6afef1d9d748a51156c5 (patch)
tree091b8db25e4a1cc9c2aaaea365d18e5eddc03a92 /test
parent5fa1f0cb40153410964c2431c3e1bd16ce309b0e (diff)
test: improve test coverage #28
- remove reducer spec warninns, test spec before compiling instead. - cover more forms of webhook.clj, webhook_presets.clj, microformats/reducer.clj, microformats/searcher.clj, http/downloader.clj - remove unused code from config.clj - format all tests
Diffstat (limited to 'test')
-rw-r--r--test/weepinbell/downloader_test.clj33
-rw-r--r--test/weepinbell/microformats_test.clj100
-rw-r--r--test/weepinbell/processor_starter_test.clj2
-rw-r--r--test/weepinbell/storage_test.clj15
-rw-r--r--test/weepinbell/webhook_test.clj66
-rw-r--r--test/weepinbell/wrapper_test.clj14
-rw-r--r--test/weepinbell/writer_test.clj2
7 files changed, 209 insertions, 23 deletions
diff --git a/test/weepinbell/downloader_test.clj b/test/weepinbell/downloader_test.clj
new file mode 100644
index 0000000..7a2d6b3
--- /dev/null
+++ b/test/weepinbell/downloader_test.clj
@@ -0,0 +1,33 @@
+(ns weepinbell.downloader-test
+ (:require [weepinbell.http.downloader :refer [download-file]]
+ [clojure.java.io :as io]
+ [org.httpkit.server :refer [run-server]]
+ [clojure.test :refer [deftest testing is]]))
+
+(deftest downloader-test
+ (testing "Downloading a regular text file with parent dirs not available"
+ (let [handler (fn [& _] {:status 200
+ :body "file content"
+ :headers {"Content-Type" "text/plain; charset: utf-8"}})
+ server (run-server handler {:port 18888 :join? false})
+ file-dst (io/file "tmp/test.txt")]
+ (is (download-file "http://localhost:18888" file-dst))
+ (is (= "file content" (slurp file-dst)))
+ (io/delete-file file-dst)
+ (server)))
+ (testing "Downloading a regular text file"
+ (let [handler (fn [& _] {:status 200
+ :body "file content"
+ :headers {"Content-Type" "text/plain; charset: utf-8"}})
+ server (run-server handler {:port 18888 :join? false})
+ file-dst (io/file "tmp/test.txt")]
+ (io/make-parents file-dst)
+ (is (download-file "http://localhost:18888" file-dst))
+ (is (= "file content" (slurp file-dst)))
+ (io/delete-file file-dst)
+ (server)))
+ (testing "Downloading a non-existant file"
+ (let [file-dst (io/file "tmp/should-not-exist.txt")]
+ (is (not (download-file "https://localhost:18888" file-dst)))
+ (is (not (.exists file-dst))))))
+
diff --git a/test/weepinbell/microformats_test.clj b/test/weepinbell/microformats_test.clj
new file mode 100644
index 0000000..b937206
--- /dev/null
+++ b/test/weepinbell/microformats_test.clj
@@ -0,0 +1,100 @@
+(ns weepinbell.microformats-test
+ (:require [weepinbell.microformats.reducer :refer [reduce-mf]]
+ [weepinbell.microformats.searcher :as sr]
+ [clojure.spec.alpha :as s]
+ [clojure.test :refer [deftest testing is]]))
+
+(def testdata
+ [{:in {:items [{:type ["h-entry"]
+ :properties {:content [{:html "<div>test</div>"
+ :text "test"}]
+ :in-reply-to ["https://test.com"]
+ :published [52341243232]
+ :author [{:type ["h-card"]
+ :properties {:name ["test"]
+ :nickname ["testie"]
+ :photo [{:alt "testie's selfie"
+ :value "https://test.com/photo.png"}]
+ :url ["https://test.com"]}}]}}]}
+ :out {:author
+ {:name "test",
+ :url "https://test.com",
+ :photo "https://test.com/photo.png"},
+ :type :in-reply-to,
+ :published 52341243232,
+ :content {:html "<div>test</div>", :text "test"}}}
+ {:in {:items [{:type ["h-entry"]
+ :properties {:content [{:html "<div>test</div>"
+ :text "test"}]
+ :published [52341243232]}}
+ {:type ["h-card"]
+ :properties {:name ["test"]
+ :nickname ["testie"]
+ :photo [{:alt "testie's selfie"
+ :value "https://test.com/photo.png"}]
+ :url ["https://test.com"]}}]}
+ :out {:author
+ {:name "test",
+ :url "https://test.com",
+ :photo "https://test.com/photo.png"},
+ :type :mention,
+ :published 52341243232,
+ :content {:html "<div>test</div>", :text "test"}}}])
+
+(def spec-check (partial s/valid? :weepinbell.microformats.reducer/reduced-microformats))
+(deftest reducer-test
+ (testing "Normal microformats reduction"
+ (->> testdata
+ (map #(let [reduced (reduce-mf (:in %))]
+ (is (= reduced (:out %)))
+ (is (spec-check reduced))))
+ doall))
+ (testing "spec check invalid reduced microformats"
+ (is (not (spec-check {:author nil :type :mention :published 1 :content nil})))
+ (is (not (spec-check [])))))
+
+(deftest searcher-test
+ (testing "use-items gets a list of microformats items"
+ (->> testdata
+ (map #(is (= (sr/use-items (:in %))
+ (sr/use-items (:items (:in %)))
+ (get-in % [:in :items]))))
+ doall))
+ (testing "use-items returns nil if not items or cannot get items in it"
+ (is (nil? (sr/use-items {:no-items nil})))
+ (is (nil? (sr/use-items "no-items")))
+ (is (nil? (sr/use-items [])))
+ (is (nil? (sr/use-items 1))))
+ (testing "use-props get properties of a microformats item"
+ (->> testdata
+ (map #(is (= (->> % sr/use-items sr/find-h-entry (sr/use-prop :content))
+ (get-in % [:items first :properties :content first]))))
+ doall))
+ (testing "use-props works with out :properties key as well"
+ (is (= (sr/use-prop :key {:properties {:key ["value"]}})
+ (sr/use-prop :key {:key ["value"]})
+ "value")))
+ (testing "find-type functions"
+ (is (= ["h-entry"]
+ (->> testdata first :in sr/use-items sr/find-h-entry :type)))
+ (is (= ["h-card"]
+ (->> testdata second :in sr/use-items sr/find-h-card :type))))
+ (testing "search photos in h-card"
+ (let [photo-url "https://test.com/photo.png"
+ testdata-a {:type ["h-card"]
+ :properties {:photo [photo-url]}}
+ testdata-b {:type ["h-card"]
+ :properties {:photo [{:alt "photo"
+ :value photo-url}]}}
+ testdata-c {:type ["h-entry"]
+ :properties {:author [{:type ["h-card"]
+ :properties {:photo [photo-url]}}]}}
+ testdata-d {:type ["h-card"]
+ :properties {:author [{:type ["h-card"]
+ :properties {}}]
+ :org [{:type ["h-card"]
+ :properties {:photo [photo-url]}}]}}]
+ (is (= photo-url (sr/search-photo testdata-a)))
+ (is (= photo-url (sr/search-photo testdata-b)))
+ (is (= photo-url (sr/search-photo testdata-c)))
+ (is (= photo-url (sr/search-photo testdata-d))))))
diff --git a/test/weepinbell/processor_starter_test.clj b/test/weepinbell/processor_starter_test.clj
index d19ac2a..65f6427 100644
--- a/test/weepinbell/processor_starter_test.clj
+++ b/test/weepinbell/processor_starter_test.clj
@@ -18,7 +18,7 @@
:config {:base-url "https://test.com"
:allowed-target-domains ["test.com"]}})
-(deftest start-processor-test
+(deftest start-processor-test
(testing "starting processor and putting a fake webmention in queue"
(start-processor processor-meta)
(put! test-wmc {:s "s" :t "t"})
diff --git a/test/weepinbell/storage_test.clj b/test/weepinbell/storage_test.clj
index 41b92a2..abd9ea6 100644
--- a/test/weepinbell/storage_test.clj
+++ b/test/weepinbell/storage_test.clj
@@ -2,11 +2,18 @@
(:require [clojure.test :refer [testing is deftest]]
[weepinbell.storage.edn-storage :as edns]
[clojure.spec.alpha :as s]
- [weepinbell.storage.edn-storage]
[weepinbell.storage.spec]))
-(deftest edn-storage-conformity-test
+(def spec-check (partial s/valid? :weepinbell.storage.spec/vtable))
+(deftest storage-conformity-test
(testing "edn-storage should conform storage spec."
(with-redefs [weepinbell.storage.edn-storage/file-exists? (fn [_] true)]
- (is (s/valid? :weepinbell.storage.spec/vtable
- (edns/use-store "source.edn"))))))
+ (is (spec-check (edns/use-store "source.edn")))))
+ (testing "spec-check invalid storage vtables"
+ (is (not (spec-check {:get-by-domain (fn [_])})))
+ (is (not (spec-check {:append (fn [_]) :get (fn [_])})))
+ (is (not (spec-check nil)))
+ (is (not (spec-check 1)))
+ (is (not (spec-check "I am storage. Trust me.")))
+ (is (not (spec-check [])))
+ (is (not (spec-check {})))))
diff --git a/test/weepinbell/webhook_test.clj b/test/weepinbell/webhook_test.clj
index ac2a0e6..7f7cc18 100644
--- a/test/weepinbell/webhook_test.clj
+++ b/test/weepinbell/webhook_test.clj
@@ -1,6 +1,7 @@
(ns weepinbell.webhook-test
(:require [clojure.test :refer [testing is deftest]]
[org.httpkit.server :refer [run-server]]
+ [ring.middleware.params :refer [wrap-params]]
[weepinbell.webhook :as webhook]))
(def test-wm-data {:webmention {:target "https://target.net/"
@@ -8,6 +9,28 @@
:extra {:proxied-photo "https://test.com/photo.png"}})
(deftest webhook-test
+ (testing "Test webhooks triggers with bark request"
+ (let [received (promise)
+ payload-ok (promise)
+ handler (fn [req]
+ (deliver received true)
+ (let [params (:form-params req)
+ title (get params "title")
+ icon (get params "icon")
+ url (get params "url")]
+ (when (and (= title "source.net mentioned you!")
+ (= url "https://source.net/")
+ (= icon "https://test.com/photo.png"))
+ (deliver payload-ok true)))
+ {:status 200 :headers {} :body "ok"})
+ server (run-server (wrap-params handler) {:port 18888 :join? false})]
+ (webhook/trigger :on-create
+ [{:url "http://127.0.0.1:18888/webhook-test"
+ :request-fn :bark}]
+ test-wm-data)
+ (is (deref received 2000 nil))
+ (is (deref payload-ok 2000 nil))
+ (server)))
(testing "Test webhooks triggers with ntfy request"
(let [received (promise)
payload-ok (promise)
@@ -29,9 +52,17 @@
test-wm-data)
(is (deref received 2000 nil))
(is (deref payload-ok 2000 nil))
+ (server)))
+ (testing "Webhook handle invalid URLs"
+ (let [received (promise)
+ handler (fn [_] (deliver received true))
+ server (run-server handler {:port 18888 :join? false})]
+ (webhook/trigger :on-update ["test"] test-wm-data)
+ (is (not (deref received 100 false)))
(server))))
(def test-make (partial webhook/make-url :on-create test-wm-data))
+(def test-make-empty (partial webhook/make-url :on-delete {}))
(deftest make-url-test
(testing "Test webhook replacing dynamic parameters in URL"
(is (= (test-make "https://webhook.test/{event}")
@@ -43,15 +74,30 @@
(is (= (test-make "https://hook.{target-domain}/update")
"https://hook.target.net/update"))
(is (= (test-make "https://webhook.test?=source={source}&target={target}")
- "https://webhook.test?=source=https://source.net/&target=https://target.net/"))))
+ "https://webhook.test?=source=https://source.net/&target=https://target.net/")))
+ (testing "Dynamic URL parameters with empty data"
+ (is (= (test-make-empty "{source}{target}{source-encoded}{target-encoded}{source-domain}{target-domain}{photo}{event}")
+ "on-delete"))))
(deftest make-request-test
- (testing "Test webhook constructing request options dynamically"
- (let [test-data {:webmention {:target "https://target.net/"
- :source "https://source.net/"}
- :extra {:proxied-photo "https://test.com/photo.png"}}]
- (is (= (webhook/make-request :on-create test-data :ntfy)
- {:body "from https://source.net/\nto https://target.net/"
- :headers {"Title" "source.net mentioned you!"
- "Click" "https://source.net/"
- "Icon" "https://test.com/photo.png"}})))))
+ (testing "Webhook constructing request options dynamically with presets"
+ (is (= (webhook/make-request :on-create test-wm-data :ntfy)
+ {:body "from https://source.net/\nto https://target.net/"
+ :headers {"Title" "source.net mentioned you!"
+ "Click" "https://source.net/"
+ "Icon" "https://test.com/photo.png"}})))
+ (testing "Webhook constructing request options with custom functions"
+ (let [custom-map {:body "customized!"}]
+ (is (= (webhook/make-request :on-receive test-wm-data (fn [& _] custom-map))
+ custom-map)))))
+
+(deftest make-actions-test
+ (testing "Constructing action map"
+ (is (= (webhook/make-actions :default ["https://test.com"
+ {:url "https://test.net" :request-fn :test-fn}])
+ [{:url "https://test.com" :request-fn :default}
+ {:url "https://test.net" :request-fn :test-fn}])))
+ (testing "Constructing action map with empty data"
+ (is (= (webhook/make-actions nil nil) []))
+ (is (= (webhook/make-actions :default []) []))))
+
diff --git a/test/weepinbell/wrapper_test.clj b/test/weepinbell/wrapper_test.clj
index cfb6a73..74bfbcf 100644
--- a/test/weepinbell/wrapper_test.clj
+++ b/test/weepinbell/wrapper_test.clj
@@ -4,7 +4,7 @@
[weepinbell.utils.digest :refer [digest]]
[weepinbell.processor.wrapper :refer [wrap]]))
-(def normal-source-html
+(def normal-source-html
"<div class=h-entry>
<div class=e-content>test</div>
<div class=\"p-author h-card\">
@@ -12,13 +12,13 @@
</div>
</div>")
-(deftest happy-path-wrap
+(deftest happy-path-wrap
(testing "Wrapping a normal webmention"
- (let [wrapped (:new-data (wrap {:ok? true
- :wm {:s "https://source.net"
- :t "https://target.org"}
- :source-html normal-source-html}
- {:base-url "https://resource.com"}))]
+ (let [wrapped (:new-data (wrap {:ok? true
+ :wm {:s "https://source.net"
+ :t "https://target.org"}
+ :source-html normal-source-html}
+ {:base-url "https://resource.com"}))]
(is (= "https://source.net" (get-in wrapped [:webmention :source])))
(is (= "https://target.org" (get-in wrapped [:webmention :target])))
(is (= "b36497f812ccfde649996e21f8df83a6" (get-in wrapped [:webmention :id])))
diff --git a/test/weepinbell/writer_test.clj b/test/weepinbell/writer_test.clj
index 1d9b14a..e5a6446 100644
--- a/test/weepinbell/writer_test.clj
+++ b/test/weepinbell/writer_test.clj
@@ -20,7 +20,7 @@
(is (deref updated 10 false)
(deref update-callbacked 10 false)))))
-(deftest writer-test
+(deftest writer-test
(testing "Append new webmentin"
(test-write {:ok? true :new? true :id "1" :new-data {}} :should-append))
(testing "Update old webmentin"