penpot/backend/test/backend_tests/util_blob_test.clj
2026-05-29 11:24:58 +02:00

107 lines
3.9 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC Sucursal en España SL
(ns backend-tests.util-blob-test
(:require
[app.util.blob :as blob]
[clojure.string :as str]
[clojure.test :as t]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; encode-str / decode-str round-trip
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(t/deftest encode-str-roundtrip-empty-map
(let [data {}]
(t/is (= data (blob/decode-str (blob/encode-str data))))))
(t/deftest encode-str-roundtrip-empty-vector
(let [data []]
(t/is (= data (blob/decode-str (blob/encode-str data))))))
(t/deftest encode-str-roundtrip-nil
(let [data nil]
(t/is (= data (blob/decode-str (blob/encode-str data))))))
(t/deftest encode-str-roundtrip-simple-map
(let [data {:name "penpot" :version 42}]
(t/is (= data (blob/decode-str (blob/encode-str data))))))
(t/deftest encode-str-roundtrip-nested-structure
(let [data {:users [{:name "Alice" :tags #{"admin" "active"}}
{:name "Bob" :tags #{"user"}}]
:config {:debug false :timeout 3000}}]
(t/is (= data (blob/decode-str (blob/encode-str data))))))
(t/deftest encode-str-roundtrip-vector-of-maps
(let [data [{:name "navigate" :type "action" :source "telemetry"}
{:name "create-file" :type "action" :source "telemetry"}]]
(t/is (= data (blob/decode-str (blob/encode-str data))))))
(t/deftest encode-str-roundtrip-keywords-and-strings
(let [data {:keyword/value :foo
:string/value "hello world"
:boolean/value true
:nil/value nil}]
(t/is (= data (blob/decode-str (blob/encode-str data))))))
(t/deftest encode-str-roundtrip-numeric-types
(let [data {:int 42
:neg -7
:zero 0
:big 9999999999}]
(t/is (= data (blob/decode-str (blob/encode-str data))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; URL-safe encoding properties
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(t/deftest encode-str-url-safe-no-unsafe-chars
;; URL-safe base64 must not contain +, /, or padding =
(let [data {:a (apply str (repeat 100 "x"))
:b (range 200)
:c {"key" "value with special chars: @#$%^&*()"}}
encoded (blob/encode-str data)]
(t/is (not (str/includes? encoded "+")))
(t/is (not (str/includes? encoded "/")))
(t/is (not (str/includes? encoded "=")))))
(t/deftest encode-str-url-safe-roundtrip-after-encoding
;; Ensure the URL-safe encoding still round-trips correctly
(let [data {:payload (vec (range 500))
:nested {:a {:b {:c "deep"}}}}
encoded (blob/encode-str data)
decoded (blob/decode-str encoded)]
(t/is (= data decoded))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; version-specific encoding
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(t/deftest encode-str-with-version-4
(let [data {:events [{:name "click"} {:name "scroll"}]}
encoded (blob/encode-str data {:version 4})
decoded (blob/decode-str encoded)]
(t/is (= data decoded))))
(t/deftest encode-str-with-version-5
(let [data {:events [{:name "click"} {:name "scroll"}]}
encoded (blob/encode-str data {:version 5})
decoded (blob/decode-str encoded)]
(t/is (= data decoded))))
(t/deftest encode-str-with-version-1
(let [data {:simple "data"}
encoded (blob/encode-str data {:version 1})
decoded (blob/decode-str encoded)]
(t/is (= data decoded))))
(t/deftest encode-str-with-version-3
(let [data {:simple "data"}
encoded (blob/encode-str data {:version 3})
decoded (blob/decode-str encoded)]
(t/is (= data decoded))))