From 85cee85b1085bb7483f2e1643dfeffd03047cecf Mon Sep 17 00:00:00 2001 From: hangy Date: Fri, 22 Sep 2023 09:41:34 +0200 Subject: [PATCH] feat: Use 'GS1 Barcode Syntax Engine' in READ API v3 (#9050) --- cgi/search.pl | 24 +- lib/ProductOpener/API.pm | 6 +- lib/ProductOpener/APIProductRead.pm | 2 +- lib/ProductOpener/APIProductWrite.pm | 2 +- lib/ProductOpener/Products.pm | 39 +- lib/ProductOpener/Routing.pm | 26 +- tests/integration/api_v3_product_read.t | 62 +- .../get-attribute-groups-fr.json | 2 +- .../get-attribute-groups.json | 2 +- .../get-auth-good-password.json | 4 +- .../get-existing-product-gs1-ai-data-str.json | 1014 +++++++++++++++++ .../get-existing-product-gs1-caret.json | 1014 +++++++++++++++++ .../get-existing-product-gs1-data-uri.json | 1014 +++++++++++++++++ .../get-existing-product-gs1-fnc1.json | 1014 +++++++++++++++++ .../get-existing-product-gs1-gs.json | 1014 +++++++++++++++++ .../get-existing-product.json | 29 +- .../get-fields-all-knowledge-panels.json | 31 +- .../api_v3_product_read/get-fields-all.json | 29 +- ...attribute-groups-all-knowledge-panels.json | 29 +- .../api_v3_product_read/get-fields-raw.json | 29 +- .../get-images-to-update.json | 2 +- .../get-knowledge-panels-fr.json | 2 +- .../get-knowledge-panels.json | 2 +- .../get-packagings-fr.json | 2 +- .../api_v3_product_read/get-packagings.json | 2 +- .../get-specific-fields.json | 2 +- tests/unit/products.t | 71 ++ tests/unit/routing.t | 54 +- 28 files changed, 5390 insertions(+), 133 deletions(-) create mode 100644 tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-ai-data-str.json create mode 100644 tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-caret.json create mode 100644 tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-data-uri.json create mode 100644 tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-fnc1.json create mode 100644 tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-gs.json diff --git a/cgi/search.pl b/cgi/search.pl index c393ab001e658..fe61c7d76ec83 100755 --- a/cgi/search.pl +++ b/cgi/search.pl @@ -138,31 +138,31 @@ } # check if the search term looks like a barcode - if ( (not defined single_param('json')) and (not defined single_param('jsonp')) and (not defined single_param('jqm')) and (not defined single_param('jqm_loadmore')) and (not defined single_param('xml')) and (not defined single_param('rss')) - and ($search_terms =~ /^(\d{4,24})$/)) + and ($search_terms =~ /^(\d{4,24}|(?:[\^(\N{U+001D}\N{U+241D}]|https?:\/\/).+)$/)) { my $code = normalize_code($search_terms); + if ((defined $code) and (length($code) > 0)) { + my $product_id = product_id_for_owner($Owner_id, $code); - my $product_id = product_id_for_owner($Owner_id, $code); - - my $product_ref = product_exists($product_id); # returns 0 if not + my $product_ref = product_exists($product_id); # returns 0 if not - if ($product_ref) { - $log->info("product code exists, redirecting to product page", {code => $code}); - my $location = product_url($product_ref); + if ($product_ref) { + $log->info("product code exists, redirecting to product page", {code => $code}); + my $location = product_url($product_ref); - my $r = shift; - $r->headers_out->set(Location => $location); - $r->status(301); - return 301; + my $r = shift; + $r->headers_out->set(Location => $location); + $r->status(301); + return 301; + } } } diff --git a/lib/ProductOpener/API.pm b/lib/ProductOpener/API.pm index 9deb115057f26..b2cbe30253f26 100644 --- a/lib/ProductOpener/API.pm +++ b/lib/ProductOpener/API.pm @@ -449,13 +449,13 @@ Reference to the response object. =head3 Return value -Normalized code. +Normalized code and, if available, GS1 AI data string. =cut sub normalize_requested_code ($requested_code, $response_ref) { - my $code = normalize_code($requested_code); + my ($code, $ai_data_str) = &normalize_code_with_gs1_ai($requested_code); $response_ref->{code} = $code; # Add a warning if the normalized code is different from the requested code @@ -470,7 +470,7 @@ sub normalize_requested_code ($requested_code, $response_ref) { ); } - return $code; + return ($code, $ai_data_str); } =head2 get_images_to_update($product_ref, $target_lc) diff --git a/lib/ProductOpener/APIProductRead.pm b/lib/ProductOpener/APIProductRead.pm index f4a69336b2631..04721b4a82843 100644 --- a/lib/ProductOpener/APIProductRead.pm +++ b/lib/ProductOpener/APIProductRead.pm @@ -83,7 +83,7 @@ sub read_product_api ($request_ref) { || ""; } - my $code = normalize_requested_code($request_ref->{code}, $response_ref); + my ($code, $ai_data_string) = &normalize_requested_code($request_ref->{code}, $response_ref); my $product_ref; my $product_id; diff --git a/lib/ProductOpener/APIProductWrite.pm b/lib/ProductOpener/APIProductWrite.pm index fd4e9bbe148ed..b13e4f169b717 100644 --- a/lib/ProductOpener/APIProductWrite.pm +++ b/lib/ProductOpener/APIProductWrite.pm @@ -394,7 +394,7 @@ sub write_product_api ($request_ref) { if ($code ne 'test') { # Load the product - $code = normalize_requested_code($request_ref->{code}, $response_ref); + ($code, my $ai_data_string) = &normalize_requested_code($request_ref->{code}, $response_ref); # Check if the code is valid if ($code !~ /^\d{4,24}$/) { diff --git a/lib/ProductOpener/Products.pm b/lib/ProductOpener/Products.pm index c633d08ca9348..9604b978fef54 100644 --- a/lib/ProductOpener/Products.pm +++ b/lib/ProductOpener/Products.pm @@ -66,6 +66,7 @@ BEGIN { use vars qw(@ISA @EXPORT_OK %EXPORT_TAGS); @EXPORT_OK = qw( &normalize_code + &normalize_code_with_gs1_ai &assign_new_code &split_code &product_id_for_owner @@ -280,9 +281,36 @@ Normalized version of the code sub normalize_code ($code) { if (defined $code) { - my $gs1_code = _try_normalize_code_gs1($code); - if ($gs1_code) { + ($code, my $gs1_ai_data_str) = &normalize_code_with_gs1_ai($code); + } + return $code; +} + +=head2 normalize_code_with_gs1_ai() + +C this function normalizes the product code by: +- running the given code through normalization method provided by GS1 to format a GS1 data string, or data URI to a GTIN, +- keeping only digits and removing spaces/dashes etc., +- normalizing the length by adding leading zeroes or removing the leading zero (in case of 14 digit codes) + +=head3 Arguments + +Product Code in the Raw form: $code + +=head3 Return Values + +Normalized version of the code, and GS1 AI data string of the code, if a valid GS1 string was given as the argument + +=cut + +sub normalize_code_with_gs1_ai ($code) { + + my $ai_data_str; + if (defined $code) { + my ($gs1_code, $gs1_ai_data_str) = &_try_normalize_code_gs1($code); + if ($gs1_code and $gs1_ai_data_str) { $code = $gs1_code; + $ai_data_str = $gs1_ai_data_str; } # Keep only digits, remove spaces, dashes and everything else @@ -308,7 +336,7 @@ sub normalize_code ($code) { $code = $'; } } - return $code; + return ($code, $ai_data_str); } sub _try_normalize_code_gs1 ($code) { @@ -346,11 +374,12 @@ sub _try_normalize_code_gs1 ($code) { }; if ($@) { $log->warn("GS1Parser error", {error => $@}) if $log->is_warn(); + $code = undef; $ai_data_str = undef; } - if ((defined $ai_data_str) and ($ai_data_str =~ /^\(01\)(\d{1,14})/)) { - return $1; + if ((defined $code) and (defined $ai_data_str) and ($ai_data_str =~ /^\(01\)(\d{1,14})/)) { + return ($1, $ai_data_str); } else { return; diff --git a/lib/ProductOpener/Routing.pm b/lib/ProductOpener/Routing.pm index 603cf6dee73f1..e41107071647d 100644 --- a/lib/ProductOpener/Routing.pm +++ b/lib/ProductOpener/Routing.pm @@ -148,33 +148,33 @@ sub analyze_request ($request_ref) { {query_string => $request_ref->{query_string}}) if $log->is_debug(); - # Decode the escaped characters in the query string - $request_ref->{query_string} = decode("utf8", URI::Escape::XS::decodeURIComponent($request_ref->{query_string})); - - $log->debug("analyzing query_string, step 3 - components UTF8 decoded", - {query_string => $request_ref->{query_string}}) - if $log->is_debug(); - - $request_ref->{page} = 1; - # some sites like FB can add query parameters, remove all of them # make sure that all query parameters of interest have already been consumed above $request_ref->{query_string} =~ s/(\&|\?).*//; - $log->debug("analyzing query_string, step 4 - removed all query parameters", + $log->debug("analyzing query_string, step 3 - removed all query parameters", {query_string => $request_ref->{query_string}}) if $log->is_debug(); + # Split query string by "/" to know where it points + my @components = (); + foreach my $component (split(/\//, $request_ref->{query_string})) { + # Decode the escaped characters in the query string + push(@components, decode("utf8", URI::Escape::XS::decodeURIComponent($component))); + } + + $log->debug("analyzing query_string, step 4 - components split and UTF8 decoded", {components => \@components}) + if $log->is_debug(); + + $request_ref->{page} = 1; + # if the query request json or xml, either through the json=1 parameter or a .json extension # set the $request_ref->{api} field if ((defined single_param('json')) or (defined single_param('jsonp')) or (defined single_param('xml'))) { $request_ref->{api} = 'v0'; } - # Split query string by "/" to know where it points - my @components = split(/\//, $request_ref->{query_string}); - # Root, ex: https://world.openfoodfacts.org/ if ($#components < 0) { $request_ref->{text} = 'index'; diff --git a/tests/integration/api_v3_product_read.t b/tests/integration/api_v3_product_read.t index 5da99d69dc9af..77cb79a50e952 100644 --- a/tests/integration/api_v3_product_read.t +++ b/tests/integration/api_v3_product_read.t @@ -28,7 +28,7 @@ my @products = ( { %{dclone(\%default_product_form)}, ( - code => '200000000034', + code => '4260392550101', product_name => "Some product", generic_name => "Tester", ingredients_text => "apple, milk, eggs, palm oil", @@ -56,90 +56,120 @@ my $tests_ref = [ { test_case => 'get-existing-product', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', + expected_status_code => 200, + }, + { + test_case => 'get-existing-product-gs1-caret', + method => 'GET', + path => '/api/v3/product/%5E0104260392550101', + expected_status_code => 200, + }, + { + test_case => 'get-existing-product-gs1-fnc1', + method => 'GET', + path => '/api/v3/product/%1D0104260392550101', + expected_status_code => 200, + }, + { + test_case => 'get-existing-product-gs1-gs', + method => 'GET', + path => '/api/v3/product/%E2%90%9D0104260392550101', + expected_status_code => 200, + }, + { + test_case => 'get-existing-product-gs1-ai-data-str', + method => 'GET', + path => '/api/v3/product/(01)04260392550101', + expected_status_code => 200, + }, + { + test_case => 'get-existing-product-gs1-data-uri', + method => 'GET', + path => '/api/v3/product/https%3A%2F%2Fid.gs1.org%2F01%2F04260392550101%2F10%2FABC%2F21%2F123456%3F17%3D211200', expected_status_code => 200, }, { test_case => 'get-specific-fields', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=product_name,categories_tags,categories_tags_en', expected_status_code => 200, }, { test_case => 'get-images-to-update', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=images_to_update_en', expected_status_code => 200, }, { test_case => 'get-attribute-groups', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=attribute_groups', expected_status_code => 200, }, { test_case => 'get-attribute-groups-fr', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=attribute_groups&lc=fr', expected_status_code => 200, }, { test_case => 'get-knowledge-panels', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=knowledge_panels', expected_status_code => 200, }, { test_case => 'get-knowledge-panels-fr', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=knowledge_panels&lc=fr', expected_status_code => 200, }, { test_case => 'get-packagings', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=packagings', expected_status_code => 200, }, { test_case => 'get-packagings-fr', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=packagings&tags_lc=fr', expected_status_code => 200, }, { test_case => 'get-fields-raw', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=raw', expected_status_code => 200, }, { test_case => 'get-fields-all', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=all', expected_status_code => 200, }, { test_case => 'get-fields-all-knowledge-panels', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=all,knowledge_panels', expected_status_code => 200, }, { test_case => 'get-fields-attribute-groups-all-knowledge-panels', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=attribute_groups,all,knowledge_panels', expected_status_code => 200, }, @@ -148,14 +178,14 @@ my $tests_ref = [ { test_case => 'get-auth-good-password', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=code,product_name&user_id=tests&password=testtest', expected_status_code => 200, }, { test_case => 'get-auth-bad-user-password', method => 'GET', - path => '/api/v3/product/200000000034', + path => '/api/v3/product/4260392550101', query_string => '?fields=code,product_name&user_id=tests&password=bad_password', expected_status_code => 200, }, diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-attribute-groups-fr.json b/tests/integration/expected_test_results/api_v3_product_read/get-attribute-groups-fr.json index e376d5af8ef6b..388b8cdd6ec37 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-attribute-groups-fr.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-attribute-groups-fr.json @@ -1,5 +1,5 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { "attribute_groups" : [ diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-attribute-groups.json b/tests/integration/expected_test_results/api_v3_product_read/get-attribute-groups.json index 975158cdbe0ca..8fcb487439908 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-attribute-groups.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-attribute-groups.json @@ -1,5 +1,5 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { "attribute_groups" : [ diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-auth-good-password.json b/tests/integration/expected_test_results/api_v3_product_read/get-auth-good-password.json index 7e6b07e248b1c..dabb415509c1c 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-auth-good-password.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-auth-good-password.json @@ -1,8 +1,8 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { - "code" : "200000000034", + "code" : "4260392550101", "product_name" : "Some product" }, "result" : { diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-ai-data-str.json b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-ai-data-str.json new file mode 100644 index 0000000000000..6b1f32a028d85 --- /dev/null +++ b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-ai-data-str.json @@ -0,0 +1,1014 @@ +{ + "code" : "4260392550101", + "errors" : [], + "product" : { + "_id" : "4260392550101", + "_keywords" : [ + "cookie", + "organic", + "product", + "some", + "tester" + ], + "added_countries_tags" : [], + "additives_n" : 0, + "additives_old_n" : 0, + "additives_old_tags" : [], + "additives_original_tags" : [], + "additives_tags" : [], + "allergens" : "", + "allergens_from_ingredients" : "en:milk, milk, eggs", + "allergens_from_user" : "(en) ", + "allergens_hierarchy" : [ + "en:eggs", + "en:milk" + ], + "allergens_tags" : [ + "en:eggs", + "en:milk" + ], + "amino_acids_tags" : [], + "categories" : "cookies", + "categories_hierarchy" : [ + "en:snacks", + "en:sweet-snacks", + "en:biscuits-and-cakes", + "en:biscuits" + ], + "categories_lc" : "en", + "categories_properties" : { + "agribalyse_proxy_food_code:en" : "24000" + }, + "categories_properties_tags" : [ + "all-products", + "categories-known", + "agribalyse-food-code-unknown", + "agribalyse-proxy-food-code-24000", + "agribalyse-proxy-food-code-known", + "ciqual-food-code-unknown", + "agribalyse-known", + "agribalyse-24000" + ], + "categories_tags" : [ + "en:snacks", + "en:sweet-snacks", + "en:biscuits-and-cakes", + "en:biscuits" + ], + "checkers_tags" : [], + "code" : "4260392550101", + "codes_tags" : [ + "code-13", + "4260392550xxx", + "426039255xxxx", + "42603925xxxxx", + "4260392xxxxxx", + "426039xxxxxxx", + "42603xxxxxxxx", + "4260xxxxxxxxx", + "426xxxxxxxxxx", + "42xxxxxxxxxxx", + "4xxxxxxxxxxxx" + ], + "complete" : 0, + "completeness" : 0.4, + "correctors_tags" : [], + "created_t" : "--ignore--", + "creator" : "tests", + "data_quality_bugs_tags" : [], + "data_quality_errors_tags" : [], + "data_quality_info_tags" : [ + "en:packaging-data-incomplete", + "en:ingredients-percent-analysis-ok", + "en:ecoscore-extended-data-not-computed", + "en:food-groups-1-known", + "en:food-groups-2-known", + "en:food-groups-3-unknown" + ], + "data_quality_tags" : [ + "en:packaging-data-incomplete", + "en:ingredients-percent-analysis-ok", + "en:ecoscore-extended-data-not-computed", + "en:food-groups-1-known", + "en:food-groups-2-known", + "en:food-groups-3-unknown", + "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", + "en:ecoscore-production-system-no-label" + ], + "data_quality_warnings_tags" : [ + "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", + "en:ecoscore-production-system-no-label" + ], + "ecoscore_data" : { + "adjustments" : { + "origins_of_ingredients" : { + "aggregated_origins" : [ + { + "epi_score" : 0, + "origin" : "en:unknown", + "percent" : 100, + "transportation_score" : null + } + ], + "epi_score" : 0, + "epi_value" : -5, + "origins_from_origins_field" : [ + "en:unknown" + ], + "transportation_score" : 0, + "transportation_scores" : { + "ad" : 0, + "al" : 0, + "at" : 0, + "ax" : 0, + "ba" : 0, + "be" : 0, + "bg" : 0, + "ch" : 0, + "cy" : 0, + "cz" : 0, + "de" : 0, + "dk" : 0, + "dz" : 0, + "ee" : 0, + "eg" : 0, + "es" : 0, + "fi" : 0, + "fo" : 0, + "fr" : 0, + "gg" : 0, + "gi" : 0, + "gr" : 0, + "hr" : 0, + "hu" : 0, + "ie" : 0, + "il" : 0, + "im" : 0, + "is" : 0, + "it" : 0, + "je" : 0, + "lb" : 0, + "li" : 0, + "lt" : 0, + "lu" : 0, + "lv" : 0, + "ly" : 0, + "ma" : 0, + "mc" : 0, + "md" : 0, + "me" : 0, + "mk" : 0, + "mt" : 0, + "nl" : 0, + "no" : 0, + "pl" : 0, + "ps" : 0, + "pt" : 0, + "ro" : 0, + "rs" : 0, + "se" : 0, + "si" : 0, + "sj" : 0, + "sk" : 0, + "sm" : 0, + "sy" : 0, + "tn" : 0, + "tr" : 0, + "ua" : 0, + "uk" : 0, + "us" : 0, + "va" : 0, + "world" : 0, + "xk" : 0 + }, + "transportation_value" : 0, + "transportation_values" : { + "ad" : 0, + "al" : 0, + "at" : 0, + "ax" : 0, + "ba" : 0, + "be" : 0, + "bg" : 0, + "ch" : 0, + "cy" : 0, + "cz" : 0, + "de" : 0, + "dk" : 0, + "dz" : 0, + "ee" : 0, + "eg" : 0, + "es" : 0, + "fi" : 0, + "fo" : 0, + "fr" : 0, + "gg" : 0, + "gi" : 0, + "gr" : 0, + "hr" : 0, + "hu" : 0, + "ie" : 0, + "il" : 0, + "im" : 0, + "is" : 0, + "it" : 0, + "je" : 0, + "lb" : 0, + "li" : 0, + "lt" : 0, + "lu" : 0, + "lv" : 0, + "ly" : 0, + "ma" : 0, + "mc" : 0, + "md" : 0, + "me" : 0, + "mk" : 0, + "mt" : 0, + "nl" : 0, + "no" : 0, + "pl" : 0, + "ps" : 0, + "pt" : 0, + "ro" : 0, + "rs" : 0, + "se" : 0, + "si" : 0, + "sj" : 0, + "sk" : 0, + "sm" : 0, + "sy" : 0, + "tn" : 0, + "tr" : 0, + "ua" : 0, + "uk" : 0, + "us" : 0, + "va" : 0, + "world" : 0, + "xk" : 0 + }, + "value" : -5, + "values" : { + "ad" : -5, + "al" : -5, + "at" : -5, + "ax" : -5, + "ba" : -5, + "be" : -5, + "bg" : -5, + "ch" : -5, + "cy" : -5, + "cz" : -5, + "de" : -5, + "dk" : -5, + "dz" : -5, + "ee" : -5, + "eg" : -5, + "es" : -5, + "fi" : -5, + "fo" : -5, + "fr" : -5, + "gg" : -5, + "gi" : -5, + "gr" : -5, + "hr" : -5, + "hu" : -5, + "ie" : -5, + "il" : -5, + "im" : -5, + "is" : -5, + "it" : -5, + "je" : -5, + "lb" : -5, + "li" : -5, + "lt" : -5, + "lu" : -5, + "lv" : -5, + "ly" : -5, + "ma" : -5, + "mc" : -5, + "md" : -5, + "me" : -5, + "mk" : -5, + "mt" : -5, + "nl" : -5, + "no" : -5, + "pl" : -5, + "ps" : -5, + "pt" : -5, + "ro" : -5, + "rs" : -5, + "se" : -5, + "si" : -5, + "sj" : -5, + "sk" : -5, + "sm" : -5, + "sy" : -5, + "tn" : -5, + "tr" : -5, + "ua" : -5, + "uk" : -5, + "us" : -5, + "va" : -5, + "world" : -5, + "xk" : -5 + }, + "warning" : "origins_are_100_percent_unknown" + }, + "packaging" : { + "non_recyclable_and_non_biodegradable_materials" : 0, + "packagings" : [ + { + "ecoscore_material_score" : 50, + "ecoscore_shape_ratio" : 1, + "material" : "en:wood", + "number_of_units" : 1, + "recycling" : "en:recycle", + "shape" : "en:box" + }, + { + "ecoscore_material_score" : 81, + "ecoscore_shape_ratio" : 1, + "material" : "en:glass", + "number_of_units" : 6, + "quantity_per_unit" : "25cl", + "quantity_per_unit_unit" : "cl", + "quantity_per_unit_value" : 25, + "recycling" : "en:reuse", + "shape" : "en:bottle" + }, + { + "ecoscore_material_score" : 76, + "ecoscore_shape_ratio" : 0.2, + "material" : "en:steel", + "number_of_units" : 3, + "recycling" : "en:recycle", + "shape" : "en:lid" + }, + { + "ecoscore_material_score" : 0, + "ecoscore_shape_ratio" : 0.1, + "material" : "en:plastic", + "non_recyclable_and_non_biodegradable" : "maybe", + "number_of_units" : 1, + "recycling" : "en:discard", + "shape" : "en:film" + } + ], + "score" : 16.2, + "value" : -8 + }, + "production_system" : { + "labels" : [], + "value" : 0, + "warning" : "no_label" + }, + "threatened_species" : { + "ingredient" : "en:palm-oil", + "value" : -10 + } + }, + "agribalyse" : { + "agribalyse_proxy_food_code" : "24000", + "co2_agriculture" : 2.3889426, + "co2_consumption" : 0, + "co2_distribution" : 0.019530673, + "co2_packaging" : 0.11014808, + "co2_processing" : 0.22878446, + "co2_total" : 2.882859363, + "co2_transportation" : 0.13545355, + "code" : "24000", + "dqr" : "2.14", + "ef_agriculture" : 0.28329233, + "ef_consumption" : 0, + "ef_distribution" : 0.0048315303, + "ef_packaging" : 0.01096965, + "ef_processing" : 0.041686082, + "ef_total" : 0.3518903043, + "ef_transportation" : 0.011110712, + "is_beverage" : 0, + "name_en" : "Biscuit (cookie)", + "name_fr" : "Biscuit sec, sans précision", + "score" : 69, + "version" : "3.1" + }, + "grade" : "c", + "grades" : { + "ad" : "c", + "al" : "c", + "at" : "c", + "ax" : "c", + "ba" : "c", + "be" : "c", + "bg" : "c", + "ch" : "c", + "cy" : "c", + "cz" : "c", + "de" : "c", + "dk" : "c", + "dz" : "c", + "ee" : "c", + "eg" : "c", + "es" : "c", + "fi" : "c", + "fo" : "c", + "fr" : "c", + "gg" : "c", + "gi" : "c", + "gr" : "c", + "hr" : "c", + "hu" : "c", + "ie" : "c", + "il" : "c", + "im" : "c", + "is" : "c", + "it" : "c", + "je" : "c", + "lb" : "c", + "li" : "c", + "lt" : "c", + "lu" : "c", + "lv" : "c", + "ly" : "c", + "ma" : "c", + "mc" : "c", + "md" : "c", + "me" : "c", + "mk" : "c", + "mt" : "c", + "nl" : "c", + "no" : "c", + "pl" : "c", + "ps" : "c", + "pt" : "c", + "ro" : "c", + "rs" : "c", + "se" : "c", + "si" : "c", + "sj" : "c", + "sk" : "c", + "sm" : "c", + "sy" : "c", + "tn" : "c", + "tr" : "c", + "ua" : "c", + "uk" : "c", + "us" : "c", + "va" : "c", + "world" : "c", + "xk" : "c" + }, + "missing" : { + "labels" : 1, + "origins" : 1 + }, + "missing_data_warning" : 1, + "score" : 46, + "scores" : { + "ad" : 46, + "al" : 46, + "at" : 46, + "ax" : 46, + "ba" : 46, + "be" : 46, + "bg" : 46, + "ch" : 46, + "cy" : 46, + "cz" : 46, + "de" : 46, + "dk" : 46, + "dz" : 46, + "ee" : 46, + "eg" : 46, + "es" : 46, + "fi" : 46, + "fo" : 46, + "fr" : 46, + "gg" : 46, + "gi" : 46, + "gr" : 46, + "hr" : 46, + "hu" : 46, + "ie" : 46, + "il" : 46, + "im" : 46, + "is" : 46, + "it" : 46, + "je" : 46, + "lb" : 46, + "li" : 46, + "lt" : 46, + "lu" : 46, + "lv" : 46, + "ly" : 46, + "ma" : 46, + "mc" : 46, + "md" : 46, + "me" : 46, + "mk" : 46, + "mt" : 46, + "nl" : 46, + "no" : 46, + "pl" : 46, + "ps" : 46, + "pt" : 46, + "ro" : 46, + "rs" : 46, + "se" : 46, + "si" : 46, + "sj" : 46, + "sk" : 46, + "sm" : 46, + "sy" : 46, + "tn" : 46, + "tr" : 46, + "ua" : 46, + "uk" : 46, + "us" : 46, + "va" : 46, + "world" : 46, + "xk" : 46 + }, + "status" : "known" + }, + "ecoscore_grade" : "c", + "ecoscore_score" : 46, + "ecoscore_tags" : [ + "c" + ], + "editors_tags" : [ + "tests" + ], + "entry_dates_tags" : "--ignore--", + "food_groups" : "en:biscuits-and-cakes", + "food_groups_tags" : [ + "en:sugary-snacks", + "en:biscuits-and-cakes" + ], + "forest_footprint_data" : { + "footprint_per_kg" : 0.00145833333333333, + "grade" : "a", + "ingredients" : [ + { + "conditions_tags" : [ + [ + "labels", + "en:organic" + ] + ], + "footprint_per_kg" : 0.00145833333333333, + "matching_tag_id" : "en:egg", + "percent" : 9.375, + "percent_estimate" : 9.375, + "processing_factor" : 1, + "tag_id" : "en:egg", + "tag_type" : "ingredients", + "type" : { + "deforestation_risk" : 0.1, + "name" : "Oeufs Bio", + "soy_feed_factor" : 0.028, + "soy_yield" : 0.18 + } + } + ] + }, + "generic_name" : "Tester", + "generic_name_en" : "Tester", + "id" : "4260392550101", + "informers_tags" : [ + "tests" + ], + "ingredients" : [ + { + "ciqual_food_code" : "13050", + "id" : "en:apple", + "percent_estimate" : 62.5, + "percent_max" : 100, + "percent_min" : 25, + "text" : "apple", + "vegan" : "yes", + "vegetarian" : "yes" + }, + { + "id" : "en:milk", + "percent_estimate" : 18.75, + "percent_max" : 50, + "percent_min" : 0, + "text" : "milk", + "vegan" : "no", + "vegetarian" : "yes" + }, + { + "ciqual_food_code" : "22000", + "id" : "en:egg", + "percent_estimate" : 9.375, + "percent_max" : 33.3333333333333, + "percent_min" : 0, + "text" : "eggs", + "vegan" : "no", + "vegetarian" : "yes" + }, + { + "ciqual_food_code" : "16129", + "from_palm_oil" : "yes", + "id" : "en:palm-oil", + "percent_estimate" : 9.375, + "percent_max" : 25, + "percent_min" : 0, + "text" : "palm oil", + "vegan" : "yes", + "vegetarian" : "yes" + } + ], + "ingredients_analysis" : { + "en:non-vegan" : [ + "en:milk", + "en:egg" + ], + "en:palm-oil" : [ + "en:palm-oil" + ] + }, + "ingredients_analysis_tags" : [ + "en:palm-oil", + "en:non-vegan", + "en:vegetarian" + ], + "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_tags" : [], + "ingredients_hierarchy" : [ + "en:apple", + "en:fruit", + "en:malaceous-fruit", + "en:milk", + "en:dairy", + "en:egg", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" + ], + "ingredients_lc" : "en", + "ingredients_n" : 4, + "ingredients_n_tags" : [ + "4", + "1-10" + ], + "ingredients_original_tags" : [ + "en:apple", + "en:milk", + "en:egg", + "en:palm-oil" + ], + "ingredients_percent_analysis" : 1, + "ingredients_tags" : [ + "en:apple", + "en:fruit", + "en:malaceous-fruit", + "en:milk", + "en:dairy", + "en:egg", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" + ], + "ingredients_text" : "apple, milk, eggs, palm oil", + "ingredients_text_en" : "apple, milk, eggs, palm oil", + "ingredients_text_with_allergens" : "apple, milk, eggs, palm oil", + "ingredients_text_with_allergens_en" : "apple, milk, eggs, palm oil", + "ingredients_that_may_be_from_palm_oil_n" : 0, + "ingredients_that_may_be_from_palm_oil_tags" : [], + "ingredients_with_specified_percent_n" : 0, + "ingredients_with_specified_percent_sum" : 0, + "ingredients_with_unspecified_percent_n" : 4, + "ingredients_with_unspecified_percent_sum" : 100, + "ingredients_without_ciqual_codes" : [ + "en:milk" + ], + "ingredients_without_ciqual_codes_n" : 1, + "interface_version_created" : "20150316.jqm2", + "interface_version_modified" : "20150316.jqm2", + "known_ingredients_n" : 10, + "labels" : "organic", + "labels_hierarchy" : [ + "en:organic" + ], + "labels_lc" : "en", + "labels_tags" : [ + "en:organic" + ], + "lang" : "en", + "languages" : { + "en:english" : 5 + }, + "languages_codes" : { + "en" : 5 + }, + "languages_hierarchy" : [ + "en:english" + ], + "languages_tags" : [ + "en:english", + "en:1" + ], + "last_edit_dates_tags" : "--ignore--", + "last_editor" : "tests", + "last_modified_by" : "tests", + "last_modified_t" : "--ignore--", + "lc" : "en", + "link" : "http://world.openfoodfacts.org/", + "main_countries_tags" : [], + "minerals_tags" : [], + "misc_tags" : [ + "en:nutrition-not-enough-data-to-compute-nutrition-score", + "en:nutriscore-missing-nutrition-data", + "en:nutriscore-missing-nutrition-data-energy", + "en:nutriscore-missing-nutrition-data-fat", + "en:nutriscore-missing-nutrition-data-saturated-fat", + "en:nutriscore-missing-nutrition-data-sugars", + "en:nutriscore-missing-nutrition-data-sodium", + "en:nutriscore-missing-nutrition-data-proteins", + "en:nutrition-no-fiber", + "en:nutriscore-not-computed", + "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", + "en:nutrition-no-fiber-or-fruits-vegetables-nuts", + "en:nutrition-fruits-vegetables-legumes-estimate-from-ingredients", + "en:packagings-number-of-components-4", + "en:packagings-not-complete", + "en:packagings-not-empty-but-not-complete", + "en:packagings-not-empty", + "en:ecoscore-extended-data-not-computed", + "en:ecoscore-missing-data-warning", + "en:ecoscore-missing-data-labels", + "en:ecoscore-missing-data-origins", + "en:ecoscore-computed", + "en:ecoscore-changed", + "en:ecoscore-grade-changed", + "en:forest-footprint-computed", + "en:forest-footprint-a", + "en:main-countries-new-product" + ], + "nova_group" : 3, + "nova_group_debug" : "", + "nova_groups" : "3", + "nova_groups_markers" : { + "3" : [ + [ + "categories", + "en:sweet-snacks" + ] + ] + }, + "nova_groups_tags" : [ + "en:3-processed-foods" + ], + "nucleotides_tags" : [], + "nutrient_levels" : {}, + "nutrient_levels_tags" : [], + "nutriments" : { + "fruits-vegetables-legumes-estimate-from-ingredients_100g" : 62.5, + "fruits-vegetables-legumes-estimate-from-ingredients_serving" : 62.5, + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 62.5, + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 62.5, + "nova-group" : 3, + "nova-group_100g" : 3, + "nova-group_serving" : 3 + }, + "nutriscore" : { + "2021" : { + "category_available" : 1, + "data" : { + "energy" : null, + "fiber" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 62.5, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "proteins" : null, + "saturated_fat" : null, + "sodium" : null, + "sugars" : null + }, + "grade" : "unknown", + "nutrients_available" : 0, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 0 + }, + "2023" : { + "category_available" : 1, + "data" : { + "energy" : null, + "fiber" : 0, + "fruits_vegetables_legumes" : 62.5, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat_oil_nuts_seeds" : 0, + "is_water" : 0, + "proteins" : null, + "salt" : null, + "saturated_fat" : null, + "sugars" : null + }, + "grade" : "unknown", + "nutrients_available" : 0, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 0 + } + }, + "nutriscore_2021_tags" : [ + "unknown" + ], + "nutriscore_2023_tags" : [ + "unknown" + ], + "nutriscore_grade" : "unknown", + "nutriscore_tags" : [ + "unknown" + ], + "nutriscore_version" : "2021", + "nutrition_data_per" : "100g", + "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "unknown", + "nutrition_grades" : "unknown", + "nutrition_grades_tags" : [ + "unknown" + ], + "nutrition_score_beverage" : 0, + "nutrition_score_debug" : "missing energy_100g - missing fat_100g - missing saturated-fat_100g - missing sugars_100g - missing sodium_100g - missing proteins_100g", + "nutrition_score_warning_fruits_vegetables_legumes_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_legumes_estimate_from_ingredients_value" : 62.5, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 62.5, + "nutrition_score_warning_no_fiber" : 1, + "origin" : "france", + "origin_en" : "france", + "other_nutritional_substances_tags" : [], + "packaging_materials_tags" : [ + "en:glass", + "en:plastic", + "en:steel", + "en:wood" + ], + "packaging_recycling_tags" : [ + "en:discard", + "en:recycle", + "en:reuse" + ], + "packaging_shapes_tags" : [ + "en:bottle", + "en:box", + "en:film", + "en:lid" + ], + "packaging_text" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard", + "packaging_text_en" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard", + "packagings" : [ + { + "material" : { + "id" : "en:wood" + }, + "number_of_units" : 1, + "recycling" : { + "id" : "en:recycle" + }, + "shape" : { + "id" : "en:box" + } + }, + { + "material" : { + "id" : "en:glass" + }, + "number_of_units" : 6, + "quantity_per_unit" : "25cl", + "quantity_per_unit_unit" : "cl", + "quantity_per_unit_value" : 25, + "recycling" : { + "id" : "en:reuse" + }, + "shape" : { + "id" : "en:bottle" + } + }, + { + "material" : { + "id" : "en:steel" + }, + "number_of_units" : 3, + "recycling" : { + "id" : "en:recycle" + }, + "shape" : { + "id" : "en:lid" + } + }, + { + "material" : { + "id" : "en:plastic" + }, + "number_of_units" : 1, + "recycling" : { + "id" : "en:discard" + }, + "shape" : { + "id" : "en:film" + } + } + ], + "packagings_materials" : { + "all" : {}, + "en:glass" : {}, + "en:metal" : {}, + "en:plastic" : {}, + "en:unknown" : {} + }, + "packagings_n" : 4, + "photographers_tags" : [], + "pnns_groups_1" : "Sugary snacks", + "pnns_groups_1_tags" : [ + "sugary-snacks", + "known" + ], + "pnns_groups_2" : "Biscuits and cakes", + "pnns_groups_2_tags" : [ + "biscuits-and-cakes", + "known" + ], + "popularity_key" : 0, + "product_name" : "Some product", + "product_name_en" : "Some product", + "product_quantity" : "100", + "quantity" : "100 g", + "removed_countries_tags" : [], + "rev" : 1, + "serving_quantity" : "10", + "serving_size" : "10 g", + "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", + "states_hierarchy" : [ + "en:to-be-completed", + "en:nutrition-facts-to-be-completed", + "en:ingredients-completed", + "en:expiration-date-to-be-completed", + "en:packaging-code-to-be-completed", + "en:characteristics-to-be-completed", + "en:origins-to-be-completed", + "en:categories-completed", + "en:brands-to-be-completed", + "en:packaging-to-be-completed", + "en:quantity-completed", + "en:product-name-completed", + "en:photos-to-be-uploaded" + ], + "states_tags" : [ + "en:to-be-completed", + "en:nutrition-facts-to-be-completed", + "en:ingredients-completed", + "en:expiration-date-to-be-completed", + "en:packaging-code-to-be-completed", + "en:characteristics-to-be-completed", + "en:origins-to-be-completed", + "en:categories-completed", + "en:brands-to-be-completed", + "en:packaging-to-be-completed", + "en:quantity-completed", + "en:product-name-completed", + "en:photos-to-be-uploaded" + ], + "traces" : "", + "traces_from_ingredients" : "", + "traces_from_user" : "(en) ", + "traces_hierarchy" : [], + "traces_tags" : [], + "unknown_ingredients_n" : 0, + "unknown_nutrients_tags" : [], + "vitamins_tags" : [], + "weighers_tags" : [] + }, + "result" : { + "id" : "product_found", + "lc_name" : "Product found", + "name" : "Product found" + }, + "status" : "success_with_warnings", + "warnings" : [ + { + "field" : { + "id" : "code", + "value" : "4260392550101" + }, + "impact" : { + "id" : "none", + "lc_name" : "None", + "name" : "None" + }, + "message" : { + "id" : "different_normalized_product_code", + "lc_name" : "", + "name" : "" + } + } + ] +} diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-caret.json b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-caret.json new file mode 100644 index 0000000000000..6b1f32a028d85 --- /dev/null +++ b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-caret.json @@ -0,0 +1,1014 @@ +{ + "code" : "4260392550101", + "errors" : [], + "product" : { + "_id" : "4260392550101", + "_keywords" : [ + "cookie", + "organic", + "product", + "some", + "tester" + ], + "added_countries_tags" : [], + "additives_n" : 0, + "additives_old_n" : 0, + "additives_old_tags" : [], + "additives_original_tags" : [], + "additives_tags" : [], + "allergens" : "", + "allergens_from_ingredients" : "en:milk, milk, eggs", + "allergens_from_user" : "(en) ", + "allergens_hierarchy" : [ + "en:eggs", + "en:milk" + ], + "allergens_tags" : [ + "en:eggs", + "en:milk" + ], + "amino_acids_tags" : [], + "categories" : "cookies", + "categories_hierarchy" : [ + "en:snacks", + "en:sweet-snacks", + "en:biscuits-and-cakes", + "en:biscuits" + ], + "categories_lc" : "en", + "categories_properties" : { + "agribalyse_proxy_food_code:en" : "24000" + }, + "categories_properties_tags" : [ + "all-products", + "categories-known", + "agribalyse-food-code-unknown", + "agribalyse-proxy-food-code-24000", + "agribalyse-proxy-food-code-known", + "ciqual-food-code-unknown", + "agribalyse-known", + "agribalyse-24000" + ], + "categories_tags" : [ + "en:snacks", + "en:sweet-snacks", + "en:biscuits-and-cakes", + "en:biscuits" + ], + "checkers_tags" : [], + "code" : "4260392550101", + "codes_tags" : [ + "code-13", + "4260392550xxx", + "426039255xxxx", + "42603925xxxxx", + "4260392xxxxxx", + "426039xxxxxxx", + "42603xxxxxxxx", + "4260xxxxxxxxx", + "426xxxxxxxxxx", + "42xxxxxxxxxxx", + "4xxxxxxxxxxxx" + ], + "complete" : 0, + "completeness" : 0.4, + "correctors_tags" : [], + "created_t" : "--ignore--", + "creator" : "tests", + "data_quality_bugs_tags" : [], + "data_quality_errors_tags" : [], + "data_quality_info_tags" : [ + "en:packaging-data-incomplete", + "en:ingredients-percent-analysis-ok", + "en:ecoscore-extended-data-not-computed", + "en:food-groups-1-known", + "en:food-groups-2-known", + "en:food-groups-3-unknown" + ], + "data_quality_tags" : [ + "en:packaging-data-incomplete", + "en:ingredients-percent-analysis-ok", + "en:ecoscore-extended-data-not-computed", + "en:food-groups-1-known", + "en:food-groups-2-known", + "en:food-groups-3-unknown", + "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", + "en:ecoscore-production-system-no-label" + ], + "data_quality_warnings_tags" : [ + "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", + "en:ecoscore-production-system-no-label" + ], + "ecoscore_data" : { + "adjustments" : { + "origins_of_ingredients" : { + "aggregated_origins" : [ + { + "epi_score" : 0, + "origin" : "en:unknown", + "percent" : 100, + "transportation_score" : null + } + ], + "epi_score" : 0, + "epi_value" : -5, + "origins_from_origins_field" : [ + "en:unknown" + ], + "transportation_score" : 0, + "transportation_scores" : { + "ad" : 0, + "al" : 0, + "at" : 0, + "ax" : 0, + "ba" : 0, + "be" : 0, + "bg" : 0, + "ch" : 0, + "cy" : 0, + "cz" : 0, + "de" : 0, + "dk" : 0, + "dz" : 0, + "ee" : 0, + "eg" : 0, + "es" : 0, + "fi" : 0, + "fo" : 0, + "fr" : 0, + "gg" : 0, + "gi" : 0, + "gr" : 0, + "hr" : 0, + "hu" : 0, + "ie" : 0, + "il" : 0, + "im" : 0, + "is" : 0, + "it" : 0, + "je" : 0, + "lb" : 0, + "li" : 0, + "lt" : 0, + "lu" : 0, + "lv" : 0, + "ly" : 0, + "ma" : 0, + "mc" : 0, + "md" : 0, + "me" : 0, + "mk" : 0, + "mt" : 0, + "nl" : 0, + "no" : 0, + "pl" : 0, + "ps" : 0, + "pt" : 0, + "ro" : 0, + "rs" : 0, + "se" : 0, + "si" : 0, + "sj" : 0, + "sk" : 0, + "sm" : 0, + "sy" : 0, + "tn" : 0, + "tr" : 0, + "ua" : 0, + "uk" : 0, + "us" : 0, + "va" : 0, + "world" : 0, + "xk" : 0 + }, + "transportation_value" : 0, + "transportation_values" : { + "ad" : 0, + "al" : 0, + "at" : 0, + "ax" : 0, + "ba" : 0, + "be" : 0, + "bg" : 0, + "ch" : 0, + "cy" : 0, + "cz" : 0, + "de" : 0, + "dk" : 0, + "dz" : 0, + "ee" : 0, + "eg" : 0, + "es" : 0, + "fi" : 0, + "fo" : 0, + "fr" : 0, + "gg" : 0, + "gi" : 0, + "gr" : 0, + "hr" : 0, + "hu" : 0, + "ie" : 0, + "il" : 0, + "im" : 0, + "is" : 0, + "it" : 0, + "je" : 0, + "lb" : 0, + "li" : 0, + "lt" : 0, + "lu" : 0, + "lv" : 0, + "ly" : 0, + "ma" : 0, + "mc" : 0, + "md" : 0, + "me" : 0, + "mk" : 0, + "mt" : 0, + "nl" : 0, + "no" : 0, + "pl" : 0, + "ps" : 0, + "pt" : 0, + "ro" : 0, + "rs" : 0, + "se" : 0, + "si" : 0, + "sj" : 0, + "sk" : 0, + "sm" : 0, + "sy" : 0, + "tn" : 0, + "tr" : 0, + "ua" : 0, + "uk" : 0, + "us" : 0, + "va" : 0, + "world" : 0, + "xk" : 0 + }, + "value" : -5, + "values" : { + "ad" : -5, + "al" : -5, + "at" : -5, + "ax" : -5, + "ba" : -5, + "be" : -5, + "bg" : -5, + "ch" : -5, + "cy" : -5, + "cz" : -5, + "de" : -5, + "dk" : -5, + "dz" : -5, + "ee" : -5, + "eg" : -5, + "es" : -5, + "fi" : -5, + "fo" : -5, + "fr" : -5, + "gg" : -5, + "gi" : -5, + "gr" : -5, + "hr" : -5, + "hu" : -5, + "ie" : -5, + "il" : -5, + "im" : -5, + "is" : -5, + "it" : -5, + "je" : -5, + "lb" : -5, + "li" : -5, + "lt" : -5, + "lu" : -5, + "lv" : -5, + "ly" : -5, + "ma" : -5, + "mc" : -5, + "md" : -5, + "me" : -5, + "mk" : -5, + "mt" : -5, + "nl" : -5, + "no" : -5, + "pl" : -5, + "ps" : -5, + "pt" : -5, + "ro" : -5, + "rs" : -5, + "se" : -5, + "si" : -5, + "sj" : -5, + "sk" : -5, + "sm" : -5, + "sy" : -5, + "tn" : -5, + "tr" : -5, + "ua" : -5, + "uk" : -5, + "us" : -5, + "va" : -5, + "world" : -5, + "xk" : -5 + }, + "warning" : "origins_are_100_percent_unknown" + }, + "packaging" : { + "non_recyclable_and_non_biodegradable_materials" : 0, + "packagings" : [ + { + "ecoscore_material_score" : 50, + "ecoscore_shape_ratio" : 1, + "material" : "en:wood", + "number_of_units" : 1, + "recycling" : "en:recycle", + "shape" : "en:box" + }, + { + "ecoscore_material_score" : 81, + "ecoscore_shape_ratio" : 1, + "material" : "en:glass", + "number_of_units" : 6, + "quantity_per_unit" : "25cl", + "quantity_per_unit_unit" : "cl", + "quantity_per_unit_value" : 25, + "recycling" : "en:reuse", + "shape" : "en:bottle" + }, + { + "ecoscore_material_score" : 76, + "ecoscore_shape_ratio" : 0.2, + "material" : "en:steel", + "number_of_units" : 3, + "recycling" : "en:recycle", + "shape" : "en:lid" + }, + { + "ecoscore_material_score" : 0, + "ecoscore_shape_ratio" : 0.1, + "material" : "en:plastic", + "non_recyclable_and_non_biodegradable" : "maybe", + "number_of_units" : 1, + "recycling" : "en:discard", + "shape" : "en:film" + } + ], + "score" : 16.2, + "value" : -8 + }, + "production_system" : { + "labels" : [], + "value" : 0, + "warning" : "no_label" + }, + "threatened_species" : { + "ingredient" : "en:palm-oil", + "value" : -10 + } + }, + "agribalyse" : { + "agribalyse_proxy_food_code" : "24000", + "co2_agriculture" : 2.3889426, + "co2_consumption" : 0, + "co2_distribution" : 0.019530673, + "co2_packaging" : 0.11014808, + "co2_processing" : 0.22878446, + "co2_total" : 2.882859363, + "co2_transportation" : 0.13545355, + "code" : "24000", + "dqr" : "2.14", + "ef_agriculture" : 0.28329233, + "ef_consumption" : 0, + "ef_distribution" : 0.0048315303, + "ef_packaging" : 0.01096965, + "ef_processing" : 0.041686082, + "ef_total" : 0.3518903043, + "ef_transportation" : 0.011110712, + "is_beverage" : 0, + "name_en" : "Biscuit (cookie)", + "name_fr" : "Biscuit sec, sans précision", + "score" : 69, + "version" : "3.1" + }, + "grade" : "c", + "grades" : { + "ad" : "c", + "al" : "c", + "at" : "c", + "ax" : "c", + "ba" : "c", + "be" : "c", + "bg" : "c", + "ch" : "c", + "cy" : "c", + "cz" : "c", + "de" : "c", + "dk" : "c", + "dz" : "c", + "ee" : "c", + "eg" : "c", + "es" : "c", + "fi" : "c", + "fo" : "c", + "fr" : "c", + "gg" : "c", + "gi" : "c", + "gr" : "c", + "hr" : "c", + "hu" : "c", + "ie" : "c", + "il" : "c", + "im" : "c", + "is" : "c", + "it" : "c", + "je" : "c", + "lb" : "c", + "li" : "c", + "lt" : "c", + "lu" : "c", + "lv" : "c", + "ly" : "c", + "ma" : "c", + "mc" : "c", + "md" : "c", + "me" : "c", + "mk" : "c", + "mt" : "c", + "nl" : "c", + "no" : "c", + "pl" : "c", + "ps" : "c", + "pt" : "c", + "ro" : "c", + "rs" : "c", + "se" : "c", + "si" : "c", + "sj" : "c", + "sk" : "c", + "sm" : "c", + "sy" : "c", + "tn" : "c", + "tr" : "c", + "ua" : "c", + "uk" : "c", + "us" : "c", + "va" : "c", + "world" : "c", + "xk" : "c" + }, + "missing" : { + "labels" : 1, + "origins" : 1 + }, + "missing_data_warning" : 1, + "score" : 46, + "scores" : { + "ad" : 46, + "al" : 46, + "at" : 46, + "ax" : 46, + "ba" : 46, + "be" : 46, + "bg" : 46, + "ch" : 46, + "cy" : 46, + "cz" : 46, + "de" : 46, + "dk" : 46, + "dz" : 46, + "ee" : 46, + "eg" : 46, + "es" : 46, + "fi" : 46, + "fo" : 46, + "fr" : 46, + "gg" : 46, + "gi" : 46, + "gr" : 46, + "hr" : 46, + "hu" : 46, + "ie" : 46, + "il" : 46, + "im" : 46, + "is" : 46, + "it" : 46, + "je" : 46, + "lb" : 46, + "li" : 46, + "lt" : 46, + "lu" : 46, + "lv" : 46, + "ly" : 46, + "ma" : 46, + "mc" : 46, + "md" : 46, + "me" : 46, + "mk" : 46, + "mt" : 46, + "nl" : 46, + "no" : 46, + "pl" : 46, + "ps" : 46, + "pt" : 46, + "ro" : 46, + "rs" : 46, + "se" : 46, + "si" : 46, + "sj" : 46, + "sk" : 46, + "sm" : 46, + "sy" : 46, + "tn" : 46, + "tr" : 46, + "ua" : 46, + "uk" : 46, + "us" : 46, + "va" : 46, + "world" : 46, + "xk" : 46 + }, + "status" : "known" + }, + "ecoscore_grade" : "c", + "ecoscore_score" : 46, + "ecoscore_tags" : [ + "c" + ], + "editors_tags" : [ + "tests" + ], + "entry_dates_tags" : "--ignore--", + "food_groups" : "en:biscuits-and-cakes", + "food_groups_tags" : [ + "en:sugary-snacks", + "en:biscuits-and-cakes" + ], + "forest_footprint_data" : { + "footprint_per_kg" : 0.00145833333333333, + "grade" : "a", + "ingredients" : [ + { + "conditions_tags" : [ + [ + "labels", + "en:organic" + ] + ], + "footprint_per_kg" : 0.00145833333333333, + "matching_tag_id" : "en:egg", + "percent" : 9.375, + "percent_estimate" : 9.375, + "processing_factor" : 1, + "tag_id" : "en:egg", + "tag_type" : "ingredients", + "type" : { + "deforestation_risk" : 0.1, + "name" : "Oeufs Bio", + "soy_feed_factor" : 0.028, + "soy_yield" : 0.18 + } + } + ] + }, + "generic_name" : "Tester", + "generic_name_en" : "Tester", + "id" : "4260392550101", + "informers_tags" : [ + "tests" + ], + "ingredients" : [ + { + "ciqual_food_code" : "13050", + "id" : "en:apple", + "percent_estimate" : 62.5, + "percent_max" : 100, + "percent_min" : 25, + "text" : "apple", + "vegan" : "yes", + "vegetarian" : "yes" + }, + { + "id" : "en:milk", + "percent_estimate" : 18.75, + "percent_max" : 50, + "percent_min" : 0, + "text" : "milk", + "vegan" : "no", + "vegetarian" : "yes" + }, + { + "ciqual_food_code" : "22000", + "id" : "en:egg", + "percent_estimate" : 9.375, + "percent_max" : 33.3333333333333, + "percent_min" : 0, + "text" : "eggs", + "vegan" : "no", + "vegetarian" : "yes" + }, + { + "ciqual_food_code" : "16129", + "from_palm_oil" : "yes", + "id" : "en:palm-oil", + "percent_estimate" : 9.375, + "percent_max" : 25, + "percent_min" : 0, + "text" : "palm oil", + "vegan" : "yes", + "vegetarian" : "yes" + } + ], + "ingredients_analysis" : { + "en:non-vegan" : [ + "en:milk", + "en:egg" + ], + "en:palm-oil" : [ + "en:palm-oil" + ] + }, + "ingredients_analysis_tags" : [ + "en:palm-oil", + "en:non-vegan", + "en:vegetarian" + ], + "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_tags" : [], + "ingredients_hierarchy" : [ + "en:apple", + "en:fruit", + "en:malaceous-fruit", + "en:milk", + "en:dairy", + "en:egg", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" + ], + "ingredients_lc" : "en", + "ingredients_n" : 4, + "ingredients_n_tags" : [ + "4", + "1-10" + ], + "ingredients_original_tags" : [ + "en:apple", + "en:milk", + "en:egg", + "en:palm-oil" + ], + "ingredients_percent_analysis" : 1, + "ingredients_tags" : [ + "en:apple", + "en:fruit", + "en:malaceous-fruit", + "en:milk", + "en:dairy", + "en:egg", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" + ], + "ingredients_text" : "apple, milk, eggs, palm oil", + "ingredients_text_en" : "apple, milk, eggs, palm oil", + "ingredients_text_with_allergens" : "apple, milk, eggs, palm oil", + "ingredients_text_with_allergens_en" : "apple, milk, eggs, palm oil", + "ingredients_that_may_be_from_palm_oil_n" : 0, + "ingredients_that_may_be_from_palm_oil_tags" : [], + "ingredients_with_specified_percent_n" : 0, + "ingredients_with_specified_percent_sum" : 0, + "ingredients_with_unspecified_percent_n" : 4, + "ingredients_with_unspecified_percent_sum" : 100, + "ingredients_without_ciqual_codes" : [ + "en:milk" + ], + "ingredients_without_ciqual_codes_n" : 1, + "interface_version_created" : "20150316.jqm2", + "interface_version_modified" : "20150316.jqm2", + "known_ingredients_n" : 10, + "labels" : "organic", + "labels_hierarchy" : [ + "en:organic" + ], + "labels_lc" : "en", + "labels_tags" : [ + "en:organic" + ], + "lang" : "en", + "languages" : { + "en:english" : 5 + }, + "languages_codes" : { + "en" : 5 + }, + "languages_hierarchy" : [ + "en:english" + ], + "languages_tags" : [ + "en:english", + "en:1" + ], + "last_edit_dates_tags" : "--ignore--", + "last_editor" : "tests", + "last_modified_by" : "tests", + "last_modified_t" : "--ignore--", + "lc" : "en", + "link" : "http://world.openfoodfacts.org/", + "main_countries_tags" : [], + "minerals_tags" : [], + "misc_tags" : [ + "en:nutrition-not-enough-data-to-compute-nutrition-score", + "en:nutriscore-missing-nutrition-data", + "en:nutriscore-missing-nutrition-data-energy", + "en:nutriscore-missing-nutrition-data-fat", + "en:nutriscore-missing-nutrition-data-saturated-fat", + "en:nutriscore-missing-nutrition-data-sugars", + "en:nutriscore-missing-nutrition-data-sodium", + "en:nutriscore-missing-nutrition-data-proteins", + "en:nutrition-no-fiber", + "en:nutriscore-not-computed", + "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", + "en:nutrition-no-fiber-or-fruits-vegetables-nuts", + "en:nutrition-fruits-vegetables-legumes-estimate-from-ingredients", + "en:packagings-number-of-components-4", + "en:packagings-not-complete", + "en:packagings-not-empty-but-not-complete", + "en:packagings-not-empty", + "en:ecoscore-extended-data-not-computed", + "en:ecoscore-missing-data-warning", + "en:ecoscore-missing-data-labels", + "en:ecoscore-missing-data-origins", + "en:ecoscore-computed", + "en:ecoscore-changed", + "en:ecoscore-grade-changed", + "en:forest-footprint-computed", + "en:forest-footprint-a", + "en:main-countries-new-product" + ], + "nova_group" : 3, + "nova_group_debug" : "", + "nova_groups" : "3", + "nova_groups_markers" : { + "3" : [ + [ + "categories", + "en:sweet-snacks" + ] + ] + }, + "nova_groups_tags" : [ + "en:3-processed-foods" + ], + "nucleotides_tags" : [], + "nutrient_levels" : {}, + "nutrient_levels_tags" : [], + "nutriments" : { + "fruits-vegetables-legumes-estimate-from-ingredients_100g" : 62.5, + "fruits-vegetables-legumes-estimate-from-ingredients_serving" : 62.5, + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 62.5, + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 62.5, + "nova-group" : 3, + "nova-group_100g" : 3, + "nova-group_serving" : 3 + }, + "nutriscore" : { + "2021" : { + "category_available" : 1, + "data" : { + "energy" : null, + "fiber" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 62.5, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "proteins" : null, + "saturated_fat" : null, + "sodium" : null, + "sugars" : null + }, + "grade" : "unknown", + "nutrients_available" : 0, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 0 + }, + "2023" : { + "category_available" : 1, + "data" : { + "energy" : null, + "fiber" : 0, + "fruits_vegetables_legumes" : 62.5, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat_oil_nuts_seeds" : 0, + "is_water" : 0, + "proteins" : null, + "salt" : null, + "saturated_fat" : null, + "sugars" : null + }, + "grade" : "unknown", + "nutrients_available" : 0, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 0 + } + }, + "nutriscore_2021_tags" : [ + "unknown" + ], + "nutriscore_2023_tags" : [ + "unknown" + ], + "nutriscore_grade" : "unknown", + "nutriscore_tags" : [ + "unknown" + ], + "nutriscore_version" : "2021", + "nutrition_data_per" : "100g", + "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "unknown", + "nutrition_grades" : "unknown", + "nutrition_grades_tags" : [ + "unknown" + ], + "nutrition_score_beverage" : 0, + "nutrition_score_debug" : "missing energy_100g - missing fat_100g - missing saturated-fat_100g - missing sugars_100g - missing sodium_100g - missing proteins_100g", + "nutrition_score_warning_fruits_vegetables_legumes_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_legumes_estimate_from_ingredients_value" : 62.5, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 62.5, + "nutrition_score_warning_no_fiber" : 1, + "origin" : "france", + "origin_en" : "france", + "other_nutritional_substances_tags" : [], + "packaging_materials_tags" : [ + "en:glass", + "en:plastic", + "en:steel", + "en:wood" + ], + "packaging_recycling_tags" : [ + "en:discard", + "en:recycle", + "en:reuse" + ], + "packaging_shapes_tags" : [ + "en:bottle", + "en:box", + "en:film", + "en:lid" + ], + "packaging_text" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard", + "packaging_text_en" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard", + "packagings" : [ + { + "material" : { + "id" : "en:wood" + }, + "number_of_units" : 1, + "recycling" : { + "id" : "en:recycle" + }, + "shape" : { + "id" : "en:box" + } + }, + { + "material" : { + "id" : "en:glass" + }, + "number_of_units" : 6, + "quantity_per_unit" : "25cl", + "quantity_per_unit_unit" : "cl", + "quantity_per_unit_value" : 25, + "recycling" : { + "id" : "en:reuse" + }, + "shape" : { + "id" : "en:bottle" + } + }, + { + "material" : { + "id" : "en:steel" + }, + "number_of_units" : 3, + "recycling" : { + "id" : "en:recycle" + }, + "shape" : { + "id" : "en:lid" + } + }, + { + "material" : { + "id" : "en:plastic" + }, + "number_of_units" : 1, + "recycling" : { + "id" : "en:discard" + }, + "shape" : { + "id" : "en:film" + } + } + ], + "packagings_materials" : { + "all" : {}, + "en:glass" : {}, + "en:metal" : {}, + "en:plastic" : {}, + "en:unknown" : {} + }, + "packagings_n" : 4, + "photographers_tags" : [], + "pnns_groups_1" : "Sugary snacks", + "pnns_groups_1_tags" : [ + "sugary-snacks", + "known" + ], + "pnns_groups_2" : "Biscuits and cakes", + "pnns_groups_2_tags" : [ + "biscuits-and-cakes", + "known" + ], + "popularity_key" : 0, + "product_name" : "Some product", + "product_name_en" : "Some product", + "product_quantity" : "100", + "quantity" : "100 g", + "removed_countries_tags" : [], + "rev" : 1, + "serving_quantity" : "10", + "serving_size" : "10 g", + "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", + "states_hierarchy" : [ + "en:to-be-completed", + "en:nutrition-facts-to-be-completed", + "en:ingredients-completed", + "en:expiration-date-to-be-completed", + "en:packaging-code-to-be-completed", + "en:characteristics-to-be-completed", + "en:origins-to-be-completed", + "en:categories-completed", + "en:brands-to-be-completed", + "en:packaging-to-be-completed", + "en:quantity-completed", + "en:product-name-completed", + "en:photos-to-be-uploaded" + ], + "states_tags" : [ + "en:to-be-completed", + "en:nutrition-facts-to-be-completed", + "en:ingredients-completed", + "en:expiration-date-to-be-completed", + "en:packaging-code-to-be-completed", + "en:characteristics-to-be-completed", + "en:origins-to-be-completed", + "en:categories-completed", + "en:brands-to-be-completed", + "en:packaging-to-be-completed", + "en:quantity-completed", + "en:product-name-completed", + "en:photos-to-be-uploaded" + ], + "traces" : "", + "traces_from_ingredients" : "", + "traces_from_user" : "(en) ", + "traces_hierarchy" : [], + "traces_tags" : [], + "unknown_ingredients_n" : 0, + "unknown_nutrients_tags" : [], + "vitamins_tags" : [], + "weighers_tags" : [] + }, + "result" : { + "id" : "product_found", + "lc_name" : "Product found", + "name" : "Product found" + }, + "status" : "success_with_warnings", + "warnings" : [ + { + "field" : { + "id" : "code", + "value" : "4260392550101" + }, + "impact" : { + "id" : "none", + "lc_name" : "None", + "name" : "None" + }, + "message" : { + "id" : "different_normalized_product_code", + "lc_name" : "", + "name" : "" + } + } + ] +} diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-data-uri.json b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-data-uri.json new file mode 100644 index 0000000000000..6b1f32a028d85 --- /dev/null +++ b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-data-uri.json @@ -0,0 +1,1014 @@ +{ + "code" : "4260392550101", + "errors" : [], + "product" : { + "_id" : "4260392550101", + "_keywords" : [ + "cookie", + "organic", + "product", + "some", + "tester" + ], + "added_countries_tags" : [], + "additives_n" : 0, + "additives_old_n" : 0, + "additives_old_tags" : [], + "additives_original_tags" : [], + "additives_tags" : [], + "allergens" : "", + "allergens_from_ingredients" : "en:milk, milk, eggs", + "allergens_from_user" : "(en) ", + "allergens_hierarchy" : [ + "en:eggs", + "en:milk" + ], + "allergens_tags" : [ + "en:eggs", + "en:milk" + ], + "amino_acids_tags" : [], + "categories" : "cookies", + "categories_hierarchy" : [ + "en:snacks", + "en:sweet-snacks", + "en:biscuits-and-cakes", + "en:biscuits" + ], + "categories_lc" : "en", + "categories_properties" : { + "agribalyse_proxy_food_code:en" : "24000" + }, + "categories_properties_tags" : [ + "all-products", + "categories-known", + "agribalyse-food-code-unknown", + "agribalyse-proxy-food-code-24000", + "agribalyse-proxy-food-code-known", + "ciqual-food-code-unknown", + "agribalyse-known", + "agribalyse-24000" + ], + "categories_tags" : [ + "en:snacks", + "en:sweet-snacks", + "en:biscuits-and-cakes", + "en:biscuits" + ], + "checkers_tags" : [], + "code" : "4260392550101", + "codes_tags" : [ + "code-13", + "4260392550xxx", + "426039255xxxx", + "42603925xxxxx", + "4260392xxxxxx", + "426039xxxxxxx", + "42603xxxxxxxx", + "4260xxxxxxxxx", + "426xxxxxxxxxx", + "42xxxxxxxxxxx", + "4xxxxxxxxxxxx" + ], + "complete" : 0, + "completeness" : 0.4, + "correctors_tags" : [], + "created_t" : "--ignore--", + "creator" : "tests", + "data_quality_bugs_tags" : [], + "data_quality_errors_tags" : [], + "data_quality_info_tags" : [ + "en:packaging-data-incomplete", + "en:ingredients-percent-analysis-ok", + "en:ecoscore-extended-data-not-computed", + "en:food-groups-1-known", + "en:food-groups-2-known", + "en:food-groups-3-unknown" + ], + "data_quality_tags" : [ + "en:packaging-data-incomplete", + "en:ingredients-percent-analysis-ok", + "en:ecoscore-extended-data-not-computed", + "en:food-groups-1-known", + "en:food-groups-2-known", + "en:food-groups-3-unknown", + "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", + "en:ecoscore-production-system-no-label" + ], + "data_quality_warnings_tags" : [ + "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", + "en:ecoscore-production-system-no-label" + ], + "ecoscore_data" : { + "adjustments" : { + "origins_of_ingredients" : { + "aggregated_origins" : [ + { + "epi_score" : 0, + "origin" : "en:unknown", + "percent" : 100, + "transportation_score" : null + } + ], + "epi_score" : 0, + "epi_value" : -5, + "origins_from_origins_field" : [ + "en:unknown" + ], + "transportation_score" : 0, + "transportation_scores" : { + "ad" : 0, + "al" : 0, + "at" : 0, + "ax" : 0, + "ba" : 0, + "be" : 0, + "bg" : 0, + "ch" : 0, + "cy" : 0, + "cz" : 0, + "de" : 0, + "dk" : 0, + "dz" : 0, + "ee" : 0, + "eg" : 0, + "es" : 0, + "fi" : 0, + "fo" : 0, + "fr" : 0, + "gg" : 0, + "gi" : 0, + "gr" : 0, + "hr" : 0, + "hu" : 0, + "ie" : 0, + "il" : 0, + "im" : 0, + "is" : 0, + "it" : 0, + "je" : 0, + "lb" : 0, + "li" : 0, + "lt" : 0, + "lu" : 0, + "lv" : 0, + "ly" : 0, + "ma" : 0, + "mc" : 0, + "md" : 0, + "me" : 0, + "mk" : 0, + "mt" : 0, + "nl" : 0, + "no" : 0, + "pl" : 0, + "ps" : 0, + "pt" : 0, + "ro" : 0, + "rs" : 0, + "se" : 0, + "si" : 0, + "sj" : 0, + "sk" : 0, + "sm" : 0, + "sy" : 0, + "tn" : 0, + "tr" : 0, + "ua" : 0, + "uk" : 0, + "us" : 0, + "va" : 0, + "world" : 0, + "xk" : 0 + }, + "transportation_value" : 0, + "transportation_values" : { + "ad" : 0, + "al" : 0, + "at" : 0, + "ax" : 0, + "ba" : 0, + "be" : 0, + "bg" : 0, + "ch" : 0, + "cy" : 0, + "cz" : 0, + "de" : 0, + "dk" : 0, + "dz" : 0, + "ee" : 0, + "eg" : 0, + "es" : 0, + "fi" : 0, + "fo" : 0, + "fr" : 0, + "gg" : 0, + "gi" : 0, + "gr" : 0, + "hr" : 0, + "hu" : 0, + "ie" : 0, + "il" : 0, + "im" : 0, + "is" : 0, + "it" : 0, + "je" : 0, + "lb" : 0, + "li" : 0, + "lt" : 0, + "lu" : 0, + "lv" : 0, + "ly" : 0, + "ma" : 0, + "mc" : 0, + "md" : 0, + "me" : 0, + "mk" : 0, + "mt" : 0, + "nl" : 0, + "no" : 0, + "pl" : 0, + "ps" : 0, + "pt" : 0, + "ro" : 0, + "rs" : 0, + "se" : 0, + "si" : 0, + "sj" : 0, + "sk" : 0, + "sm" : 0, + "sy" : 0, + "tn" : 0, + "tr" : 0, + "ua" : 0, + "uk" : 0, + "us" : 0, + "va" : 0, + "world" : 0, + "xk" : 0 + }, + "value" : -5, + "values" : { + "ad" : -5, + "al" : -5, + "at" : -5, + "ax" : -5, + "ba" : -5, + "be" : -5, + "bg" : -5, + "ch" : -5, + "cy" : -5, + "cz" : -5, + "de" : -5, + "dk" : -5, + "dz" : -5, + "ee" : -5, + "eg" : -5, + "es" : -5, + "fi" : -5, + "fo" : -5, + "fr" : -5, + "gg" : -5, + "gi" : -5, + "gr" : -5, + "hr" : -5, + "hu" : -5, + "ie" : -5, + "il" : -5, + "im" : -5, + "is" : -5, + "it" : -5, + "je" : -5, + "lb" : -5, + "li" : -5, + "lt" : -5, + "lu" : -5, + "lv" : -5, + "ly" : -5, + "ma" : -5, + "mc" : -5, + "md" : -5, + "me" : -5, + "mk" : -5, + "mt" : -5, + "nl" : -5, + "no" : -5, + "pl" : -5, + "ps" : -5, + "pt" : -5, + "ro" : -5, + "rs" : -5, + "se" : -5, + "si" : -5, + "sj" : -5, + "sk" : -5, + "sm" : -5, + "sy" : -5, + "tn" : -5, + "tr" : -5, + "ua" : -5, + "uk" : -5, + "us" : -5, + "va" : -5, + "world" : -5, + "xk" : -5 + }, + "warning" : "origins_are_100_percent_unknown" + }, + "packaging" : { + "non_recyclable_and_non_biodegradable_materials" : 0, + "packagings" : [ + { + "ecoscore_material_score" : 50, + "ecoscore_shape_ratio" : 1, + "material" : "en:wood", + "number_of_units" : 1, + "recycling" : "en:recycle", + "shape" : "en:box" + }, + { + "ecoscore_material_score" : 81, + "ecoscore_shape_ratio" : 1, + "material" : "en:glass", + "number_of_units" : 6, + "quantity_per_unit" : "25cl", + "quantity_per_unit_unit" : "cl", + "quantity_per_unit_value" : 25, + "recycling" : "en:reuse", + "shape" : "en:bottle" + }, + { + "ecoscore_material_score" : 76, + "ecoscore_shape_ratio" : 0.2, + "material" : "en:steel", + "number_of_units" : 3, + "recycling" : "en:recycle", + "shape" : "en:lid" + }, + { + "ecoscore_material_score" : 0, + "ecoscore_shape_ratio" : 0.1, + "material" : "en:plastic", + "non_recyclable_and_non_biodegradable" : "maybe", + "number_of_units" : 1, + "recycling" : "en:discard", + "shape" : "en:film" + } + ], + "score" : 16.2, + "value" : -8 + }, + "production_system" : { + "labels" : [], + "value" : 0, + "warning" : "no_label" + }, + "threatened_species" : { + "ingredient" : "en:palm-oil", + "value" : -10 + } + }, + "agribalyse" : { + "agribalyse_proxy_food_code" : "24000", + "co2_agriculture" : 2.3889426, + "co2_consumption" : 0, + "co2_distribution" : 0.019530673, + "co2_packaging" : 0.11014808, + "co2_processing" : 0.22878446, + "co2_total" : 2.882859363, + "co2_transportation" : 0.13545355, + "code" : "24000", + "dqr" : "2.14", + "ef_agriculture" : 0.28329233, + "ef_consumption" : 0, + "ef_distribution" : 0.0048315303, + "ef_packaging" : 0.01096965, + "ef_processing" : 0.041686082, + "ef_total" : 0.3518903043, + "ef_transportation" : 0.011110712, + "is_beverage" : 0, + "name_en" : "Biscuit (cookie)", + "name_fr" : "Biscuit sec, sans précision", + "score" : 69, + "version" : "3.1" + }, + "grade" : "c", + "grades" : { + "ad" : "c", + "al" : "c", + "at" : "c", + "ax" : "c", + "ba" : "c", + "be" : "c", + "bg" : "c", + "ch" : "c", + "cy" : "c", + "cz" : "c", + "de" : "c", + "dk" : "c", + "dz" : "c", + "ee" : "c", + "eg" : "c", + "es" : "c", + "fi" : "c", + "fo" : "c", + "fr" : "c", + "gg" : "c", + "gi" : "c", + "gr" : "c", + "hr" : "c", + "hu" : "c", + "ie" : "c", + "il" : "c", + "im" : "c", + "is" : "c", + "it" : "c", + "je" : "c", + "lb" : "c", + "li" : "c", + "lt" : "c", + "lu" : "c", + "lv" : "c", + "ly" : "c", + "ma" : "c", + "mc" : "c", + "md" : "c", + "me" : "c", + "mk" : "c", + "mt" : "c", + "nl" : "c", + "no" : "c", + "pl" : "c", + "ps" : "c", + "pt" : "c", + "ro" : "c", + "rs" : "c", + "se" : "c", + "si" : "c", + "sj" : "c", + "sk" : "c", + "sm" : "c", + "sy" : "c", + "tn" : "c", + "tr" : "c", + "ua" : "c", + "uk" : "c", + "us" : "c", + "va" : "c", + "world" : "c", + "xk" : "c" + }, + "missing" : { + "labels" : 1, + "origins" : 1 + }, + "missing_data_warning" : 1, + "score" : 46, + "scores" : { + "ad" : 46, + "al" : 46, + "at" : 46, + "ax" : 46, + "ba" : 46, + "be" : 46, + "bg" : 46, + "ch" : 46, + "cy" : 46, + "cz" : 46, + "de" : 46, + "dk" : 46, + "dz" : 46, + "ee" : 46, + "eg" : 46, + "es" : 46, + "fi" : 46, + "fo" : 46, + "fr" : 46, + "gg" : 46, + "gi" : 46, + "gr" : 46, + "hr" : 46, + "hu" : 46, + "ie" : 46, + "il" : 46, + "im" : 46, + "is" : 46, + "it" : 46, + "je" : 46, + "lb" : 46, + "li" : 46, + "lt" : 46, + "lu" : 46, + "lv" : 46, + "ly" : 46, + "ma" : 46, + "mc" : 46, + "md" : 46, + "me" : 46, + "mk" : 46, + "mt" : 46, + "nl" : 46, + "no" : 46, + "pl" : 46, + "ps" : 46, + "pt" : 46, + "ro" : 46, + "rs" : 46, + "se" : 46, + "si" : 46, + "sj" : 46, + "sk" : 46, + "sm" : 46, + "sy" : 46, + "tn" : 46, + "tr" : 46, + "ua" : 46, + "uk" : 46, + "us" : 46, + "va" : 46, + "world" : 46, + "xk" : 46 + }, + "status" : "known" + }, + "ecoscore_grade" : "c", + "ecoscore_score" : 46, + "ecoscore_tags" : [ + "c" + ], + "editors_tags" : [ + "tests" + ], + "entry_dates_tags" : "--ignore--", + "food_groups" : "en:biscuits-and-cakes", + "food_groups_tags" : [ + "en:sugary-snacks", + "en:biscuits-and-cakes" + ], + "forest_footprint_data" : { + "footprint_per_kg" : 0.00145833333333333, + "grade" : "a", + "ingredients" : [ + { + "conditions_tags" : [ + [ + "labels", + "en:organic" + ] + ], + "footprint_per_kg" : 0.00145833333333333, + "matching_tag_id" : "en:egg", + "percent" : 9.375, + "percent_estimate" : 9.375, + "processing_factor" : 1, + "tag_id" : "en:egg", + "tag_type" : "ingredients", + "type" : { + "deforestation_risk" : 0.1, + "name" : "Oeufs Bio", + "soy_feed_factor" : 0.028, + "soy_yield" : 0.18 + } + } + ] + }, + "generic_name" : "Tester", + "generic_name_en" : "Tester", + "id" : "4260392550101", + "informers_tags" : [ + "tests" + ], + "ingredients" : [ + { + "ciqual_food_code" : "13050", + "id" : "en:apple", + "percent_estimate" : 62.5, + "percent_max" : 100, + "percent_min" : 25, + "text" : "apple", + "vegan" : "yes", + "vegetarian" : "yes" + }, + { + "id" : "en:milk", + "percent_estimate" : 18.75, + "percent_max" : 50, + "percent_min" : 0, + "text" : "milk", + "vegan" : "no", + "vegetarian" : "yes" + }, + { + "ciqual_food_code" : "22000", + "id" : "en:egg", + "percent_estimate" : 9.375, + "percent_max" : 33.3333333333333, + "percent_min" : 0, + "text" : "eggs", + "vegan" : "no", + "vegetarian" : "yes" + }, + { + "ciqual_food_code" : "16129", + "from_palm_oil" : "yes", + "id" : "en:palm-oil", + "percent_estimate" : 9.375, + "percent_max" : 25, + "percent_min" : 0, + "text" : "palm oil", + "vegan" : "yes", + "vegetarian" : "yes" + } + ], + "ingredients_analysis" : { + "en:non-vegan" : [ + "en:milk", + "en:egg" + ], + "en:palm-oil" : [ + "en:palm-oil" + ] + }, + "ingredients_analysis_tags" : [ + "en:palm-oil", + "en:non-vegan", + "en:vegetarian" + ], + "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_tags" : [], + "ingredients_hierarchy" : [ + "en:apple", + "en:fruit", + "en:malaceous-fruit", + "en:milk", + "en:dairy", + "en:egg", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" + ], + "ingredients_lc" : "en", + "ingredients_n" : 4, + "ingredients_n_tags" : [ + "4", + "1-10" + ], + "ingredients_original_tags" : [ + "en:apple", + "en:milk", + "en:egg", + "en:palm-oil" + ], + "ingredients_percent_analysis" : 1, + "ingredients_tags" : [ + "en:apple", + "en:fruit", + "en:malaceous-fruit", + "en:milk", + "en:dairy", + "en:egg", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" + ], + "ingredients_text" : "apple, milk, eggs, palm oil", + "ingredients_text_en" : "apple, milk, eggs, palm oil", + "ingredients_text_with_allergens" : "apple, milk, eggs, palm oil", + "ingredients_text_with_allergens_en" : "apple, milk, eggs, palm oil", + "ingredients_that_may_be_from_palm_oil_n" : 0, + "ingredients_that_may_be_from_palm_oil_tags" : [], + "ingredients_with_specified_percent_n" : 0, + "ingredients_with_specified_percent_sum" : 0, + "ingredients_with_unspecified_percent_n" : 4, + "ingredients_with_unspecified_percent_sum" : 100, + "ingredients_without_ciqual_codes" : [ + "en:milk" + ], + "ingredients_without_ciqual_codes_n" : 1, + "interface_version_created" : "20150316.jqm2", + "interface_version_modified" : "20150316.jqm2", + "known_ingredients_n" : 10, + "labels" : "organic", + "labels_hierarchy" : [ + "en:organic" + ], + "labels_lc" : "en", + "labels_tags" : [ + "en:organic" + ], + "lang" : "en", + "languages" : { + "en:english" : 5 + }, + "languages_codes" : { + "en" : 5 + }, + "languages_hierarchy" : [ + "en:english" + ], + "languages_tags" : [ + "en:english", + "en:1" + ], + "last_edit_dates_tags" : "--ignore--", + "last_editor" : "tests", + "last_modified_by" : "tests", + "last_modified_t" : "--ignore--", + "lc" : "en", + "link" : "http://world.openfoodfacts.org/", + "main_countries_tags" : [], + "minerals_tags" : [], + "misc_tags" : [ + "en:nutrition-not-enough-data-to-compute-nutrition-score", + "en:nutriscore-missing-nutrition-data", + "en:nutriscore-missing-nutrition-data-energy", + "en:nutriscore-missing-nutrition-data-fat", + "en:nutriscore-missing-nutrition-data-saturated-fat", + "en:nutriscore-missing-nutrition-data-sugars", + "en:nutriscore-missing-nutrition-data-sodium", + "en:nutriscore-missing-nutrition-data-proteins", + "en:nutrition-no-fiber", + "en:nutriscore-not-computed", + "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", + "en:nutrition-no-fiber-or-fruits-vegetables-nuts", + "en:nutrition-fruits-vegetables-legumes-estimate-from-ingredients", + "en:packagings-number-of-components-4", + "en:packagings-not-complete", + "en:packagings-not-empty-but-not-complete", + "en:packagings-not-empty", + "en:ecoscore-extended-data-not-computed", + "en:ecoscore-missing-data-warning", + "en:ecoscore-missing-data-labels", + "en:ecoscore-missing-data-origins", + "en:ecoscore-computed", + "en:ecoscore-changed", + "en:ecoscore-grade-changed", + "en:forest-footprint-computed", + "en:forest-footprint-a", + "en:main-countries-new-product" + ], + "nova_group" : 3, + "nova_group_debug" : "", + "nova_groups" : "3", + "nova_groups_markers" : { + "3" : [ + [ + "categories", + "en:sweet-snacks" + ] + ] + }, + "nova_groups_tags" : [ + "en:3-processed-foods" + ], + "nucleotides_tags" : [], + "nutrient_levels" : {}, + "nutrient_levels_tags" : [], + "nutriments" : { + "fruits-vegetables-legumes-estimate-from-ingredients_100g" : 62.5, + "fruits-vegetables-legumes-estimate-from-ingredients_serving" : 62.5, + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 62.5, + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 62.5, + "nova-group" : 3, + "nova-group_100g" : 3, + "nova-group_serving" : 3 + }, + "nutriscore" : { + "2021" : { + "category_available" : 1, + "data" : { + "energy" : null, + "fiber" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 62.5, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "proteins" : null, + "saturated_fat" : null, + "sodium" : null, + "sugars" : null + }, + "grade" : "unknown", + "nutrients_available" : 0, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 0 + }, + "2023" : { + "category_available" : 1, + "data" : { + "energy" : null, + "fiber" : 0, + "fruits_vegetables_legumes" : 62.5, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat_oil_nuts_seeds" : 0, + "is_water" : 0, + "proteins" : null, + "salt" : null, + "saturated_fat" : null, + "sugars" : null + }, + "grade" : "unknown", + "nutrients_available" : 0, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 0 + } + }, + "nutriscore_2021_tags" : [ + "unknown" + ], + "nutriscore_2023_tags" : [ + "unknown" + ], + "nutriscore_grade" : "unknown", + "nutriscore_tags" : [ + "unknown" + ], + "nutriscore_version" : "2021", + "nutrition_data_per" : "100g", + "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "unknown", + "nutrition_grades" : "unknown", + "nutrition_grades_tags" : [ + "unknown" + ], + "nutrition_score_beverage" : 0, + "nutrition_score_debug" : "missing energy_100g - missing fat_100g - missing saturated-fat_100g - missing sugars_100g - missing sodium_100g - missing proteins_100g", + "nutrition_score_warning_fruits_vegetables_legumes_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_legumes_estimate_from_ingredients_value" : 62.5, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 62.5, + "nutrition_score_warning_no_fiber" : 1, + "origin" : "france", + "origin_en" : "france", + "other_nutritional_substances_tags" : [], + "packaging_materials_tags" : [ + "en:glass", + "en:plastic", + "en:steel", + "en:wood" + ], + "packaging_recycling_tags" : [ + "en:discard", + "en:recycle", + "en:reuse" + ], + "packaging_shapes_tags" : [ + "en:bottle", + "en:box", + "en:film", + "en:lid" + ], + "packaging_text" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard", + "packaging_text_en" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard", + "packagings" : [ + { + "material" : { + "id" : "en:wood" + }, + "number_of_units" : 1, + "recycling" : { + "id" : "en:recycle" + }, + "shape" : { + "id" : "en:box" + } + }, + { + "material" : { + "id" : "en:glass" + }, + "number_of_units" : 6, + "quantity_per_unit" : "25cl", + "quantity_per_unit_unit" : "cl", + "quantity_per_unit_value" : 25, + "recycling" : { + "id" : "en:reuse" + }, + "shape" : { + "id" : "en:bottle" + } + }, + { + "material" : { + "id" : "en:steel" + }, + "number_of_units" : 3, + "recycling" : { + "id" : "en:recycle" + }, + "shape" : { + "id" : "en:lid" + } + }, + { + "material" : { + "id" : "en:plastic" + }, + "number_of_units" : 1, + "recycling" : { + "id" : "en:discard" + }, + "shape" : { + "id" : "en:film" + } + } + ], + "packagings_materials" : { + "all" : {}, + "en:glass" : {}, + "en:metal" : {}, + "en:plastic" : {}, + "en:unknown" : {} + }, + "packagings_n" : 4, + "photographers_tags" : [], + "pnns_groups_1" : "Sugary snacks", + "pnns_groups_1_tags" : [ + "sugary-snacks", + "known" + ], + "pnns_groups_2" : "Biscuits and cakes", + "pnns_groups_2_tags" : [ + "biscuits-and-cakes", + "known" + ], + "popularity_key" : 0, + "product_name" : "Some product", + "product_name_en" : "Some product", + "product_quantity" : "100", + "quantity" : "100 g", + "removed_countries_tags" : [], + "rev" : 1, + "serving_quantity" : "10", + "serving_size" : "10 g", + "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", + "states_hierarchy" : [ + "en:to-be-completed", + "en:nutrition-facts-to-be-completed", + "en:ingredients-completed", + "en:expiration-date-to-be-completed", + "en:packaging-code-to-be-completed", + "en:characteristics-to-be-completed", + "en:origins-to-be-completed", + "en:categories-completed", + "en:brands-to-be-completed", + "en:packaging-to-be-completed", + "en:quantity-completed", + "en:product-name-completed", + "en:photos-to-be-uploaded" + ], + "states_tags" : [ + "en:to-be-completed", + "en:nutrition-facts-to-be-completed", + "en:ingredients-completed", + "en:expiration-date-to-be-completed", + "en:packaging-code-to-be-completed", + "en:characteristics-to-be-completed", + "en:origins-to-be-completed", + "en:categories-completed", + "en:brands-to-be-completed", + "en:packaging-to-be-completed", + "en:quantity-completed", + "en:product-name-completed", + "en:photos-to-be-uploaded" + ], + "traces" : "", + "traces_from_ingredients" : "", + "traces_from_user" : "(en) ", + "traces_hierarchy" : [], + "traces_tags" : [], + "unknown_ingredients_n" : 0, + "unknown_nutrients_tags" : [], + "vitamins_tags" : [], + "weighers_tags" : [] + }, + "result" : { + "id" : "product_found", + "lc_name" : "Product found", + "name" : "Product found" + }, + "status" : "success_with_warnings", + "warnings" : [ + { + "field" : { + "id" : "code", + "value" : "4260392550101" + }, + "impact" : { + "id" : "none", + "lc_name" : "None", + "name" : "None" + }, + "message" : { + "id" : "different_normalized_product_code", + "lc_name" : "", + "name" : "" + } + } + ] +} diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-fnc1.json b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-fnc1.json new file mode 100644 index 0000000000000..6b1f32a028d85 --- /dev/null +++ b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-fnc1.json @@ -0,0 +1,1014 @@ +{ + "code" : "4260392550101", + "errors" : [], + "product" : { + "_id" : "4260392550101", + "_keywords" : [ + "cookie", + "organic", + "product", + "some", + "tester" + ], + "added_countries_tags" : [], + "additives_n" : 0, + "additives_old_n" : 0, + "additives_old_tags" : [], + "additives_original_tags" : [], + "additives_tags" : [], + "allergens" : "", + "allergens_from_ingredients" : "en:milk, milk, eggs", + "allergens_from_user" : "(en) ", + "allergens_hierarchy" : [ + "en:eggs", + "en:milk" + ], + "allergens_tags" : [ + "en:eggs", + "en:milk" + ], + "amino_acids_tags" : [], + "categories" : "cookies", + "categories_hierarchy" : [ + "en:snacks", + "en:sweet-snacks", + "en:biscuits-and-cakes", + "en:biscuits" + ], + "categories_lc" : "en", + "categories_properties" : { + "agribalyse_proxy_food_code:en" : "24000" + }, + "categories_properties_tags" : [ + "all-products", + "categories-known", + "agribalyse-food-code-unknown", + "agribalyse-proxy-food-code-24000", + "agribalyse-proxy-food-code-known", + "ciqual-food-code-unknown", + "agribalyse-known", + "agribalyse-24000" + ], + "categories_tags" : [ + "en:snacks", + "en:sweet-snacks", + "en:biscuits-and-cakes", + "en:biscuits" + ], + "checkers_tags" : [], + "code" : "4260392550101", + "codes_tags" : [ + "code-13", + "4260392550xxx", + "426039255xxxx", + "42603925xxxxx", + "4260392xxxxxx", + "426039xxxxxxx", + "42603xxxxxxxx", + "4260xxxxxxxxx", + "426xxxxxxxxxx", + "42xxxxxxxxxxx", + "4xxxxxxxxxxxx" + ], + "complete" : 0, + "completeness" : 0.4, + "correctors_tags" : [], + "created_t" : "--ignore--", + "creator" : "tests", + "data_quality_bugs_tags" : [], + "data_quality_errors_tags" : [], + "data_quality_info_tags" : [ + "en:packaging-data-incomplete", + "en:ingredients-percent-analysis-ok", + "en:ecoscore-extended-data-not-computed", + "en:food-groups-1-known", + "en:food-groups-2-known", + "en:food-groups-3-unknown" + ], + "data_quality_tags" : [ + "en:packaging-data-incomplete", + "en:ingredients-percent-analysis-ok", + "en:ecoscore-extended-data-not-computed", + "en:food-groups-1-known", + "en:food-groups-2-known", + "en:food-groups-3-unknown", + "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", + "en:ecoscore-production-system-no-label" + ], + "data_quality_warnings_tags" : [ + "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", + "en:ecoscore-production-system-no-label" + ], + "ecoscore_data" : { + "adjustments" : { + "origins_of_ingredients" : { + "aggregated_origins" : [ + { + "epi_score" : 0, + "origin" : "en:unknown", + "percent" : 100, + "transportation_score" : null + } + ], + "epi_score" : 0, + "epi_value" : -5, + "origins_from_origins_field" : [ + "en:unknown" + ], + "transportation_score" : 0, + "transportation_scores" : { + "ad" : 0, + "al" : 0, + "at" : 0, + "ax" : 0, + "ba" : 0, + "be" : 0, + "bg" : 0, + "ch" : 0, + "cy" : 0, + "cz" : 0, + "de" : 0, + "dk" : 0, + "dz" : 0, + "ee" : 0, + "eg" : 0, + "es" : 0, + "fi" : 0, + "fo" : 0, + "fr" : 0, + "gg" : 0, + "gi" : 0, + "gr" : 0, + "hr" : 0, + "hu" : 0, + "ie" : 0, + "il" : 0, + "im" : 0, + "is" : 0, + "it" : 0, + "je" : 0, + "lb" : 0, + "li" : 0, + "lt" : 0, + "lu" : 0, + "lv" : 0, + "ly" : 0, + "ma" : 0, + "mc" : 0, + "md" : 0, + "me" : 0, + "mk" : 0, + "mt" : 0, + "nl" : 0, + "no" : 0, + "pl" : 0, + "ps" : 0, + "pt" : 0, + "ro" : 0, + "rs" : 0, + "se" : 0, + "si" : 0, + "sj" : 0, + "sk" : 0, + "sm" : 0, + "sy" : 0, + "tn" : 0, + "tr" : 0, + "ua" : 0, + "uk" : 0, + "us" : 0, + "va" : 0, + "world" : 0, + "xk" : 0 + }, + "transportation_value" : 0, + "transportation_values" : { + "ad" : 0, + "al" : 0, + "at" : 0, + "ax" : 0, + "ba" : 0, + "be" : 0, + "bg" : 0, + "ch" : 0, + "cy" : 0, + "cz" : 0, + "de" : 0, + "dk" : 0, + "dz" : 0, + "ee" : 0, + "eg" : 0, + "es" : 0, + "fi" : 0, + "fo" : 0, + "fr" : 0, + "gg" : 0, + "gi" : 0, + "gr" : 0, + "hr" : 0, + "hu" : 0, + "ie" : 0, + "il" : 0, + "im" : 0, + "is" : 0, + "it" : 0, + "je" : 0, + "lb" : 0, + "li" : 0, + "lt" : 0, + "lu" : 0, + "lv" : 0, + "ly" : 0, + "ma" : 0, + "mc" : 0, + "md" : 0, + "me" : 0, + "mk" : 0, + "mt" : 0, + "nl" : 0, + "no" : 0, + "pl" : 0, + "ps" : 0, + "pt" : 0, + "ro" : 0, + "rs" : 0, + "se" : 0, + "si" : 0, + "sj" : 0, + "sk" : 0, + "sm" : 0, + "sy" : 0, + "tn" : 0, + "tr" : 0, + "ua" : 0, + "uk" : 0, + "us" : 0, + "va" : 0, + "world" : 0, + "xk" : 0 + }, + "value" : -5, + "values" : { + "ad" : -5, + "al" : -5, + "at" : -5, + "ax" : -5, + "ba" : -5, + "be" : -5, + "bg" : -5, + "ch" : -5, + "cy" : -5, + "cz" : -5, + "de" : -5, + "dk" : -5, + "dz" : -5, + "ee" : -5, + "eg" : -5, + "es" : -5, + "fi" : -5, + "fo" : -5, + "fr" : -5, + "gg" : -5, + "gi" : -5, + "gr" : -5, + "hr" : -5, + "hu" : -5, + "ie" : -5, + "il" : -5, + "im" : -5, + "is" : -5, + "it" : -5, + "je" : -5, + "lb" : -5, + "li" : -5, + "lt" : -5, + "lu" : -5, + "lv" : -5, + "ly" : -5, + "ma" : -5, + "mc" : -5, + "md" : -5, + "me" : -5, + "mk" : -5, + "mt" : -5, + "nl" : -5, + "no" : -5, + "pl" : -5, + "ps" : -5, + "pt" : -5, + "ro" : -5, + "rs" : -5, + "se" : -5, + "si" : -5, + "sj" : -5, + "sk" : -5, + "sm" : -5, + "sy" : -5, + "tn" : -5, + "tr" : -5, + "ua" : -5, + "uk" : -5, + "us" : -5, + "va" : -5, + "world" : -5, + "xk" : -5 + }, + "warning" : "origins_are_100_percent_unknown" + }, + "packaging" : { + "non_recyclable_and_non_biodegradable_materials" : 0, + "packagings" : [ + { + "ecoscore_material_score" : 50, + "ecoscore_shape_ratio" : 1, + "material" : "en:wood", + "number_of_units" : 1, + "recycling" : "en:recycle", + "shape" : "en:box" + }, + { + "ecoscore_material_score" : 81, + "ecoscore_shape_ratio" : 1, + "material" : "en:glass", + "number_of_units" : 6, + "quantity_per_unit" : "25cl", + "quantity_per_unit_unit" : "cl", + "quantity_per_unit_value" : 25, + "recycling" : "en:reuse", + "shape" : "en:bottle" + }, + { + "ecoscore_material_score" : 76, + "ecoscore_shape_ratio" : 0.2, + "material" : "en:steel", + "number_of_units" : 3, + "recycling" : "en:recycle", + "shape" : "en:lid" + }, + { + "ecoscore_material_score" : 0, + "ecoscore_shape_ratio" : 0.1, + "material" : "en:plastic", + "non_recyclable_and_non_biodegradable" : "maybe", + "number_of_units" : 1, + "recycling" : "en:discard", + "shape" : "en:film" + } + ], + "score" : 16.2, + "value" : -8 + }, + "production_system" : { + "labels" : [], + "value" : 0, + "warning" : "no_label" + }, + "threatened_species" : { + "ingredient" : "en:palm-oil", + "value" : -10 + } + }, + "agribalyse" : { + "agribalyse_proxy_food_code" : "24000", + "co2_agriculture" : 2.3889426, + "co2_consumption" : 0, + "co2_distribution" : 0.019530673, + "co2_packaging" : 0.11014808, + "co2_processing" : 0.22878446, + "co2_total" : 2.882859363, + "co2_transportation" : 0.13545355, + "code" : "24000", + "dqr" : "2.14", + "ef_agriculture" : 0.28329233, + "ef_consumption" : 0, + "ef_distribution" : 0.0048315303, + "ef_packaging" : 0.01096965, + "ef_processing" : 0.041686082, + "ef_total" : 0.3518903043, + "ef_transportation" : 0.011110712, + "is_beverage" : 0, + "name_en" : "Biscuit (cookie)", + "name_fr" : "Biscuit sec, sans précision", + "score" : 69, + "version" : "3.1" + }, + "grade" : "c", + "grades" : { + "ad" : "c", + "al" : "c", + "at" : "c", + "ax" : "c", + "ba" : "c", + "be" : "c", + "bg" : "c", + "ch" : "c", + "cy" : "c", + "cz" : "c", + "de" : "c", + "dk" : "c", + "dz" : "c", + "ee" : "c", + "eg" : "c", + "es" : "c", + "fi" : "c", + "fo" : "c", + "fr" : "c", + "gg" : "c", + "gi" : "c", + "gr" : "c", + "hr" : "c", + "hu" : "c", + "ie" : "c", + "il" : "c", + "im" : "c", + "is" : "c", + "it" : "c", + "je" : "c", + "lb" : "c", + "li" : "c", + "lt" : "c", + "lu" : "c", + "lv" : "c", + "ly" : "c", + "ma" : "c", + "mc" : "c", + "md" : "c", + "me" : "c", + "mk" : "c", + "mt" : "c", + "nl" : "c", + "no" : "c", + "pl" : "c", + "ps" : "c", + "pt" : "c", + "ro" : "c", + "rs" : "c", + "se" : "c", + "si" : "c", + "sj" : "c", + "sk" : "c", + "sm" : "c", + "sy" : "c", + "tn" : "c", + "tr" : "c", + "ua" : "c", + "uk" : "c", + "us" : "c", + "va" : "c", + "world" : "c", + "xk" : "c" + }, + "missing" : { + "labels" : 1, + "origins" : 1 + }, + "missing_data_warning" : 1, + "score" : 46, + "scores" : { + "ad" : 46, + "al" : 46, + "at" : 46, + "ax" : 46, + "ba" : 46, + "be" : 46, + "bg" : 46, + "ch" : 46, + "cy" : 46, + "cz" : 46, + "de" : 46, + "dk" : 46, + "dz" : 46, + "ee" : 46, + "eg" : 46, + "es" : 46, + "fi" : 46, + "fo" : 46, + "fr" : 46, + "gg" : 46, + "gi" : 46, + "gr" : 46, + "hr" : 46, + "hu" : 46, + "ie" : 46, + "il" : 46, + "im" : 46, + "is" : 46, + "it" : 46, + "je" : 46, + "lb" : 46, + "li" : 46, + "lt" : 46, + "lu" : 46, + "lv" : 46, + "ly" : 46, + "ma" : 46, + "mc" : 46, + "md" : 46, + "me" : 46, + "mk" : 46, + "mt" : 46, + "nl" : 46, + "no" : 46, + "pl" : 46, + "ps" : 46, + "pt" : 46, + "ro" : 46, + "rs" : 46, + "se" : 46, + "si" : 46, + "sj" : 46, + "sk" : 46, + "sm" : 46, + "sy" : 46, + "tn" : 46, + "tr" : 46, + "ua" : 46, + "uk" : 46, + "us" : 46, + "va" : 46, + "world" : 46, + "xk" : 46 + }, + "status" : "known" + }, + "ecoscore_grade" : "c", + "ecoscore_score" : 46, + "ecoscore_tags" : [ + "c" + ], + "editors_tags" : [ + "tests" + ], + "entry_dates_tags" : "--ignore--", + "food_groups" : "en:biscuits-and-cakes", + "food_groups_tags" : [ + "en:sugary-snacks", + "en:biscuits-and-cakes" + ], + "forest_footprint_data" : { + "footprint_per_kg" : 0.00145833333333333, + "grade" : "a", + "ingredients" : [ + { + "conditions_tags" : [ + [ + "labels", + "en:organic" + ] + ], + "footprint_per_kg" : 0.00145833333333333, + "matching_tag_id" : "en:egg", + "percent" : 9.375, + "percent_estimate" : 9.375, + "processing_factor" : 1, + "tag_id" : "en:egg", + "tag_type" : "ingredients", + "type" : { + "deforestation_risk" : 0.1, + "name" : "Oeufs Bio", + "soy_feed_factor" : 0.028, + "soy_yield" : 0.18 + } + } + ] + }, + "generic_name" : "Tester", + "generic_name_en" : "Tester", + "id" : "4260392550101", + "informers_tags" : [ + "tests" + ], + "ingredients" : [ + { + "ciqual_food_code" : "13050", + "id" : "en:apple", + "percent_estimate" : 62.5, + "percent_max" : 100, + "percent_min" : 25, + "text" : "apple", + "vegan" : "yes", + "vegetarian" : "yes" + }, + { + "id" : "en:milk", + "percent_estimate" : 18.75, + "percent_max" : 50, + "percent_min" : 0, + "text" : "milk", + "vegan" : "no", + "vegetarian" : "yes" + }, + { + "ciqual_food_code" : "22000", + "id" : "en:egg", + "percent_estimate" : 9.375, + "percent_max" : 33.3333333333333, + "percent_min" : 0, + "text" : "eggs", + "vegan" : "no", + "vegetarian" : "yes" + }, + { + "ciqual_food_code" : "16129", + "from_palm_oil" : "yes", + "id" : "en:palm-oil", + "percent_estimate" : 9.375, + "percent_max" : 25, + "percent_min" : 0, + "text" : "palm oil", + "vegan" : "yes", + "vegetarian" : "yes" + } + ], + "ingredients_analysis" : { + "en:non-vegan" : [ + "en:milk", + "en:egg" + ], + "en:palm-oil" : [ + "en:palm-oil" + ] + }, + "ingredients_analysis_tags" : [ + "en:palm-oil", + "en:non-vegan", + "en:vegetarian" + ], + "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_tags" : [], + "ingredients_hierarchy" : [ + "en:apple", + "en:fruit", + "en:malaceous-fruit", + "en:milk", + "en:dairy", + "en:egg", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" + ], + "ingredients_lc" : "en", + "ingredients_n" : 4, + "ingredients_n_tags" : [ + "4", + "1-10" + ], + "ingredients_original_tags" : [ + "en:apple", + "en:milk", + "en:egg", + "en:palm-oil" + ], + "ingredients_percent_analysis" : 1, + "ingredients_tags" : [ + "en:apple", + "en:fruit", + "en:malaceous-fruit", + "en:milk", + "en:dairy", + "en:egg", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" + ], + "ingredients_text" : "apple, milk, eggs, palm oil", + "ingredients_text_en" : "apple, milk, eggs, palm oil", + "ingredients_text_with_allergens" : "apple, milk, eggs, palm oil", + "ingredients_text_with_allergens_en" : "apple, milk, eggs, palm oil", + "ingredients_that_may_be_from_palm_oil_n" : 0, + "ingredients_that_may_be_from_palm_oil_tags" : [], + "ingredients_with_specified_percent_n" : 0, + "ingredients_with_specified_percent_sum" : 0, + "ingredients_with_unspecified_percent_n" : 4, + "ingredients_with_unspecified_percent_sum" : 100, + "ingredients_without_ciqual_codes" : [ + "en:milk" + ], + "ingredients_without_ciqual_codes_n" : 1, + "interface_version_created" : "20150316.jqm2", + "interface_version_modified" : "20150316.jqm2", + "known_ingredients_n" : 10, + "labels" : "organic", + "labels_hierarchy" : [ + "en:organic" + ], + "labels_lc" : "en", + "labels_tags" : [ + "en:organic" + ], + "lang" : "en", + "languages" : { + "en:english" : 5 + }, + "languages_codes" : { + "en" : 5 + }, + "languages_hierarchy" : [ + "en:english" + ], + "languages_tags" : [ + "en:english", + "en:1" + ], + "last_edit_dates_tags" : "--ignore--", + "last_editor" : "tests", + "last_modified_by" : "tests", + "last_modified_t" : "--ignore--", + "lc" : "en", + "link" : "http://world.openfoodfacts.org/", + "main_countries_tags" : [], + "minerals_tags" : [], + "misc_tags" : [ + "en:nutrition-not-enough-data-to-compute-nutrition-score", + "en:nutriscore-missing-nutrition-data", + "en:nutriscore-missing-nutrition-data-energy", + "en:nutriscore-missing-nutrition-data-fat", + "en:nutriscore-missing-nutrition-data-saturated-fat", + "en:nutriscore-missing-nutrition-data-sugars", + "en:nutriscore-missing-nutrition-data-sodium", + "en:nutriscore-missing-nutrition-data-proteins", + "en:nutrition-no-fiber", + "en:nutriscore-not-computed", + "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", + "en:nutrition-no-fiber-or-fruits-vegetables-nuts", + "en:nutrition-fruits-vegetables-legumes-estimate-from-ingredients", + "en:packagings-number-of-components-4", + "en:packagings-not-complete", + "en:packagings-not-empty-but-not-complete", + "en:packagings-not-empty", + "en:ecoscore-extended-data-not-computed", + "en:ecoscore-missing-data-warning", + "en:ecoscore-missing-data-labels", + "en:ecoscore-missing-data-origins", + "en:ecoscore-computed", + "en:ecoscore-changed", + "en:ecoscore-grade-changed", + "en:forest-footprint-computed", + "en:forest-footprint-a", + "en:main-countries-new-product" + ], + "nova_group" : 3, + "nova_group_debug" : "", + "nova_groups" : "3", + "nova_groups_markers" : { + "3" : [ + [ + "categories", + "en:sweet-snacks" + ] + ] + }, + "nova_groups_tags" : [ + "en:3-processed-foods" + ], + "nucleotides_tags" : [], + "nutrient_levels" : {}, + "nutrient_levels_tags" : [], + "nutriments" : { + "fruits-vegetables-legumes-estimate-from-ingredients_100g" : 62.5, + "fruits-vegetables-legumes-estimate-from-ingredients_serving" : 62.5, + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 62.5, + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 62.5, + "nova-group" : 3, + "nova-group_100g" : 3, + "nova-group_serving" : 3 + }, + "nutriscore" : { + "2021" : { + "category_available" : 1, + "data" : { + "energy" : null, + "fiber" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 62.5, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "proteins" : null, + "saturated_fat" : null, + "sodium" : null, + "sugars" : null + }, + "grade" : "unknown", + "nutrients_available" : 0, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 0 + }, + "2023" : { + "category_available" : 1, + "data" : { + "energy" : null, + "fiber" : 0, + "fruits_vegetables_legumes" : 62.5, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat_oil_nuts_seeds" : 0, + "is_water" : 0, + "proteins" : null, + "salt" : null, + "saturated_fat" : null, + "sugars" : null + }, + "grade" : "unknown", + "nutrients_available" : 0, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 0 + } + }, + "nutriscore_2021_tags" : [ + "unknown" + ], + "nutriscore_2023_tags" : [ + "unknown" + ], + "nutriscore_grade" : "unknown", + "nutriscore_tags" : [ + "unknown" + ], + "nutriscore_version" : "2021", + "nutrition_data_per" : "100g", + "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "unknown", + "nutrition_grades" : "unknown", + "nutrition_grades_tags" : [ + "unknown" + ], + "nutrition_score_beverage" : 0, + "nutrition_score_debug" : "missing energy_100g - missing fat_100g - missing saturated-fat_100g - missing sugars_100g - missing sodium_100g - missing proteins_100g", + "nutrition_score_warning_fruits_vegetables_legumes_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_legumes_estimate_from_ingredients_value" : 62.5, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 62.5, + "nutrition_score_warning_no_fiber" : 1, + "origin" : "france", + "origin_en" : "france", + "other_nutritional_substances_tags" : [], + "packaging_materials_tags" : [ + "en:glass", + "en:plastic", + "en:steel", + "en:wood" + ], + "packaging_recycling_tags" : [ + "en:discard", + "en:recycle", + "en:reuse" + ], + "packaging_shapes_tags" : [ + "en:bottle", + "en:box", + "en:film", + "en:lid" + ], + "packaging_text" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard", + "packaging_text_en" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard", + "packagings" : [ + { + "material" : { + "id" : "en:wood" + }, + "number_of_units" : 1, + "recycling" : { + "id" : "en:recycle" + }, + "shape" : { + "id" : "en:box" + } + }, + { + "material" : { + "id" : "en:glass" + }, + "number_of_units" : 6, + "quantity_per_unit" : "25cl", + "quantity_per_unit_unit" : "cl", + "quantity_per_unit_value" : 25, + "recycling" : { + "id" : "en:reuse" + }, + "shape" : { + "id" : "en:bottle" + } + }, + { + "material" : { + "id" : "en:steel" + }, + "number_of_units" : 3, + "recycling" : { + "id" : "en:recycle" + }, + "shape" : { + "id" : "en:lid" + } + }, + { + "material" : { + "id" : "en:plastic" + }, + "number_of_units" : 1, + "recycling" : { + "id" : "en:discard" + }, + "shape" : { + "id" : "en:film" + } + } + ], + "packagings_materials" : { + "all" : {}, + "en:glass" : {}, + "en:metal" : {}, + "en:plastic" : {}, + "en:unknown" : {} + }, + "packagings_n" : 4, + "photographers_tags" : [], + "pnns_groups_1" : "Sugary snacks", + "pnns_groups_1_tags" : [ + "sugary-snacks", + "known" + ], + "pnns_groups_2" : "Biscuits and cakes", + "pnns_groups_2_tags" : [ + "biscuits-and-cakes", + "known" + ], + "popularity_key" : 0, + "product_name" : "Some product", + "product_name_en" : "Some product", + "product_quantity" : "100", + "quantity" : "100 g", + "removed_countries_tags" : [], + "rev" : 1, + "serving_quantity" : "10", + "serving_size" : "10 g", + "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", + "states_hierarchy" : [ + "en:to-be-completed", + "en:nutrition-facts-to-be-completed", + "en:ingredients-completed", + "en:expiration-date-to-be-completed", + "en:packaging-code-to-be-completed", + "en:characteristics-to-be-completed", + "en:origins-to-be-completed", + "en:categories-completed", + "en:brands-to-be-completed", + "en:packaging-to-be-completed", + "en:quantity-completed", + "en:product-name-completed", + "en:photos-to-be-uploaded" + ], + "states_tags" : [ + "en:to-be-completed", + "en:nutrition-facts-to-be-completed", + "en:ingredients-completed", + "en:expiration-date-to-be-completed", + "en:packaging-code-to-be-completed", + "en:characteristics-to-be-completed", + "en:origins-to-be-completed", + "en:categories-completed", + "en:brands-to-be-completed", + "en:packaging-to-be-completed", + "en:quantity-completed", + "en:product-name-completed", + "en:photos-to-be-uploaded" + ], + "traces" : "", + "traces_from_ingredients" : "", + "traces_from_user" : "(en) ", + "traces_hierarchy" : [], + "traces_tags" : [], + "unknown_ingredients_n" : 0, + "unknown_nutrients_tags" : [], + "vitamins_tags" : [], + "weighers_tags" : [] + }, + "result" : { + "id" : "product_found", + "lc_name" : "Product found", + "name" : "Product found" + }, + "status" : "success_with_warnings", + "warnings" : [ + { + "field" : { + "id" : "code", + "value" : "4260392550101" + }, + "impact" : { + "id" : "none", + "lc_name" : "None", + "name" : "None" + }, + "message" : { + "id" : "different_normalized_product_code", + "lc_name" : "", + "name" : "" + } + } + ] +} diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-gs.json b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-gs.json new file mode 100644 index 0000000000000..6b1f32a028d85 --- /dev/null +++ b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product-gs1-gs.json @@ -0,0 +1,1014 @@ +{ + "code" : "4260392550101", + "errors" : [], + "product" : { + "_id" : "4260392550101", + "_keywords" : [ + "cookie", + "organic", + "product", + "some", + "tester" + ], + "added_countries_tags" : [], + "additives_n" : 0, + "additives_old_n" : 0, + "additives_old_tags" : [], + "additives_original_tags" : [], + "additives_tags" : [], + "allergens" : "", + "allergens_from_ingredients" : "en:milk, milk, eggs", + "allergens_from_user" : "(en) ", + "allergens_hierarchy" : [ + "en:eggs", + "en:milk" + ], + "allergens_tags" : [ + "en:eggs", + "en:milk" + ], + "amino_acids_tags" : [], + "categories" : "cookies", + "categories_hierarchy" : [ + "en:snacks", + "en:sweet-snacks", + "en:biscuits-and-cakes", + "en:biscuits" + ], + "categories_lc" : "en", + "categories_properties" : { + "agribalyse_proxy_food_code:en" : "24000" + }, + "categories_properties_tags" : [ + "all-products", + "categories-known", + "agribalyse-food-code-unknown", + "agribalyse-proxy-food-code-24000", + "agribalyse-proxy-food-code-known", + "ciqual-food-code-unknown", + "agribalyse-known", + "agribalyse-24000" + ], + "categories_tags" : [ + "en:snacks", + "en:sweet-snacks", + "en:biscuits-and-cakes", + "en:biscuits" + ], + "checkers_tags" : [], + "code" : "4260392550101", + "codes_tags" : [ + "code-13", + "4260392550xxx", + "426039255xxxx", + "42603925xxxxx", + "4260392xxxxxx", + "426039xxxxxxx", + "42603xxxxxxxx", + "4260xxxxxxxxx", + "426xxxxxxxxxx", + "42xxxxxxxxxxx", + "4xxxxxxxxxxxx" + ], + "complete" : 0, + "completeness" : 0.4, + "correctors_tags" : [], + "created_t" : "--ignore--", + "creator" : "tests", + "data_quality_bugs_tags" : [], + "data_quality_errors_tags" : [], + "data_quality_info_tags" : [ + "en:packaging-data-incomplete", + "en:ingredients-percent-analysis-ok", + "en:ecoscore-extended-data-not-computed", + "en:food-groups-1-known", + "en:food-groups-2-known", + "en:food-groups-3-unknown" + ], + "data_quality_tags" : [ + "en:packaging-data-incomplete", + "en:ingredients-percent-analysis-ok", + "en:ecoscore-extended-data-not-computed", + "en:food-groups-1-known", + "en:food-groups-2-known", + "en:food-groups-3-unknown", + "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", + "en:ecoscore-production-system-no-label" + ], + "data_quality_warnings_tags" : [ + "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", + "en:ecoscore-production-system-no-label" + ], + "ecoscore_data" : { + "adjustments" : { + "origins_of_ingredients" : { + "aggregated_origins" : [ + { + "epi_score" : 0, + "origin" : "en:unknown", + "percent" : 100, + "transportation_score" : null + } + ], + "epi_score" : 0, + "epi_value" : -5, + "origins_from_origins_field" : [ + "en:unknown" + ], + "transportation_score" : 0, + "transportation_scores" : { + "ad" : 0, + "al" : 0, + "at" : 0, + "ax" : 0, + "ba" : 0, + "be" : 0, + "bg" : 0, + "ch" : 0, + "cy" : 0, + "cz" : 0, + "de" : 0, + "dk" : 0, + "dz" : 0, + "ee" : 0, + "eg" : 0, + "es" : 0, + "fi" : 0, + "fo" : 0, + "fr" : 0, + "gg" : 0, + "gi" : 0, + "gr" : 0, + "hr" : 0, + "hu" : 0, + "ie" : 0, + "il" : 0, + "im" : 0, + "is" : 0, + "it" : 0, + "je" : 0, + "lb" : 0, + "li" : 0, + "lt" : 0, + "lu" : 0, + "lv" : 0, + "ly" : 0, + "ma" : 0, + "mc" : 0, + "md" : 0, + "me" : 0, + "mk" : 0, + "mt" : 0, + "nl" : 0, + "no" : 0, + "pl" : 0, + "ps" : 0, + "pt" : 0, + "ro" : 0, + "rs" : 0, + "se" : 0, + "si" : 0, + "sj" : 0, + "sk" : 0, + "sm" : 0, + "sy" : 0, + "tn" : 0, + "tr" : 0, + "ua" : 0, + "uk" : 0, + "us" : 0, + "va" : 0, + "world" : 0, + "xk" : 0 + }, + "transportation_value" : 0, + "transportation_values" : { + "ad" : 0, + "al" : 0, + "at" : 0, + "ax" : 0, + "ba" : 0, + "be" : 0, + "bg" : 0, + "ch" : 0, + "cy" : 0, + "cz" : 0, + "de" : 0, + "dk" : 0, + "dz" : 0, + "ee" : 0, + "eg" : 0, + "es" : 0, + "fi" : 0, + "fo" : 0, + "fr" : 0, + "gg" : 0, + "gi" : 0, + "gr" : 0, + "hr" : 0, + "hu" : 0, + "ie" : 0, + "il" : 0, + "im" : 0, + "is" : 0, + "it" : 0, + "je" : 0, + "lb" : 0, + "li" : 0, + "lt" : 0, + "lu" : 0, + "lv" : 0, + "ly" : 0, + "ma" : 0, + "mc" : 0, + "md" : 0, + "me" : 0, + "mk" : 0, + "mt" : 0, + "nl" : 0, + "no" : 0, + "pl" : 0, + "ps" : 0, + "pt" : 0, + "ro" : 0, + "rs" : 0, + "se" : 0, + "si" : 0, + "sj" : 0, + "sk" : 0, + "sm" : 0, + "sy" : 0, + "tn" : 0, + "tr" : 0, + "ua" : 0, + "uk" : 0, + "us" : 0, + "va" : 0, + "world" : 0, + "xk" : 0 + }, + "value" : -5, + "values" : { + "ad" : -5, + "al" : -5, + "at" : -5, + "ax" : -5, + "ba" : -5, + "be" : -5, + "bg" : -5, + "ch" : -5, + "cy" : -5, + "cz" : -5, + "de" : -5, + "dk" : -5, + "dz" : -5, + "ee" : -5, + "eg" : -5, + "es" : -5, + "fi" : -5, + "fo" : -5, + "fr" : -5, + "gg" : -5, + "gi" : -5, + "gr" : -5, + "hr" : -5, + "hu" : -5, + "ie" : -5, + "il" : -5, + "im" : -5, + "is" : -5, + "it" : -5, + "je" : -5, + "lb" : -5, + "li" : -5, + "lt" : -5, + "lu" : -5, + "lv" : -5, + "ly" : -5, + "ma" : -5, + "mc" : -5, + "md" : -5, + "me" : -5, + "mk" : -5, + "mt" : -5, + "nl" : -5, + "no" : -5, + "pl" : -5, + "ps" : -5, + "pt" : -5, + "ro" : -5, + "rs" : -5, + "se" : -5, + "si" : -5, + "sj" : -5, + "sk" : -5, + "sm" : -5, + "sy" : -5, + "tn" : -5, + "tr" : -5, + "ua" : -5, + "uk" : -5, + "us" : -5, + "va" : -5, + "world" : -5, + "xk" : -5 + }, + "warning" : "origins_are_100_percent_unknown" + }, + "packaging" : { + "non_recyclable_and_non_biodegradable_materials" : 0, + "packagings" : [ + { + "ecoscore_material_score" : 50, + "ecoscore_shape_ratio" : 1, + "material" : "en:wood", + "number_of_units" : 1, + "recycling" : "en:recycle", + "shape" : "en:box" + }, + { + "ecoscore_material_score" : 81, + "ecoscore_shape_ratio" : 1, + "material" : "en:glass", + "number_of_units" : 6, + "quantity_per_unit" : "25cl", + "quantity_per_unit_unit" : "cl", + "quantity_per_unit_value" : 25, + "recycling" : "en:reuse", + "shape" : "en:bottle" + }, + { + "ecoscore_material_score" : 76, + "ecoscore_shape_ratio" : 0.2, + "material" : "en:steel", + "number_of_units" : 3, + "recycling" : "en:recycle", + "shape" : "en:lid" + }, + { + "ecoscore_material_score" : 0, + "ecoscore_shape_ratio" : 0.1, + "material" : "en:plastic", + "non_recyclable_and_non_biodegradable" : "maybe", + "number_of_units" : 1, + "recycling" : "en:discard", + "shape" : "en:film" + } + ], + "score" : 16.2, + "value" : -8 + }, + "production_system" : { + "labels" : [], + "value" : 0, + "warning" : "no_label" + }, + "threatened_species" : { + "ingredient" : "en:palm-oil", + "value" : -10 + } + }, + "agribalyse" : { + "agribalyse_proxy_food_code" : "24000", + "co2_agriculture" : 2.3889426, + "co2_consumption" : 0, + "co2_distribution" : 0.019530673, + "co2_packaging" : 0.11014808, + "co2_processing" : 0.22878446, + "co2_total" : 2.882859363, + "co2_transportation" : 0.13545355, + "code" : "24000", + "dqr" : "2.14", + "ef_agriculture" : 0.28329233, + "ef_consumption" : 0, + "ef_distribution" : 0.0048315303, + "ef_packaging" : 0.01096965, + "ef_processing" : 0.041686082, + "ef_total" : 0.3518903043, + "ef_transportation" : 0.011110712, + "is_beverage" : 0, + "name_en" : "Biscuit (cookie)", + "name_fr" : "Biscuit sec, sans précision", + "score" : 69, + "version" : "3.1" + }, + "grade" : "c", + "grades" : { + "ad" : "c", + "al" : "c", + "at" : "c", + "ax" : "c", + "ba" : "c", + "be" : "c", + "bg" : "c", + "ch" : "c", + "cy" : "c", + "cz" : "c", + "de" : "c", + "dk" : "c", + "dz" : "c", + "ee" : "c", + "eg" : "c", + "es" : "c", + "fi" : "c", + "fo" : "c", + "fr" : "c", + "gg" : "c", + "gi" : "c", + "gr" : "c", + "hr" : "c", + "hu" : "c", + "ie" : "c", + "il" : "c", + "im" : "c", + "is" : "c", + "it" : "c", + "je" : "c", + "lb" : "c", + "li" : "c", + "lt" : "c", + "lu" : "c", + "lv" : "c", + "ly" : "c", + "ma" : "c", + "mc" : "c", + "md" : "c", + "me" : "c", + "mk" : "c", + "mt" : "c", + "nl" : "c", + "no" : "c", + "pl" : "c", + "ps" : "c", + "pt" : "c", + "ro" : "c", + "rs" : "c", + "se" : "c", + "si" : "c", + "sj" : "c", + "sk" : "c", + "sm" : "c", + "sy" : "c", + "tn" : "c", + "tr" : "c", + "ua" : "c", + "uk" : "c", + "us" : "c", + "va" : "c", + "world" : "c", + "xk" : "c" + }, + "missing" : { + "labels" : 1, + "origins" : 1 + }, + "missing_data_warning" : 1, + "score" : 46, + "scores" : { + "ad" : 46, + "al" : 46, + "at" : 46, + "ax" : 46, + "ba" : 46, + "be" : 46, + "bg" : 46, + "ch" : 46, + "cy" : 46, + "cz" : 46, + "de" : 46, + "dk" : 46, + "dz" : 46, + "ee" : 46, + "eg" : 46, + "es" : 46, + "fi" : 46, + "fo" : 46, + "fr" : 46, + "gg" : 46, + "gi" : 46, + "gr" : 46, + "hr" : 46, + "hu" : 46, + "ie" : 46, + "il" : 46, + "im" : 46, + "is" : 46, + "it" : 46, + "je" : 46, + "lb" : 46, + "li" : 46, + "lt" : 46, + "lu" : 46, + "lv" : 46, + "ly" : 46, + "ma" : 46, + "mc" : 46, + "md" : 46, + "me" : 46, + "mk" : 46, + "mt" : 46, + "nl" : 46, + "no" : 46, + "pl" : 46, + "ps" : 46, + "pt" : 46, + "ro" : 46, + "rs" : 46, + "se" : 46, + "si" : 46, + "sj" : 46, + "sk" : 46, + "sm" : 46, + "sy" : 46, + "tn" : 46, + "tr" : 46, + "ua" : 46, + "uk" : 46, + "us" : 46, + "va" : 46, + "world" : 46, + "xk" : 46 + }, + "status" : "known" + }, + "ecoscore_grade" : "c", + "ecoscore_score" : 46, + "ecoscore_tags" : [ + "c" + ], + "editors_tags" : [ + "tests" + ], + "entry_dates_tags" : "--ignore--", + "food_groups" : "en:biscuits-and-cakes", + "food_groups_tags" : [ + "en:sugary-snacks", + "en:biscuits-and-cakes" + ], + "forest_footprint_data" : { + "footprint_per_kg" : 0.00145833333333333, + "grade" : "a", + "ingredients" : [ + { + "conditions_tags" : [ + [ + "labels", + "en:organic" + ] + ], + "footprint_per_kg" : 0.00145833333333333, + "matching_tag_id" : "en:egg", + "percent" : 9.375, + "percent_estimate" : 9.375, + "processing_factor" : 1, + "tag_id" : "en:egg", + "tag_type" : "ingredients", + "type" : { + "deforestation_risk" : 0.1, + "name" : "Oeufs Bio", + "soy_feed_factor" : 0.028, + "soy_yield" : 0.18 + } + } + ] + }, + "generic_name" : "Tester", + "generic_name_en" : "Tester", + "id" : "4260392550101", + "informers_tags" : [ + "tests" + ], + "ingredients" : [ + { + "ciqual_food_code" : "13050", + "id" : "en:apple", + "percent_estimate" : 62.5, + "percent_max" : 100, + "percent_min" : 25, + "text" : "apple", + "vegan" : "yes", + "vegetarian" : "yes" + }, + { + "id" : "en:milk", + "percent_estimate" : 18.75, + "percent_max" : 50, + "percent_min" : 0, + "text" : "milk", + "vegan" : "no", + "vegetarian" : "yes" + }, + { + "ciqual_food_code" : "22000", + "id" : "en:egg", + "percent_estimate" : 9.375, + "percent_max" : 33.3333333333333, + "percent_min" : 0, + "text" : "eggs", + "vegan" : "no", + "vegetarian" : "yes" + }, + { + "ciqual_food_code" : "16129", + "from_palm_oil" : "yes", + "id" : "en:palm-oil", + "percent_estimate" : 9.375, + "percent_max" : 25, + "percent_min" : 0, + "text" : "palm oil", + "vegan" : "yes", + "vegetarian" : "yes" + } + ], + "ingredients_analysis" : { + "en:non-vegan" : [ + "en:milk", + "en:egg" + ], + "en:palm-oil" : [ + "en:palm-oil" + ] + }, + "ingredients_analysis_tags" : [ + "en:palm-oil", + "en:non-vegan", + "en:vegetarian" + ], + "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_tags" : [], + "ingredients_hierarchy" : [ + "en:apple", + "en:fruit", + "en:malaceous-fruit", + "en:milk", + "en:dairy", + "en:egg", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" + ], + "ingredients_lc" : "en", + "ingredients_n" : 4, + "ingredients_n_tags" : [ + "4", + "1-10" + ], + "ingredients_original_tags" : [ + "en:apple", + "en:milk", + "en:egg", + "en:palm-oil" + ], + "ingredients_percent_analysis" : 1, + "ingredients_tags" : [ + "en:apple", + "en:fruit", + "en:malaceous-fruit", + "en:milk", + "en:dairy", + "en:egg", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" + ], + "ingredients_text" : "apple, milk, eggs, palm oil", + "ingredients_text_en" : "apple, milk, eggs, palm oil", + "ingredients_text_with_allergens" : "apple, milk, eggs, palm oil", + "ingredients_text_with_allergens_en" : "apple, milk, eggs, palm oil", + "ingredients_that_may_be_from_palm_oil_n" : 0, + "ingredients_that_may_be_from_palm_oil_tags" : [], + "ingredients_with_specified_percent_n" : 0, + "ingredients_with_specified_percent_sum" : 0, + "ingredients_with_unspecified_percent_n" : 4, + "ingredients_with_unspecified_percent_sum" : 100, + "ingredients_without_ciqual_codes" : [ + "en:milk" + ], + "ingredients_without_ciqual_codes_n" : 1, + "interface_version_created" : "20150316.jqm2", + "interface_version_modified" : "20150316.jqm2", + "known_ingredients_n" : 10, + "labels" : "organic", + "labels_hierarchy" : [ + "en:organic" + ], + "labels_lc" : "en", + "labels_tags" : [ + "en:organic" + ], + "lang" : "en", + "languages" : { + "en:english" : 5 + }, + "languages_codes" : { + "en" : 5 + }, + "languages_hierarchy" : [ + "en:english" + ], + "languages_tags" : [ + "en:english", + "en:1" + ], + "last_edit_dates_tags" : "--ignore--", + "last_editor" : "tests", + "last_modified_by" : "tests", + "last_modified_t" : "--ignore--", + "lc" : "en", + "link" : "http://world.openfoodfacts.org/", + "main_countries_tags" : [], + "minerals_tags" : [], + "misc_tags" : [ + "en:nutrition-not-enough-data-to-compute-nutrition-score", + "en:nutriscore-missing-nutrition-data", + "en:nutriscore-missing-nutrition-data-energy", + "en:nutriscore-missing-nutrition-data-fat", + "en:nutriscore-missing-nutrition-data-saturated-fat", + "en:nutriscore-missing-nutrition-data-sugars", + "en:nutriscore-missing-nutrition-data-sodium", + "en:nutriscore-missing-nutrition-data-proteins", + "en:nutrition-no-fiber", + "en:nutriscore-not-computed", + "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", + "en:nutrition-no-fiber-or-fruits-vegetables-nuts", + "en:nutrition-fruits-vegetables-legumes-estimate-from-ingredients", + "en:packagings-number-of-components-4", + "en:packagings-not-complete", + "en:packagings-not-empty-but-not-complete", + "en:packagings-not-empty", + "en:ecoscore-extended-data-not-computed", + "en:ecoscore-missing-data-warning", + "en:ecoscore-missing-data-labels", + "en:ecoscore-missing-data-origins", + "en:ecoscore-computed", + "en:ecoscore-changed", + "en:ecoscore-grade-changed", + "en:forest-footprint-computed", + "en:forest-footprint-a", + "en:main-countries-new-product" + ], + "nova_group" : 3, + "nova_group_debug" : "", + "nova_groups" : "3", + "nova_groups_markers" : { + "3" : [ + [ + "categories", + "en:sweet-snacks" + ] + ] + }, + "nova_groups_tags" : [ + "en:3-processed-foods" + ], + "nucleotides_tags" : [], + "nutrient_levels" : {}, + "nutrient_levels_tags" : [], + "nutriments" : { + "fruits-vegetables-legumes-estimate-from-ingredients_100g" : 62.5, + "fruits-vegetables-legumes-estimate-from-ingredients_serving" : 62.5, + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 62.5, + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 62.5, + "nova-group" : 3, + "nova-group_100g" : 3, + "nova-group_serving" : 3 + }, + "nutriscore" : { + "2021" : { + "category_available" : 1, + "data" : { + "energy" : null, + "fiber" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 62.5, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "proteins" : null, + "saturated_fat" : null, + "sodium" : null, + "sugars" : null + }, + "grade" : "unknown", + "nutrients_available" : 0, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 0 + }, + "2023" : { + "category_available" : 1, + "data" : { + "energy" : null, + "fiber" : 0, + "fruits_vegetables_legumes" : 62.5, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat_oil_nuts_seeds" : 0, + "is_water" : 0, + "proteins" : null, + "salt" : null, + "saturated_fat" : null, + "sugars" : null + }, + "grade" : "unknown", + "nutrients_available" : 0, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 0 + } + }, + "nutriscore_2021_tags" : [ + "unknown" + ], + "nutriscore_2023_tags" : [ + "unknown" + ], + "nutriscore_grade" : "unknown", + "nutriscore_tags" : [ + "unknown" + ], + "nutriscore_version" : "2021", + "nutrition_data_per" : "100g", + "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "unknown", + "nutrition_grades" : "unknown", + "nutrition_grades_tags" : [ + "unknown" + ], + "nutrition_score_beverage" : 0, + "nutrition_score_debug" : "missing energy_100g - missing fat_100g - missing saturated-fat_100g - missing sugars_100g - missing sodium_100g - missing proteins_100g", + "nutrition_score_warning_fruits_vegetables_legumes_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_legumes_estimate_from_ingredients_value" : 62.5, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 62.5, + "nutrition_score_warning_no_fiber" : 1, + "origin" : "france", + "origin_en" : "france", + "other_nutritional_substances_tags" : [], + "packaging_materials_tags" : [ + "en:glass", + "en:plastic", + "en:steel", + "en:wood" + ], + "packaging_recycling_tags" : [ + "en:discard", + "en:recycle", + "en:reuse" + ], + "packaging_shapes_tags" : [ + "en:bottle", + "en:box", + "en:film", + "en:lid" + ], + "packaging_text" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard", + "packaging_text_en" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard", + "packagings" : [ + { + "material" : { + "id" : "en:wood" + }, + "number_of_units" : 1, + "recycling" : { + "id" : "en:recycle" + }, + "shape" : { + "id" : "en:box" + } + }, + { + "material" : { + "id" : "en:glass" + }, + "number_of_units" : 6, + "quantity_per_unit" : "25cl", + "quantity_per_unit_unit" : "cl", + "quantity_per_unit_value" : 25, + "recycling" : { + "id" : "en:reuse" + }, + "shape" : { + "id" : "en:bottle" + } + }, + { + "material" : { + "id" : "en:steel" + }, + "number_of_units" : 3, + "recycling" : { + "id" : "en:recycle" + }, + "shape" : { + "id" : "en:lid" + } + }, + { + "material" : { + "id" : "en:plastic" + }, + "number_of_units" : 1, + "recycling" : { + "id" : "en:discard" + }, + "shape" : { + "id" : "en:film" + } + } + ], + "packagings_materials" : { + "all" : {}, + "en:glass" : {}, + "en:metal" : {}, + "en:plastic" : {}, + "en:unknown" : {} + }, + "packagings_n" : 4, + "photographers_tags" : [], + "pnns_groups_1" : "Sugary snacks", + "pnns_groups_1_tags" : [ + "sugary-snacks", + "known" + ], + "pnns_groups_2" : "Biscuits and cakes", + "pnns_groups_2_tags" : [ + "biscuits-and-cakes", + "known" + ], + "popularity_key" : 0, + "product_name" : "Some product", + "product_name_en" : "Some product", + "product_quantity" : "100", + "quantity" : "100 g", + "removed_countries_tags" : [], + "rev" : 1, + "serving_quantity" : "10", + "serving_size" : "10 g", + "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", + "states_hierarchy" : [ + "en:to-be-completed", + "en:nutrition-facts-to-be-completed", + "en:ingredients-completed", + "en:expiration-date-to-be-completed", + "en:packaging-code-to-be-completed", + "en:characteristics-to-be-completed", + "en:origins-to-be-completed", + "en:categories-completed", + "en:brands-to-be-completed", + "en:packaging-to-be-completed", + "en:quantity-completed", + "en:product-name-completed", + "en:photos-to-be-uploaded" + ], + "states_tags" : [ + "en:to-be-completed", + "en:nutrition-facts-to-be-completed", + "en:ingredients-completed", + "en:expiration-date-to-be-completed", + "en:packaging-code-to-be-completed", + "en:characteristics-to-be-completed", + "en:origins-to-be-completed", + "en:categories-completed", + "en:brands-to-be-completed", + "en:packaging-to-be-completed", + "en:quantity-completed", + "en:product-name-completed", + "en:photos-to-be-uploaded" + ], + "traces" : "", + "traces_from_ingredients" : "", + "traces_from_user" : "(en) ", + "traces_hierarchy" : [], + "traces_tags" : [], + "unknown_ingredients_n" : 0, + "unknown_nutrients_tags" : [], + "vitamins_tags" : [], + "weighers_tags" : [] + }, + "result" : { + "id" : "product_found", + "lc_name" : "Product found", + "name" : "Product found" + }, + "status" : "success_with_warnings", + "warnings" : [ + { + "field" : { + "id" : "code", + "value" : "4260392550101" + }, + "impact" : { + "id" : "none", + "lc_name" : "None", + "name" : "None" + }, + "message" : { + "id" : "different_normalized_product_code", + "lc_name" : "", + "name" : "" + } + } + ] +} diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-existing-product.json b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product.json index e5a0ba75183ca..288345066a12d 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-existing-product.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product.json @@ -1,8 +1,8 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { - "_id" : "200000000034", + "_id" : "4260392550101", "_keywords" : [ "cookie", "organic", @@ -56,18 +56,19 @@ "en:biscuits" ], "checkers_tags" : [], - "code" : "200000000034", + "code" : "4260392550101", "codes_tags" : [ - "code-12", - "200000000xxx", - "20000000xxxx", - "2000000xxxxx", - "200000xxxxxx", - "20000xxxxxxx", - "2000xxxxxxxx", - "200xxxxxxxxx", - "20xxxxxxxxxx", - "2xxxxxxxxxxx" + "code-13", + "4260392550xxx", + "426039255xxxx", + "42603925xxxxx", + "4260392xxxxxx", + "426039xxxxxxx", + "42603xxxxxxxx", + "4260xxxxxxxxx", + "426xxxxxxxxxx", + "42xxxxxxxxxxx", + "4xxxxxxxxxxxx" ], "complete" : 0, "completeness" : 0.4, @@ -573,7 +574,7 @@ }, "generic_name" : "Tester", "generic_name_en" : "Tester", - "id" : "200000000034", + "id" : "4260392550101", "informers_tags" : [ "tests" ], diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-fields-all-knowledge-panels.json b/tests/integration/expected_test_results/api_v3_product_read/get-fields-all-knowledge-panels.json index a1db9bb1eb128..74c74fd3dcef9 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-fields-all-knowledge-panels.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-fields-all-knowledge-panels.json @@ -1,8 +1,8 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { - "_id" : "200000000034", + "_id" : "4260392550101", "_keywords" : [ "cookie", "organic", @@ -56,18 +56,19 @@ "en:biscuits" ], "checkers_tags" : [], - "code" : "200000000034", + "code" : "4260392550101", "codes_tags" : [ - "code-12", - "200000000xxx", - "20000000xxxx", - "2000000xxxxx", - "200000xxxxxx", - "20000xxxxxxx", - "2000xxxxxxxx", - "200xxxxxxxxx", - "20xxxxxxxxxx", - "2xxxxxxxxxxx" + "code-13", + "4260392550xxx", + "426039255xxxx", + "42603925xxxxx", + "4260392xxxxxx", + "426039xxxxxxx", + "42603xxxxxxxx", + "4260xxxxxxxxx", + "426xxxxxxxxxx", + "42xxxxxxxxxxx", + "4xxxxxxxxxxxx" ], "complete" : 0, "completeness" : 0.4, @@ -103,7 +104,7 @@ "origins_of_ingredients" : { "aggregated_origins" : [ { - "epi_score" : "0", + "epi_score" : 0, "origin" : "en:unknown", "percent" : 100, "transportation_score" : null @@ -573,7 +574,7 @@ }, "generic_name" : "Tester", "generic_name_en" : "Tester", - "id" : "200000000034", + "id" : "4260392550101", "informers_tags" : [ "tests" ], diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-fields-all.json b/tests/integration/expected_test_results/api_v3_product_read/get-fields-all.json index e5a0ba75183ca..288345066a12d 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-fields-all.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-fields-all.json @@ -1,8 +1,8 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { - "_id" : "200000000034", + "_id" : "4260392550101", "_keywords" : [ "cookie", "organic", @@ -56,18 +56,19 @@ "en:biscuits" ], "checkers_tags" : [], - "code" : "200000000034", + "code" : "4260392550101", "codes_tags" : [ - "code-12", - "200000000xxx", - "20000000xxxx", - "2000000xxxxx", - "200000xxxxxx", - "20000xxxxxxx", - "2000xxxxxxxx", - "200xxxxxxxxx", - "20xxxxxxxxxx", - "2xxxxxxxxxxx" + "code-13", + "4260392550xxx", + "426039255xxxx", + "42603925xxxxx", + "4260392xxxxxx", + "426039xxxxxxx", + "42603xxxxxxxx", + "4260xxxxxxxxx", + "426xxxxxxxxxx", + "42xxxxxxxxxxx", + "4xxxxxxxxxxxx" ], "complete" : 0, "completeness" : 0.4, @@ -573,7 +574,7 @@ }, "generic_name" : "Tester", "generic_name_en" : "Tester", - "id" : "200000000034", + "id" : "4260392550101", "informers_tags" : [ "tests" ], diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-fields-attribute-groups-all-knowledge-panels.json b/tests/integration/expected_test_results/api_v3_product_read/get-fields-attribute-groups-all-knowledge-panels.json index fd64f25d83b69..ce0a486340cf8 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-fields-attribute-groups-all-knowledge-panels.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-fields-attribute-groups-all-knowledge-panels.json @@ -1,8 +1,8 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { - "_id" : "200000000034", + "_id" : "4260392550101", "_keywords" : [ "cookie", "organic", @@ -380,18 +380,19 @@ "en:biscuits" ], "checkers_tags" : [], - "code" : "200000000034", + "code" : "4260392550101", "codes_tags" : [ - "code-12", - "200000000xxx", - "20000000xxxx", - "2000000xxxxx", - "200000xxxxxx", - "20000xxxxxxx", - "2000xxxxxxxx", - "200xxxxxxxxx", - "20xxxxxxxxxx", - "2xxxxxxxxxxx" + "code-13", + "4260392550xxx", + "426039255xxxx", + "42603925xxxxx", + "4260392xxxxxx", + "426039xxxxxxx", + "42603xxxxxxxx", + "4260xxxxxxxxx", + "426xxxxxxxxxx", + "42xxxxxxxxxxx", + "4xxxxxxxxxxxx" ], "complete" : 0, "completeness" : 0.4, @@ -897,7 +898,7 @@ }, "generic_name" : "Tester", "generic_name_en" : "Tester", - "id" : "200000000034", + "id" : "4260392550101", "informers_tags" : [ "tests" ], diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-fields-raw.json b/tests/integration/expected_test_results/api_v3_product_read/get-fields-raw.json index 58154ead10cb8..6b8bbcb1a0c59 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-fields-raw.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-fields-raw.json @@ -1,8 +1,8 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { - "_id" : "200000000034", + "_id" : "4260392550101", "_keywords" : [ "cookie", "organic", @@ -56,18 +56,19 @@ "en:biscuits" ], "checkers_tags" : [], - "code" : "200000000034", + "code" : "4260392550101", "codes_tags" : [ - "code-12", - "200000000xxx", - "20000000xxxx", - "2000000xxxxx", - "200000xxxxxx", - "20000xxxxxxx", - "2000xxxxxxxx", - "200xxxxxxxxx", - "20xxxxxxxxxx", - "2xxxxxxxxxxx" + "code-13", + "4260392550xxx", + "426039255xxxx", + "42603925xxxxx", + "4260392xxxxxx", + "426039xxxxxxx", + "42603xxxxxxxx", + "4260xxxxxxxxx", + "426xxxxxxxxxx", + "42xxxxxxxxxxx", + "4xxxxxxxxxxxx" ], "complete" : 0, "completeness" : 0.4, @@ -568,7 +569,7 @@ }, "generic_name" : "Tester", "generic_name_en" : "Tester", - "id" : "200000000034", + "id" : "4260392550101", "informers_tags" : [ "tests" ], diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-images-to-update.json b/tests/integration/expected_test_results/api_v3_product_read/get-images-to-update.json index bfa45977db88e..6a05f3a846b68 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-images-to-update.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-images-to-update.json @@ -1,5 +1,5 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { "images_to_update_en" : { diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels-fr.json b/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels-fr.json index ba04236f7ca3d..7b63bd1000103 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels-fr.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels-fr.json @@ -1,5 +1,5 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { "knowledge_panels" : { diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels.json b/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels.json index 5c25f6b4b1d57..9f36fb602efb8 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels.json @@ -1,5 +1,5 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { "knowledge_panels" : { diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-packagings-fr.json b/tests/integration/expected_test_results/api_v3_product_read/get-packagings-fr.json index 316bf9faed97d..4ba6d99cbf905 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-packagings-fr.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-packagings-fr.json @@ -1,5 +1,5 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { "packagings" : [ diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-packagings.json b/tests/integration/expected_test_results/api_v3_product_read/get-packagings.json index 527151e72f788..5b80869531bf8 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-packagings.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-packagings.json @@ -1,5 +1,5 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { "packagings" : [ diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-specific-fields.json b/tests/integration/expected_test_results/api_v3_product_read/get-specific-fields.json index 2aed24b83db8f..ca0da01900146 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-specific-fields.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-specific-fields.json @@ -1,5 +1,5 @@ { - "code" : "200000000034", + "code" : "4260392550101", "errors" : [], "product" : { "categories_tags" : [ diff --git a/tests/unit/products.t b/tests/unit/products.t index 4b229b5893a3c..7fa31448e922e 100644 --- a/tests/unit/products.t +++ b/tests/unit/products.t @@ -37,6 +37,77 @@ is(normalize_code('https://example.com/01/00012345000058?17=271200'), is(normalize_code('https://world.openfoodfacts.org/'), '', 'non-GS1 URIs should return an empty string'); is(normalize_code('http://spam.zip/'), '', 'non-GS1 URIs should return an empty string'); +# code normalization with GS1 AI +is(normalize_code_with_gs1_ai('036000291452'), ('0036000291452', undef), 'GS1: should add leading 0 to valid UPC12'); +is( + normalize_code_with_gs1_ai('036000291455'), + ('036000291455', undef), + 'GS1: should not add 0 to invalid UPC12, just return as-is' +); +is(normalize_code_with_gs1_ai('4015533014963'), ('4015533014963', undef), 'GS1: should just return invalid EAN13'); +ok(!(defined normalize_code_with_gs1_ai(undef)), 'GS1: undef should stay undef'); +is( + normalize_code_with_gs1_ai(' just a simple test 4015533014963 here we go '), + ('4015533014963', undef), + 'GS1: barcode should always be cleaned from anything but digits' +); +is( + normalize_code_with_gs1_ai(' just a simple test 036000291452 here we go '), + ('0036000291452', undef), + 'GS1: should add leading 0 to cleaned valid UPC12' +); +is( + normalize_code_with_gs1_ai(' just a simple test 036000291455 here we go '), + ('036000291455', undef), + 'GS1: should not add leading 0 to cleaned invalid UPC12' +); +is( + normalize_code_with_gs1_ai('0104044782317112'), + ('4044782317112', '(01)04044782317112'), + 'GS1: should reduce GS1 AI unbracketed string to GTIN' +); +is( + normalize_code_with_gs1_ai('(01)04044782317112(17)270101'), + ('4044782317112', '(01)04044782317112(17)270101'), + 'GS1: should reduce GS1 AI bracketed string to GTIN' +); +is( + normalize_code_with_gs1_ai('^010404478231711217270101'), + ('4044782317112', '(01)04044782317112(17)270101'), + 'GS1: should reduce GS1 AI unbracketed string with ^ as FNC1 to GTIN' +); +is( + normalize_code_with_gs1_ai("\x{001d}010404478231711217270101"), + ('4044782317112', '(01)04044782317112(17)270101'), + 'GS1: should reduce GS1 AI unbracketed string with original FNC1 to GTIN' +); +is( + normalize_code_with_gs1_ai("\x{241d}010404478231711217270101"), + ('4044782317112', '(01)04044782317112(17)270101'), + 'GS1: should reduce GS1 AI unbracketed string with GS as FNC1 to GTIN' +); +is( + normalize_code_with_gs1_ai('https://id.gs1.org/01/04044782317112/22/2A'), + ('4044782317112', '(01)04044782317112(22)2A'), + 'GS1: should reduce GS1 Digital Link URI string with ^ as FNC1 to GTIN' +); +is( + normalize_code_with_gs1_ai('https://dalgiardino.com/01/09506000134376/10/ABC/21/123456?17=211200'), + ('9506000134376', '(01)09506000134376(10)ABC(21)123456(17)211200'), + 'GS1: should reduce GS1 Digital Link URI to GTIN' +); +is( + normalize_code_with_gs1_ai('https://example.com/01/00012345000058?17=271200'), + ('0012345000058', '(01)00012345000058(17)271200'), + 'GS1: should reduce GS1 Digital Link URI to GTIN' +); +is( + normalize_code_with_gs1_ai('https://world.openfoodfacts.org/'), + ('', undef), + 'GS1: non-GS1 URIs should return an empty string' +); +is(normalize_code_with_gs1_ai('http://spam.zip/'), ('', undef), 'GS1: non-GS1 URIs should return an empty string'); + # product storage path is(product_path_from_id('not a real code'), 'invalid', 'non digit code should return "invalid"'); is( diff --git a/tests/unit/routing.t b/tests/unit/routing.t index ce5d8a71d4942..a5380d6c1fe41 100644 --- a/tests/unit/routing.t +++ b/tests/unit/routing.t @@ -145,7 +145,59 @@ my @tests = ( 'is_crawl_bot' => '0' }, }, - + { + desc => "API v3 URL with product code", + lc => "en", + input_request => { + cc => "world", + lc => "en", + original_query_string => 'api/v3/product/03564703999971', + no_index => '0', + is_crawl_bot => '0' + }, + expected_output_request => { + 'api' => 'v3', + 'api_action' => 'product', + 'api_method' => undef, + 'api_version' => '3', + 'cc' => 'world', + 'lc' => 'en', + 'original_query_string' => 'api/v3/product/03564703999971', + 'query_string' => 'api/v3/product/03564703999971', + 'code' => '03564703999971', + 'page' => '1', + 'no_index' => '0', + 'is_crawl_bot' => '0' + }, + }, + { + desc => "API v3 URL with product GS1 Data URI", + lc => "en", + input_request => { + cc => "world", + lc => "en", + original_query_string => + 'api/v3/product/https%3A%2F%2Fid.gs1.org%2F01%2F03564703999971%2F10%2FABC%2F21%2F123456%3F17%3D211200', + no_index => '0', + is_crawl_bot => '0' + }, + expected_output_request => { + 'api' => 'v3', + 'api_action' => 'product', + 'api_method' => undef, + 'api_version' => '3', + 'cc' => 'world', + 'lc' => 'en', + 'original_query_string' => + 'api/v3/product/https%3A%2F%2Fid.gs1.org%2F01%2F03564703999971%2F10%2FABC%2F21%2F123456%3F17%3D211200', + 'query_string' => + 'api/v3/product/https%3A%2F%2Fid.gs1.org%2F01%2F03564703999971%2F10%2FABC%2F21%2F123456%3F17%3D211200', + 'code' => 'https://id.gs1.org/01/03564703999971/10/ABC/21/123456?17=211200', + 'page' => '1', + 'no_index' => '0', + 'is_crawl_bot' => '0' + }, + }, ); foreach my $test_ref (@tests) {