From 8802f599ac67369f97c4e7c848516bfcabe5657e Mon Sep 17 00:00:00 2001 From: Mose Schmiedel Date: Mon, 24 Mar 2025 18:15:53 +0100 Subject: [PATCH 1/8] Add offset to move position when change in move direction occured while dragging --- lib/Coocook/Controller/Ajax/MealsDishesEditor.pm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm b/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm index d4c3254d8..63d380759 100644 --- a/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm +++ b/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm @@ -103,7 +103,15 @@ sub move_meal_or_dish : POST Chained('/project/base') PathPart('move_meal_dish') if ( $source_path->{item_type} eq 'dish' and $target_path->{item_type} eq 'dish' ) { - $moved->move_to_group( { meal_id => $target->meal->id }, $target->position ); + # Calculate positional offset because move_to_group() first removes the item, then inserts + # it at the specified position. This is only necessary if the moved item is above the target + # position. + my $pos_offset = + ( $moved->position > $target->position and $direction eq "under" ) ? +1 + : ( $moved->position < $target->position and $direction eq "over" ) ? -1 + : 0; + + $moved->move_to_group( { meal_id => $target->meal->id }, $target->position + $pos_offset ); } elsif ( $source_path->{item_type} eq 'dish' and $target_path->{item_type} eq 'meal' ) -- GitLab From 2fda18adefc650b4fbb8665d5ea8de8e847a5018 Mon Sep 17 00:00:00 2001 From: Mose Schmiedel Date: Mon, 24 Mar 2025 18:26:57 +0100 Subject: [PATCH 2/8] Only add $pos_offset when dish is moved inside one meal, not when moved to another meal --- .../Controller/Ajax/MealsDishesEditor.pm | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm b/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm index 63d380759..88d9e3bb8 100644 --- a/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm +++ b/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm @@ -106,10 +106,31 @@ sub move_meal_or_dish : POST Chained('/project/base') PathPart('move_meal_dish') # Calculate positional offset because move_to_group() first removes the item, then inserts # it at the specified position. This is only necessary if the moved item is above the target # position. - my $pos_offset = - ( $moved->position > $target->position and $direction eq "under" ) ? +1 - : ( $moved->position < $target->position and $direction eq "over" ) ? -1 - : 0; + if ( $moved->meal_id == $target->meal_id ) { + my $pos_offset = sub { + if ($moved->meal_id == $target->meal_id) { + if ( $moved->position > $target->position and $direction eq "under" ) { + return +1; + } elsif ( $moved->position < $target->position and $direction eq "over" ) { + return -1; + } + } + return 0; + }->(); + + $moved->move_to_group( { project_id => $project->id, meal_id => $target->meal_id }, + $target->position + $pos_offset ); + } + else { + my $pos_offset = do { + ( $moved->position > $target->position and $direction eq "under" ) ? +1 + : ( $moved->position < $target->position and $direction eq "over" ) ? -1 + : 0; + } else { + 0; + } + }; + } $moved->move_to_group( { meal_id => $target->meal->id }, $target->position + $pos_offset ); } -- GitLab From bc86f59c8575d70fca8fca265e848d78ddc79f2a Mon Sep 17 00:00:00 2001 From: Mose Schmiedel Date: Mon, 24 Mar 2025 18:27:45 +0100 Subject: [PATCH 3/8] Also calculate $pos_offset for moving meals on meals --- lib/Coocook/Controller/Ajax/MealsDishesEditor.pm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm b/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm index 88d9e3bb8..4f015bf45 100644 --- a/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm +++ b/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm @@ -158,7 +158,12 @@ sub move_meal_or_dish : POST Chained('/project/base') PathPart('move_meal_dish') ] ); } - $moved->move_to_group( { project_id => $project->id, date => $target->date }, $target->position ); + my $pos_offset = + ( $moved->position > $target->position and $direction eq "under" ) ? 1 + : ( $moved->position < $target->position and $direction eq "over" ) ? -1 + : 0; + $moved->move_to_group( { project_id => $project->id, date => $target->date }, + $target->position + $pos_offset ); } $moved = $moved->for_meals_dishes_editor; -- GitLab From e38a2e43cbf51a38f072120e376ba3dad23a243a Mon Sep 17 00:00:00 2001 From: Mose Schmiedel Date: Mon, 24 Mar 2025 18:40:56 +0100 Subject: [PATCH 4/8] $direction == "under" should always offset move $position by 1 when moving between different groups (dates for meals or meals for dishes) --- .../Controller/Ajax/MealsDishesEditor.pm | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm b/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm index 4f015bf45..400cdccc3 100644 --- a/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm +++ b/lib/Coocook/Controller/Ajax/MealsDishesEditor.pm @@ -106,31 +106,21 @@ sub move_meal_or_dish : POST Chained('/project/base') PathPart('move_meal_dish') # Calculate positional offset because move_to_group() first removes the item, then inserts # it at the specified position. This is only necessary if the moved item is above the target # position. - if ( $moved->meal_id == $target->meal_id ) { - my $pos_offset = sub { - if ($moved->meal_id == $target->meal_id) { - if ( $moved->position > $target->position and $direction eq "under" ) { - return +1; - } elsif ( $moved->position < $target->position and $direction eq "over" ) { - return -1; - } + my $pos_offset = sub { + if ( $moved->meal_id == $target->meal_id ) { + if ( $moved->position > $target->position and $direction eq "under" ) { + return +1; } - return 0; - }->(); - - $moved->move_to_group( { project_id => $project->id, meal_id => $target->meal_id }, - $target->position + $pos_offset ); - } - else { - my $pos_offset = do { - ( $moved->position > $target->position and $direction eq "under" ) ? +1 - : ( $moved->position < $target->position and $direction eq "over" ) ? -1 - : 0; - } else { - 0; - } - }; - } + elsif ( $moved->position < $target->position and $direction eq "over" ) { + return -1; + } + } + elsif ( $direction eq "under" ) { + return +1; + } + return 0; + } + ->(); $moved->move_to_group( { meal_id => $target->meal->id }, $target->position + $pos_offset ); } @@ -158,10 +148,23 @@ sub move_meal_or_dish : POST Chained('/project/base') PathPart('move_meal_dish') ] ); } - my $pos_offset = - ( $moved->position > $target->position and $direction eq "under" ) ? 1 - : ( $moved->position < $target->position and $direction eq "over" ) ? -1 - : 0; + my $pos_offset = sub { + if ( $moved->date == $target->date ) { + if ( $moved->position > $target->position and $direction eq "under" ) { + return +1; + } + elsif ( $moved->position < $target->position and $direction eq "over" ) { + return -1; + } + } + elsif ( $direction eq "under" ) { + return +1; + } + + return 0; + } + ->(); + $moved->move_to_group( { project_id => $project->id, date => $target->date }, $target->position + $pos_offset ); } -- GitLab From 3b9350f0bd198f5d29c9c6174b295097cd80d77c Mon Sep 17 00:00:00 2001 From: Mose Schmiedel Date: Mon, 24 Mar 2025 19:19:24 +0100 Subject: [PATCH 5/8] Add tests for dish movement --- share/test_data.sql | 3 +- t/controller_Ajax_MealsDishesEditor.t | 221 ++++++++++++++++++++------ 2 files changed, 177 insertions(+), 47 deletions(-) diff --git a/share/test_data.sql b/share/test_data.sql index f6f58779f..2f178482a 100644 --- a/share/test_data.sql +++ b/share/test_data.sql @@ -103,7 +103,8 @@ INSERT INTO "dishes" (id, meal_id, position, from_recipe_id, name, servings, prepare_at_meal_id, preparation, description, comment) VALUES ( 1, 1, 1, NULL, 'pancakes', 4, NULL, '', 'Make them really sweet!', 'sweet'), ( 2, 2, 2, 1, 'pizza', 2, NULL, '', '', ''), -( 3, 3, 3, NULL, 'bread', 4, 2, 'Bake bread!', '', ''); +( 3, 3, 3, NULL, 'bread', 4, 2, 'Bake bread!', '', ''), +( 4, 1, 2, NULL, 'burger', 4, NULL, '', '', ''); INSERT INTO "dish_ingredients" (id, position, dish_id, prepare, value, unit_id, article_id, comment, item_id) VALUES diff --git a/t/controller_Ajax_MealsDishesEditor.t b/t/controller_Ajax_MealsDishesEditor.t index a34796835..10d26bf7a 100644 --- a/t/controller_Ajax_MealsDishesEditor.t +++ b/t/controller_Ajax_MealsDishesEditor.t @@ -5,57 +5,186 @@ use DateTime; use lib 't/lib'; use Test::Coocook; -plan(17); +plan(16); my $t = Test::Coocook->new(); $t->get_ok('/'); $t->login_ok( 'john_doe', 'P@ssw0rd' ); -ok $t->post('/project/1/Test-Project/move_meal_dish'), "empty formdata request"; -$t->status_is(400); +subtest "move_meal_dish empty formdata request" => sub { + ok $t->post('/project/1/Test-Project/move_meal_dish'), "empty formdata request"; + $t->status_is(400); +}; -ok $t->post_json( '/project/1/Test-Project/move_meal_dish', {} ), "empty JSON request"; -$t->status_is(400); +subtest "move_meal_dish empty JSON request" => sub { + ok $t->post_json( '/project/1/Test-Project/move_meal_dish', {} ), "empty JSON request"; + $t->status_is(400); +}; -ok $t->post_json( - 'https://localhost/project/1/Test-Project/move_meal_dish', - { - direction => 'under', - source_path => { - date => '2000-01-01', - meal_id => 1, - dish_id => 1, - item_type => 'dish', - type => 'elem', - }, - target_path => { - date => '2000-01-02', - meal_id => 2, - dish_id => 2, - item_type => 'dish', - type => 'elem', - }, - } -); -$t->status_is(200); -$t->json_is( - { - id => 1, - meal_id => 2, - from_recipe_id => undef, - prepare_at_meal_id => undef, - position => 2, - date => '2000-01-02', - servings => 4, - name => L(), - comment => L(), - description => L(), - preparation => '', - update_url => 'https://localhost/project/1/Test-Project/dish/1/update', - delete_url => 'https://localhost/project/1/Test-Project/dish/1/delete', - } -); +subtest "move_meal_dish dish under dish in same meal" => sub { + ok $t->post_json( + 'https://localhost/project/1/Test-Project/move_meal_dish', + { + direction => 'under', + source_path => { + date => '2000-01-01', + meal_id => 1, + dish_id => 1, + item_type => 'dish', + type => 'elem', + }, + target_path => { + date => '2000-01-01', + meal_id => 1, + dish_id => 4, + item_type => 'dish', + type => 'elem', + }, + } + ); + $t->status_is(200); + $t->json_is( + { + id => 1, + meal_id => 1, + from_recipe_id => undef, + prepare_at_meal_id => undef, + position => 2, + date => '2000-01-01', + servings => 4, + name => L(), + comment => L(), + description => L(), + preparation => '', + update_url => 'https://localhost/project/1/Test-Project/dish/1/update', + delete_url => 'https://localhost/project/1/Test-Project/dish/1/delete', + } + ); +}; + +subtest "move_meal_dish dish over dish in same meal" => sub { + ok $t->post_json( + 'https://localhost/project/1/Test-Project/move_meal_dish', + { + direction => 'over', + source_path => { + date => '2000-01-01', + meal_id => 1, + dish_id => 1, + item_type => 'dish', + type => 'elem', + }, + target_path => { + date => '2000-01-01', + meal_id => 1, + dish_id => 4, + item_type => 'dish', + type => 'elem', + }, + } + ); + $t->status_is(200); + $t->json_is( + { + id => 1, + meal_id => 1, + from_recipe_id => undef, + prepare_at_meal_id => undef, + position => 1, + date => '2000-01-01', + servings => 4, + name => L(), + comment => L(), + description => L(), + preparation => '', + update_url => 'https://localhost/project/1/Test-Project/dish/1/update', + delete_url => 'https://localhost/project/1/Test-Project/dish/1/delete', + } + ); +}; + +subtest "move_meal_dish dish under dish in different meal" => sub { + ok $t->post_json( + 'https://localhost/project/1/Test-Project/move_meal_dish', + { + direction => 'under', + source_path => { + date => '2000-01-01', + meal_id => 1, + dish_id => 1, + item_type => 'dish', + type => 'elem', + }, + target_path => { + date => '2000-01-02', + meal_id => 2, + dish_id => 2, + item_type => 'dish', + type => 'elem', + }, + } + ); + $t->status_is(200); + $t->json_is( + { + id => 1, + meal_id => 2, + from_recipe_id => undef, + prepare_at_meal_id => undef, + position => 3, + date => '2000-01-02', + servings => 4, + name => L(), + comment => L(), + description => L(), + preparation => '', + update_url => 'https://localhost/project/1/Test-Project/dish/1/update', + delete_url => 'https://localhost/project/1/Test-Project/dish/1/delete', + } + ); +}; + +subtest "move_meal_dish dish over dish in different meal" => sub { + ok $t->post_json( + 'https://localhost/project/1/Test-Project/move_meal_dish', + { + direction => 'over', + source_path => { + date => '2000-01-02', + meal_id => 2, + dish_id => 1, + item_type => 'dish', + type => 'elem', + }, + target_path => { + date => '2000-01-01', + meal_id => 1, + dish_id => 4, + item_type => 'dish', + type => 'elem', + }, + } + ); + $t->status_is(200); + $t->json_is( + { + id => 1, + meal_id => 1, + from_recipe_id => undef, + prepare_at_meal_id => undef, + position => 1, + date => '2000-01-01', + servings => 4, + name => L(), + comment => L(), + description => L(), + preparation => '', + update_url => 'https://localhost/project/1/Test-Project/dish/1/update', + delete_url => 'https://localhost/project/1/Test-Project/dish/1/delete', + } + ); +}; $t->post_ok( '/project/1/Test-Project/meals/create', @@ -131,9 +260,9 @@ subtest "update mals" => sub { position => 1, comment => __FILE__, date => '2000-01-02', - deletable => T(), - prepared_dishes => {}, - dishes => {}, + deletable => F(), + prepared_dishes => hash { etc() }, + dishes => hash { etc() }, } ); -- GitLab From b27bf290de5c07089b5e8e6a8aca4e473c5a4990 Mon Sep 17 00:00:00 2001 From: Mose Schmiedel Date: Mon, 24 Mar 2025 19:39:23 +0100 Subject: [PATCH 6/8] Add tests for meal movement --- share/test_data.sql | 11 +- t/controller_Ajax_MealsDishesEditor.t | 156 +++++++++++++++++++++++++- 2 files changed, 160 insertions(+), 7 deletions(-) diff --git a/share/test_data.sql b/share/test_data.sql index 2f178482a..dfa79504a 100644 --- a/share/test_data.sql +++ b/share/test_data.sql @@ -51,11 +51,12 @@ INSERT INTO "articles" ( 6, 2, 9, NULL, NULL, NULL, 'other article', ''); INSERT INTO "meals" -(id, project_id, position, date, name, comment) VALUES -( 1, 1, 1, '2000-01-01', 'breakfast', 'Best meal of the day!'), -( 2, 1, 1, '2000-01-02', 'lunch', ''), -( 3, 1, 1, '2000-01-03', 'dinner', ''), -( 9, 2, 1, '2000-01-01', 'other meal', ''); +(id, project_id, position, date, name, comment) VALUES +( 1, 1, 1, '2000-01-01', 'breakfast', 'Best meal of the day!'), +( 2, 1, 1, '2000-01-02', 'lunch', ''), +( 3, 1, 1, '2000-01-03', 'dinner', ''), +( 9, 2, 1, '2000-01-01', 'other meal', ''), +( 10, 1, 2, '2000-01-01', '2nd breakfast', ''); INSERT INTO "units" (id, project_id, short_name, long_name) VALUES diff --git a/t/controller_Ajax_MealsDishesEditor.t b/t/controller_Ajax_MealsDishesEditor.t index 10d26bf7a..d4ae101a7 100644 --- a/t/controller_Ajax_MealsDishesEditor.t +++ b/t/controller_Ajax_MealsDishesEditor.t @@ -5,7 +5,7 @@ use DateTime; use lib 't/lib'; use Test::Coocook; -plan(16); +plan(20); my $t = Test::Coocook->new(); @@ -186,6 +186,158 @@ subtest "move_meal_dish dish over dish in different meal" => sub { ); }; +subtest "move_meal_dish meal under meal on same date" => sub { + ok $t->post_json( + 'https://localhost/project/1/Test-Project/move_meal_dish', + { + direction => 'under', + source_path => { + date => '2000-01-01', + meal_id => 1, + item_type => 'meal', + type => 'elem', + }, + target_path => { + date => '2000-01-01', + meal_id => 10, + item_type => 'meal', + type => 'elem', + }, + } + ); + $t->status_is(200); + $t->json_is( + { + project_id => 1, + id => 1, + position => 2, + date => '2000-01-01', + name => L(), + comment => L(), + deletable => F(), + delete_dishes_url => 'https://localhost/project/1/Test-Project/meals/1/delete_dishes', + update_url => 'https://localhost/project/1/Test-Project/meals/1/update', + delete_url => 'https://localhost/project/1/Test-Project/meals/1/delete', + prepared_dishes => hash { etc() }, + dishes => hash { etc() }, + } + ); +}; + +subtest "move_meal_dish meal over meal on same date" => sub { + ok $t->post_json( + 'https://localhost/project/1/Test-Project/move_meal_dish', + { + direction => 'over', + source_path => { + date => '2000-01-01', + meal_id => 1, + item_type => 'meal', + type => 'elem', + }, + target_path => { + date => '2000-01-01', + meal_id => 10, + item_type => 'meal', + type => 'elem', + }, + } + ); + $t->status_is(200); + $t->json_is( + { + project_id => 1, + id => 1, + position => 1, + date => '2000-01-01', + name => L(), + comment => L(), + deletable => F(), + delete_dishes_url => 'https://localhost/project/1/Test-Project/meals/1/delete_dishes', + update_url => 'https://localhost/project/1/Test-Project/meals/1/update', + delete_url => 'https://localhost/project/1/Test-Project/meals/1/delete', + prepared_dishes => hash { etc() }, + dishes => hash { etc() }, + } + ); +}; + +subtest "move_meal_dish meal under meal on different date" => sub { + ok $t->post_json( + 'https://localhost/project/1/Test-Project/move_meal_dish', + { + direction => 'under', + source_path => { + date => '2000-01-01', + meal_id => 1, + item_type => 'meal', + type => 'elem', + }, + target_path => { + date => '2000-01-02', + meal_id => 2, + item_type => 'meal', + type => 'elem', + }, + } + ); + $t->status_is(200); + $t->json_is( + { + project_id => 1, + id => 1, + position => 2, + date => '2000-01-02', + name => L(), + comment => L(), + deletable => F(), + delete_dishes_url => 'https://localhost/project/1/Test-Project/meals/1/delete_dishes', + update_url => 'https://localhost/project/1/Test-Project/meals/1/update', + delete_url => 'https://localhost/project/1/Test-Project/meals/1/delete', + prepared_dishes => hash { etc() }, + dishes => hash { etc() }, + } + ); +}; + +subtest "move_meal_dish meal over meal on different date" => sub { + ok $t->post_json( + 'https://localhost/project/1/Test-Project/move_meal_dish', + { + direction => 'over', + source_path => { + date => '2000-01-02', + meal_id => 1, + item_type => 'meal', + type => 'elem', + }, + target_path => { + date => '2000-01-01', + meal_id => 10, + item_type => 'meal', + type => 'elem', + }, + } + ); + $t->status_is(200); + $t->json_is( + { + project_id => 1, + id => 1, + position => 1, + date => '2000-01-01', + name => L(), + comment => L(), + deletable => F(), + delete_dishes_url => 'https://localhost/project/1/Test-Project/meals/1/delete_dishes', + update_url => 'https://localhost/project/1/Test-Project/meals/1/update', + delete_url => 'https://localhost/project/1/Test-Project/meals/1/delete', + prepared_dishes => hash { etc() }, + dishes => hash { etc() }, + } + ); +}; + $t->post_ok( '/project/1/Test-Project/meals/create', { @@ -198,7 +350,7 @@ $t->post_ok( $t->json_is( { meal => hash { - field id => 10; + field id => 11; field name => 'meal from test'; etc(); }, -- GitLab From 4249427dc853fddf8b2e288839483148e18707c1 Mon Sep 17 00:00:00 2001 From: Mose Schmiedel Date: Mon, 24 Mar 2025 21:08:26 +0100 Subject: [PATCH 7/8] Change old tests after inserting new test data --- t/model_Plan.t | 46 +++++++++++++++++++++++++++++++++++++++++++++- t/schema.t | 4 ++-- t/schema_Project.t | 8 ++++---- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/t/model_Plan.t b/t/model_Plan.t index f19a447cc..164740a18 100644 --- a/t/model_Plan.t +++ b/t/model_Plan.t @@ -73,8 +73,24 @@ is 'value' => '0.5' } ], + }, + { + 'id' => 4, + 'name' => 'burger', + 'comment' => '', + 'servings' => 4, + 'preparation' => '', + 'description' => '', + 'has_prepared_ingredients' => F(), + 'ingredients' => [], } ], + }, + { + name => '2nd breakfast', + comment => "", + prepared_dishes => [], + dishes => [], } ], "day(2000-01-01)"; @@ -136,10 +152,37 @@ is my $project_plan = $plan->project($project) => array { field servings => 4; end(); }; + item hash { + field id => 4; + field position => 2; + field meal_id => 1; + field meal => hash { field id => 1; etc() }; + field prepare_at_meal_id => U(); + field from_recipe_id => U(); + field name => 'burger'; + field preparation => ''; + field description => ''; + field comment => ''; + field servings => 4; + end(); + }; + end(); }; field prepared_dishes => []; end(); }; + item hash { + field id => 10; + field project_id => 1; + field position => 2; + field date => string '2000-01-01T00:00:00'; + field name => '2nd breakfast'; + field comment => ''; + field deletable => T(); + field dishes => []; + field prepared_dishes => []; + end(); + }; end(); }; end(); @@ -242,7 +285,8 @@ subtest "order of meals from day() and project()" => sub { item hash { field date => string '2000-01-01T00:00:00'; field meals => array { - item hash { field name => "breakfast"; etc() }; + item hash { field name => "breakfast"; etc() }; + item hash { field name => "2nd breakfast"; etc() }; end(); }; end(); diff --git a/t/schema.t b/t/schema.t index 3183824d7..92bbe1a22 100644 --- a/t/schema.t +++ b/t/schema.t @@ -10,7 +10,7 @@ plan(9); ok my $db = TestDB->new; -is $db->count() => 89, "count()"; +is $db->count() => 91, "count()"; is $db->count(qw< Article Unit >) => 15, "count(Article Unit)"; subtest "one_row() in favor of first()" => sub { @@ -31,7 +31,7 @@ subtest statistics => sub { field users => 2; field organizations => 1; field recipes => 3; - field dishes_served => 4 + 2 + 4; + field dishes_served => 4 + 2 + 4 + 4; field dishes_planned => 0; etc(); }; diff --git a/t/schema_Project.t b/t/schema_Project.t index 0736e5cc0..c4e483d9c 100644 --- a/t/schema_Project.t +++ b/t/schema_Project.t @@ -15,8 +15,8 @@ subtest inventory => sub { is $inventory => { articles => 5, - dishes => 3, - meals => 3, + dishes => 4, + meals => 4, purchase_lists => 2, recipes => 1, shop_sections => 2, @@ -151,10 +151,10 @@ subtest find_or_create_tags_from_names => sub { subtest dishes => sub { isa_ok my $dishes = $project->dishes => 'Coocook::Schema::ResultSet::Dish'; - is $dishes->count => 3; + is $dishes->count => 4; }; subtest items => sub { isa_ok my $meals = $project->meals => 'Coocook::Schema::ResultSet::Meal'; - is $meals->count => 3; + is $meals->count => 4; }; -- GitLab From 4a4859b2c222428a8a860440b0fa14f0d6c41e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6hmer?= Date: Sun, 27 Jul 2025 22:56:46 +0200 Subject: [PATCH 8/8] Change test data, adjust and improve tests - consecutive meal_id 4 for new meal - dish_ids ordered by meal_id - servings of 2 for dishes in meal with two dishes - use txn_do_and_rollback() do create easier to understand test cases instead of having the remaining test file depend on results of previous test cases --- share/test_data.sql | 36 +++---- t/controller_Ajax_IngredientsEditor.t | 2 +- t/controller_Ajax_MealsDishesEditor.t | 140 +++++++++++++------------- t/model_Plan.t | 60 +++++------ t/schema.t | 2 +- t/schema_Dish.t | 4 +- 6 files changed, 120 insertions(+), 124 deletions(-) diff --git a/share/test_data.sql b/share/test_data.sql index dfa79504a..1915ffa22 100644 --- a/share/test_data.sql +++ b/share/test_data.sql @@ -51,12 +51,12 @@ INSERT INTO "articles" ( 6, 2, 9, NULL, NULL, NULL, 'other article', ''); INSERT INTO "meals" -(id, project_id, position, date, name, comment) VALUES -( 1, 1, 1, '2000-01-01', 'breakfast', 'Best meal of the day!'), -( 2, 1, 1, '2000-01-02', 'lunch', ''), -( 3, 1, 1, '2000-01-03', 'dinner', ''), -( 9, 2, 1, '2000-01-01', 'other meal', ''), -( 10, 1, 2, '2000-01-01', '2nd breakfast', ''); +(id, project_id, position, date, name, comment) VALUES +( 1, 1, 1, '2000-01-01', 'breakfast', 'Best meal of the day!'), +( 2, 1, 1, '2000-01-02', 'lunch', ''), +( 3, 1, 1, '2000-01-03', 'dinner', ''), +( 4, 1, 2, '2000-01-03', 'midnight snack', ''), +( 9, 2, 1, '2000-01-01', 'other meal', ''); INSERT INTO "units" (id, project_id, short_name, long_name) VALUES @@ -102,24 +102,24 @@ INSERT INTO "recipe_ingredients" INSERT INTO "dishes" (id, meal_id, position, from_recipe_id, name, servings, prepare_at_meal_id, preparation, description, comment) VALUES -( 1, 1, 1, NULL, 'pancakes', 4, NULL, '', 'Make them really sweet!', 'sweet'), -( 2, 2, 2, 1, 'pizza', 2, NULL, '', '', ''), -( 3, 3, 3, NULL, 'bread', 4, 2, 'Bake bread!', '', ''), -( 4, 1, 2, NULL, 'burger', 4, NULL, '', '', ''); +( 1, 1, 1, NULL, 'pancakes', 2, NULL, '', 'Make them really sweet!', 'sweet'), +( 2, 1, 2, NULL, 'cerials', 2, NULL, '', '', ''), +( 3, 2, 2, 1, 'pizza', 4, NULL, '', '', ''), +( 4, 3, 3, NULL, 'bread', 4, 2, 'Bake bread!', '', ''); INSERT INTO "dish_ingredients" (id, position, dish_id, prepare, value, unit_id, article_id, comment, item_id) VALUES ( 1, 1, 1, FALSE, 500.0, 1, 1, '', NULL), ( 2, 2, 1, FALSE, 5.0, 1, 2, '', NULL), ( 3, 3, 1, FALSE, 0.5, 3, 3, '', NULL), -( 4, 1, 2, FALSE, 0.5, 2, 1, '', NULL), -( 5, 2, 2, FALSE, 0.25, 3, 3, '', NULL), -( 6, 3, 2, FALSE, 12.5, 1, 2, '', NULL), -( 7, 1, 3, TRUE, 1.0, 2, 1, '', NULL), -( 8, 2, 3, TRUE, 25.0, 1, 2, '', NULL), -( 9, 3, 3, TRUE, 1.0, 3, 3, '', NULL), -(10, 4, 3, FALSE, 500.0, 1, 4, '', NULL), -(11, 5, 3, FALSE, 12.5, 2, 1, '', NULL); +( 4, 1, 3, FALSE, 0.5, 2, 1, '', NULL), +( 5, 2, 3, FALSE, 0.25, 3, 3, '', NULL), +( 6, 3, 3, FALSE, 12.5, 1, 2, '', NULL), +( 7, 1, 4, TRUE, 1.0, 2, 1, '', NULL), +( 8, 2, 4, TRUE, 25.0, 1, 2, '', NULL), +( 9, 3, 4, TRUE, 1.0, 3, 3, '', NULL), +(10, 4, 4, FALSE, 500.0, 1, 4, '', NULL), +(11, 5, 4, FALSE, 12.5, 2, 1, '', NULL); INSERT INTO "purchase_lists" (id, project_id, name, date) VALUES diff --git a/t/controller_Ajax_IngredientsEditor.t b/t/controller_Ajax_IngredientsEditor.t index 905d4e67a..7c74b82a5 100644 --- a/t/controller_Ajax_IngredientsEditor.t +++ b/t/controller_Ajax_IngredientsEditor.t @@ -46,7 +46,7 @@ subtest "delete ingredients", txn_do_and_rollback $t->schema, sub { "item was updated"; note "Deleting remaining ingredients of item ..."; - for ( [ 2, 6 ], [ 3, 8 ] ) { + for ( [ 3, 6 ], [ 4, 8 ] ) { my ( $dish_id, $ingredient_id ) = @$_; ok $t->post_json( "https://localhost/project/1/Test-Project/dish/$dish_id/ingredients/delete", diff --git a/t/controller_Ajax_MealsDishesEditor.t b/t/controller_Ajax_MealsDishesEditor.t index d4ae101a7..19c526fb5 100644 --- a/t/controller_Ajax_MealsDishesEditor.t +++ b/t/controller_Ajax_MealsDishesEditor.t @@ -3,11 +3,13 @@ use Test2::V0; use DateTime; use lib 't/lib'; +use TestDB qw(txn_do_and_rollback); use Test::Coocook; plan(20); -my $t = Test::Coocook->new(); +my $t = Test::Coocook->new(); +my $db = $t->schema; $t->get_ok('/'); $t->login_ok( 'john_doe', 'P@ssw0rd' ); @@ -22,7 +24,7 @@ subtest "move_meal_dish empty JSON request" => sub { $t->status_is(400); }; -subtest "move_meal_dish dish under dish in same meal" => sub { +subtest "move_meal_dish dish under dish in same meal" => txn_do_and_rollback $db => sub { ok $t->post_json( 'https://localhost/project/1/Test-Project/move_meal_dish', { @@ -37,7 +39,7 @@ subtest "move_meal_dish dish under dish in same meal" => sub { target_path => { date => '2000-01-01', meal_id => 1, - dish_id => 4, + dish_id => 2, item_type => 'dish', type => 'elem', }, @@ -52,7 +54,7 @@ subtest "move_meal_dish dish under dish in same meal" => sub { prepare_at_meal_id => undef, position => 2, date => '2000-01-01', - servings => 4, + servings => 2, name => L(), comment => L(), description => L(), @@ -63,7 +65,7 @@ subtest "move_meal_dish dish under dish in same meal" => sub { ); }; -subtest "move_meal_dish dish over dish in same meal" => sub { +subtest "move_meal_dish dish over dish in same meal" => txn_do_and_rollback $db => sub { ok $t->post_json( 'https://localhost/project/1/Test-Project/move_meal_dish', { @@ -71,14 +73,14 @@ subtest "move_meal_dish dish over dish in same meal" => sub { source_path => { date => '2000-01-01', meal_id => 1, - dish_id => 1, + dish_id => 2, item_type => 'dish', type => 'elem', }, target_path => { date => '2000-01-01', meal_id => 1, - dish_id => 4, + dish_id => 1, item_type => 'dish', type => 'elem', }, @@ -87,24 +89,24 @@ subtest "move_meal_dish dish over dish in same meal" => sub { $t->status_is(200); $t->json_is( { - id => 1, + id => 2, meal_id => 1, from_recipe_id => undef, prepare_at_meal_id => undef, position => 1, date => '2000-01-01', - servings => 4, + servings => 2, name => L(), - comment => L(), - description => L(), + comment => D(), + description => D(), preparation => '', - update_url => 'https://localhost/project/1/Test-Project/dish/1/update', - delete_url => 'https://localhost/project/1/Test-Project/dish/1/delete', + update_url => 'https://localhost/project/1/Test-Project/dish/2/update', + delete_url => 'https://localhost/project/1/Test-Project/dish/2/delete', } ); }; -subtest "move_meal_dish dish under dish in different meal" => sub { +subtest "move_meal_dish dish under dish in different meal" => txn_do_and_rollback $db => sub { ok $t->post_json( 'https://localhost/project/1/Test-Project/move_meal_dish', { @@ -119,7 +121,7 @@ subtest "move_meal_dish dish under dish in different meal" => sub { target_path => { date => '2000-01-02', meal_id => 2, - dish_id => 2, + dish_id => 3, item_type => 'dish', type => 'elem', }, @@ -134,7 +136,7 @@ subtest "move_meal_dish dish under dish in different meal" => sub { prepare_at_meal_id => undef, position => 3, date => '2000-01-02', - servings => 4, + servings => 2, name => L(), comment => L(), description => L(), @@ -145,7 +147,7 @@ subtest "move_meal_dish dish under dish in different meal" => sub { ); }; -subtest "move_meal_dish dish over dish in different meal" => sub { +subtest "move_meal_dish dish over dish in different meal" => txn_do_and_rollback $db => sub { ok $t->post_json( 'https://localhost/project/1/Test-Project/move_meal_dish', { @@ -153,14 +155,14 @@ subtest "move_meal_dish dish over dish in different meal" => sub { source_path => { date => '2000-01-02', meal_id => 2, - dish_id => 1, + dish_id => 3, item_type => 'dish', type => 'elem', }, target_path => { date => '2000-01-01', meal_id => 1, - dish_id => 4, + dish_id => 2, item_type => 'dish', type => 'elem', }, @@ -169,37 +171,37 @@ subtest "move_meal_dish dish over dish in different meal" => sub { $t->status_is(200); $t->json_is( { - id => 1, + id => 3, meal_id => 1, - from_recipe_id => undef, + from_recipe_id => 1, prepare_at_meal_id => undef, - position => 1, + position => 2, date => '2000-01-01', servings => 4, name => L(), - comment => L(), - description => L(), + comment => D(), + description => D(), preparation => '', - update_url => 'https://localhost/project/1/Test-Project/dish/1/update', - delete_url => 'https://localhost/project/1/Test-Project/dish/1/delete', + update_url => 'https://localhost/project/1/Test-Project/dish/3/update', + delete_url => 'https://localhost/project/1/Test-Project/dish/3/delete', } ); }; -subtest "move_meal_dish meal under meal on same date" => sub { +subtest "move_meal_dish meal under meal on same date" => txn_do_and_rollback $db => sub { ok $t->post_json( 'https://localhost/project/1/Test-Project/move_meal_dish', { direction => 'under', source_path => { - date => '2000-01-01', - meal_id => 1, + date => '2000-01-03', + meal_id => 3, item_type => 'meal', type => 'elem', }, target_path => { - date => '2000-01-01', - meal_id => 10, + date => '2000-01-03', + meal_id => 4, item_type => 'meal', type => 'elem', }, @@ -209,35 +211,35 @@ subtest "move_meal_dish meal under meal on same date" => sub { $t->json_is( { project_id => 1, - id => 1, + id => 3, position => 2, - date => '2000-01-01', + date => '2000-01-03', name => L(), - comment => L(), + comment => D(), deletable => F(), - delete_dishes_url => 'https://localhost/project/1/Test-Project/meals/1/delete_dishes', - update_url => 'https://localhost/project/1/Test-Project/meals/1/update', - delete_url => 'https://localhost/project/1/Test-Project/meals/1/delete', + delete_dishes_url => 'https://localhost/project/1/Test-Project/meals/3/delete_dishes', + update_url => 'https://localhost/project/1/Test-Project/meals/3/update', + delete_url => 'https://localhost/project/1/Test-Project/meals/3/delete', prepared_dishes => hash { etc() }, dishes => hash { etc() }, } ); }; -subtest "move_meal_dish meal over meal on same date" => sub { +subtest "move_meal_dish meal over meal on same date" => txn_do_and_rollback $db => sub { ok $t->post_json( 'https://localhost/project/1/Test-Project/move_meal_dish', { direction => 'over', source_path => { - date => '2000-01-01', - meal_id => 1, + date => '2000-01-03', + meal_id => 4, item_type => 'meal', type => 'elem', }, target_path => { - date => '2000-01-01', - meal_id => 10, + date => '2000-01-03', + meal_id => 3, item_type => 'meal', type => 'elem', }, @@ -247,35 +249,35 @@ subtest "move_meal_dish meal over meal on same date" => sub { $t->json_is( { project_id => 1, - id => 1, + id => 4, position => 1, - date => '2000-01-01', + date => '2000-01-03', name => L(), - comment => L(), - deletable => F(), - delete_dishes_url => 'https://localhost/project/1/Test-Project/meals/1/delete_dishes', - update_url => 'https://localhost/project/1/Test-Project/meals/1/update', - delete_url => 'https://localhost/project/1/Test-Project/meals/1/delete', + comment => D(), + deletable => T(), + delete_dishes_url => 'https://localhost/project/1/Test-Project/meals/4/delete_dishes', + update_url => 'https://localhost/project/1/Test-Project/meals/4/update', + delete_url => 'https://localhost/project/1/Test-Project/meals/4/delete', prepared_dishes => hash { etc() }, dishes => hash { etc() }, } ); }; -subtest "move_meal_dish meal under meal on different date" => sub { +subtest "move_meal_dish meal under meal on different date" => txn_do_and_rollback $db => sub { ok $t->post_json( 'https://localhost/project/1/Test-Project/move_meal_dish', { direction => 'under', source_path => { - date => '2000-01-01', - meal_id => 1, + date => '2000-01-03', + meal_id => 3, item_type => 'meal', type => 'elem', }, target_path => { - date => '2000-01-02', - meal_id => 2, + date => '2000-01-03', + meal_id => 4, item_type => 'meal', type => 'elem', }, @@ -285,35 +287,35 @@ subtest "move_meal_dish meal under meal on different date" => sub { $t->json_is( { project_id => 1, - id => 1, + id => 3, position => 2, - date => '2000-01-02', + date => '2000-01-03', name => L(), - comment => L(), + comment => D(), deletable => F(), - delete_dishes_url => 'https://localhost/project/1/Test-Project/meals/1/delete_dishes', - update_url => 'https://localhost/project/1/Test-Project/meals/1/update', - delete_url => 'https://localhost/project/1/Test-Project/meals/1/delete', + delete_dishes_url => 'https://localhost/project/1/Test-Project/meals/3/delete_dishes', + update_url => 'https://localhost/project/1/Test-Project/meals/3/update', + delete_url => 'https://localhost/project/1/Test-Project/meals/3/delete', prepared_dishes => hash { etc() }, dishes => hash { etc() }, } ); }; -subtest "move_meal_dish meal over meal on different date" => sub { +subtest "move_meal_dish meal over meal on different date" => txn_do_and_rollback $db => sub { ok $t->post_json( 'https://localhost/project/1/Test-Project/move_meal_dish', { direction => 'over', source_path => { - date => '2000-01-02', + date => '2000-01-01', meal_id => 1, item_type => 'meal', type => 'elem', }, target_path => { - date => '2000-01-01', - meal_id => 10, + date => '2000-01-03', + meal_id => 4, item_type => 'meal', type => 'elem', }, @@ -324,8 +326,8 @@ subtest "move_meal_dish meal over meal on different date" => sub { { project_id => 1, id => 1, - position => 1, - date => '2000-01-01', + position => 2, + date => '2000-01-03', name => L(), comment => L(), deletable => F(), @@ -346,12 +348,12 @@ $t->post_ok( comment => __FILE__, } ); - $t->json_is( { meal => hash { - field id => 11; - field name => 'meal from test'; + field id => 10; + field name => 'meal from test'; + field comment => __FILE__; etc(); }, } diff --git a/t/model_Plan.t b/t/model_Plan.t index 164740a18..d5fc41666 100644 --- a/t/model_Plan.t +++ b/t/model_Plan.t @@ -28,7 +28,7 @@ is 'id' => 1, 'name' => 'pancakes', 'comment' => 'sweet', - 'servings' => 4, + 'servings' => 2, 'preparation' => '', 'description' => 'Make them really sweet!', 'has_prepared_ingredients' => F(), @@ -75,22 +75,16 @@ is ], }, { - 'id' => 4, - 'name' => 'burger', + 'id' => 2, + 'name' => 'cerials', 'comment' => '', - 'servings' => 4, + 'servings' => 2, 'preparation' => '', 'description' => '', 'has_prepared_ingredients' => F(), 'ingredients' => [], } ], - }, - { - name => '2nd breakfast', - comment => "", - prepared_dishes => [], - dishes => [], } ], "day(2000-01-01)"; @@ -149,21 +143,21 @@ is my $project_plan = $plan->project($project) => array { field preparation => ''; field description => 'Make them really sweet!'; field comment => 'sweet'; - field servings => 4; + field servings => 2; end(); }; item hash { - field id => 4; + field id => 2; field position => 2; field meal_id => 1; field meal => hash { field id => 1; etc() }; field prepare_at_meal_id => U(); field from_recipe_id => U(); - field name => 'burger'; + field name => 'cerials'; field preparation => ''; field description => ''; field comment => ''; - field servings => 4; + field servings => 2; end(); }; end(); @@ -171,18 +165,6 @@ is my $project_plan = $plan->project($project) => array { field prepared_dishes => []; end(); }; - item hash { - field id => 10; - field project_id => 1; - field position => 2; - field date => string '2000-01-01T00:00:00'; - field name => '2nd breakfast'; - field comment => ''; - field deletable => T(); - field dishes => []; - field prepared_dishes => []; - end(); - }; end(); }; end(); @@ -200,7 +182,7 @@ is my $project_plan = $plan->project($project) => array { field deletable => F(); field dishes => array { item hash { - field id => 2; + field id => 3; field position => 2; field meal_id => 2; field meal => hash { field id => 2; etc() }; @@ -210,13 +192,13 @@ is my $project_plan = $plan->project($project) => array { field preparation => ''; field description => ''; field comment => ''; - field servings => 2; + field servings => 4; end(); }; }; field prepared_dishes => array { item $bread = hash { - field id => 3; + field id => 4; field meal_id => 3; field position => 3; field meal => hash { field id => 3; etc() }; @@ -249,6 +231,18 @@ is my $project_plan = $plan->project($project) => array { field comment => ''; end(); }; + item hash { + field id => 4; + field project_id => 1; + field position => 2; + field date => string '2000-01-03T00:00:00'; + field name => 'midnight snack'; + field deletable => T(); + field dishes => []; + field prepared_dishes => []; + field comment => ''; + end(); + }; }; }; }, @@ -260,7 +254,7 @@ subtest deletable => sub { ok !$plan->project($project)->[1]{meals}[0]{deletable}; $db->resultset('Meal')->find(2)->delete_dishes(); ok !$plan->project($project)->[1]{meals}[0]{deletable}; - $db->resultset('Dish')->find(3)->update( { prepare_at_meal_id => undef } ); + $db->resultset('Dish')->find(4)->update( { prepare_at_meal_id => undef } ); ok $plan->project($project)->[1]{meals}[0]{deletable}; }; @@ -285,8 +279,7 @@ subtest "order of meals from day() and project()" => sub { item hash { field date => string '2000-01-01T00:00:00'; field meals => array { - item hash { field name => "breakfast"; etc() }; - item hash { field name => "2nd breakfast"; etc() }; + item hash { field name => "breakfast"; etc() }; end(); }; end(); @@ -304,7 +297,8 @@ subtest "order of meals from day() and project()" => sub { item hash { field date => string '2000-01-03T00:00:00'; field meals => array { - item hash { field name => "dinner"; etc() }; + item hash { field name => "dinner"; etc() }; + item hash { field name => "midnight snack"; etc() }; end() }; end(); diff --git a/t/schema.t b/t/schema.t index 92bbe1a22..3acef983f 100644 --- a/t/schema.t +++ b/t/schema.t @@ -31,7 +31,7 @@ subtest statistics => sub { field users => 2; field organizations => 1; field recipes => 3; - field dishes_served => 4 + 2 + 4 + 4; + field dishes_served => 2 + 2 + 4 + 4; field dishes_planned => 0; etc(); }; diff --git a/t/schema_Dish.t b/t/schema_Dish.t index b350fcc28..4a9640f8c 100644 --- a/t/schema_Dish.t +++ b/t/schema_Dish.t @@ -11,10 +11,10 @@ my $db = TestDB->new(); subtest recalculate => sub { my $dish = $db->resultset('Dish')->find(1); - ok $dish->recalculate(6), "recalculate()"; + ok $dish->recalculate(3), "recalculate()"; $dish->discard_changes(); - is $dish->servings => 6, "servings"; + is $dish->servings => 3, "servings"; is [ $dish->ingredients->hri->all ] => array { item hash { field value => 750; field unit_id => 1; field article_id => 1; etc }; -- GitLab