diff --git a/cgi/suggest.pl b/cgi/suggest.pl index fb59a76e26a5b..d014ef205a7e8 100644 --- a/cgi/suggest.pl +++ b/cgi/suggest.pl @@ -47,7 +47,7 @@ # The API accepts a string input in the "string" field or "term" field. # - term is used by the jquery Autocomplete widget: https://api.jqueryui.com/autocomplete/ # Use "string" only if both are present. -my $string = decode("utf8", (request_param($request_ref, 'string') || request_param($request_ref, 'term'))); +my $string = request_param($request_ref, 'string') || request_param($request_ref, 'term'); # /cgi/suggest.pl supports only limited context (use /api/v3/taxonomy_suggestions to use richer context) my $context_ref = {country => $request_ref->{country},}; diff --git a/lib/ProductOpener/APITaxonomySuggestions.pm b/lib/ProductOpener/APITaxonomySuggestions.pm index ce7eb027f39d8..a44d580310f5a 100644 --- a/lib/ProductOpener/APITaxonomySuggestions.pm +++ b/lib/ProductOpener/APITaxonomySuggestions.pm @@ -80,14 +80,14 @@ sub taxonomy_suggestions_api ($request_ref) { # The API accepts a string input in the "string" field or "term" field. # - term is used by the jquery Autocomplete widget: https://api.jqueryui.com/autocomplete/ # Use "string" only if both are present. - my $string = decode("utf8", (request_param($request_ref, 'string') || request_param($request_ref, 'term'))); + my $string = request_param($request_ref, 'string') || request_param($request_ref, 'term'); # We can use the context (e.g. are the suggestions for a specific product sold in a specific country, with specific categories etc.) # to rank higher suggestions that are popular for similar products my $context_ref = { country => $request_ref->{country}, - categories => decode("utf8", request_param($request_ref, "categories")), # list of product categories - shape => decode("utf8", request_param($request_ref, "shape")), # packaging shape + categories => request_param($request_ref, "categories"), # list of product categories + shape => request_param($request_ref, "shape"), # packaging shape }; # Options define how many suggestions should be returned, in which format etc. diff --git a/lib/ProductOpener/Display.pm b/lib/ProductOpener/Display.pm index 90d0d6bd2e1c7..5e2c3df127bb0 100644 --- a/lib/ProductOpener/Display.pm +++ b/lib/ProductOpener/Display.pm @@ -200,7 +200,7 @@ use boolean; use Excel::Writer::XLSX; use Template; use Devel::Size qw(size total_size); -use Data::DeepAccess qw(deep_get); +use Data::DeepAccess qw(deep_get deep_set); use Log::Log4perl; use LWP::UserAgent; @@ -529,7 +529,13 @@ A scalar value for the parameter, or undef if the parameter is not defined. =cut sub request_param ($request_ref, $param_name) { - return (scalar param($param_name)) || deep_get($request_ref, "body_json", $param_name); + my $cgi_param = scalar param($param_name); + if (defined $cgi_param) { + return decode utf8 => $cgi_param; + } + else { + return deep_get($request_ref, "body_json", $param_name); + } } =head2 init_request () @@ -4202,16 +4208,16 @@ HTML foreach my $tag_ref (@{$request_ref->{tags}}) { if ($tagtype eq 'users') { - param('creator', $tagid); + deep_set($request_ref, "body_json", "creator", $tagid); } else { my $field_name = $tag_ref->{tagtype} . "_tags"; - my $current_value = param($field_name); + my $current_value = deep_get($request_ref, "body_json", $field_name); my $new_value = ($tag_ref->{tag_prefix} // '') . ($tag_ref->{canon_tagid} // $tag_ref->{tagid}); if ($current_value) { $new_value = $current_value . ',' . $new_value; } - param($field_name, $new_value); + deep_set($request_ref, "body_json", $field_name, $new_value); } } @@ -4291,6 +4297,25 @@ HTML return; } +=head2 display_list_of_tags ( $request_ref, $query_ref ) + +Return an array of names of all request parameters. + +=cut + +sub list_all_request_params ($request_ref) { + + # CGI params (query string and POST body) + my @params = multi_param(); + + # Add params from the JSON body if any + if (defined $request_ref->{body_json}) { + push @params, keys %{$request_ref->{body_json}}; + } + + return @params; +} + =head2 display_search_results ( $request_ref ) This function builds the HTML returned by the /search endpoint. @@ -4318,7 +4343,7 @@ sub display_search_results ($request_ref) { my $current_link = ''; - foreach my $field (multi_param()) { + foreach my $field (list_all_request_params($request_ref)) { if ( ($field eq "page") or ($field eq "fields") @@ -4584,7 +4609,7 @@ sub add_params_to_query ($request_ref, $query_ref) { my $and = $query_ref->{"\$and"}; - foreach my $field (multi_param()) { + foreach my $field (list_all_request_params($request_ref)) { $log->debug("add_params_to_query - field", {field => $field}) if $log->is_debug(); @@ -4616,7 +4641,7 @@ sub add_params_to_query ($request_ref, $query_ref) { # xyz_tags=-c products without the c tag # xyz_tags=a,b,-c,-d - my $values = remove_tags_and_quote(decode utf8 => single_param($field)); + my $values = remove_tags_and_quote(request_param($request_ref, $field)); $log->debug("add_params_to_query - tags param", {field => $field, lc => $lc, tag_lc => $tag_lc, values => $values}) @@ -4748,7 +4773,7 @@ sub add_params_to_query ($request_ref, $query_ref) { # We can have multiple conditions, separated with a comma # e.g. sugars_100g=>10,<=20 - my $conditions = single_param($field); + my $conditions = request_param($request_ref, $field); $log->debug("add_params_to_query - nutrient conditions", {field => $field, conditions => $conditions}) if $log->is_debug(); @@ -4766,7 +4791,7 @@ sub add_params_to_query ($request_ref, $query_ref) { } else { $operator = '='; - $value = single_param($field); + $value = request_param($request_ref, $field); } $log->debug("add_params_to_query - nutrient condition", @@ -4796,7 +4821,7 @@ sub add_params_to_query ($request_ref, $query_ref) { # Exact match on a specific field (e.g. "code") elsif (defined $valid_params{$field}) { - my $values = remove_tags_and_quote(decode utf8 => single_param($field)); + my $values = remove_tags_and_quote(request_param($request_ref, $field)); # Possible values: # xyz=a diff --git a/lib/ProductOpener/Users.pm b/lib/ProductOpener/Users.pm index c2a7c52a66056..a4c646abb9ec4 100644 --- a/lib/ProductOpener/Users.pm +++ b/lib/ProductOpener/Users.pm @@ -1088,8 +1088,7 @@ sub init_user ($request_ref) { $user_id = $user_ref->{'userid'}; $log->context->{user_id} = $user_id; - my $hash_is_correct - = check_password_hash(encode_utf8(decode utf8 => request_param($request_ref, 'password')), + my $hash_is_correct = check_password_hash(encode_utf8(request_param($request_ref, 'password')), $user_ref->{'encrypted_password'}); # We don't have the right password if (not $hash_is_correct) { diff --git a/tests/integration/expected_test_results/facets/brand_-brand1.json b/tests/integration/expected_test_results/facets/brand_-brand1.json index bd6716c5a7c6a..f2e3f301e2dbf 100644 --- a/tests/integration/expected_test_results/facets/brand_-brand1.json +++ b/tests/integration/expected_test_results/facets/brand_-brand1.json @@ -1,7 +1,7 @@ { - "count" : 8, + "count" : 9, "page" : 1, - "page_count" : 8, + "page_count" : 9, "page_size" : 24, "products" : [ { @@ -19,6 +19,9 @@ { "product_name" : "Carrots - No label - Belgium - brand2" }, + { + "product_name" : "Chocolate - Organic, Café Label - Martinique" + }, { "product_name" : "Chocolate - Organic, Fair trade - Martinique" }, diff --git a/tests/integration/expected_test_results/facets/brand_unknown.json b/tests/integration/expected_test_results/facets/brand_unknown.json index 7c7ce41ca6924..146f17cc9d8b9 100644 --- a/tests/integration/expected_test_results/facets/brand_unknown.json +++ b/tests/integration/expected_test_results/facets/brand_unknown.json @@ -1,7 +1,7 @@ { - "count" : 5, + "count" : 6, "page" : 1, - "page_count" : 5, + "page_count" : 6, "page_size" : 24, "products" : [ { @@ -13,6 +13,9 @@ { "product_name" : "Apples - Organic, Fair trade - France" }, + { + "product_name" : "Chocolate - Organic, Café Label - Martinique" + }, { "product_name" : "Chocolate - Organic, Fair trade - Martinique" }, diff --git a/tests/integration/expected_test_results/facets/category_-apples.json b/tests/integration/expected_test_results/facets/category_-apples.json index 3d1fc27a2fafb..607e9907150ea 100644 --- a/tests/integration/expected_test_results/facets/category_-apples.json +++ b/tests/integration/expected_test_results/facets/category_-apples.json @@ -1,7 +1,7 @@ { - "count" : 10, + "count" : 11, "page" : 1, - "page_count" : 10, + "page_count" : 11, "page_size" : 24, "products" : [ { @@ -22,6 +22,9 @@ { "product_name" : "Carrots - Organic - France - brand1, brand2" }, + { + "product_name" : "Chocolate - Organic, Café Label - Martinique" + }, { "product_name" : "Chocolate - Organic, Fair trade - Martinique" }, diff --git a/tests/integration/expected_test_results/facets/category_-apples_label_organic.json b/tests/integration/expected_test_results/facets/category_-apples_label_organic.json index 3dcaa4d1b27a5..03df4c72bd40c 100644 --- a/tests/integration/expected_test_results/facets/category_-apples_label_organic.json +++ b/tests/integration/expected_test_results/facets/category_-apples_label_organic.json @@ -1,7 +1,7 @@ { - "count" : 7, + "count" : 8, "page" : 1, - "page_count" : 7, + "page_count" : 8, "page_size" : 24, "products" : [ { @@ -16,6 +16,9 @@ { "product_name" : "Carrots - Organic - France - brand1, brand2" }, + { + "product_name" : "Chocolate - Organic, Café Label - Martinique" + }, { "product_name" : "Chocolate - Organic, Fair trade - Martinique" }, diff --git a/tests/integration/expected_test_results/facets/contributor-alice.json b/tests/integration/expected_test_results/facets/contributor-alice.json index 5550899dc9fed..7093f96d13846 100644 --- a/tests/integration/expected_test_results/facets/contributor-alice.json +++ b/tests/integration/expected_test_results/facets/contributor-alice.json @@ -1,7 +1,7 @@ { - "count" : 12, + "count" : 13, "page" : 1, - "page_count" : 12, + "page_count" : 13, "page_size" : 24, "products" : [ { @@ -31,6 +31,9 @@ { "product_name" : "Carrots - Organic - France - brand1, brand2" }, + { + "product_name" : "Chocolate - Organic, Café Label - Martinique" + }, { "product_name" : "Chocolate - Organic, Fair trade - Martinique" }, diff --git a/tests/integration/expected_test_results/facets/de-accented-cafe-label.json b/tests/integration/expected_test_results/facets/de-accented-cafe-label.json new file mode 100644 index 0000000000000..0804ea9932752 --- /dev/null +++ b/tests/integration/expected_test_results/facets/de-accented-cafe-label.json @@ -0,0 +1,17 @@ +{ + "count" : 1, + "page" : 1, + "page_count" : 1, + "page_size" : 24, + "products" : [ + { + "labels_tags" : [ + "en:fair-trade", + "en:organic", + "de:café-label" + ], + "product_name" : "Chocolate - Organic, Café Label - Martinique" + } + ], + "skip" : 0 +} diff --git a/tests/integration/facets.t b/tests/integration/facets.t index 350a4a6fae3e1..3ba7830478a10 100644 --- a/tests/integration/facets.t +++ b/tests/integration/facets.t @@ -162,6 +162,18 @@ my @products = ( origins => "en:martinique", ), }, + # German product with accents in labels + { + %{dclone(\%empty_product_form)}, + ( + code => '200000000013', + product_name => "Chocolate - Organic, Café Label - Martinique", + categories => "en:chocolate", + labels => "en:organic,en:fair-trade,Café Label", + lang => "de", + lc => "de", + ), + }, ); foreach my $product_ref (@products) { @@ -175,7 +187,7 @@ edit_product( { %{dclone(\%empty_product_form)}, ( - code => '200000000013', + code => '200000000101', product_name => "Yogurt - Organic, Fair trade - Martinique", categories => "en:yogurt", labels => "en:organic,en:fair-trade", @@ -310,6 +322,15 @@ my $tests_ref = [ expected_status_code => 200, sort_products_by => 'product_name', }, + # accented facet value in German + { + test_case => 'de-accented-cafe-label', + method => 'GET', + subdomain => 'world-de', + path => '/label/café-label.json?fields=product_name,labels_tags', + expected_status_code => 200, + sort_products_by => 'product_name', + }, ]; # note: we need to execute the tests with bob, because we need authentication diff --git a/tests/unit/display.t b/tests/unit/display.t index 27dae373add04..613dbd081b6d7 100644 --- a/tests/unit/display.t +++ b/tests/unit/display.t @@ -199,4 +199,8 @@ display_tag($facets_ref); is($facets_ref->{'current_link'}, '/category/breads/data-quality'); is($facets_ref->{'redirect'}, '/category/breads/data-quality'); +$request_ref->{body_json}{labels_tags} = 'en:organic'; +is(request_param($request_ref, 'unexisting_field'), undef); +is(request_param($request_ref, 'labels_tags'), 'en:organic') or diag explain request_param($request_ref, 'labels_tags'); + done_testing();