diff --git a/deps.edn b/deps.edn index a8dd1d85..9c49dd3f 100644 --- a/deps.edn +++ b/deps.edn @@ -42,7 +42,8 @@ :sha "423bd6c301ce8503f5c18b43df098bbe64f8f1ab"} com.yetanalytics/lrs-test-runner {:git/url "https://github.com/yetanalytics/lrs-test-runner.git" - :sha "0fcd42854f9c79a043c13d436d629826bfc5133d"}}} + :sha "0fcd42854f9c79a043c13d436d629826bfc5133d"} + babashka/babashka.curl {:mvn/version "0.1.2"}}} ;; bench utils for LRS implementations :bench {:extra-paths ["src/bench"] diff --git a/dev-resources/attachments/attachment_post_body.txt b/dev-resources/attachments/attachment_post_body.txt new file mode 100644 index 00000000..47f7b05a --- /dev/null +++ b/dev-resources/attachments/attachment_post_body.txt @@ -0,0 +1,45 @@ +--105423a5219f5a63362a375ba7a64a8f234da19c7d01e56800c3c64b26bb2fa0 +Content-Type:application/json + +{ + "actor": { + "mbox": "mailto:sample.agent@example.com", + "name": "Sample Agent", + "objectType": "Agent" + }, + "verb": { + "id": "http://adlnet.gov/expapi/verbs/answered", + "display": { + "en-US": "answered" + } + }, + "object": { + "id": "http://www.example.com/tincan/activities/multipart", + "objectType": "Activity", + "definition": { + "name": { + "en-US": "Multi Part Activity" + }, + "description": { + "en-US": "Multi Part Activity Description" + } + } + }, + "attachments": [ + { + "usageType": "http://example.com/attachment-usage/test", + "display": { "en-US": "A test attachment" }, + "description": { "en-US": "A test attachment (description)" }, + "contentType": "text/plain; charset=ascii", + "length": 27, + "sha2": "495395e777cd98da653df9615d09c0fd6bb2f8d4788394cd53c56a3bfdcd848a" + } + ] +} +--105423a5219f5a63362a375ba7a64a8f234da19c7d01e56800c3c64b26bb2fa0 +Content-Type:text/plain +Content-Transfer-Encoding:binary +X-Experience-API-Hash:495395e777cd98da653df9615d09c0fd6bb2f8d4788394cd53c56a3bfdcd848a + +here is a simple attachment +--105423a5219f5a63362a375ba7a64a8f234da19c7d01e56800c3c64b26bb2fa0-- diff --git a/src/test/com/yetanalytics/lrs/scan_test.clj b/src/test/com/yetanalytics/lrs/scan_test.clj new file mode 100644 index 00000000..3bbe4954 --- /dev/null +++ b/src/test/com/yetanalytics/lrs/scan_test.clj @@ -0,0 +1,79 @@ +(ns com.yetanalytics.lrs.scan-test + (:require [clojure.test :refer [deftest testing is use-fixtures]] + [babashka.curl :as curl] + [io.pedestal.http :as http] + [com.yetanalytics.test-support :as support])) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Tests +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(def attachment-post-params + {:basic-auth ["username" "password"] + :headers + {"X-Experience-API-Version" "1.0.3" + "Content-Type" + "multipart/mixed; boundary=105423a5219f5a63362a375ba7a64a8f234da19c7d01e56800c3c64b26bb2fa0"} + :body (slurp "dev-resources/attachments/attachment_post_body.txt") + :throw false}) + +(def doc-post-params + {:basic-auth ["username" "password"] + :headers {"X-Experience-API-Version" "1.0.3"} + :query-params + {"activityId" "http://www.example.com/activityId/hashset" + "agent" + "{\"objectType\":\"Agent\",\"account\":{\"homePage\":\"http://www.example.com/agentId/1\",\"name\":\"Rick James\"}}" + "stateId" "f8128f68-74e2-4951-8c5f-ef7cce73b4ff"} + :body "I'm a little teapot" + :throw false}) + +(deftest scan-test + (testing "File/Document Scanning" + ;; Stub out a scanner that always fails + (testing "Failure" + (let [server (support/test-server + :route-opts + {:file-scanner + (fn [in] + (slurp in) + {:message "Scan Fail!"})})] + (try + (http/start server) + (testing "Attachment" + (is (= {:status 400 + :body "{\"error\":{\"message\":\"Attachment scan failed, Errors: Scan Fail!\"}}"} + (select-keys + (curl/post + "http://localhost:8080/xapi/statements" + attachment-post-params) + [:body :status])))) + (testing "Document" + (is (= {:status 400 + :body "{\"error\":{\"message\":\"Document scan failed, Error: Scan Fail!\"}}"} + (select-keys + (curl/post + "http://localhost:8080/xapi/activities/state" + doc-post-params) + [:body :status])))) + (finally + (http/stop server))))) + (testing "Success" + (let [server (support/test-server)] + (try + (http/start server) + (testing "Attachment" + (is (= 200 + (:status + (curl/post + "http://localhost:8080/xapi/statements" + attachment-post-params))))) + (testing "Document" + (is (= 204 + (:status + (curl/post + "http://localhost:8080/xapi/activities/state" + doc-post-params))))) + (finally + (http/stop server))))))) diff --git a/src/test/com/yetanalytics/test_runner.cljc b/src/test/com/yetanalytics/test_runner.cljc index a5685317..933c8ae5 100644 --- a/src/test/com/yetanalytics/test_runner.cljc +++ b/src/test/com/yetanalytics/test_runner.cljc @@ -4,8 +4,9 @@ clojure.test.check.properties [clojure.test :as test :refer [run-tests] :include-macros true] - #?(:clj com.yetanalytics.lrs-test - :cljs [cljs.nodejs :refer [process]]) + #?@(:clj [com.yetanalytics.lrs-test + com.yetanalytics.lrs.scan-test] + :cljs [[cljs.nodejs :refer [process]]]) com.yetanalytics.lrs.xapi.activities-test com.yetanalytics.lrs.xapi.agents-test com.yetanalytics.lrs.xapi.document-test @@ -43,7 +44,8 @@ (defn- run-lrs-tests [] (run-tests - #?(:clj 'com.yetanalytics.lrs-test) + #?@(:clj ['com.yetanalytics.lrs-test + 'com.yetanalytics.lrs.scan-test]) 'com.yetanalytics.lrs.xapi.activities-test 'com.yetanalytics.lrs.xapi.agents-test 'com.yetanalytics.lrs.xapi.document-test diff --git a/src/test/com/yetanalytics/test_support.cljc b/src/test/com/yetanalytics/test_support.cljc index fef843d4..dfc2067a 100644 --- a/src/test/com/yetanalytics/test_support.cljc +++ b/src/test/com/yetanalytics/test_support.cljc @@ -4,7 +4,12 @@ [clojure.spec.alpha :as s :include-macros true] [clojure.test :refer [deftest testing is #?(:cljs async)] :include-macros true] [clojure.test.check] - #?@(:clj [[clojure.spec.test.alpha :as stest :include-macros true]]))) + #?@(:clj [[clojure.spec.test.alpha :as stest :include-macros true]]) + [io.pedestal.http :as http] + [com.yetanalytics.lrs.impl.memory :as mem] + [com.yetanalytics.lrs.pedestal.routes :as r] + [com.yetanalytics.lrs.pedestal.interceptor :as i] + #?(:cljs [com.yetanalytics.node-chain-provider :as provider]))) #?(:clj (alias 'stc 'clojure.spec.test.check)) @@ -61,3 +66,35 @@ :cljs (async done (a/take! ch (fn [_] (done)))))) + +(defn test-server + "Create (but do not start) an in-memory LRS for testing purposes." + [& {:keys [port + lrs-mode + route-opts] + :or {port 8080 + lrs-mode :sync + route-opts {}}}] + (let [lrs (mem/new-lrs {}) + service {:env :dev + ::lrs lrs + ::http/routes (r/build + (merge + {:lrs lrs + :wrap-interceptors + [i/error-interceptor]} + route-opts)) + #?@(:clj [::http/resource-path "/public"]) + ::http/host "0.0.0.0" + ::http/port port + ::http/container-options {:h2c? true + :h2? false + :ssl? false} + ::http/allowed-origins {:creds true + :allowed-origins (constantly true)} + ::http/type #?(:clj :jetty + :cljs provider/macchiato-server-fn) + ::http/join? false}] + (-> service + i/xapi-default-interceptors + http/create-server)))