🐛 Prevent nil theme in profile updates

Omit nil optional profile fields before frontend schema validation and RPC persistence. Preserve omitted language and theme values in backend updates, and add regression coverage for partial profile saves.

AI-assisted-by: gpt-5.6-luna
This commit is contained in:
Andrey Antukh 2026-08-18 11:18:44 +00:00
parent d745dc4a3c
commit 5b4a5776cb
5 changed files with 55 additions and 4 deletions

View File

@ -166,8 +166,12 @@
;; the same row/object.
(let [profile (get-profile conn profile-id ::db/for-update true)
fullname (d/normalize-string fullname)
lang (d/normalize-string lang)
theme (d/normalize-string theme)
lang (if (contains? params :lang)
(d/normalize-string lang)
(:lang profile))
theme (if (contains? params :theme)
(d/normalize-string theme)
(:theme profile))
;; Update the profile map with direct params
profile (-> profile
(assoc :fullname fullname)

View File

@ -125,6 +125,17 @@
(t/is (= "en" (:lang result)))
(t/is (= "dark" (:theme result))))))
(t/testing "update profile preserves omitted optional fields"
(let [data {::th/type :update-profile
::rpc/profile-id (:id profile)
:fullname "Updated Name"}
out (th/command! data)]
(t/is (nil? (:error out)))
(t/is (= "Updated Name" (get-in out [:result :fullname])))
(t/is (= "en" (get-in out [:result :lang])))
(t/is (= "dark" (get-in out [:result :theme])))))
(t/testing "update photo"
(let [data {::th/type :update-profile-photo
::rpc/profile-id (:id profile)

View File

@ -122,6 +122,10 @@
;; --- Update Profile
(defn profile-update-params
[profile]
(d/without-nils (select-keys profile [:fullname :lang :theme])))
(defn persist-profile
[& {:as opts}]
(ptk/reify ::persist-profile
@ -130,7 +134,7 @@
(let [on-success (:on-success opts identity)
on-error (:on-error opts rx/throw)
profile (:profile state)
params (select-keys profile [:fullname :lang :theme])]
params (profile-update-params profile)]
(->> (rp/cmd! :update-profile params)
(rx/tap on-success)
(rx/map set-profile)
@ -143,7 +147,7 @@
props"
[profile]
(let [profile (check-profile profile)]
(let [profile (check-profile (d/without-nils profile))]
(ptk/reify ::update-profile
ptk/WatchEvent
(watch [_ state _]

View File

@ -0,0 +1,30 @@
;; 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 frontend-tests.data.profile-test
(:require
[app.common.uuid :as uuid]
[app.main.data.profile :as dprof]
[cljs.test :as t :include-macros true]))
(t/deftest profile-update-params-omits-nil-values
(t/is (= {:fullname "Updated Name"}
(dprof/profile-update-params {:fullname "Updated Name"
:lang nil
:theme nil}))))
(t/deftest profile-update-params-preserves-present-values
(t/is (= {:fullname "Updated Name"
:lang "en"
:theme "dark"}
(dprof/profile-update-params {:fullname "Updated Name"
:lang "en"
:theme "dark"}))))
(t/deftest update-profile-accepts-nil-optional-values
(t/is (some? (dprof/update-profile {:id uuid/zero
:fullname "Updated Name"
:theme nil}))))

View File

@ -11,6 +11,7 @@
[frontend-tests.data.dashboard-test]
[frontend-tests.data.exports-assets-test]
[frontend-tests.data.nitrate-test]
[frontend-tests.data.profile-test]
[frontend-tests.data.repo-test]
[frontend-tests.data.store-test]
[frontend-tests.data.uploads-test]
@ -106,6 +107,7 @@
'frontend-tests.copy-as-svg-test
'frontend-tests.data.dashboard-test
'frontend-tests.data.nitrate-test
'frontend-tests.data.profile-test
'frontend-tests.data.repo-test
'frontend-tests.data.store-test
'frontend-tests.data.exports-assets-test