1"""Saving design requirements must not erase the ones the form did not send.
3``POST /api/optimizer/design-requirements`` used to rebuild ``design_requirements`` from the
4request body alone (only ``frozen_parameters`` was merged). A form that sends the dozen
5fields it knows about therefore reset every other key -- the ~100 ``layer1_*`` knobs, the
6injector face limits, the pinned random seed -- to their schema defaults, and the next run
7optimised a different problem with the UI giving no sign. This is the same hazard already
8recorded for the checkout path ("an open Design Requirements tab reverts the backend to form
11Semantics pinned here: a key ABSENT from the payload keeps its current value; a key sent
12with an explicit ``null`` is cleared. Those are different intents and both must work.
17sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
22 "target_thrust": 6500.0,
23 "optimal_of_ratio": 1.5,
24 "layer1_random_seed": 37,
25 "layer1_injector_center_clear_dia_m": 0.0381,
26 "layer1_W_MASS": 3000.0,
27 "frozen_parameters": {
"Lstar": 1.0},
32 out = merge_design_requirements(OLD, {
"target_thrust": 6600.0})
33 assert out[
"target_thrust"] == 6600.0
34 assert out[
"optimal_of_ratio"] == 1.5
35 assert out[
"layer1_random_seed"] == 37
36 assert out[
"layer1_injector_center_clear_dia_m"] == 0.0381
37 assert out[
"layer1_W_MASS"] == 3000.0
41 out = merge_design_requirements(OLD, {
"layer1_random_seed":
None})
42 assert out[
"layer1_random_seed"]
is None
43 assert out[
"layer1_W_MASS"] == 3000.0
47 out = merge_design_requirements(OLD, {
"frozen_parameters": {
"n_elements": 24}})
48 assert out[
"frozen_parameters"] == {
"Lstar": 1.0,
"n_elements": 24}
49 out = merge_design_requirements(OLD, {
"frozen_parameters": {
"Lstar":
None}})
50 assert out[
"frozen_parameters"]
is None
54 out = merge_design_requirements(
None, {
"target_thrust": 1.0})
55 assert out == {
"target_thrust": 1.0}
test_frozen_parameters_merge_key_by_key()
test_absent_keys_survive()
test_no_previous_requirements()
test_explicit_null_clears()