(ns frontend.handler.db-based.sync-test (:require [cljs.test :refer [deftest is async]] [clojure.string :as string] [frontend.db :as db] [frontend.handler.db-based.sync :as db-sync] [frontend.handler.user :as user-handler] [frontend.state :as state] [logseq.db :as ldb] [logseq.db.sqlite.util :as sqlite-util] [promesa.core :as p])) (def ^:private test-text-encoder (js/TextEncoder.)) (defn- frame-bytes [^js data] (let [len (.-byteLength data) out (js/Uint8Array. (+ 4 len)) view (js/DataView. (.-buffer out))] (.setUint32 view 0 len false) (.set out data 4) out)) (defn- encode-framed-rows [rows] (let [payload (.encode test-text-encoder (sqlite-util/write-transit-str rows))] (frame-bytes payload))) (defn- (p/with-redefs [db-sync/http-base (fn [] "http://base") db-sync/fetch-json (fn [url opts _] (reset! called {:url url :opts opts}) (p/resolved {:ok true})) user-handler/task--ensure-id&access-token (fn [resolve _reject] (resolve true))] (p/let [_ (db-sync/ (p/with-redefs [db-sync/http-base (fn [] "http://base") db-sync/fetch-json (fn [url opts _] (reset! called {:url url :opts opts}) (p/resolved {:ok true})) user-handler/task--ensure-id&access-token (fn [resolve _reject] (resolve true)) user-handler/user-uuid (fn [] "user-1")] (p/let [_ (db-sync/ (p/with-redefs [user-handler/user-uuid (fn [] nil)] (db-sync/ (p/with-redefs [state/get-rtc-graphs (fn [] [{:url "repo-other"}]) state/ (p/with-redefs [state/get-rtc-graphs (fn [] [{:url "repo-current"}]) state/ (p/with-redefs [state/get-rtc-graphs (fn [] [{:url "repo-current"}]) state/*db-worker worker] (p/let [start-p (db-sync/ (p/with-redefs [state/get-rtc-graphs (fn [] [{:url "repo-other"}]) state/*db-worker worker] (p/let [start-p (db-sync/ (p/with-redefs [db-sync/http-base (fn [] "http://base") user-handler/task--ensure-id&access-token (fn [resolve _reject] (resolve true)) db/get-db (fn [] :db) ldb/get-graph-schema-version (fn [_] {:major 65}) db-sync/fetch-json (fn [url opts _] (reset! fetch-called {:url url :opts opts}) (p/resolved {:graph-id "graph-1" :graph-e2ee? false})) ldb/transact! (fn [repo tx-data] (reset! tx-called {:repo repo :tx-data tx-data}) nil)] (db-sync/ @fetch-called (get-in [:opts :body]) js/JSON.parse (js->clj :keywordize-keys true)) tx-data (:tx-data @tx-called)] (is (= "graph-1" graph-id)) (is (= "http://base/graphs" (:url @fetch-called))) (is (= false (:graph-e2ee? request-body))) (is (= :logseq.kv/graph-rtc-e2ee? (get-in tx-data [2 :db/ident]))) (is (= false (get-in tx-data [2 :kv/value])))) (done))) (p/catch (fn [e] (is false (str e)) (done))))))) (deftest rtc-create-graph-defaults-e2ee-enabled-test (async done (let [fetch-called (atom nil) tx-called (atom nil)] (-> (p/with-redefs [db-sync/http-base (fn [] "http://base") user-handler/task--ensure-id&access-token (fn [resolve _reject] (resolve true)) db/get-db (fn [] :db) ldb/get-graph-schema-version (fn [_] {:major 65}) db-sync/fetch-json (fn [url opts _] (reset! fetch-called {:url url :opts opts}) (p/resolved {:graph-id "graph-2"})) ldb/transact! (fn [repo tx-data] (reset! tx-called {:repo repo :tx-data tx-data}) nil)] (db-sync/ @fetch-called (get-in [:opts :body]) js/JSON.parse (js->clj :keywordize-keys true)) tx-data (:tx-data @tx-called)] (is (= "graph-2" graph-id)) (is (= "http://base/graphs" (:url @fetch-called))) (is (= true (:graph-e2ee? request-body))) (is (= :logseq.kv/graph-rtc-e2ee? (get-in tx-data [2 :db/ident]))) (is (= true (get-in tx-data [2 :kv/value])))) (done))) (p/catch (fn [e] (is false (str e)) (done))))))) (deftest rtc-download-graph-emits-feedback-before-snapshot-fetch-test (let [trace (atom []) log-events (atom [])] (with-redefs [db-sync/http-base (fn [] "http://base") state/set-state! (fn [k v] (swap! trace conj [:set k v])) state/pub-event! (fn [[event payload :as e]] (when (and (= :rtc/log event) (= "graph-1" (:graph-uuid payload))) (swap! trace conj :log) (swap! log-events conj e))) ;; Keep auth pending so we only validate immediate click-time feedback. user-handler/task--ensure-id&access-token (fn [_resolve _reject] nil) db-sync/fetch-json (fn [url _opts _schema] (swap! trace conj [:fetch url]) (p/resolved {:t 1}))] (db-sync/ (p/let [gzip-bytes ( (p/with-redefs [db-sync/http-base (fn [] "http://base") db-sync/fetch-json (fn [url _opts _schema] (cond (string/ends-with? url "/pull") (p/resolved {:t 42}) :else (p/rejected (ex-info "unexpected fetch-json URL" {:url url})))) user-handler/task--ensure-id&access-token (fn [resolve _reject] (resolve true)) state/