penpot/frontend/test/frontend_tests/ui/history_test.cljs
Andrey Antukh 4b978767ea
🌐 Clean up en translations (#11853)
Drop 277 keys nothing references from en.po (verified against
frontend/src and common/src) and let sync propagate the
deletions to every locale. Clear all 10 fuzzy entries: fill
the 5 empty translations, keep the 4 valid ones, and drop the
duplicated max-quote-reached in favor of max-quota-reached
(the backend code stays, the UI maps it to the quota text).

Recover 22 used-but-missing keys with translations: the 19
shortcuts section/subsection labels plus connected-to,
pixel-grid-color and tokens.add-set. Make the rest
statically visible to rehash instead: :label fns on shortcut
commands, sections and subsections (one debug-only and one
colorpicker-local id exempt); case branches in place of
dm/str-built keys (export modal, text decoration and
transform, undo history with raw-key fallback); hoist
conditionals out of tr calls; pre-translate modal props and
role labels; replace the lone (i18n/tr ...) site with tr.
Turn static :error/code data into eager :error/fn calls in
the common schemas and the auth/password forms. Rename the
two keys containing spaces and point team leave at
max-quota-reached. Backend-driven keys stay dynamic by
design, declared with (tr ...) comments: the five
weak-password details, team and organization notifications.

Tooling: rehash also scans common/src and no longer treats
a missing -l as no locale; new clj-kondo tr-dynamic warning
flags non-literal tr args (lint scripts use --fail-level
error so it never fails CI); tr docstring states the
literal-only rule. Tests cover the shortcut label wiring,
the undo-history fallback and the :error/fn schemas.
Translations memory rewritten to match; es check word list
gains three entries.

Rebased onto develop: adopt the register field-error UX
(the weak-password declarations move onto the :options
code), keep develop's newer keys (connection-error,
account-locked, save-retrying, tokens-source strings) with
fresh references, and reword the shortcuts.cljs prose
comment so rehash does not invent a "literal" key.

AI-assisted-by: muse-spark-1.3-contributor
2026-09-25 11:11:44 +02:00

50 lines
2.2 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 SUBSIDIARY SL
(ns frontend-tests.ui.history-test
(:require
[app.main.ui.workspace.sidebar.history :as history]
[app.util.i18n :as i18n]
[cljs.test :as t :include-macros true]
[frontend-tests.helpers.mock :as mock]))
;; entry-type->message resolves every undo entry type through a static
;; (tr "literal") call (see :penpot/tr-dynamic). The stub marks keys that
;; go through tr, so the test locks the exact key per type and proves
;; unknown types fall back to the raw key without translation.
(def ^:private multiple-attributes
["circle" "color" "component" "curve" "frame" "group" "media" "multiple"
"page" "path" "rect" "shape" "text" "typography"])
(def ^:private single-attributes
["circle" "color" "component" "curve" "frame" "group" "image" "media"
"multiple" "page" "path" "rect" "shape" "text" "typography"])
(t/deftest entry-type-message-uses-static-keys
(with-redefs [i18n/tr (mock/stub (fn [k] (str "TR:" k)))]
(t/testing "multiple arity resolves a literal key per attribute"
(doseq [attribute multiple-attributes]
(t/is (= (str "TR:workspace.undo.entry.multiple." attribute)
(history/entry-type->message (keyword attribute) true))
attribute)))
(t/testing "single arity resolves a literal key per attribute"
(doseq [attribute single-attributes]
(t/is (= (str "TR:workspace.undo.entry.single." attribute)
(history/entry-type->message (keyword attribute) false))
attribute)))
(t/testing "nil type reads as multiple"
(t/is (= "TR:workspace.undo.entry.single.multiple"
(history/entry-type->message nil false))))
(t/testing "unknown attributes fall back to the raw key"
(t/is (= "workspace.undo.entry.single.frobnicate"
(history/entry-type->message :frobnicate false)))
(t/is (= "workspace.undo.entry.multiple.frobnicate"
(history/entry-type->message :frobnicate true))))))