|
5 | 5 | import pytest
|
6 | 6 |
|
7 | 7 | from caluma.caluma_form import structure
|
| 8 | +from caluma.caluma_form.api import save_answer |
8 | 9 | from caluma.caluma_form.models import Answer, Document, FormQuestion, Question
|
9 | 10 |
|
10 | 11 |
|
@@ -422,3 +423,60 @@ def test_fastloader_no_duplicate_options(
|
422 | 423 | assert len(the_options) == len(
|
423 | 424 | struc._fastloader.options_for_question(choice_q.slug)
|
424 | 425 | )
|
| 426 | + |
| 427 | + |
| 428 | +def test_multistage_calculation_updates( |
| 429 | + simple_form_structure, |
| 430 | + form_factory, |
| 431 | + django_assert_num_queries, |
| 432 | + form_question_factory, |
| 433 | +): |
| 434 | + """Verify recalculation behaviour across multiple calc stages. |
| 435 | +
|
| 436 | + A chain of calculations across tables is done to ensure we get the right |
| 437 | + values at each step and don't end up in a cache trap |
| 438 | + """ |
| 439 | + form_question_factory( |
| 440 | + form_id="root", |
| 441 | + question__type=Question.TYPE_CALCULATED_FLOAT, |
| 442 | + question__slug="outer-calc", |
| 443 | + question__calc_expression="'sub_table'|answer([])|mapby('row_calc')|sum", |
| 444 | + ) |
| 445 | + |
| 446 | + struc0 = structure.FieldSet(simple_form_structure) |
| 447 | + |
| 448 | + assert struc0._fastloader._questions["leaf2"].calc_dependents == ["row_calc"] |
| 449 | + assert struc0._fastloader._questions["row_field_2"].calc_dependents == ["row_calc"] |
| 450 | + assert struc0._fastloader._questions["row_calc"].calc_dependents == ["outer-calc"] |
| 451 | + assert struc0._fastloader._questions["outer-calc"].calc_dependents == [] |
| 452 | + |
| 453 | + for field in struc0.find_all_fields_by_slug("row_field_2"): |
| 454 | + answer = save_answer( |
| 455 | + field.question, field.answer.document, value=field.answer.value + 2 |
| 456 | + ) |
| 457 | + field.refresh(answer) |
| 458 | + |
| 459 | + struc1 = structure.FieldSet(simple_form_structure) |
| 460 | + |
| 461 | + # The struc0 should be internally-refreshed, so must match another |
| 462 | + # structure constructed freshly from DB |
| 463 | + assert struc0.list_structure() == struc1.list_structure() |
| 464 | + |
| 465 | + assert struc1.list_structure() == [ |
| 466 | + " FieldSet(root)", |
| 467 | + " Field(leaf1, Some Value)", |
| 468 | + " Field(leaf2, 33)", |
| 469 | + " FieldSet(measure-evening)", |
| 470 | + " Field(sub_leaf1, None)", |
| 471 | + " Field(sub_leaf2, None)", |
| 472 | + " RowSet(too-wonder-option)", |
| 473 | + " FieldSet(too-wonder-option)", |
| 474 | + " Field(row_field_1, 2025-01-13)", |
| 475 | + " Field(row_field_2, 101.5)", |
| 476 | + " Field(row_calc, 134.5)", |
| 477 | + " FieldSet(too-wonder-option)", |
| 478 | + " Field(row_field_1, 2025-01-10)", |
| 479 | + " Field(row_field_2, 25.0)", |
| 480 | + " Field(row_calc, 58.0)", |
| 481 | + " Field(outer-calc, 192.5)", |
| 482 | + ] |
0 commit comments