Browse Source

fix(rtc): fix update-block-attrs, add tests

rcmerci 1 year ago
parent
commit
c826cf5d4e

+ 28 - 27
src/main/frontend/worker/rtc/remote_update.cljs

@@ -2,7 +2,6 @@
   "Fns about applying remote updates"
   (:require [clojure.data :as data]
             [clojure.set :as set]
-            [cognitect.transit :as transit]
             [datascript.core :as d]
             [frontend.schema-register :as sr]
             [frontend.worker.batch-tx :as batch-tx]
@@ -22,8 +21,6 @@
   "remote-update's :remote-t-before > :local-tx,
    so need to pull earlier remote-data from websocket.")
 
-(def ^:private transit-r (transit/reader :json))
-
 (defmulti ^:private transact-db! (fn [action & _args] action))
 
 (defmethod transact-db! :delete-blocks [_ & args]
@@ -302,7 +299,7 @@
         first-remote-parent (first parents)]
     (when-let [local-parent (d/entity db [:block/uuid first-remote-parent])]
       (let [page-name (:block/name local-parent)
-            properties* (transit/read transit-r properties)
+            properties* (ldb/read-transit-str properties)
             shape-property-id (db-property-util/get-pid repo :logseq.property.tldraw/shape)
             shape (and (map? properties*)
                        (get properties* shape-property-id))]
@@ -357,17 +354,25 @@
 
 (defn- diff-block-map->tx-data
   [db e local-block-map remote-block-map]
-  (mapcat
-   (fn [[k local-v]]
-     (let [remote-v (get remote-block-map k)]
-       (seq (diff-block-kv->tx-data db (d/schema db) e k local-v remote-v))))
-   local-block-map))
+  (let [db-schema (d/schema db)
+        tx-data1
+        (mapcat
+         (fn [[k local-v]]
+           (let [remote-v (get remote-block-map k)]
+             (seq (diff-block-kv->tx-data db db-schema e k local-v remote-v))))
+         local-block-map)
+        tx-data2
+        (mapcat
+         (fn [[k remote-v]]
+           (let [local-v (get local-block-map k)]
+             (seq (diff-block-kv->tx-data db db-schema e k local-v remote-v))))
+         (apply dissoc remote-block-map (keys local-block-map)))]
+    (concat tx-data1 tx-data2)))
 
 (defn- remote-op-value->tx-data
-  [conn block-uuid op-value]
-  (let [db @conn
-        db-schema (d/schema db)
-        ent (d/entity @conn [:block/uuid block-uuid])
+  [db block-uuid op-value]
+  (let [db-schema (d/schema db)
+        ent (d/entity db [:block/uuid block-uuid])
         local-block-map (->> (select-keys ent watched-attrs)
                              (map (fn [[k v]]
                                     (let [k-schema (get db-schema k)
@@ -378,7 +383,7 @@
                                          [true true]
                                          (keep (fn [x] (when-let [e (:db/id x)] (:block/uuid (d/entity db e)))) v)
                                          [true false]
-                                         (let [v* (some->> (:db/id v) (d/entity @conn) :block/uuid)]
+                                         (let [v* (some->> (:db/id v) (d/entity db) :block/uuid)]
                                            (assert (some? v*) v)
                                            v*)
                                          ;; else
@@ -387,19 +392,15 @@
     (diff-block-map->tx-data db (:db/id ent) local-block-map op-value)))
 
 (defn- update-block-attrs
-  [repo conn block-uuid {:keys [parents properties _content] :as op-value}]
-  (let [key-set (set/intersection
-                 (conj rtc-const/general-attr-set :content)
-                 (set (keys op-value)))]
-    (when (seq key-set)
-      (let [first-remote-parent (first parents)
-            local-parent (d/entity @conn [:block/uuid first-remote-parent])
-            whiteboard-page-block? (whiteboard-page-block? local-parent)]
-        (if (and whiteboard-page-block? properties)
-          (upsert-whiteboard-block repo conn op-value)
-          (when-let [tx-data (seq (remote-op-value->tx-data conn block-uuid op-value))]
-            (ldb/transact! conn tx-data {:persist-op? false
-                                         :gen-undo-ops? false})))))))
+  [repo conn block-uuid {:keys [parents _content] :as op-value}]
+  (let [first-remote-parent (first parents)
+        local-parent (d/entity @conn [:block/uuid first-remote-parent])
+        whiteboard-page-block? (whiteboard-page-block? local-parent)]
+    (if whiteboard-page-block?
+      (upsert-whiteboard-block repo conn op-value)
+      (when-let [tx-data (seq (remote-op-value->tx-data @conn block-uuid op-value))]
+        (ldb/transact! conn tx-data {:persist-op? false
+                                     :gen-undo-ops? false})))))
 
 (defn- apply-remote-update-ops
   [repo conn update-ops]

+ 49 - 0
src/test/frontend/worker/rtc/remote_update_test.cljs

@@ -0,0 +1,49 @@
+(ns frontend.worker.rtc.remote-update-test
+  (:require [cljs.test :as t :refer [deftest is testing]]
+            [datascript.core :as d]
+            [frontend.worker.rtc.remote-update :as subject]
+            [logseq.db :as ldb]
+            [logseq.db.frontend.schema :as db-schema]))
+
+(deftest remote-op-value->tx-data-test
+  (let [[block-uuid ref-uuid1 ref-uuid2] (repeatedly random-uuid)
+        db (d/empty-db db-schema/schema-for-db-based-graph)]
+    (testing ":block/content"
+      (let [db (d/db-with db [{:block/uuid block-uuid
+                               :block/content "local-content"}])
+            op-value {:block/content (ldb/write-transit-str "remote-content")}]
+        (is (= [[:db/add (:db/id (d/entity db [:block/uuid block-uuid])) :block/content "remote-content"]]
+               (#'subject/remote-op-value->tx-data db block-uuid op-value)))))
+
+    (testing ":block/tags (1)"
+      (let [db (d/db-with db [{:block/uuid block-uuid}
+                              {:block/uuid ref-uuid1}
+                              {:block/uuid ref-uuid2}])
+            op-value {:block/tags [ref-uuid1 ref-uuid2]}
+            [db-id ref1 ref2] (map :db/id (d/pull-many db [:db/id] [[:block/uuid block-uuid]
+                                                                    [:block/uuid ref-uuid1]
+                                                                    [:block/uuid ref-uuid2]]))]
+        (is (= #{[:db/add db-id :block/tags ref1] [:db/add db-id :block/tags ref2]}
+               (set (#'subject/remote-op-value->tx-data db block-uuid op-value))))))
+
+    (testing ":block/tags (2)"
+      (let [db (d/db-with db [{:db/id "ref1"
+                               :block/uuid ref-uuid1}
+                              {:block/uuid ref-uuid2}
+                              {:block/uuid block-uuid
+                               :block/tags ["ref1"]}])
+            op-value {:block/tags [ref-uuid2]}
+            [db-id ref2] (map :db/id (d/pull-many db [:db/id] [[:block/uuid block-uuid]
+                                                               [:block/uuid ref-uuid2]]))]
+        (is (= #{[:db/retract db-id :block/tags [:block/uuid ref-uuid1]]
+                 [:db/add db-id :block/tags ref2]}
+               (set (#'subject/remote-op-value->tx-data db block-uuid op-value))))))
+
+    (testing ":block/tags (3): ref2 not exist"
+      (let [db (d/db-with db [{:db/id "ref1"
+                               :block/uuid ref-uuid1}
+                              {:block/uuid block-uuid
+                               :block/tags ["ref1"]}])
+            op-value {:block/tags [ref-uuid2]}]
+        (is (= #{[:db/retract (:db/id (d/entity db [:block/uuid block-uuid])) :block/tags [:block/uuid ref-uuid1]]}
+               (set (#'subject/remote-op-value->tx-data db block-uuid op-value))))))))