Skip to content

Commit d70e6ad

Browse files
authored
Merge pull request #405 from yetanalytics/empty-lang-maps
Empty language maps
2 parents b5ccdf7 + 61e8c09 commit d70e6ad

File tree

3 files changed

+146
-35
lines changed

3 files changed

+146
-35
lines changed

deps.edn

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@
4040
xyz.capybara/clamav-client {:mvn/version "2.1.2"}
4141
;; Yet Analytics deps
4242
com.yetanalytics/lrs
43-
{:mvn/version "1.2.17"
43+
{:mvn/version "1.2.18"
4444
:exclusions [org.clojure/clojure
4545
org.clojure/clojurescript
4646
com.yetanalytics/xapi-schema]}
4747
com.yetanalytics/xapi-schema
48-
{:mvn/version "1.2.2"
48+
{:mvn/version "1.3.0"
4949
:exclusions [org.clojure/clojure
5050
org.clojure/clojurescript]}
5151
com.yetanalytics/colossal-squuid

src/main/lrsql/util/statement.clj

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,54 @@
99

1010
;; If a Statement lacks a version, the version MUST be set to 1.0.0
1111
;; TODO: Change for version 2.0.0
12+
;; FIXME: Why is this not version 1.0.3?
1213
(def xapi-version "1.0.0")
1314

1415
;; NOTE: SQL LRS overwrites any pre-existing authority object in a statement, as
1516
;; suggested by the spec:
1617
;; https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Data.md#requirements-14
1718

19+
(defn- dissoc-empty-lang-maps*
20+
[{:strs [display name description] :as m}]
21+
(cond-> m
22+
(empty? display) (dissoc "display")
23+
(empty? name) (dissoc "name")
24+
(empty? description) (dissoc "description")))
25+
26+
(defn- dissoc-empty-lang-maps
27+
[statement]
28+
(cond-> statement
29+
;; Dissoc empty verb display
30+
true
31+
(update "verb" dissoc-empty-lang-maps*)
32+
;; Dissoc empty object activity name + description
33+
(= "Activity" (get-in statement ["object" "objectType"]))
34+
(update-in ["object" "definition"]
35+
(fn [{:strs [choices scale source target steps] :as obj-def}]
36+
(cond-> (dissoc-empty-lang-maps* obj-def)
37+
choices (update "choices" #(mapv dissoc-empty-lang-maps* %))
38+
scale (update "scale" #(mapv dissoc-empty-lang-maps* %))
39+
source (update "source" #(mapv dissoc-empty-lang-maps* %))
40+
target (update "target" #(mapv dissoc-empty-lang-maps* %))
41+
steps (update "steps" #(mapv dissoc-empty-lang-maps* %)))))
42+
;; Dissoc empty attachemnt name + description
43+
(contains? statement "attachments")
44+
(update "attachments" #(mapv dissoc-empty-lang-maps* %))))
45+
46+
(defn- assoc-to-statement
47+
"Assoc while also changing the meta of `statement`."
48+
[statement k v]
49+
(-> statement
50+
(assoc k v)
51+
(vary-meta update
52+
:assigned-vals
53+
conj
54+
(keyword k))))
55+
1856
(defn prepare-statement
1957
"Prepare `statement` for LRS storage by coll-ifying context activities
2058
and setting missing id, timestamp, authority, version, and stored
21-
properties."
59+
properties. In addition, removes empty maps from `statement`."
2260
[authority statement]
2361
(let [{?id "id"
2462
?timestamp "timestamp"
@@ -28,31 +66,34 @@
2866
squuid-ts :timestamp
2967
squuid-base :base-uuid}
3068
(u/generate-squuid*)
31-
assoc-to-stmt (fn [stmt k v] ; Assoc while also changing the meta
32-
(-> stmt
33-
(assoc k v)
34-
(vary-meta update
35-
:assigned-vals
36-
conj
37-
(keyword k))))
38-
squuid-ts-str (u/time->str squuid-ts)]
39-
(cond-> statement
40-
true
41-
ss/fix-statement-context-activities
42-
true
43-
(vary-meta assoc :assigned-vals #{})
44-
true
45-
(vary-meta assoc :primary-key squuid)
46-
true
47-
(assoc-to-stmt "stored" squuid-ts-str)
48-
true
49-
(assoc-to-stmt "authority" authority)
69+
squuid-ts-str
70+
(u/time->str squuid-ts)
71+
{{activity-def* "definition"} "object"
72+
context* "context"
73+
result* "result"
74+
:as statement*}
75+
(-> statement
76+
dissoc-empty-lang-maps
77+
ss/fix-statement-context-activities
78+
(vary-meta assoc :assigned-vals #{})
79+
(vary-meta assoc :primary-key squuid)
80+
(assoc-to-statement "stored" squuid-ts-str)
81+
(assoc-to-statement "authority" authority))]
82+
(cond-> statement*
83+
;; Dissoc empty properties
84+
(empty? activity-def*)
85+
(update "object" dissoc "definition")
86+
(empty? context*)
87+
(dissoc "context")
88+
(empty? result*)
89+
(dissoc "result")
90+
;; Assoc missing properties
5091
(not ?id)
51-
(assoc-to-stmt "id" (u/uuid->str squuid-base))
92+
(assoc-to-statement "id" (u/uuid->str squuid-base))
5293
(not ?timestamp)
53-
(assoc-to-stmt "timestamp" squuid-ts-str)
94+
(assoc-to-statement "timestamp" squuid-ts-str)
5495
(not ?version)
55-
(assoc-to-stmt "version" xapi-version))))
96+
(assoc-to-statement "version" xapi-version))))
5697

5798
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5899
;; Statement Equality

src/test/lrsql/util/statement_test.clj

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
(ns lrsql.util.statement-test
22
(:require [clojure.test :refer [deftest testing is]]
3-
[lrsql.util.statement :as su]))
3+
[lrsql.util.statement :as su]
4+
[lrsql.util :as u]))
45

56
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
67
;; Fixtures
@@ -46,6 +47,14 @@
4647
{"id" "http://www.example.com/tincan/activities/multipart"
4748
"objectType" "Activity"})
4849

50+
(def sample-attachment
51+
{"usageType" "http://example.com/attachment-usage/test"
52+
"display" {"en-US" "A test attachment"}
53+
"description" {"en-US" "A test attachment (description)"}
54+
"contentType" "text/plain"
55+
"length" 27
56+
"sha2" "495395e777cd98da653df9615d09c0fd6bb2f8d4788394cd53c56a3bfdcd848a"})
57+
4958
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5059
;; Tests
5160
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -54,17 +63,78 @@
5463
(let [lrs-authority {"mbox" "mailto:a@example.com"
5564
"objectType" "Agent"}
5665
foreign-authority {"mbox" "mailto:b@example.com"
57-
"objectType" "Agent"}]
66+
"objectType" "Agent"}
67+
;; Statements
68+
statement-1 {"id" sample-id
69+
"actor" sample-group
70+
"verb" sample-verb
71+
"object" sample-activity}
72+
statement-2 {"id" sample-id
73+
"actor" sample-group
74+
"verb" sample-verb
75+
"object" sample-activity
76+
"authority" foreign-authority}
77+
statement-3 {"id" sample-id
78+
"actor" sample-group
79+
"verb" (assoc sample-verb "display" {})
80+
"object" (assoc sample-activity
81+
"definition"
82+
{"name" {}
83+
"description" {}})
84+
"attachments" [(-> sample-attachment
85+
(assoc "display" {})
86+
(assoc "description" {}))]
87+
"context" {}
88+
"result" {}}
89+
statement-4 {"id" sample-id
90+
"actor" sample-group
91+
"verb" sample-verb
92+
"object" (assoc sample-activity
93+
"definition"
94+
{;; Doesn't form a valid statement but
95+
;; we need to test these lang maps
96+
"choices" [{"id" "Choice"
97+
"description" {}}]
98+
"scale" [{"id" "Scale"
99+
"description" {}}]
100+
"source" [{"id" "Source"
101+
"description" {}}]
102+
"target" [{"id" "Target"
103+
"description" {}}]
104+
"steps" [{"id" "Step"
105+
"description" {}}]})}]
106+
(testing "adds timestamp, stored, version, and authority"
107+
(let [statement* (su/prepare-statement lrs-authority statement-1)]
108+
(is (inst? (u/str->time (get statement* "timestamp"))))
109+
(is (inst? (u/str->time (get statement* "stored"))))
110+
(is (= su/xapi-version (get statement* "version")))
111+
(is (= lrs-authority (get statement* "authority")))))
58112
(testing "overwrites authority"
59113
(is (= lrs-authority
60-
(-> (su/prepare-statement
61-
lrs-authority
62-
{"id" sample-id
63-
"actor" sample-group
64-
"verb" sample-verb
65-
"object" sample-activity
66-
"authority" foreign-authority})
67-
(get "authority")))))))
114+
(-> (su/prepare-statement lrs-authority statement-2)
115+
(get "authority")))))
116+
(testing "dissocs empty maps"
117+
(is (= {"id" sample-id
118+
"actor" sample-group
119+
"verb" sample-verb-dissoc
120+
"object" sample-activity-dissoc
121+
"attachments" [(dissoc sample-attachment
122+
"display"
123+
"description")]}
124+
(-> (su/prepare-statement lrs-authority statement-3)
125+
(dissoc "timestamp" "stored" "authority" "version"))))
126+
(is (= {"id" sample-id
127+
"actor" sample-group
128+
"verb" sample-verb
129+
"object" (assoc sample-activity
130+
"definition"
131+
{"choices" [{"id" "Choice"}]
132+
"scale" [{"id" "Scale"}]
133+
"source" [{"id" "Source"}]
134+
"target" [{"id" "Target"}]
135+
"steps" [{"id" "Step"}]})}
136+
(-> (su/prepare-statement lrs-authority statement-4)
137+
(dissoc "timestamp" "stored" "authority" "version")))))))
68138

69139
(deftest statements-equal-test
70140
(testing "statement equality"

0 commit comments

Comments
 (0)