Browse Source

Add initial tests on property handler

Tienson Qin 2 years ago
parent
commit
f342303e6a

+ 1 - 1
src/main/frontend/extensions/pdf/assets.cljs

@@ -204,7 +204,7 @@
                        (assoc (pu/get-pid :id) (str id)))
                properties (->>
                            (wrap-props props)
-                           (property-handler/replace-key-with-id! (state/get-current-repo)))]
+                           (property-handler/replace-key-with-id (state/get-current-repo)))]
            (when (string? text)
              (editor-handler/api-insert-new-block!
               text (merge {:page        (:block/name ref-page)

+ 2 - 2
src/main/frontend/handler/db_based/property.cljs

@@ -162,7 +162,7 @@
                                   :block/refs refs}]
                                 {:outliner-op :save-block}))))))))))
 
-(defn resolve-tag
+(defn- resolve-tag
   "Change `v` to a tag's UUID if v is a string tag, e.g. `#book`"
   [v]
   (when (and (string? v)
@@ -477,7 +477,7 @@
                                      {})
                 (remove-block-property! repo (:block/uuid block) property-id)))))))))
 
-(defn replace-key-with-id!
+(defn replace-key-with-id
   "Notice: properties need to be created first"
   [m]
   (zipmap

+ 1 - 1
src/main/frontend/handler/editor.cljs

@@ -550,7 +550,7 @@
                             (wrap-parse-block)
                             (assoc :block/uuid (or custom-uuid (db/new-block-id))))
               new-block (if (and db-based? (seq properties))
-                          (assoc new-block :block/properties (db-property-handler/replace-key-with-id! properties))
+                          (assoc new-block :block/properties (db-property-handler/replace-key-with-id properties))
                           new-block)
               new-block (merge new-block other-attrs)
               [block-m sibling?] (cond

+ 3 - 3
src/main/frontend/handler/property.cljs

@@ -65,8 +65,8 @@
       (db-property-handler/batch-set-property! repo block-ids key value))
     (file-property-handler/batch-set-block-property! block-ids key value)))
 
-(defn replace-key-with-id!
+(defn replace-key-with-id
   [repo m]
   (if (config/db-based-graph? repo)
-    (db-property-handler/replace-key-with-id! m)
-    m))
+    (db-property-handler/replace-key-with-id m)
+    m))

+ 7 - 5
src/main/frontend/handler/property/util.cljs

@@ -11,10 +11,12 @@
 (defn lookup
   "Get the value of coll's (a map) `key`. For file and db graphs"
   [coll key]
-  (let [repo (state/get-current-repo)]
-    (if (and (config/db-based-graph? repo)
-             (keyword? key))
-      (when-let [property (db/entity repo [:block/name (gp-util/page-name-sanity-lc (name key))])]
+  (let [repo (state/get-current-repo)
+        property-name (if (keyword? key)
+                        (name key)
+                        key)]
+    (if (config/db-based-graph? repo)
+      (when-let [property (db/entity repo [:block/name (gp-util/page-name-sanity-lc property-name)])]
         (get coll (:block/uuid property)))
       (get coll key))))
 
@@ -47,4 +49,4 @@
   (get-property block :logseq.tldraw.page))
 
 (defn shape-block? [block]
-  (= :whiteboard-shape (get-property block :ls-type)))
+  (= :whiteboard-shape (get-property block :ls-type)))

+ 1 - 0
src/test/frontend/handler/db_based/page_test.cljs

@@ -0,0 +1 @@
+(ns frontend.handler.db-based.page-test)

+ 188 - 0
src/test/frontend/handler/db_based/property_test.cljs

@@ -0,0 +1,188 @@
+(ns frontend.handler.db-based.property-test
+  (:require [frontend.handler.db-based.property :as property]
+            [frontend.db :as db]
+            [clojure.test :refer [deftest is testing are use-fixtures]]
+            [frontend.test.helper :as test-helper]
+            [datascript.core :as d]
+            [frontend.handler.property.util :as pu]
+            [frontend.state]
+            [frontend.config]))
+
+(def repo test-helper/test-db-name-db-version)
+
+(def init-data (test-helper/initial-test-page-and-blocks))
+(defn start-and-destroy-db
+  [f]
+  (test-helper/db-based-start-and-destroy-db
+   f
+   {:init-data (fn [conn] (d/transact! conn init-data))}))
+
+;; init page id
+;; (def pid (:block/uuid (first init-data)))
+;; first block id
+(def fbid (:block/uuid (second init-data)))
+(def sbid (:block/uuid (nth init-data 2)))
+
+(use-fixtures :each start-and-destroy-db)
+
+;; set-block-property!
+;; remove-block-property!
+;; batch-set-property!
+;; batch-remove-property!
+;; upsert-property!
+;; update-property!
+(deftest set-block-property-test
+  (testing "Add a property to a block"
+    (property/set-block-property! repo fbid "property-1" "value" {})
+    (let [block (db/entity [:block/uuid fbid])
+          properties (:block/properties block)
+          property (db/entity [:block/name "property-1"])]
+      ;; ensure property exists
+      (are [x y] (= x y)
+        (:block/schema property)
+        {:type :default}
+        (:block/type property)
+        #{"property"})
+      ;; check block's properties
+      (are [x y] (= x y)
+        (count properties)
+        1
+        (uuid? (ffirst properties))
+        true
+        (second (first properties))
+        "value")))
+
+  (testing "Add another property"
+    (property/set-block-property! repo fbid "property-2" "1" {})
+    (let [block (db/entity [:block/uuid fbid])
+          properties (:block/properties block)
+          property (db/entity [:block/name "property-2"])]
+      ;; ensure property exists
+      (are [x y] (= x y)
+        (:block/schema property)
+        {:type :number}
+        (:block/type property)
+        #{"property"})
+      ;; check block's properties
+      (are [x y] (= x y)
+        (count properties)
+        2
+        (every? uuid? (map first properties))
+        true
+        (second (second properties))
+        1)))
+
+  (testing "Update property value"
+    (property/set-block-property! repo fbid "property-2" 2 {})
+    (let [block (db/entity [:block/uuid fbid])
+          properties (:block/properties block)]
+      ;; check block's properties
+      (are [x y] (= x y)
+        (count properties)
+        2
+        (second (second properties))
+        2)))
+
+  (testing "Wrong type property value shouldn't transacted"
+    (property/set-block-property! repo fbid "property-2" "Not a number" {})
+    (let [block (db/entity [:block/uuid fbid])
+          properties (:block/properties block)]
+      ;; check block's properties
+      (are [x y] (= x y)
+        (count properties)
+        2
+        (second (second properties))
+        2)))
+
+  (testing "Add a multi-values property"
+    (property/upsert-property! repo "property-3" {:type :default :cardinality :many} {})
+    (property/set-block-property! repo fbid "property-3" "value 1" {})
+    (property/set-block-property! repo fbid "property-3" "value 2" {})
+    (property/set-block-property! repo fbid "property-3" "value 3" {})
+    (let [block (db/entity [:block/uuid fbid])
+          properties (:block/properties block)
+          property (db/entity [:block/name "property-3"])]
+      ;; ensure property exists
+      (are [x y] (= x y)
+        (:block/schema property)
+        {:type :default :cardinality :many}
+        (:block/type property)
+        #{"property"})
+      ;; check block's properties
+      (are [x y] (= x y)
+        (count properties)
+        3
+        (get properties (:block/uuid property))
+        #{"value 1" "value 2" "value 3"}))
+
+    ;; update property value from "value 1" to "value 4"
+    (property/set-block-property! repo fbid "property-3" "value 4" {:old-value "value 1"})
+    (let [block (db/entity [:block/uuid fbid])
+          properties (:block/properties block)
+          property (db/entity [:block/name "property-3"])]
+      ;; check block's properties
+      (are [x y] (= x y)
+        (count properties)
+        3
+        (get properties (:block/uuid property))
+        #{"value 4" "value 2" "value 3"})))
+
+  (testing "Remove a property"
+    (property/remove-block-property! repo fbid "property-3")
+    (let [block (db/entity [:block/uuid fbid])
+          properties (:block/properties block)
+          property (db/entity [:block/name "property-3"])]
+      ;; check block's properties
+      (are [x y] (= x y)
+        (count properties)
+        2
+        (contains? (set (keys properties)) (:block/uuid property))
+        false)))
+
+  (testing "Batch set properties"
+    (let [k "property-4"
+          v "batch value"]
+      (property/batch-set-property! repo [fbid sbid] k v)
+      (let [fb (db/entity [:block/uuid fbid])
+            sb (db/entity [:block/uuid sbid])]
+        (are [x y] (= x y)
+          (pu/get-property fb k)
+          v
+          (pu/get-property sb k)
+          v))))
+
+  (testing "Batch remove properties"
+    (let [k "property-4"]
+      (property/batch-remove-property! repo [fbid sbid] k)
+      (let [fb (db/entity [:block/uuid fbid])
+            sb (db/entity [:block/uuid sbid])]
+        (are [x y] (= x y)
+          (count (:block/properties fb))
+          2
+          (count (:block/properties sb))
+          0)))))
+
+;; delete-property-value!
+;; property-create-new-block
+
+;; class related
+;; class-add-property!
+;; class-remove-property!
+;; class-set-schema!
+;; get-block-classes-properties
+
+;; closed values related
+;; upsert-closed-value
+;; add-existing-values-to-closed-values!
+;; delete-closed-value
+;; get-property-block-created-block
+
+;; template (TBD, template implementation not settle down yet)
+;; property-create-new-block-from-template
+
+;; others
+;; convert-property-input-string
+;; replace-key-with-id
+;; collapse-expand-property! TODO
+
+#_(cljs.test/run-tests)

+ 1 - 0
src/test/frontend/handler/db_based/recent_test.cljs

@@ -0,0 +1 @@
+(ns frontend.handler.db-based.recent-test)

+ 1 - 0
src/test/frontend/handler/property_test.cljs

@@ -0,0 +1 @@
+(ns frontend.handler.property-test)

+ 50 - 9
src/test/frontend/test/helper.cljs

@@ -13,21 +13,26 @@
 
 (def node? (exists? js/process))
 
-(defonce test-db
-  (if (and node? (some? js/process.env.DB_GRAPH)) "logseq_db_test-db" "test-db"))
+(def test-db-name "test-db")
+(def test-db-name-db-version "logseq_db_test-db")
+(def test-db
+  (if (and node? (some? js/process.env.DB_GRAPH)) test-db-name-db-version test-db-name))
 
 (defn start-test-db!
-  []
-  (conn/start! test-db))
+  [& {:as opts}]
+  (let [test-db (if (:db-graph? opts)
+                  test-db-name-db-version
+                  test-db-name)]
+    (conn/start! test-db opts)))
 
 (defn destroy-test-db!
   []
   (conn/destroy-all!))
 
 (defn reset-test-db!
-  []
+  [& {:as opts}]
   (destroy-test-db!)
-  (start-test-db!))
+  (start-test-db! opts))
 
 (defn- parse-property-value [value]
   (if-let [refs (seq (map #(or (second %) (get % 2))
@@ -194,18 +199,54 @@ This can be called in synchronous contexts as no async fns should be invoked"
    ;; Set :refresh? to avoid creating default files in after-parse
      {:re-render? false :verbose false :refresh? true})))
 
+(defn initial-test-page-and-blocks
+  []
+  (let [page-uuid (random-uuid)
+        first-block-uuid (random-uuid)
+        second-block-uuid (random-uuid)
+        page-id [:block/uuid page-uuid]]
+    (->>
+     [;; page
+      {:block/uuid page-uuid
+       :block/name "test"
+       :block/original-name "test"}
+      ;; first block
+      {:block/uuid first-block-uuid
+       :block/page page-id
+       :block/parent page-id
+       :block/left page-id
+       :block/content "block 1"
+       :block/format :markdown}
+      ;; second block
+      {:block/uuid second-block-uuid
+       :block/page page-id
+       :block/parent page-id
+       :block/left [:block/uuid first-block-uuid]
+       :block/content "block 2"
+       :block/format :markdown}]
+     (map sqlite-util/block-with-timestamps))))
+
 (defn start-and-destroy-db
   "Sets up a db connection and current repo like fixtures/reset-datascript. It
   also seeds the db with the same default data that the app does and destroys a db
   connection when done with it."
-  [f]
+  [f & {:as start-opts}]
   ;; Set current-repo explicitly since it's not the default
-  (state/set-current-repo! test-db)
-  (start-test-db!)
+  (state/set-current-repo! test-db-name-db-version)
+  (start-test-db! start-opts)
+  (when-let [init-f (:init-data start-opts)]
+    (assert (fn? f) "init-data should be a fn")
+    (init-f (db/get-db test-db-name-db-version false)))
   (f)
   (state/set-current-repo! nil)
   (destroy-test-db!))
 
+(defn db-based-start-and-destroy-db
+  [f & {:as start-opts}]
+  (set! test-db "logseq_db_test-db")
+  (start-and-destroy-db f (assoc start-opts :db-graph? true))
+  (set! test-db "test-db"))
+
 (def start-and-destroy-db-map-fixture
   "To avoid 'Fixtures may not be of mixed types' error
   when use together with other map-type fixtures"