diff --git a/docs/api/ref/schemas/product_ingredients.yaml b/docs/api/ref/schemas/product_ingredients.yaml
index b885d5a69e945..b3705886a54e6 100644
--- a/docs/api/ref/schemas/product_ingredients.yaml
+++ b/docs/api/ref/schemas/product_ingredients.yaml
@@ -70,6 +70,13 @@ properties:
type: array
items:
type: string
+ ingredients_lc:
+ type: string
+ description: |
+ Language that was used to parse the ingredient list. If `ingredients_text` is available
+ for the product main language (`lang`), `ingredients_lc=lang`, otherwise we look at
+ `ingredients_text` fields for other languages and set `ingredients_lc` to the first
+ non-empty `ingredient_text`.
ingredients_text:
type: string
description: |
diff --git a/docs/dev/how-to-write-and-run-tests.md b/docs/dev/how-to-write-and-run-tests.md
index db70aed63cded..136e93f19eebf 100644
--- a/docs/dev/how-to-write-and-run-tests.md
+++ b/docs/dev/how-to-write-and-run-tests.md
@@ -88,7 +88,7 @@ If you made change that impact stored expected results, you can use:
* or to generate expected results for a single test
(here for integration test, `test-unit` otherwise)
```bash
- make test-int="filename.t --update-expected results"
+ make test-int test="filename.t --update-expected-results"
```
If you re-generate test results, be sure to look carefully that the changes your commit are expected changes.
diff --git a/lib/ProductOpener/APITest.pm b/lib/ProductOpener/APITest.pm
index b282a7870753e..33891f20ccbaf 100644
--- a/lib/ProductOpener/APITest.pm
+++ b/lib/ProductOpener/APITest.pm
@@ -515,7 +515,7 @@ sub execute_api_tests ($file, $tests_ref, $ua = undef) {
my $response_content = $response->decoded_content;
- if ($test_ref->{expected_type} eq 'text') {
+ if ((defined $test_ref->{expected_type}) and ($test_ref->{expected_type} eq 'text')) {
# Check that the text file is the same as expected (useful for checking dynamic robots.txt)
is(
compare_file_to_expected_results(
diff --git a/lib/ProductOpener/Display.pm b/lib/ProductOpener/Display.pm
index 06cc5d1a7988a..3533145ecaa7e 100644
--- a/lib/ProductOpener/Display.pm
+++ b/lib/ProductOpener/Display.pm
@@ -7838,7 +7838,7 @@ JS
# try to display ingredients in the local language if available
my $ingredients_text = $product_ref->{ingredients_text};
- my $ingredients_text_lang = $product_ref->{lc};
+ my $ingredients_text_lang = $product_ref->{ingredients_lc};
if (defined $product_ref->{ingredients_text_with_allergens}) {
$ingredients_text = $product_ref->{ingredients_text_with_allergens};
@@ -11049,7 +11049,8 @@ sub data_to_display_ingredients_analysis_details ($product_ref) {
my $result_data_ref = {};
- my $ingredients_text = "";
+ my $ingredients_text_lc = $product_ref->{ingredients_lc};
+ my $ingredients_text = "$ingredients_text_lc: ";
my $ingredients_list = "";
display_nested_list_of_ingredients($product_ref->{ingredients}, \$ingredients_text, \$ingredients_list);
diff --git a/lib/ProductOpener/Ingredients.pm b/lib/ProductOpener/Ingredients.pm
index 103f4b59a95aa..5c979559a52da 100644
--- a/lib/ProductOpener/Ingredients.pm
+++ b/lib/ProductOpener/Ingredients.pm
@@ -63,6 +63,7 @@ BEGIN {
&clean_ingredients_text_for_lang
&cut_ingredients_text_for_lang
&clean_ingredients_text
+ &select_ingredients_lc
&detect_allergens_from_text
@@ -860,7 +861,7 @@ Array of specific ingredients.
sub add_specific_ingredients_from_labels ($product_ref) {
- my $product_lc = $product_ref->{lc};
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
if (defined $product_ref->{labels_tags}) {
foreach my $labelid (@{$product_ref->{labels_tags}}) {
@@ -920,7 +921,7 @@ Array of specific ingredients.
sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_or_quantity_regexp) {
- my $product_lc = $product_ref->{lc};
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
# Go through the ingredient lists multiple times
# as long as we have one match
@@ -940,7 +941,7 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_or_quant
# Regexps should match until we reach a . ; or the end of the text
- if ($product_lc eq "en") {
+ if ($ingredients_lc eq "en") {
# examples:
# Total Milk Content 73%.
@@ -961,7 +962,7 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_or_quant
}
# Origin of the milk: United Kingdom
- elsif (match_origin_of_the_ingredient_origin($product_lc, \$text, $matched_ingredient_ref)) {
+ elsif (match_origin_of_the_ingredient_origin($ingredients_lc, \$text, $matched_ingredient_ref)) {
$origins = $matched_ingredient_ref->{origins};
$ingredient = $matched_ingredient_ref->{ingredient};
$matched_text = $matched_ingredient_ref->{matched_text};
@@ -969,7 +970,7 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_or_quant
$ingredient =~ s/\s+$//;
}
}
- elsif ($product_lc eq "fr") {
+ elsif ($ingredients_lc eq "fr") {
# examples:
# Teneur en lait 25% minimum.
@@ -1011,7 +1012,7 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_or_quant
}
# Origine du Cacao: Pérou
- elsif (match_origin_of_the_ingredient_origin($product_lc, \$text, $matched_ingredient_ref)) {
+ elsif (match_origin_of_the_ingredient_origin($ingredients_lc, \$text, $matched_ingredient_ref)) {
$origins = $matched_ingredient_ref->{origins};
$ingredient = $matched_ingredient_ref->{ingredient};
$matched_text = $matched_ingredient_ref->{matched_text};
@@ -1024,7 +1025,8 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_or_quant
# If we found an ingredient, save it in specific_ingredients
if (defined $ingredient) {
my $ingredient_id
- = get_taxonomyid($product_lc, canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient));
+ = get_taxonomyid($ingredients_lc,
+ canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient));
$matched_text =~ s/^\s+//;
@@ -1049,11 +1051,12 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_or_quant
# Add origin field
- my $and_or = $and_or{$product_lc};
+ my $and_or = $and_or{$ingredients_lc};
defined $origins
and $specific_ingredients_ref->{origins}
- = join(",", map {canonicalize_taxonomy_tag($product_lc, "origins", $_)} split(/,|$and_or/, $origins));
+ = join(",",
+ map {canonicalize_taxonomy_tag($ingredients_lc, "origins", $_)} split(/,|$and_or/, $origins));
push @{$product_ref->{specific_ingredients}}, $specific_ingredients_ref;
}
@@ -1067,11 +1070,11 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_or_quant
# Regexps should match until we reach a . ; or the end of the text
-sub match_ingredient_origin ($product_lc, $text_ref, $matched_ingredient_ref) {
+sub match_ingredient_origin ($ingredients_lc, $text_ref, $matched_ingredient_ref) {
- my $origins_regexp = $origins_regexps{$product_lc};
- my $and_or = $and_or{$product_lc} || ',';
- my $from = $from{$product_lc} || ':';
+ my $origins_regexp = $origins_regexps{$ingredients_lc};
+ my $and_or = $and_or{$ingredients_lc} || ',';
+ my $from = $from{$ingredients_lc} || ':';
# Strawberries: Spain, Italy and Portugal
# Strawberries from Spain, Italy and Portugal
@@ -1110,7 +1113,7 @@ sub match_ingredient_origin ($product_lc, $text_ref, $matched_ingredient_ref) {
not(
exists_taxonomy_tag(
"ingredients",
- canonicalize_taxonomy_tag($product_lc, "ingredients", $matched_ingredient_ref->{ingredient})
+ canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $matched_ingredient_ref->{ingredient})
)
)
)
@@ -1127,16 +1130,16 @@ sub match_ingredient_origin ($product_lc, $text_ref, $matched_ingredient_ref) {
return 0;
}
-sub match_origin_of_the_ingredient_origin ($product_lc, $text_ref, $matched_ingredient_ref) {
+sub match_origin_of_the_ingredient_origin ($ingredients_lc, $text_ref, $matched_ingredient_ref) {
my %origin_of_the_regexp_in_lc = (
en => "(?:origin of (?:the )?)",
fr => "(?:origine (?:de |du |de la |des |de l'))",
);
- my $origin_of_the_regexp = $origin_of_the_regexp_in_lc{$product_lc} || $origin_of_the_regexp_in_lc{en};
- my $origins_regexp = $origins_regexps{$product_lc};
- my $and_or = $and_or{$product_lc} || ',';
+ my $origin_of_the_regexp = $origin_of_the_regexp_in_lc{$ingredients_lc} || $origin_of_the_regexp_in_lc{en};
+ my $origins_regexp = $origins_regexps{$ingredients_lc};
+ my $and_or = $and_or{$ingredients_lc} || ',';
# Origin of the milk: United Kingdom.
if (
@@ -1190,7 +1193,7 @@ Array of specific ingredients.
sub parse_origins_from_text ($product_ref, $text) {
- my $product_lc = $product_ref->{lc};
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
# Normalize single quotes
$text =~ s/’/'/g;
@@ -1209,12 +1212,13 @@ sub parse_origins_from_text ($product_ref, $text) {
# Call match functions to look for different ways to specify origins etc.
foreach my $match_function_ref (\&match_origin_of_the_ingredient_origin, \&match_ingredient_origin) {
- if ($match_function_ref->($product_lc, \$text, $matched_ingredient_ref)) {
+ if ($match_function_ref->($ingredients_lc, \$text, $matched_ingredient_ref)) {
my $matched_text = $matched_ingredient_ref->{matched_text};
my $ingredient = $matched_ingredient_ref->{ingredient};
my $ingredient_id
- = get_taxonomyid($product_lc, canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient));
+ = get_taxonomyid($ingredients_lc,
+ canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient));
# Remove extra spaces
$ingredient =~ s/\s+$//;
@@ -1227,9 +1231,9 @@ sub parse_origins_from_text ($product_ref, $text) {
};
if (defined $matched_ingredient_ref->{origins}) {
- my $and_or = $and_or{$product_lc};
+ my $and_or = $and_or{$ingredients_lc};
$specific_ingredients_ref->{origins} = join(",",
- map {canonicalize_taxonomy_tag($product_lc, "origins", $_)}
+ map {canonicalize_taxonomy_tag($ingredients_lc, "origins", $_)}
split(/,|$and_or/, $matched_ingredient_ref->{origins}));
}
@@ -1244,6 +1248,34 @@ sub parse_origins_from_text ($product_ref, $text) {
return $text;
}
+=head2 select_ingredients_lc ($product_ref)
+
+Return the `ingredients_lc` field to save in $product_ref.
+
+This is the language that will be used to parse ingredients. We first check that ingredients_text_{lang}
+exists and is non-empty for the product main language (`lc`), and return it if it does.
+Otherwise we look at all languages defined in `languages_codes` for a non-empty `ingredients_text_lang`.
+
+=head3 Arguments
+
+=head4 $product_ref
+
+=cut
+
+sub select_ingredients_lc ($product_ref) {
+ if (defined $product_ref->{languages_codes}) {
+ # We sort the keys so that the order is deterministic
+ foreach my $language ($product_ref->{lc}, sort keys %{$product_ref->{languages_codes}}) {
+ if ( (defined $product_ref->{"ingredients_text_" . $language})
+ and ($product_ref->{"ingredients_text_" . $language} ne ""))
+ {
+ return $language;
+ }
+ }
+ }
+ return $product_ref->{lc};
+}
+
=head2 get_percent_or_quantity_and_normalized_quantity($percent_or_quantity_value, $percent_or_quantity_unit)
Used to assign percent or quantity for strings parsed with $percent_or_quantity_regexp.
@@ -1322,9 +1354,10 @@ sub parse_ingredients_text ($product_ref) {
$log->debug("extracting ingredients from text", {text => $text}) if $log->is_debug();
- my $product_lc = $product_ref->{lc};
+ # $product_ref->{ingredients_lc} is defined in extract_ingredients_from_text()
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
- $text = preparse_ingredients_text($product_lc, $text);
+ $text = preparse_ingredients_text($ingredients_lc, $text);
$log->debug("preparsed ingredients from text", {text => $text}) if $log->is_debug();
@@ -1332,8 +1365,8 @@ sub parse_ingredients_text ($product_ref) {
# jus de pomme, eau, sucre. Traces possibles de c\x{e9}leri, moutarde et gluten.",
# -> jus de pomme, eau, sucre. Traces éventuelles : céleri, Traces éventuelles : moutarde, Traces éventuelles : gluten.
- my $traces = $Lang{traces}{$product_lc};
- my $allergens = $Lang{allergens}{$product_lc};
+ my $traces = $Lang{traces}{$ingredients_lc};
+ my $allergens = $Lang{allergens}{$ingredients_lc};
$text =~ s/\b($traces|$allergens)\s?:\s?([^,\.]+)//ig;
# unify newline feeds to \n
@@ -1354,15 +1387,15 @@ sub parse_ingredients_text ($product_ref) {
$text =~ s/(\d),(\d)/$1‚$2/g;
- my $and = $and{$product_lc} || " and ";
+ my $and = $and{$ingredients_lc} || " and ";
my $min_regexp = "";
- if (defined $min_regexp{$product_lc}) {
- $min_regexp = $min_regexp{$product_lc};
+ if (defined $min_regexp{$ingredients_lc}) {
+ $min_regexp = $min_regexp{$ingredients_lc};
}
my $ignore_strings_after_percent = "";
- if (defined $ignore_strings_after_percent{$product_lc}) {
- $ignore_strings_after_percent = $ignore_strings_after_percent{$product_lc};
+ if (defined $ignore_strings_after_percent{$ingredients_lc}) {
+ $ignore_strings_after_percent = $ignore_strings_after_percent{$ingredients_lc};
}
# Regular expression to find percent or quantities
@@ -1479,7 +1512,7 @@ sub parse_ingredients_text ($product_ref) {
# sel marin (France, Italie)
# -> if we have origins, put "origins:" before
if ( ($between =~ $separators)
- and (exists_taxonomy_tag("origins", canonicalize_taxonomy_tag($product_lc, "origins", $`))))
+ and (exists_taxonomy_tag("origins", canonicalize_taxonomy_tag($ingredients_lc, "origins", $`))))
{
$between =~ s/^(.*?$separators)/origins:$1/;
}
@@ -1542,14 +1575,14 @@ sub parse_ingredients_text ($product_ref) {
}
else {
$origin = join(",",
- map {canonicalize_taxonomy_tag($product_lc, "origins", $_)}
+ map {canonicalize_taxonomy_tag($ingredients_lc, "origins", $_)}
split(/,/, $origin_string));
}
}
else {
# origins: Fraise (France)
- my $originid = canonicalize_taxonomy_tag($product_lc, "origins", $between);
+ my $originid = canonicalize_taxonomy_tag($ingredients_lc, "origins", $between);
if (exists_taxonomy_tag("origins", $originid)) {
$origin = $originid;
$debug_ingredients
@@ -1562,7 +1595,7 @@ sub parse_ingredients_text ($product_ref) {
# Skip too short entries (1 or 2 letters) to avoid false positives
elsif (length($between) >= 3) {
- my $labelid = canonicalize_taxonomy_tag($product_lc, "labels", $between);
+ my $labelid = canonicalize_taxonomy_tag($ingredients_lc, "labels", $between);
if (exists_taxonomy_tag("labels", $labelid)) {
if (defined $labels) {
$labels .= ", " . $labelid;
@@ -1597,7 +1630,7 @@ sub parse_ingredients_text ($product_ref) {
# processing method?
my $processingid
- = canonicalize_taxonomy_tag($product_lc, "ingredients_processing",
+ = canonicalize_taxonomy_tag($ingredients_lc, "ingredients_processing",
$between);
if (exists_taxonomy_tag("ingredients_processing", $processingid)) {
if (defined $processing) {
@@ -1681,7 +1714,7 @@ sub parse_ingredients_text ($product_ref) {
$ingredient2 =~ s/\s$percent_or_quantity_regexp$//i;
# check if the whole ingredient is an ingredient
- my $canon_ingredient = canonicalize_taxonomy_tag($product_lc, "ingredients", $before);
+ my $canon_ingredient = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $before);
$debug_ingredients and $log->debug(
"ingredient contains 'and', checking if it exists",
@@ -1691,8 +1724,8 @@ sub parse_ingredients_text ($product_ref) {
if (not exists_taxonomy_tag("ingredients", $canon_ingredient)) {
# otherwise check the 2 sub ingredients
- my $canon_ingredient1 = canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient1);
- my $canon_ingredient2 = canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient2);
+ my $canon_ingredient1 = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient1);
+ my $canon_ingredient2 = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient2);
$debug_ingredients and $log->debug(
"ingredient containing 'and' did not exist. 2 known ingredients?",
@@ -1818,16 +1851,16 @@ sub parse_ingredients_text ($product_ref) {
}
else {
$origin = join(",",
- map {canonicalize_taxonomy_tag($product_lc, "origins", $_)} split(/,/, $origin_string));
+ map {canonicalize_taxonomy_tag($ingredients_lc, "origins", $_)} split(/,/, $origin_string));
}
}
# Check if we have an ingredient + some specific labels like organic and fair-trade.
# If we do, remove the label from the ingredient and add the label to labels
- if (defined $labels_regexps{$product_lc}) {
+ if (defined $labels_regexps{$ingredients_lc}) {
# start with uncomposed labels first, so that we decompose "fair-trade organic" into "fair-trade, organic"
foreach my $labelid (reverse @labels) {
- my $regexp = $labels_regexps{$product_lc}{$labelid};
+ my $regexp = $labels_regexps{$ingredients_lc}{$labelid};
$debug_ingredients and $log->trace("checking labels regexps",
{ingredient => $ingredient, labelid => $labelid, regexp => $regexp})
if $log->is_trace();
@@ -1857,7 +1890,7 @@ sub parse_ingredients_text ($product_ref) {
$ingredient =~ s/^\s+//;
$ingredient =~ s/\s+$//;
- $ingredient_id = canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient);
+ $ingredient_id = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient);
if (exists_taxonomy_tag("ingredients", $ingredient_id)) {
$ingredient_recognized = 1;
@@ -1875,22 +1908,22 @@ sub parse_ingredients_text ($product_ref) {
my @maybe_origins_ingredients = ();
# California almonds
- if (($product_lc eq "en") and ($ingredient =~ /^(\S+) (.+)$/)) {
+ if (($ingredients_lc eq "en") and ($ingredient =~ /^(\S+) (.+)$/)) {
push @maybe_origins_ingredients, [$1, $2];
}
# South Carolina black olives
- if (($product_lc eq "en") and ($ingredient =~ /^(\S+ \S+) (.+)$/)) {
+ if (($ingredients_lc eq "en") and ($ingredient =~ /^(\S+ \S+) (.+)$/)) {
push @maybe_origins_ingredients, [$1, $2];
}
- if (($product_lc eq "en") and ($ingredient =~ /^(\S+ \S+ \S+) (.+)$/)) {
+ if (($ingredients_lc eq "en") and ($ingredient =~ /^(\S+ \S+ \S+) (.+)$/)) {
push @maybe_origins_ingredients, [$1, $2];
}
# Currently does not work: pitted California prunes
# Oranges from Florida
- if (defined $from{$product_lc}) {
- my $from = $from{$product_lc};
+ if (defined $from{$ingredients_lc}) {
+ my $from = $from{$ingredients_lc};
if ($ingredient =~ /^(.+)($from)(.+)$/i) {
push @maybe_origins_ingredients, [$3, $1];
}
@@ -1903,7 +1936,7 @@ sub parse_ingredients_text ($product_ref) {
# skip origins that are too small (avoid false positives with country initials etc.)
next if (length($maybe_origin) < 4);
- my $origin_id = canonicalize_taxonomy_tag($product_lc, "origins", $maybe_origin);
+ my $origin_id = canonicalize_taxonomy_tag($ingredients_lc, "origins", $maybe_origin);
if ((exists_taxonomy_tag("origins", $origin_id)) and ($origin_id ne "en:unknown")) {
$debug_ingredients and $log->debug(
@@ -1917,21 +1950,21 @@ sub parse_ingredients_text ($product_ref) {
$origin = $origin_id;
$ingredient = $maybe_ingredient;
- $ingredient_id = canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient);
+ $ingredient_id = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient);
last;
}
}
# Try to remove ingredients processing "cooked rice" -> "rice"
- if (defined $ingredients_processing_regexps{$product_lc}) {
+ if (defined $ingredients_processing_regexps{$ingredients_lc}) {
my $matches = 0;
my $new_ingredient = $ingredient;
my $new_processing = '';
my $matching = 1; # remove prefixes / suffixes one by one
while ($matching) {
$matching = 0;
- foreach
- my $ingredient_processing_regexp_ref (@{$ingredients_processing_regexps{$product_lc}})
+ foreach my $ingredient_processing_regexp_ref (
+ @{$ingredients_processing_regexps{$ingredients_lc}})
{
my $regexp = $ingredient_processing_regexp_ref->[1];
$debug_ingredients and $log->trace("checking processing regexps",
@@ -1941,22 +1974,22 @@ sub parse_ingredients_text ($product_ref) {
if (
# match before or after the ingredient, require a space
(
- #($product_lc =~ /^(en|es|it|fr)$/)
+ #($ingredients_lc =~ /^(en|es|it|fr)$/)
(
- ($product_lc eq 'ar')
- or ($product_lc eq 'bg')
- or ($product_lc eq 'bs')
- or ($product_lc eq 'cs')
- or ($product_lc eq 'el')
- or ($product_lc eq 'en')
- or ($product_lc eq 'es')
- or ($product_lc eq 'fr')
- or ($product_lc eq 'hr')
- or ($product_lc eq 'it')
- or ($product_lc eq 'mk')
- or ($product_lc eq 'pl')
- or ($product_lc eq 'sl')
- or ($product_lc eq 'sr')
+ ($ingredients_lc eq 'ar')
+ or ($ingredients_lc eq 'bg')
+ or ($ingredients_lc eq 'bs')
+ or ($ingredients_lc eq 'cs')
+ or ($ingredients_lc eq 'el')
+ or ($ingredients_lc eq 'en')
+ or ($ingredients_lc eq 'es')
+ or ($ingredients_lc eq 'fr')
+ or ($ingredients_lc eq 'hr')
+ or ($ingredients_lc eq 'it')
+ or ($ingredients_lc eq 'mk')
+ or ($ingredients_lc eq 'pl')
+ or ($ingredients_lc eq 'sl')
+ or ($ingredients_lc eq 'sr')
)
and ($new_ingredient =~ /(^($regexp)\b|\b($regexp)$)/i)
)
@@ -1964,10 +1997,10 @@ sub parse_ingredients_text ($product_ref) {
# match before or after the ingredient, does not require a space
or (
(
- ($product_lc eq 'de')
- or ($product_lc eq 'hu')
- or ($product_lc eq 'ja')
- or ($product_lc eq 'nl')
+ ($ingredients_lc eq 'de')
+ or ($ingredients_lc eq 'hu')
+ or ($ingredients_lc eq 'ja')
+ or ($ingredients_lc eq 'nl')
)
and ($new_ingredient =~ /(^($regexp)|($regexp)$)/i)
)
@@ -1976,12 +2009,12 @@ sub parse_ingredients_text ($product_ref) {
# match before the ingredient, require a space
or (
(
- ($product_lc eq 'da')
- or ($product_lc eq 'fi')
- or ($product_lc eq 'nb')
- or ($product_lc eq 'no')
- or ($product_lc eq 'nn')
- or ($product_lc eq 'sv')
+ ($ingredients_lc eq 'da')
+ or ($ingredients_lc eq 'fi')
+ or ($ingredients_lc eq 'nb')
+ or ($ingredients_lc eq 'no')
+ or ($ingredients_lc eq 'nn')
+ or ($ingredients_lc eq 'sv')
)
and ($new_ingredient =~ /(^($regexp)\b|($regexp)$)/i)
)
@@ -2013,7 +2046,7 @@ sub parse_ingredients_text ($product_ref) {
# Stop if we now have a known ingredient.
# e.g. "jambon cru en tranches" -> keep "jambon cru".
my $new_ingredient_id
- = canonicalize_taxonomy_tag($product_lc, "ingredients", $new_ingredient);
+ = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $new_ingredient);
if (exists_taxonomy_tag("ingredients", $new_ingredient_id)) {
$debug_ingredients and $log->debug(
@@ -2035,7 +2068,7 @@ sub parse_ingredients_text ($product_ref) {
if ($matches) {
my $new_ingredient_id
- = canonicalize_taxonomy_tag($product_lc, "ingredients", $new_ingredient);
+ = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $new_ingredient);
if (exists_taxonomy_tag("ingredients", $new_ingredient_id)) {
$debug_ingredients and $log->debug(
"found existing ingredient after removing processing",
@@ -2070,11 +2103,11 @@ sub parse_ingredients_text ($product_ref) {
# We need to be careful with stopwords, "produit" was a stopword,
# and "France" matched "produit de France" / made in France (bug #2927)
- my $label_id = canonicalize_taxonomy_tag($product_lc, "labels", $ingredient);
+ my $label_id = canonicalize_taxonomy_tag($ingredients_lc, "labels", $ingredient);
if (exists_taxonomy_tag("labels", $label_id)) {
# Add the label to the product
- add_tags_to_field($product_ref, $product_lc, "labels", $label_id);
+ add_tags_to_field($product_ref, $ingredients_lc, "labels", $label_id);
$ingredient_recognized = 1;
@@ -2268,8 +2301,8 @@ sub parse_ingredients_text ($product_ref) {
],
);
- if (defined $ignore_regexps{$product_lc}) {
- foreach my $regexp (@{$ignore_regexps{$product_lc}}) {
+ if (defined $ignore_regexps{$ingredients_lc}) {
+ foreach my $regexp (@{$ignore_regexps{$ingredients_lc}}) {
if ($ingredient =~ /$regexp/i) {
$debug_ingredients and $log->debug(
@@ -2290,7 +2323,7 @@ sub parse_ingredients_text ($product_ref) {
if (not $skip_ingredient) {
my %ingredient = (
- id => get_taxonomyid($product_ref->{lc}, $ingredient_id),
+ id => get_taxonomyid($ingredients_lc, $ingredient_id),
text => $ingredient
);
@@ -2484,18 +2517,19 @@ sub compute_ingredients_tags ($product_ref) {
my $field = "ingredients";
$product_ref->{ingredients_original_tags} = $product_ref->{ingredients_tags};
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
if (defined $taxonomy_fields{$field}) {
$product_ref->{$field . "_hierarchy"} = [
gen_ingredients_tags_hierarchy_taxonomy(
- $product_ref->{lc}, join(", ", @{$product_ref->{ingredients_original_tags}})
+ $ingredients_lc, join(", ", @{$product_ref->{ingredients_original_tags}})
)
];
$product_ref->{$field . "_tags"} = [];
my $unknown = 0;
my $known = 0;
foreach my $tag (@{$product_ref->{$field . "_hierarchy"}}) {
- my $tagid = get_taxonomyid($product_ref->{lc}, $tag);
+ my $tagid = get_taxonomyid($ingredients_lc, $tag);
push @{$product_ref->{$field . "_tags"}}, $tagid;
if (exists_taxonomy_tag("ingredients", $tagid)) {
$known++;
@@ -2551,11 +2585,12 @@ sub extract_ingredients_from_text ($product_ref) {
$product_ref->{specific_ingredients} = [];
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
+
# Ingredients origins may be listed in the origin field
# e.g. "Origin of the rice: Thailand."
- my $product_lc = $product_ref->{lc};
- if (defined $product_ref->{"origin_" . $product_lc}) {
- parse_origins_from_text($product_ref, $product_ref->{"origin_" . $product_lc});
+ if (defined $product_ref->{"origin_" . $ingredients_lc}) {
+ parse_origins_from_text($product_ref, $product_ref->{"origin_" . $ingredients_lc});
}
# Add specific ingredients from labels
@@ -4416,7 +4451,6 @@ sub cut_ingredients_text_for_lang ($text, $language) {
}
sub clean_ingredients_text ($product_ref) {
-
if (defined $product_ref->{languages_codes}) {
foreach my $language (keys %{$product_ref->{languages_codes}}) {
@@ -4438,7 +4472,7 @@ sub clean_ingredients_text ($product_ref) {
$product_ref->{"ingredients_text_" . $language} = $text;
}
- if ($language eq $product_ref->{lc}) {
+ if ($language eq ($product_ref->{ingredients_lc} || $product_ref->{lc})) {
$product_ref->{"ingredients_text"} = $product_ref->{"ingredients_text_" . $language};
}
}
@@ -4462,9 +4496,9 @@ sub is_compound_word_with_dash ($word_lc, $compound_word) {
# additive class + additive (e.g. "colour caramel" -> "colour : caramel"
# warning: the additive class may also be the start of the name of an additive.
# e.g. "regulatory kwasowości: kwas cytrynowy i cytryniany sodu." -> "kwas" means acid / acidifier.
-sub separate_additive_class ($product_lc, $additive_class, $spaces, $colon, $after) {
+sub separate_additive_class ($ingredients_lc, $additive_class, $spaces, $colon, $after) {
- my $and = $and{$product_lc} || " and ";
+ my $and = $and{$ingredients_lc} || " and ";
# check that we have an additive after the additive class
# keep only what is before the first separator
@@ -4485,13 +4519,13 @@ sub separate_additive_class ($product_lc, $additive_class, $spaces, $colon, $aft
if (
(
not exists_taxonomy_tag(
- "additives", canonicalize_taxonomy_tag($product_lc, "additives", $additive_class . " " . $after)
+ "additives", canonicalize_taxonomy_tag($ingredients_lc, "additives", $additive_class . " " . $after)
)
)
and (
- exists_taxonomy_tag("additives", canonicalize_taxonomy_tag($product_lc, "additives", $after))
+ exists_taxonomy_tag("additives", canonicalize_taxonomy_tag($ingredients_lc, "additives", $after))
or ((defined $after2)
- and exists_taxonomy_tag("additives", canonicalize_taxonomy_tag($product_lc, "additives", $after2)))
+ and exists_taxonomy_tag("additives", canonicalize_taxonomy_tag($ingredients_lc, "additives", $after2)))
)
)
{
@@ -4535,7 +4569,7 @@ sub replace_additive ($number, $letter, $variant) {
return $additive;
}
-=head2 develop_ingredients_categories_and_types ( $product_lc, $text ) - turn "oil (sunflower, olive and palm)" into "sunflower oil, olive oil, palm oil"
+=head2 develop_ingredients_categories_and_types ( $ingredients_lc, $text ) - turn "oil (sunflower, olive and palm)" into "sunflower oil, olive oil, palm oil"
Some ingredients are specified by an ingredient "category" (e.g. "oil", "flavouring") and a "type" (e.g. "sunflower", "palm" or "strawberry", "vanilla").
@@ -4718,11 +4752,11 @@ my %ingredients_categories_and_types = (
my @symbols = ('\*\*\*', '\*\*', '\*', '°°°', '°°', '°', '\(1\)', '\(2\)', '¹', '²');
my $symbols_regexp = join('|', @symbols);
-sub develop_ingredients_categories_and_types ($product_lc, $text) {
+sub develop_ingredients_categories_and_types ($ingredients_lc, $text) {
- if (defined $ingredients_categories_and_types{$product_lc}) {
+ if (defined $ingredients_categories_and_types{$ingredients_lc}) {
- foreach my $categories_and_types_ref (@{$ingredients_categories_and_types{$product_lc}}) {
+ foreach my $categories_and_types_ref (@{$ingredients_categories_and_types{$ingredients_lc}}) {
my $category_regexp = "";
foreach my $category (@{$categories_and_types_ref->[0]}) {
@@ -4735,10 +4769,10 @@ sub develop_ingredients_categories_and_types ($product_lc, $text) {
}
$category_regexp =~ s/^\|//;
- if ($product_lc eq "en") {
+ if ($ingredients_lc eq "en") {
$category_regexp = '(?:organic |fair trade )*(?:' . $category_regexp . ')(?:' . $symbols_regexp . ')*';
}
- elsif ($product_lc eq "fr") {
+ elsif ($ingredients_lc eq "fr") {
$category_regexp
= '(?:' . $category_regexp . ')(?: bio| biologique| équitable|s|\s|' . $symbols_regexp . ')*';
}
@@ -4762,36 +4796,36 @@ sub develop_ingredients_categories_and_types ($product_lc, $text) {
$text =~ s/($type_regexp)-($type_regexp)/$1, $2/g;
my $and = ' - ';
- if (defined $and{$product_lc}) {
- $and = $and{$product_lc};
+ if (defined $and{$ingredients_lc}) {
+ $and = $and{$ingredients_lc};
}
my $of = ' - ';
- if (defined $of{$product_lc}) {
- $of = $of{$product_lc};
+ if (defined $of{$ingredients_lc}) {
+ $of = $of{$ingredients_lc};
}
my $and_of = ' - ';
- if (defined $and_of{$product_lc}) {
- $and_of = $and_of{$product_lc};
+ if (defined $and_of{$ingredients_lc}) {
+ $and_of = $and_of{$ingredients_lc};
}
my $and_or = ' - ';
- if (defined $and_or{$product_lc}) {
- $and_or = $and_or{$product_lc};
+ if (defined $and_or{$ingredients_lc}) {
+ $and_or = $and_or{$ingredients_lc};
}
- if (($product_lc eq "en") or ($product_lc eq "ru") or ($product_lc eq "pl")) {
+ if (($ingredients_lc eq "en") or ($ingredients_lc eq "ru") or ($ingredients_lc eq "pl")) {
# vegetable oil (palm, sunflower and olive)
$text
- =~ s/($category_regexp)(?::|\(|\[| | $of )+((($type_regexp)($symbols_regexp|\s)*( |\/| \/ | - |,|, |$and|$of|$and_of|$and_or)+)+($type_regexp)($symbols_regexp|\s)*)\b(\s?(\)|\]))?/normalize_enumeration($product_lc,$1,$2)/ieg;
+ =~ s/($category_regexp)(?::|\(|\[| | $of )+((($type_regexp)($symbols_regexp|\s)*( |\/| \/ | - |,|, |$and|$of|$and_of|$and_or)+)+($type_regexp)($symbols_regexp|\s)*)\b(\s?(\)|\]))?/normalize_enumeration($ingredients_lc,$1,$2)/ieg;
# vegetable oil (palm)
$text
- =~ s/($category_regexp)\s?(?:\(|\[)\s?($type_regexp)\b(\s?(\)|\]))/normalize_enumeration($product_lc,$1,$2)/ieg;
+ =~ s/($category_regexp)\s?(?:\(|\[)\s?($type_regexp)\b(\s?(\)|\]))/normalize_enumeration($ingredients_lc,$1,$2)/ieg;
# vegetable oil: palm
$text
- =~ s/($category_regexp)\s?(?::)\s?($type_regexp)(?=$separators|$)/normalize_enumeration($product_lc,$1,$2)/ieg;
+ =~ s/($category_regexp)\s?(?::)\s?($type_regexp)(?=$separators|$)/normalize_enumeration($ingredients_lc,$1,$2)/ieg;
}
- elsif ($product_lc eq "fr") {
+ elsif ($ingredients_lc eq "fr") {
# arôme naturel de pomme avec d'autres âromes
$text =~ s/ (ou|et|avec) (d')?autres /, /g;
@@ -4803,21 +4837,21 @@ sub develop_ingredients_categories_and_types ($product_lc, $text) {
# TODO 18/07/2020 remove when we have a better solution
$text =~ s/fer (é|e)l(é|e)mentaire/fer_élémentaire/ig;
$text
- =~ s/($category_regexp)(?::|\(|\[| | de | d')+((($type_regexp)($symbols_regexp|\s)*( |\/| \/ | - |,|, | et | de | et de | et d'| d')+)+($type_regexp)($symbols_regexp|\s)*)\b(\s?(\)|\]))?/normalize_enumeration($product_lc,$1,$2)/ieg;
+ =~ s/($category_regexp)(?::|\(|\[| | de | d')+((($type_regexp)($symbols_regexp|\s)*( |\/| \/ | - |,|, | et | de | et de | et d'| d')+)+($type_regexp)($symbols_regexp|\s)*)\b(\s?(\)|\]))?/normalize_enumeration($ingredients_lc,$1,$2)/ieg;
$text =~ s/fer_élémentaire/fer élémentaire/ig;
# huile végétale (colza)
$text
- =~ s/($category_regexp)\s?(?:\(|\[)\s?($type_regexp)\b(\s?(\)|\]))/normalize_enumeration($product_lc,$1,$2)/ieg;
+ =~ s/($category_regexp)\s?(?:\(|\[)\s?($type_regexp)\b(\s?(\)|\]))/normalize_enumeration($ingredients_lc,$1,$2)/ieg;
# huile végétale : colza,
$text
- =~ s/($category_regexp)\s?(?::)\s?($type_regexp)(?=$separators|$)/normalize_enumeration($product_lc,$1,$2)/ieg;
+ =~ s/($category_regexp)\s?(?::)\s?($type_regexp)(?=$separators|$)/normalize_enumeration($ingredients_lc,$1,$2)/ieg;
}
}
# Some additives have "et" in their name: need to recombine them
- if ($product_lc eq "fr") {
+ if ($ingredients_lc eq "fr") {
# Sels de sodium et de potassium de complexes cupriques de chlorophyllines,
@@ -4865,7 +4899,7 @@ INFO
return $text;
}
-=head2 preparse_ingredients_text ($product_lc, $text) - normalize the ingredient list to make parsing easier
+=head2 preparse_ingredients_text ($ingredients_lc, $text) - normalize the ingredient list to make parsing easier
This function transform the ingredients list in a more normalized list that is easier to parse.
@@ -4892,7 +4926,7 @@ It does the following:
=cut
-sub preparse_ingredients_text ($product_lc, $text) {
+sub preparse_ingredients_text ($ingredients_lc, $text) {
not defined $text and return;
@@ -4904,11 +4938,11 @@ sub preparse_ingredients_text ($product_lc, $text) {
state $prev_text = '';
state $prev_return = '';
- if (($product_lc eq $prev_lc) && ($text eq $prev_text)) {
+ if (($ingredients_lc eq $prev_lc) && ($text eq $prev_text)) {
return $prev_return;
}
- $prev_lc = $product_lc;
+ $prev_lc = $ingredients_lc;
$prev_text = $text;
if ((scalar keys %labels_regexps) == 0) {
@@ -4919,19 +4953,19 @@ sub preparse_ingredients_text ($product_lc, $text) {
init_origins_regexps();
}
- my $and = $and{$product_lc} || " and ";
+ my $and = $and{$ingredients_lc} || " and ";
my $and_without_spaces = $and;
$and_without_spaces =~ s/^ //;
$and_without_spaces =~ s/ $//;
my $of = ' - ';
- if (defined $of{$product_lc}) {
- $of = $of{$product_lc};
+ if (defined $of{$ingredients_lc}) {
+ $of = $of{$ingredients_lc};
}
my $and_of = ' - ';
- if (defined $and_of{$product_lc}) {
- $and_of = $and_of{$product_lc};
+ if (defined $and_of{$ingredients_lc}) {
+ $and_of = $and_of{$ingredients_lc};
}
# Spanish "and" is y or e when before "i" or "hi"
@@ -4942,8 +4976,8 @@ sub preparse_ingredients_text ($product_lc, $text) {
# replace "and / or" by "and"
# except if followed by a separator, a digit, or "and", to avoid false positives
my $and_or = ' - ';
- if (defined $and_or{$product_lc}) {
- $and_or = $and_or{$product_lc};
+ if (defined $and_or{$ingredients_lc}) {
+ $and_or = $and_or{$ingredients_lc};
$text =~ s/($and_or)(?!($and_without_spaces |\d|$separators))/$and/ig;
}
@@ -4965,7 +4999,7 @@ sub preparse_ingredients_text ($product_lc, $text) {
# number + gr / grams -> g
$text =~ s/(\d\s*)(gr|gram|grams)\b/$1g/ig;
- if ($product_lc eq 'fr') {
+ if ($ingredients_lc eq 'fr') {
$text =~ s/(\d\s*)(gramme|grammes)\b/$1g/ig;
}
@@ -4978,7 +5012,7 @@ sub preparse_ingredients_text ($product_lc, $text) {
$text =~ s/—/-/g;
# abbreviations, replace language specific abbreviations first
- foreach my $abbreviations_lc ($product_lc, "all") {
+ foreach my $abbreviations_lc ($ingredients_lc, "all") {
if (defined $abbreviations{$abbreviations_lc}) {
foreach my $abbreviation_ref (@{$abbreviations{$abbreviations_lc}}) {
my $source = $abbreviation_ref->[0];
@@ -4998,7 +5032,7 @@ sub preparse_ingredients_text ($product_lc, $text) {
# céleri - rave 3.9% -> stop at numbers
$text
- =~ s/((^|$separators)([^,;\-\/\.0-9]+?) - ([^,;\-\/\.0-9]+?)(?=[0-9]|$separators|$))/is_compound_word_with_dash($product_lc,$1)/ieg;
+ =~ s/((^|$separators)([^,;\-\/\.0-9]+?) - ([^,;\-\/\.0-9]+?)(?=[0-9]|$separators|$))/is_compound_word_with_dash($ingredients_lc,$1)/ieg;
# vitamins...
# vitamines A, B1, B2, B5, B6, B9, B12, C, D, H, PP et E (lactose, protéines de lait)
@@ -5051,7 +5085,7 @@ sub preparse_ingredients_text ($product_lc, $text) {
}
$text
- =~ s/\b(e|ins|sin|i-n-s|s-i-n|i\.n\.s\.?|s\.i\.n\.?)(:|\(|\[| | n| nb|#|°)+((($additivesregexp)( |\/| \/ | - |,|, |$and))+($additivesregexp))\b(\s?(\)|\]))?/normalize_additives_enumeration($product_lc,$3)/ieg;
+ =~ s/\b(e|ins|sin|i-n-s|s-i-n|i\.n\.s\.?|s\.i\.n\.?)(:|\(|\[| | n| nb|#|°)+((($additivesregexp)( |\/| \/ | - |,|, |$and))+($additivesregexp))\b(\s?(\)|\]))?/normalize_additives_enumeration($ingredients_lc,$3)/ieg;
# in India: INS 240 instead of E 240, bug #1133)
# also INS N°420, bug #3618
@@ -5088,11 +5122,11 @@ sub preparse_ingredients_text ($product_lc, $text) {
# additive class + additive (e.g. "colour caramel" -> "colour : caramel"
# warning: the additive class may also be the start of the name of an additive.
# e.g. "regulatory kwasowości: kwas cytrynowy i cytryniany sodu." -> "kwas" means acid / acidifier.
- if (defined $additives_classes_regexps{$product_lc}) {
- my $regexp = $additives_classes_regexps{$product_lc};
+ if (defined $additives_classes_regexps{$ingredients_lc}) {
+ my $regexp = $additives_classes_regexps{$ingredients_lc};
# negative look ahead so that the additive class is not preceded by other words
# e.g. "de l'acide" should not match "acide"
- $text =~ s/(?debug("preparse_ingredients_text - before language specific preparsing", {text => $text}) if $log->is_debug();
- if ($product_lc eq 'de') {
+ if ($ingredients_lc eq 'de') {
# deletes comma in "Bienenwachs, weiß und gelb" since it is just one ingredient
$text =~ s/Bienenwachs, weiß und gelb/Bienenwachs weiß und gelb/ig;
# deletes brackets in "Bienenwachs, weiß und gelb" since it is just one ingredient
$text =~ s/Bienenwachs \(weiß und gelb\)/Bienenwachs weiß und gelb/ig;
}
- elsif ($product_lc eq 'es') {
+ elsif ($ingredients_lc eq 'es') {
# Special handling for sal as it can mean salt or shorea robusta
# aceites vegetales (palma, shea, sal (shorea robusta), hueso de mango)
$text =~ s/\bsal \(shorea robusta\)/shorea robusta/ig;
$text =~ s/\bshorea robusta \(sal\)/shorea robusta/ig;
}
- elsif ($product_lc eq 'fi') {
+ elsif ($ingredients_lc eq 'fi') {
# Organic label can appear as a part of a longer word.
# Separate it so it can be detected
$text =~ s/\b(luomu)\B/$1 /ig;
}
- elsif ($product_lc eq 'fr') {
+ elsif ($ingredients_lc eq 'fr') {
# huiles de palme et de
@@ -5166,14 +5200,14 @@ sub preparse_ingredients_text ($product_lc, $text) {
$text =~ s/dient\(s\)/dients/ig;
$text =~ s/\bissu(\(e\))?(\(s\))?/issu/ig;
}
- elsif ($product_lc eq 'pl') {
+ elsif ($ingredients_lc eq 'pl') {
# remove stopwords
$text =~ s/w? (zmiennych|różnych)? proporcjach?//i;
}
- $text = develop_ingredients_categories_and_types($product_lc, $text);
+ $text = develop_ingredients_categories_and_types($ingredients_lc, $text);
# vitamines A, B1, B2, B5, B6, B9, B12, C, D, H, PP et E
# vitamines (A, B1, B2, B5, B6, B9, B12, C, D, H, PP et E)
@@ -5196,22 +5230,22 @@ sub preparse_ingredients_text ($product_lc, $text) {
# Add synonyms in target language
if (defined $translations_to{vitamins}) {
foreach my $vitamin (keys %{$translations_to{vitamins}}) {
- if (defined $translations_to{vitamins}{$vitamin}{$product_lc}) {
- push @vitaminssuffixes, $translations_to{vitamins}{$vitamin}{$product_lc};
+ if (defined $translations_to{vitamins}{$vitamin}{$ingredients_lc}) {
+ push @vitaminssuffixes, $translations_to{vitamins}{$vitamin}{$ingredients_lc};
}
}
}
# Add synonyms in target language
my $vitamin_in_lc
- = get_string_id_for_lang($product_lc, display_taxonomy_tag($product_lc, "ingredients", "en:vitamins"));
+ = get_string_id_for_lang($ingredients_lc, display_taxonomy_tag($ingredients_lc, "ingredients", "en:vitamins"));
$vitamin_in_lc =~ s/^\w\w://;
if ( (defined $synonyms_for{ingredients})
- and (defined $synonyms_for{ingredients}{$product_lc})
- and (defined $synonyms_for{ingredients}{$product_lc}{$vitamin_in_lc}))
+ and (defined $synonyms_for{ingredients}{$ingredients_lc})
+ and (defined $synonyms_for{ingredients}{$ingredients_lc}{$vitamin_in_lc}))
{
- foreach my $synonym (@{$synonyms_for{ingredients}{$product_lc}{$vitamin_in_lc}}) {
+ foreach my $synonym (@{$synonyms_for{ingredients}{$ingredients_lc}{$vitamin_in_lc}}) {
$vitaminsprefixregexp .= '|' . $synonym;
}
}
@@ -5245,7 +5279,7 @@ sub preparse_ingredients_text ($product_lc, $text) {
# vitamines (B1, acide folique (B9)) <-- we need to match (B9) which is not followed by a \b boundary, hence the ((\s?((\)|\]))|\b)) in the regexp below
$text
- =~ s/($vitaminsprefixregexp)(:|\(|\[| )+((($vitaminssuffixregexp)( |\/| \/ | - |,|, |$and)+)+($vitaminssuffixregexp))((\s?((\)|\]))|\b))/normalize_vitamins_enumeration($product_lc,$3)/ieg;
+ =~ s/($vitaminsprefixregexp)(:|\(|\[| )+((($vitaminssuffixregexp)( |\/| \/ | - |,|, |$and)+)+($vitaminssuffixregexp))((\s?((\)|\]))|\b))/normalize_vitamins_enumeration($ingredients_lc,$3)/ieg;
# Allergens and traces
# Traces de lait, d'oeufs et de soja.
@@ -5253,36 +5287,36 @@ sub preparse_ingredients_text ($product_lc, $text) {
foreach my $allergens_type ("allergens", "traces") {
- if (defined $contains_or_may_contain_regexps{$allergens_type}{$product_lc}) {
+ if (defined $contains_or_may_contain_regexps{$allergens_type}{$ingredients_lc}) {
- my $contains_or_may_contain_regexp = $contains_or_may_contain_regexps{$allergens_type}{$product_lc};
- my $allergens_regexp = $allergens_regexps{$product_lc};
+ my $contains_or_may_contain_regexp = $contains_or_may_contain_regexps{$allergens_type}{$ingredients_lc};
+ my $allergens_regexp = $allergens_regexps{$ingredients_lc};
# stopwords
# e.g. Kann Spuren von Senf und Sellerie enthalten.
my $stopwords = "";
- if (defined $allergens_stopwords{$product_lc}) {
- $stopwords = $allergens_stopwords{$product_lc};
+ if (defined $allergens_stopwords{$ingredients_lc}) {
+ $stopwords = $allergens_stopwords{$ingredients_lc};
}
# $contains_or_may_contain_regexp may be the end of a sentence, remove the beginning
# e.g. this product has been manufactured in a factory that also uses...
# Some text with comma May contain ... -> Some text with comma, May contain
# ! does not work in German and languages that have words with a capital letter
- if ($product_lc ne "de") {
+ if ($ingredients_lc ne "de") {
my $ucfirst_contains_or_may_contain_regexp = $contains_or_may_contain_regexp;
$ucfirst_contains_or_may_contain_regexp =~ s/(^|\|)(\w)/$1 . uc($2)/ieg;
$text =~ s/([a-z]) ($ucfirst_contains_or_may_contain_regexp)/$1, $2/g;
}
#$log->debug("allergens regexp", { regex => "s/([^,-\.;\(\)\/]*)\b($contains_or_may_contain_regexp)\b(:|\(|\[| |$and|$of)+((($allergens_regexp)( |\/| \/ | - |,|, |$and|$of|$and_of)+)+($allergens_regexp))\b(s?(\)|\]))?" }) if $log->is_debug();
- #$log->debug("allergens", { lc => $product_lc, may_contain_regexps => \%may_contain_regexps, contains_or_may_contain_regexp => $contains_or_may_contain_regexp, text => $text }) if $log->is_debug();
+ #$log->debug("allergens", { lc => $ingredients_lc, may_contain_regexps => \%may_contain_regexps, contains_or_may_contain_regexp => $contains_or_may_contain_regexp, text => $text }) if $log->is_debug();
# warning: we should remove a parenthesis at the end only if we remove one at the beginning
# e.g. contains (milk, eggs) -> contains milk, eggs
# chocolate (contains milk) -> chocolate (contains milk)
$text
- =~ s/([^,-\.;\(\)\/]*)\b($contains_or_may_contain_regexp)\b((:|\(|\[| |$of)+)((_?($allergens_regexp)_?\b((\s)($stopwords)\b)*( |\/| \/ | - |,|, |$and|$of|$and_of)+)*_?($allergens_regexp)_?)\b((\s)($stopwords)\b)*(\s?(\)|\]))?/normalize_allergens_enumeration($allergens_type,$product_lc,$3,$5,$17)/ieg;
+ =~ s/([^,-\.;\(\)\/]*)\b($contains_or_may_contain_regexp)\b((:|\(|\[| |$of)+)((_?($allergens_regexp)_?\b((\s)($stopwords)\b)*( |\/| \/ | - |,|, |$and|$of|$and_of)+)*_?($allergens_regexp)_?)\b((\s)($stopwords)\b)*(\s?(\)|\]))?/normalize_allergens_enumeration($allergens_type,$ingredients_lc,$3,$5,$17)/ieg;
# we may have added an extra dot in order to make sure we have at least one
$text =~ s/\.\./\./g;
}
@@ -5293,7 +5327,7 @@ sub preparse_ingredients_text ($product_lc, $text) {
# Pâte de cacao°* du Pérou 65 %, sucre de canne°*, beurre de cacao°*. °Issus de l'agriculture biologique (100 %). *Issus du commerce équitable (100 % du poids total avec 93 % SPP).
# riz* de Camargue IGP(1) (16,5%) (riz complet*, riz rouge complet*, huiles* (tournesol*, olive* vierge extra), sel marin. *issus de l'agriculture biologique. (1) IGP : Indication Géographique Protégée.
- if (defined $labels_regexps{$product_lc}) {
+ if (defined $labels_regexps{$ingredients_lc}) {
foreach my $symbol (@symbols) {
# Find the last occurence of the symbol or symbol in parenthesis: * (*)
@@ -5302,7 +5336,7 @@ sub preparse_ingredients_text ($product_lc, $text) {
my $after = $';
#print STDERR "symbol: $symbol - after: $after\n";
foreach my $labelid (@labels) {
- my $regexp = $labels_regexps{$product_lc}{$labelid};
+ my $regexp = $labels_regexps{$ingredients_lc}{$labelid};
if (defined $regexp) {
#print STDERR "-- label: $labelid - regexp: $regexp\n";
# try to also match optional precisions like "Issus de l'agriculture biologique (100 % du poids total)"
@@ -5311,8 +5345,8 @@ sub preparse_ingredients_text ($product_lc, $text) {
my $label = $1;
$text
=~ s/^(.*)(\($symbol\)|$symbol)(?!\))\s?(:|=)?\s?$label\s*(\([^\)]+\))?\s*\.?\s*/$1 /i;
- my $product_lc_label = display_taxonomy_tag($product_lc, "labels", $labelid);
- $text =~ s/$symbol/ $product_lc_label /g;
+ my $ingredients_lc_label = display_taxonomy_tag($ingredients_lc, "labels", $labelid);
+ $text =~ s/$symbol/ $ingredients_lc_label /g;
last;
}
}
@@ -5336,10 +5370,10 @@ sub preparse_ingredients_text ($product_lc, $text) {
sub extract_ingredients_classes_from_text ($product_ref) {
not defined $product_ref->{ingredients_text} and return;
-
- my $text = preparse_ingredients_text($product_ref->{lc}, $product_ref->{ingredients_text});
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
+ my $text = preparse_ingredients_text($ingredients_lc, $product_ref->{ingredients_text});
# do not match anything if we don't have a translation for "and"
- my $and = $and{$product_ref->{lc}} || " will not match ";
+ my $and = $and{$ingredients_lc} || " will not match ";
$and =~ s/ /-/g;
# remove % / percent (to avoid identifying 100% as E100 in some cases)
@@ -5349,7 +5383,7 @@ sub extract_ingredients_classes_from_text ($product_ref) {
my @ingredients_ids = ();
foreach my $ingredient (@ingredients) {
- my $ingredientid = get_string_id_for_lang($product_ref->{lc}, $ingredient);
+ my $ingredientid = get_string_id_for_lang($ingredients_lc, $ingredient);
if ((defined $ingredientid) and ($ingredientid ne '')) {
# split additives
@@ -5362,16 +5396,15 @@ sub extract_ingredients_classes_from_text ($product_ref) {
#print STDERR "ingredients_classes - ingredient1: $ingredientid1 - ingredient2: $ingredientid2\n";
# check if the whole ingredient is an additive
- my $canon_ingredient_additive
- = canonicalize_taxonomy_tag($product_ref->{lc}, "additives", $ingredientid);
+ my $canon_ingredient_additive = canonicalize_taxonomy_tag($ingredients_lc, "additives", $ingredientid);
if (not exists_taxonomy_tag("additives", $canon_ingredient_additive)) {
# otherwise check the 2 sub ingredients
my $canon_ingredient_additive1
- = canonicalize_taxonomy_tag($product_ref->{lc}, "additives", $ingredientid1);
+ = canonicalize_taxonomy_tag($ingredients_lc, "additives", $ingredientid1);
my $canon_ingredient_additive2
- = canonicalize_taxonomy_tag($product_ref->{lc}, "additives", $ingredientid2);
+ = canonicalize_taxonomy_tag($ingredients_lc, "additives", $ingredientid2);
if ( (exists_taxonomy_tag("additives", $canon_ingredient_additive1))
and (exists_taxonomy_tag("additives", $canon_ingredient_additive2)))
@@ -5445,7 +5478,7 @@ sub extract_ingredients_classes_from_text ($product_ref) {
# additive class?
my $canon_ingredient_additive_class
- = canonicalize_taxonomy_tag($product_ref->{lc}, "additives_classes", $ingredient_id_copy);
+ = canonicalize_taxonomy_tag($ingredients_lc, "additives_classes", $ingredient_id_copy);
if (exists_taxonomy_tag("additives_classes", $canon_ingredient_additive_class)) {
$current_additive_class = $canon_ingredient_additive_class;
@@ -5454,21 +5487,20 @@ sub extract_ingredients_classes_from_text ($product_ref) {
}
# additive?
- my $canon_ingredient = canonicalize_taxonomy_tag($product_ref->{lc}, $tagtype, $ingredient_id_copy);
+ my $canon_ingredient = canonicalize_taxonomy_tag($ingredients_lc, $tagtype, $ingredient_id_copy);
# in Hong Kong, the E- can be omitted in E-numbers
my $canon_e_ingredient
- = canonicalize_taxonomy_tag($product_ref->{lc}, $tagtype, "e" . $ingredient_id_copy);
+ = canonicalize_taxonomy_tag($ingredients_lc, $tagtype, "e" . $ingredient_id_copy);
my $canon_ingredient_vitamins
- = canonicalize_taxonomy_tag($product_ref->{lc}, "vitamins", $ingredient_id_copy);
+ = canonicalize_taxonomy_tag($ingredients_lc, "vitamins", $ingredient_id_copy);
my $canon_ingredient_minerals
- = canonicalize_taxonomy_tag($product_ref->{lc}, "minerals", $ingredient_id_copy);
+ = canonicalize_taxonomy_tag($ingredients_lc, "minerals", $ingredient_id_copy);
my $canon_ingredient_amino_acids
- = canonicalize_taxonomy_tag($product_ref->{lc}, "amino_acids", $ingredient_id_copy);
+ = canonicalize_taxonomy_tag($ingredients_lc, "amino_acids", $ingredient_id_copy);
my $canon_ingredient_nucleotides
- = canonicalize_taxonomy_tag($product_ref->{lc}, "nucleotides", $ingredient_id_copy);
+ = canonicalize_taxonomy_tag($ingredients_lc, "nucleotides", $ingredient_id_copy);
my $canon_ingredient_other_nutritional_substances
- = canonicalize_taxonomy_tag($product_ref->{lc}, "other_nutritional_substances",
- $ingredient_id_copy);
+ = canonicalize_taxonomy_tag($ingredients_lc, "other_nutritional_substances", $ingredient_id_copy);
$product_ref->{$tagtype} .= " [ $ingredient_id_copy -> $canon_ingredient ";
@@ -5688,14 +5720,14 @@ sub extract_ingredients_classes_from_text ($product_ref) {
and (
not exists_taxonomy_tag(
"ingredients",
- canonicalize_taxonomy_tag($product_ref->{lc}, "ingredients", $ingredient_id_copy)
+ canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient_id_copy)
)
)
)
{
my ($corrected_canon_tagid, $corrected_tagid, $corrected_tag)
- = spellcheck_taxonomy_tag($product_ref->{lc}, $tagtype, $ingredient_id_copy);
+ = spellcheck_taxonomy_tag($ingredients_lc, $tagtype, $ingredient_id_copy);
if (
(defined $corrected_canon_tagid)
and ($corrected_tag ne $ingredient_id_copy)
@@ -5717,10 +5749,10 @@ sub extract_ingredients_classes_from_text ($product_ref) {
$product_ref->{$tagtype}
.= " -- spell correction (lc: "
- . $product_ref->{lc}
+ . $ingredients_lc
. "): $ingredient_id_copy -> $corrected_tag";
print STDERR "spell correction (lc: "
- . $product_ref->{lc}
+ . $ingredients_lc
. "): $ingredient_id_copy -> $corrected_tag - code: $product_ref->{code}\n";
$ingredient_id_copy = $corrected_tag;
@@ -5735,11 +5767,11 @@ sub extract_ingredients_classes_from_text ($product_ref) {
# try to shorten the ingredient to make it less specific, to see if it matches then
# in last resort, try with the first (in French, Spanish) or last (in English) word only
- if (($product_ref->{lc} eq 'en') and ($ingredient_id_copy =~ /^([^-]+)-/)) {
+ if (($ingredients_lc eq 'en') and ($ingredient_id_copy =~ /^([^-]+)-/)) {
# soy-lecithin -> lecithin
$ingredient_id_copy = $';
}
- elsif ( (($product_ref->{lc} eq 'es') or ($product_ref->{lc} eq 'fr'))
+ elsif ( (($ingredients_lc eq 'es') or ($ingredients_lc eq 'fr'))
and ($ingredient_id_copy =~ /-([^-]+)$/))
{
# lecitina-de-girasol -> lecitina-de -> lecitina
@@ -5899,7 +5931,7 @@ sub extract_ingredients_classes_from_text ($product_ref) {
# keep the old additives for France until we can fix the new taxonomy matching to support all special cases
# e.g. lecithine de soja
- #if ($product_ref->{lc} ne 'fr') {
+ #if ($ingredients_lc ne 'fr') {
# $product_ref->{additives_tags} = $product_ref->{new_additives_tags};
# $product_ref->{additives_tags_n} = $product_ref->{new_additives_tags_n};
#}
@@ -5988,6 +6020,7 @@ sub extract_ingredients_classes_from_text ($product_ref) {
sub replace_allergen ($language, $product_ref, $allergen, $before) {
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
my $field = "allergens";
my $traces_regexp = $may_contain_regexps{$language};
@@ -5997,7 +6030,7 @@ sub replace_allergen ($language, $product_ref, $allergen, $before) {
}
# to build the product allergens list, just use the ingredients in the main language
- if ($language eq $product_ref->{lc}) {
+ if ($language eq $ingredients_lc) {
# skip allergens like "moutarde et céleri" (will be caught later by replace_allergen_between_separators)
if (not(($language eq 'fr') and $allergen =~ / et /i)) {
$product_ref->{$field . "_from_ingredients"} .= $allergen . ', ';
@@ -6009,6 +6042,7 @@ sub replace_allergen ($language, $product_ref, $allergen, $before) {
sub replace_allergen_in_caps ($language, $product_ref, $allergen, $before) {
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
my $field = "allergens";
my $traces_regexp = $may_contain_regexps{$language};
@@ -6022,7 +6056,7 @@ sub replace_allergen_in_caps ($language, $product_ref, $allergen, $before) {
if (exists_taxonomy_tag("allergens", $tagid)) {
#$allergen = display_taxonomy_tag($product_ref->{lang},"allergens", $tagid);
# to build the product allergens list, just use the ingredients in the main language
- if ($language eq $product_ref->{lc}) {
+ if ($language eq $ingredients_lc) {
$product_ref->{$field . "_from_ingredients"} .= $allergen . ', ';
}
return '' . $allergen . '';
@@ -6034,6 +6068,7 @@ sub replace_allergen_in_caps ($language, $product_ref, $allergen, $before) {
sub replace_allergen_between_separators ($language, $product_ref, $start_separator, $allergen, $end_separator, $before)
{
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
my $field = "allergens";
#print STDERR "replace_allergen_between_separators - allergen: $allergen\n";
@@ -6087,7 +6122,7 @@ sub replace_allergen_between_separators ($language, $product_ref, $start_separat
if (($tagid ne "en:none") and (exists_taxonomy_tag("allergens", $tagid))) {
#$allergen = display_taxonomy_tag($product_ref->{lang},"allergens", $tagid);
# to build the product allergens list, just use the ingredients in the main language
- if ($language eq $product_ref->{lc}) {
+ if ($language eq $ingredients_lc) {
$product_ref->{$field . "_from_ingredients"} .= $allergen . ', ';
}
return
@@ -6185,6 +6220,8 @@ sub detect_allergens_from_text ($product_ref) {
init_allergens_regexps();
}
+ my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc};
+
# Keep allergens entered by users in the allergens and traces field
foreach my $field ("allergens", "traces") {
@@ -6264,7 +6301,7 @@ sub detect_allergens_from_text ($product_ref) {
$product_ref->{"ingredients_text_with_allergens_" . $language} = $text;
- if ($language eq $product_ref->{lc}) {
+ if ($language eq $ingredients_lc) {
$product_ref->{"ingredients_text_with_allergens"} = $text;
}
@@ -6275,8 +6312,8 @@ sub detect_allergens_from_text ($product_ref) {
# Use the language the tag have been entered in
my $traces_regexp;
- if (defined $may_contain_regexps{$product_ref->{traces_lc} || $product_ref->{lc}}) {
- $traces_regexp = $may_contain_regexps{$product_ref->{traces_lc} || $product_ref->{lc}};
+ if (defined $may_contain_regexps{$product_ref->{traces_lc} || $ingredients_lc}) {
+ $traces_regexp = $may_contain_regexps{$product_ref->{traces_lc} || $ingredients_lc};
}
if ( (defined $traces_regexp)
@@ -6298,7 +6335,7 @@ sub detect_allergens_from_text ($product_ref) {
# regenerate allergens and traces from the allergens_tags field so that it is prefixed with the values in the
# main language of the product (which may be different than the $tag_lc language of the interface)
- my $tag_lc = $product_ref->{$field . "_lc"} || $product_ref->{lc} || "?";
+ my $tag_lc = $product_ref->{$field . "_lc"} || $ingredients_lc || "?";
$product_ref->{$field . "_from_user"} = "($tag_lc) " . ($product_ref->{$field} // "");
$product_ref->{$field . "_hierarchy"} = [gen_tags_hierarchy_taxonomy($tag_lc, $field, $product_ref->{$field})];
$product_ref->{$field} = join(',', @{$product_ref->{$field . "_hierarchy"}});
@@ -6314,11 +6351,11 @@ sub detect_allergens_from_text ($product_ref) {
$allergens .= ", " . $product_ref->{$field};
}
- $product_ref->{$field . "_hierarchy"} = [gen_tags_hierarchy_taxonomy($product_ref->{lc}, $field, $allergens)];
+ $product_ref->{$field . "_hierarchy"} = [gen_tags_hierarchy_taxonomy($ingredients_lc, $field, $allergens)];
$product_ref->{$field . "_tags"} = [];
# print STDERR "result for $field : ";
foreach my $tag (@{$product_ref->{$field . "_hierarchy"}}) {
- push @{$product_ref->{$field . "_tags"}}, get_taxonomyid($product_ref->{lc}, $tag);
+ push @{$product_ref->{$field . "_tags"}}, get_taxonomyid($ingredients_lc, $tag);
# print STDERR " - $tag";
}
# print STDERR "\n";
diff --git a/lib/ProductOpener/KnowledgePanels.pm b/lib/ProductOpener/KnowledgePanels.pm
index af37041f42271..5c9dadc450ead 100644
--- a/lib/ProductOpener/KnowledgePanels.pm
+++ b/lib/ProductOpener/KnowledgePanels.pm
@@ -1146,7 +1146,7 @@ sub create_ingredients_panel ($product_ref, $target_lc, $target_cc, $options_ref
my $ingredients_text = $product_ref->{ingredients_text};
my $ingredients_text_with_allergens = $product_ref->{ingredients_text_with_allergens};
- my $ingredients_text_lc = $product_ref->{lc};
+ my $ingredients_text_lc = $product_ref->{ingredients_lc};
if ( (defined $product_ref->{"ingredients_text" . "_" . $target_lc})
and ($product_ref->{"ingredients_text" . "_" . $target_lc} ne ''))
diff --git a/lib/ProductOpener/Products.pm b/lib/ProductOpener/Products.pm
index e937653f1f42e..644be0b8b9090 100644
--- a/lib/ProductOpener/Products.pm
+++ b/lib/ProductOpener/Products.pm
@@ -3558,6 +3558,8 @@ sub analyze_and_enrich_product_data ($product_ref, $response_ref) {
compute_languages($product_ref); # need languages for allergens detection and cleaning ingredients
# Ingredients classes
+ # Select best language to parse ingredients
+ $product_ref->{ingredients_lc} = select_ingredients_lc($product_ref);
clean_ingredients_text($product_ref);
extract_ingredients_from_text($product_ref);
extract_ingredients_classes_from_text($product_ref);
diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-existing-product.json b/tests/integration/expected_test_results/api_v2_product_read/get-existing-product.json
index 15ab7340f7303..279926ce5412e 100644
--- a/tests/integration/expected_test_results/api_v2_product_read/get-existing-product.json
+++ b/tests/integration/expected_test_results/api_v2_product_read/get-existing-product.json
@@ -646,6 +646,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-fields-all-knowledge-panels.json b/tests/integration/expected_test_results/api_v2_product_read/get-fields-all-knowledge-panels.json
index 5b578032d3ca8..a48ea19a83962 100644
--- a/tests/integration/expected_test_results/api_v2_product_read/get-fields-all-knowledge-panels.json
+++ b/tests/integration/expected_test_results/api_v2_product_read/get-fields-all-knowledge-panels.json
@@ -646,6 +646,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
@@ -1383,7 +1384,7 @@
{
"element_type" : "text",
"text_element" : {
- "html" : "apple, milk, eggs, palm oil"
+ "html" : "en: apple, milk, eggs, palm oil"
}
},
{
diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-fields-all.json b/tests/integration/expected_test_results/api_v2_product_read/get-fields-all.json
index 15ab7340f7303..279926ce5412e 100644
--- a/tests/integration/expected_test_results/api_v2_product_read/get-fields-all.json
+++ b/tests/integration/expected_test_results/api_v2_product_read/get-fields-all.json
@@ -646,6 +646,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-fields-attribute-groups-all-knowledge-panels.json b/tests/integration/expected_test_results/api_v2_product_read/get-fields-attribute-groups-all-knowledge-panels.json
index 19934070ea24b..af8f60293910e 100644
--- a/tests/integration/expected_test_results/api_v2_product_read/get-fields-attribute-groups-all-knowledge-panels.json
+++ b/tests/integration/expected_test_results/api_v2_product_read/get-fields-attribute-groups-all-knowledge-panels.json
@@ -970,6 +970,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
@@ -1707,7 +1708,7 @@
{
"element_type" : "text",
"text_element" : {
- "html" : "apple, milk, eggs, palm oil"
+ "html" : "en: apple, milk, eggs, palm oil"
}
},
{
diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-fields-raw.json b/tests/integration/expected_test_results/api_v2_product_read/get-fields-raw.json
index a50857702001a..18586edc6606a 100644
--- a/tests/integration/expected_test_results/api_v2_product_read/get-fields-raw.json
+++ b/tests/integration/expected_test_results/api_v2_product_read/get-fields-raw.json
@@ -641,6 +641,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels-fr.json b/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels-fr.json
index 863870adc89db..715a98a700c12 100644
--- a/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels-fr.json
+++ b/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels-fr.json
@@ -699,7 +699,7 @@
{
"element_type" : "text",
"text_element" : {
- "html" : "apple, milk, eggs, palm oil"
+ "html" : "en: apple, milk, eggs, palm oil"
}
},
{
diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels.json b/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels.json
index 8644d569d41d5..43dce689ec063 100644
--- a/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels.json
+++ b/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels.json
@@ -699,7 +699,7 @@
{
"element_type" : "text",
"text_element" : {
- "html" : "apple, milk, eggs, palm oil"
+ "html" : "en: apple, milk, eggs, palm oil"
}
},
{
diff --git a/tests/integration/expected_test_results/api_v2_product_write/get-product-auth-good-password.json b/tests/integration/expected_test_results/api_v2_product_write/get-product-auth-good-password.json
index 71e5c51d5a0d4..6ebe8b1fa8f7f 100644
--- a/tests/integration/expected_test_results/api_v2_product_write/get-product-auth-good-password.json
+++ b/tests/integration/expected_test_results/api_v2_product_write/get-product-auth-good-password.json
@@ -582,6 +582,7 @@
"en:added-sugar",
"en:disaccharide"
],
+ "ingredients_lc" : "fr",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/integration/expected_test_results/api_v2_product_write/get-product-ingredients-text-without-language.json b/tests/integration/expected_test_results/api_v2_product_write/get-product-ingredients-text-without-language.json
index 4c9bfeb54b712..8cb8b05997458 100644
--- a/tests/integration/expected_test_results/api_v2_product_write/get-product-ingredients-text-without-language.json
+++ b/tests/integration/expected_test_results/api_v2_product_write/get-product-ingredients-text-without-language.json
@@ -6,11 +6,17 @@
"sausage"
],
"added_countries_tags" : [],
+ "additives_n" : 0,
+ "additives_old_n" : 0,
+ "additives_old_tags" : [],
+ "additives_original_tags" : [],
+ "additives_tags" : [],
"allergens" : "",
"allergens_from_ingredients" : "",
- "allergens_from_user" : "(fr) ",
+ "allergens_from_user" : "(en) ",
"allergens_hierarchy" : [],
"allergens_tags" : [],
+ "amino_acids_tags" : [],
"categories" : "Sausages",
"categories_hierarchy" : [
"en:meats-and-their-products",
@@ -51,7 +57,7 @@
"1xxxxxxxxxxxx"
],
"complete" : 0,
- "completeness" : 0.2,
+ "completeness" : 0.3,
"correctors_tags" : [],
"countries" : "en:united-kingdom",
"countries_hierarchy" : [
@@ -66,6 +72,7 @@
"data_quality_errors_tags" : [],
"data_quality_info_tags" : [
"en:no-packaging-data",
+ "en:ingredients-percent-analysis-ok",
"en:ecoscore-extended-data-not-computed",
"en:food-groups-1-known",
"en:food-groups-2-known",
@@ -73,20 +80,19 @@
],
"data_quality_tags" : [
"en:no-packaging-data",
+ "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-packaging-packaging-data-missing",
- "en:ecoscore-production-system-no-label",
- "en:ecoscore-threatened-species-ingredients-missing"
+ "en:ecoscore-production-system-no-label"
],
"data_quality_warnings_tags" : [
"en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown",
"en:ecoscore-packaging-packaging-data-missing",
- "en:ecoscore-production-system-no-label",
- "en:ecoscore-threatened-species-ingredients-missing"
+ "en:ecoscore-production-system-no-label"
],
"ecoscore_data" : {
"adjustments" : {
@@ -314,16 +320,13 @@
"value" : 0,
"warning" : "no_label"
},
- "threatened_species" : {
- "warning" : "ingredients_missing"
- }
+ "threatened_species" : {}
},
"agribalyse" : {
"warning" : "missing_agribalyse_match"
},
"missing" : {
"agb_category" : 1,
- "ingredients" : 1,
"labels" : 1,
"origins" : 1,
"packagings" : 1
@@ -350,10 +353,85 @@
"informers_tags" : [
"openfoodfacts-contributors"
],
+ "ingredients" : [
+ {
+ "id" : "en:pork-meat",
+ "percent_estimate" : 75,
+ "percent_max" : 100,
+ "percent_min" : 50,
+ "text" : "Pork meat",
+ "vegan" : "no",
+ "vegetarian" : "no"
+ },
+ {
+ "ciqual_food_code" : "11058",
+ "id" : "en:salt",
+ "percent_estimate" : 25,
+ "percent_max" : 50,
+ "percent_min" : 0,
+ "text" : "salt",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ }
+ ],
+ "ingredients_analysis" : {
+ "en:non-vegan" : [
+ "en:pork-meat"
+ ],
+ "en:non-vegetarian" : [
+ "en:pork-meat"
+ ]
+ },
+ "ingredients_analysis_tags" : [
+ "en:palm-oil-free",
+ "en:non-vegan",
+ "en:non-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:pork-meat",
+ "en:animal",
+ "en:meat",
+ "en:pork",
+ "en:salt"
+ ],
+ "ingredients_lc" : "en",
+ "ingredients_n" : 2,
+ "ingredients_n_tags" : [
+ "2",
+ "1-10"
+ ],
+ "ingredients_original_tags" : [
+ "en:pork-meat",
+ "en:salt"
+ ],
+ "ingredients_percent_analysis" : 1,
+ "ingredients_tags" : [
+ "en:pork-meat",
+ "en:animal",
+ "en:meat",
+ "en:pork",
+ "en:salt"
+ ],
+ "ingredients_text" : "Pork meat, salt",
"ingredients_text_en" : "Pork meat, salt",
+ "ingredients_text_with_allergens" : "Pork meat, salt",
"ingredients_text_with_allergens_en" : "Pork meat, salt",
+ "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" : 2,
+ "ingredients_with_unspecified_percent_sum" : 100,
+ "ingredients_without_ciqual_codes" : [
+ "en:pork-meat"
+ ],
+ "ingredients_without_ciqual_codes_n" : 1,
"interface_version_created" : "20150316.jqm2",
"interface_version_modified" : "20150316.jqm2",
+ "known_ingredients_n" : 5,
"lang" : "fr",
"languages" : {
"en:english" : 2
@@ -372,6 +450,7 @@
"last_modified_t" : "--ignore--",
"lc" : "fr",
"main_countries_tags" : [],
+ "minerals_tags" : [],
"misc_tags" : [
"en:nutrition-not-enough-data-to-compute-nutrition-score",
"en:nutriscore-missing-nutrition-data",
@@ -383,7 +462,7 @@
"en:nutriscore-missing-nutrition-data-proteins",
"en:nutrition-no-fiber",
"en:nutriscore-not-computed",
- "en:nutrition-no-fruits-vegetables-nuts",
+ "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients",
"en:nutrition-no-fiber-or-fruits-vegetables-nuts",
"en:packagings-number-of-components-0",
"en:packagings-not-complete",
@@ -392,14 +471,38 @@
"en:ecoscore-not-computed",
"en:main-countries-new-product"
],
- "nova_group_debug" : "no nova group when the product does not have ingredients",
- "nova_group_error" : "missing_ingredients",
+ "nova_group" : 3,
+ "nova_group_debug" : "",
+ "nova_groups" : "3",
+ "nova_groups_markers" : {
+ "3" : [
+ [
+ "categories",
+ "en:prepared-meats"
+ ],
+ [
+ "categories",
+ "en:sausages"
+ ],
+ [
+ "ingredients",
+ "en:salt"
+ ]
+ ]
+ },
"nova_groups_tags" : [
- "unknown"
+ "en:3-processed-foods"
],
+ "nucleotides_tags" : [],
"nutrient_levels" : {},
"nutrient_levels_tags" : [],
- "nutriments" : {},
+ "nutriments" : {
+ "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 0,
+ "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 0,
+ "nova-group" : 3,
+ "nova-group_100g" : 3,
+ "nova-group_serving" : 3
+ },
"nutriscore" : {
"2021" : {
"category_available" : 1,
@@ -462,8 +565,10 @@
],
"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_nuts_estimate_from_ingredients" : 1,
+ "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 0,
"nutrition_score_warning_no_fiber" : 1,
- "nutrition_score_warning_no_fruits_vegetables_nuts" : 1,
+ "other_nutritional_substances_tags" : [],
"packaging_materials_tags" : [],
"packaging_recycling_tags" : [],
"packaging_shapes_tags" : [],
@@ -488,11 +593,11 @@
"rev" : 1,
"serving_quantity" : "20",
"serving_size" : "20 g",
- "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-to-be-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-to-be-completed, en:photos-to-be-uploaded",
+ "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-to-be-completed, en:photos-to-be-uploaded",
"states_hierarchy" : [
"en:to-be-completed",
"en:nutrition-facts-to-be-completed",
- "en:ingredients-to-be-completed",
+ "en:ingredients-completed",
"en:expiration-date-to-be-completed",
"en:packaging-code-to-be-completed",
"en:characteristics-to-be-completed",
@@ -507,7 +612,7 @@
"states_tags" : [
"en:to-be-completed",
"en:nutrition-facts-to-be-completed",
- "en:ingredients-to-be-completed",
+ "en:ingredients-completed",
"en:expiration-date-to-be-completed",
"en:packaging-code-to-be-completed",
"en:characteristics-to-be-completed",
@@ -521,10 +626,12 @@
],
"traces" : "",
"traces_from_ingredients" : "",
- "traces_from_user" : "(fr) ",
+ "traces_from_user" : "(en) ",
"traces_hierarchy" : [],
"traces_tags" : [],
+ "unknown_ingredients_n" : 0,
"unknown_nutrients_tags" : [],
+ "vitamins_tags" : [],
"weighers_tags" : []
},
"status" : 1,
diff --git a/tests/integration/expected_test_results/api_v2_product_write/get-product.json b/tests/integration/expected_test_results/api_v2_product_write/get-product.json
index d449f9c074f4e..938997a3a3866 100644
--- a/tests/integration/expected_test_results/api_v2_product_write/get-product.json
+++ b/tests/integration/expected_test_results/api_v2_product_write/get-product.json
@@ -582,6 +582,7 @@
"en:added-sugar",
"en:disaccharide"
],
+ "ingredients_lc" : "fr",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
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 6cea5f8181b67..8999dec94e561 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
@@ -647,6 +647,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
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 4fe102b568958..f42eced5fbb1b 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
@@ -647,6 +647,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
@@ -1384,7 +1385,7 @@
{
"element_type" : "text",
"text_element" : {
- "html" : "apple, milk, eggs, palm oil"
+ "html" : "en: apple, milk, eggs, palm oil"
}
},
{
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 6cea5f8181b67..8999dec94e561 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
@@ -647,6 +647,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
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 7310511a142f8..4e71cabf47512 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
@@ -971,6 +971,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
@@ -1708,7 +1709,7 @@
{
"element_type" : "text",
"text_element" : {
- "html" : "apple, milk, eggs, palm oil"
+ "html" : "en: apple, milk, eggs, palm oil"
}
},
{
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 fbc5167ff3cb4..903fe854a5333 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
@@ -642,6 +642,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
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 9ebad360bb7d1..e78bfe6f21f92 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
@@ -700,7 +700,7 @@
{
"element_type" : "text",
"text_element" : {
- "html" : "apple, milk, eggs, palm oil"
+ "html" : "en: apple, milk, eggs, palm oil"
}
},
{
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 b5dd4202232ff..029fdc4c3b73b 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
@@ -700,7 +700,7 @@
{
"element_type" : "text",
"text_element" : {
- "html" : "apple, milk, eggs, palm oil"
+ "html" : "en: apple, milk, eggs, palm oil"
}
},
{
diff --git a/tests/integration/expected_test_results/api_v3_product_write/patch-request-fields-all.json b/tests/integration/expected_test_results/api_v3_product_write/patch-request-fields-all.json
index 89ab4337af8ce..5bf39d5e68b0f 100644
--- a/tests/integration/expected_test_results/api_v3_product_write/patch-request-fields-all.json
+++ b/tests/integration/expected_test_results/api_v3_product_write/patch-request-fields-all.json
@@ -330,6 +330,7 @@
"informers_tags" : [
"openfoodfacts-contributors"
],
+ "ingredients_lc" : "en",
"interface_version_created" : "20221102/api/v3",
"lang" : "en",
"languages" : {},
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390017165.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390017165.json
index 90f5ec0e68d21..1314ce72ea7ad 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390017165.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390017165.json
@@ -363,6 +363,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020745.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020745.json
index 0025f6543656d..f051af56762cc 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020745.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020745.json
@@ -360,6 +360,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020806.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020806.json
index 60fba34163642..79dd71d53f9ef 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020806.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020806.json
@@ -349,6 +349,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020998.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020998.json
index 8bf855d0e498b..a4156223e91d9 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020998.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020998.json
@@ -363,6 +363,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021001.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021001.json
index d22f73941f416..35c3d5b4ab5f1 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021001.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021001.json
@@ -357,6 +357,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021469.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021469.json
index af95fa858f463..972aa1d577962 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021469.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021469.json
@@ -354,6 +354,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021544.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021544.json
index 0db7d0c68d0f7..d816fa03c407f 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021544.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021544.json
@@ -357,6 +357,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021568.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021568.json
index d0116fb51ef42..7151ac45b4503 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021568.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021568.json
@@ -355,6 +355,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021926.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021926.json
index cad79dc1b23b9..fceae400ea7b5 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021926.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021926.json
@@ -347,6 +347,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024781.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024781.json
index 1d960f3668cf5..5ba36a8e806d3 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024781.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024781.json
@@ -382,6 +382,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024804.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024804.json
index c69d18e822d51..1460760f18270 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024804.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024804.json
@@ -371,6 +371,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024842.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024842.json
index b6d26097b41cf..02350dab45b85 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024842.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024842.json
@@ -372,6 +372,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024866.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024866.json
index 4453e97e7b58e..e792ae40199d5 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024866.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024866.json
@@ -372,6 +372,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025399.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025399.json
index 56a0363463c53..67a8065a42eae 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025399.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025399.json
@@ -364,6 +364,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025863.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025863.json
index e4931aa3c1c20..2e04154fb1633 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025863.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025863.json
@@ -346,6 +346,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026044.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026044.json
index 03c4d73c47962..9366f848c87de 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026044.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026044.json
@@ -368,6 +368,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026648.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026648.json
index df17885cf3c7e..3a1ecfcc999c7 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026648.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026648.json
@@ -383,6 +383,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026754.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026754.json
index b2bad183153ba..cbfd68813e762 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026754.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026754.json
@@ -365,6 +365,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/3270190128403.json b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/3270190128403.json
index 56b761b0a0175..0e7758684f26a 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/3270190128403.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/3270190128403.json
@@ -600,6 +600,7 @@
"en:legume",
"en:lentils"
],
+ "ingredients_lc" : "fr",
"ingredients_n" : 1,
"ingredients_n_tags" : [
"1",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/4270190128403.json b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/4270190128403.json
index df8a7b48d3d44..60228842e9ed4 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/4270190128403.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/4270190128403.json
@@ -5,11 +5,17 @@
"test"
],
"added_countries_tags" : [],
+ "additives_n" : 0,
+ "additives_old_n" : 0,
+ "additives_old_tags" : [],
+ "additives_original_tags" : [],
+ "additives_tags" : [],
"allergens" : "",
"allergens_from_ingredients" : "",
- "allergens_from_user" : "(en) ",
+ "allergens_from_user" : "(fr) ",
"allergens_hierarchy" : [],
"allergens_tags" : [],
+ "amino_acids_tags" : [],
"brands" : "Test",
"brands_imported" : "Test",
"brands_tags" : [
@@ -49,7 +55,7 @@
"4xxxxxxxxxxxx"
],
"complete" : 0,
- "completeness" : 0.3,
+ "completeness" : 0.4,
"correctors_tags" : [],
"countries" : "Etats-Unis",
"countries_hierarchy" : [
@@ -66,6 +72,7 @@
"data_quality_errors_tags" : [],
"data_quality_info_tags" : [
"en:no-packaging-data",
+ "en:ingredients-percent-analysis-ok",
"en:ecoscore-extended-data-not-computed",
"en:food-groups-1-unknown",
"en:food-groups-2-unknown",
@@ -73,22 +80,25 @@
],
"data_quality_tags" : [
"en:no-packaging-data",
+ "en:ingredients-percent-analysis-ok",
"en:ecoscore-extended-data-not-computed",
"en:food-groups-1-unknown",
"en:food-groups-2-unknown",
"en:food-groups-3-unknown",
+ "en:ingredients-unknown-score-above-0",
+ "en:ingredients-100-percent-unknown",
"en:nutri-score-grade-from-producer-does-not-match-calculated-grade",
"en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown",
"en:ecoscore-packaging-packaging-data-missing",
- "en:ecoscore-production-system-no-label",
- "en:ecoscore-threatened-species-ingredients-missing"
+ "en:ecoscore-production-system-no-label"
],
"data_quality_warnings_tags" : [
+ "en:ingredients-unknown-score-above-0",
+ "en:ingredients-100-percent-unknown",
"en:nutri-score-grade-from-producer-does-not-match-calculated-grade",
"en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown",
"en:ecoscore-packaging-packaging-data-missing",
- "en:ecoscore-production-system-no-label",
- "en:ecoscore-threatened-species-ingredients-missing"
+ "en:ecoscore-production-system-no-label"
],
"data_sources" : "Producers, Producer - test-food-company",
"data_sources_imported" : "Producers, Producer - test-food-company",
@@ -317,16 +327,13 @@
"value" : 0,
"warning" : "no_label"
},
- "threatened_species" : {
- "warning" : "ingredients_missing"
- }
+ "threatened_species" : {}
},
"agribalyse" : {
"warning" : "missing_agribalyse_match"
},
"missing" : {
"agb_category" : 1,
- "ingredients" : 1,
"labels" : 1,
"origins" : 1,
"packagings" : 1
@@ -348,10 +355,81 @@
"informers_tags" : [
"test-user"
],
+ "ingredients" : [
+ {
+ "id" : "fr:white-peaches",
+ "percent_estimate" : 75,
+ "percent_max" : 100,
+ "percent_min" : 50,
+ "text" : "White peaches"
+ },
+ {
+ "id" : "fr:high-fructose-corn-syrup",
+ "percent_estimate" : 25,
+ "percent_max" : 50,
+ "percent_min" : 0,
+ "text" : "high fructose corn syrup"
+ }
+ ],
+ "ingredients_analysis" : {
+ "en:palm-oil-content-unknown" : [
+ "fr:white-peaches",
+ "fr:high-fructose-corn-syrup"
+ ],
+ "en:vegan-status-unknown" : [
+ "fr:white-peaches",
+ "fr:high-fructose-corn-syrup"
+ ],
+ "en:vegetarian-status-unknown" : [
+ "fr:white-peaches",
+ "fr:high-fructose-corn-syrup"
+ ]
+ },
+ "ingredients_analysis_tags" : [
+ "en:palm-oil-content-unknown",
+ "en:vegan-status-unknown",
+ "en:vegetarian-status-unknown"
+ ],
+ "ingredients_from_or_that_may_be_from_palm_oil_n" : 0,
+ "ingredients_from_palm_oil_n" : 0,
+ "ingredients_from_palm_oil_tags" : [],
+ "ingredients_hierarchy" : [
+ "fr:white-peaches",
+ "fr:high-fructose-corn-syrup"
+ ],
+ "ingredients_lc" : "fr",
+ "ingredients_n" : 2,
+ "ingredients_n_tags" : [
+ "2",
+ "1-10"
+ ],
+ "ingredients_original_tags" : [
+ "fr:white-peaches",
+ "fr:high-fructose-corn-syrup"
+ ],
+ "ingredients_percent_analysis" : 1,
+ "ingredients_tags" : [
+ "fr:white-peaches",
+ "fr:high-fructose-corn-syrup"
+ ],
+ "ingredients_text" : "White peaches, high fructose corn syrup",
"ingredients_text_fr" : "White peaches, high fructose corn syrup",
"ingredients_text_fr_imported" : "White peaches, high fructose corn syrup",
+ "ingredients_text_with_allergens" : "White peaches, high fructose corn syrup",
"ingredients_text_with_allergens_fr" : "White peaches, high fructose corn syrup",
+ "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" : 2,
+ "ingredients_with_unspecified_percent_sum" : 100,
+ "ingredients_without_ciqual_codes" : [
+ "fr:high-fructose-corn-syrup",
+ "fr:white-peaches"
+ ],
+ "ingredients_without_ciqual_codes_n" : 2,
"interface_version_created" : "import_csv_file - version 2019/09/17",
+ "known_ingredients_n" : 0,
"lang" : "en",
"lang_imported" : "en",
"languages" : {
@@ -374,6 +452,7 @@
"lc" : "en",
"lc_imported" : "en",
"main_countries_tags" : [],
+ "minerals_tags" : [],
"misc_tags" : [
"en:nutrition-not-enough-data-to-compute-nutrition-score",
"en:nutriscore-missing-nutrition-data",
@@ -384,7 +463,7 @@
"en:nutriscore-missing-nutrition-data-proteins",
"en:nutrition-no-fiber",
"en:nutriscore-not-computed",
- "en:nutrition-no-fruits-vegetables-nuts",
+ "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients",
"en:nutrition-no-fiber-or-fruits-vegetables-nuts",
"en:packagings-number-of-components-0",
"en:packagings-not-complete",
@@ -393,11 +472,12 @@
"en:ecoscore-not-computed",
"en:main-countries-new-product"
],
- "nova_group_debug" : "no nova group when the product does not have ingredients",
- "nova_group_error" : "missing_ingredients",
+ "nova_group_debug" : "no nova group if too many ingredients are unknown: 2 out of 2",
+ "nova_group_error" : "too_many_unknown_ingredients",
"nova_groups_tags" : [
"unknown"
],
+ "nucleotides_tags" : [],
"nutrient_levels" : {},
"nutrient_levels_tags" : [],
"nutriments" : {
@@ -408,7 +488,9 @@
"energy-kj_value" : 500,
"energy_100g" : 500,
"energy_unit" : "kJ",
- "energy_value" : 500
+ "energy_value" : 500,
+ "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 0,
+ "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 0
},
"nutriscore" : {
"2021" : {
@@ -475,8 +557,10 @@
],
"nutrition_score_beverage" : 0,
"nutrition_score_debug" : "missing fat_100g - missing saturated-fat_100g - missing sugars_100g - missing sodium_100g - missing proteins_100g",
+ "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1,
+ "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 0,
"nutrition_score_warning_no_fiber" : 1,
- "nutrition_score_warning_no_fruits_vegetables_nuts" : 1,
+ "other_nutritional_substances_tags" : [],
"owner" : "org-test-org",
"owner_fields" : "--ignore--",
"owners_tags" : "org-test-org",
@@ -522,11 +606,11 @@
"url" : null
}
],
- "states" : "en:to-be-completed, en:nutrition-facts-completed, en:ingredients-to-be-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-completed, en:packaging-to-be-completed, en:quantity-to-be-completed, en:product-name-to-be-completed, en:photos-to-be-uploaded",
+ "states" : "en:to-be-completed, en:nutrition-facts-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-completed, en:packaging-to-be-completed, en:quantity-to-be-completed, en:product-name-to-be-completed, en:photos-to-be-uploaded",
"states_hierarchy" : [
"en:to-be-completed",
"en:nutrition-facts-completed",
- "en:ingredients-to-be-completed",
+ "en:ingredients-completed",
"en:expiration-date-to-be-completed",
"en:packaging-code-to-be-completed",
"en:characteristics-to-be-completed",
@@ -541,7 +625,7 @@
"states_tags" : [
"en:to-be-completed",
"en:nutrition-facts-completed",
- "en:ingredients-to-be-completed",
+ "en:ingredients-completed",
"en:expiration-date-to-be-completed",
"en:packaging-code-to-be-completed",
"en:characteristics-to-be-completed",
@@ -555,9 +639,11 @@
],
"traces" : "",
"traces_from_ingredients" : "",
- "traces_from_user" : "(en) ",
+ "traces_from_user" : "(fr) ",
"traces_hierarchy" : [],
"traces_tags" : [],
+ "unknown_ingredients_n" : 2,
"unknown_nutrients_tags" : [],
+ "vitamins_tags" : [],
"weighers_tags" : []
}
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/5270190128403.json b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/5270190128403.json
index 50c44059807de..6060be76e69c3 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/5270190128403.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/5270190128403.json
@@ -369,6 +369,7 @@
"en:banana",
"en:fruit"
],
+ "ingredients_lc" : "fr",
"ingredients_n" : 1,
"ingredients_n_tags" : [
"1",
diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/7270190128403.json b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/7270190128403.json
index 03a36235dc116..1cc192bf9f9fd 100644
--- a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/7270190128403.json
+++ b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/7270190128403.json
@@ -337,6 +337,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "en",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "en",
"lang_imported" : "en",
diff --git a/tests/integration/expected_test_results/data_quality_knowledge_panel/data-quality.json b/tests/integration/expected_test_results/data_quality_knowledge_panel/data-quality.json
index 9719bc5ab77eb..f7f59d5419389 100644
--- a/tests/integration/expected_test_results/data_quality_knowledge_panel/data-quality.json
+++ b/tests/integration/expected_test_results/data_quality_knowledge_panel/data-quality.json
@@ -370,7 +370,7 @@
{
"element_type" : "text",
"text_element" : {
- "html" : "water, test_ingredient"
+ "html" : "en: water, test_ingredient"
}
},
{
diff --git a/tests/integration/expected_test_results/data_quality_knowledge_panel/no-data-quality.json b/tests/integration/expected_test_results/data_quality_knowledge_panel/no-data-quality.json
index 647119ac32cf2..4a3544d20d3fd 100644
--- a/tests/integration/expected_test_results/data_quality_knowledge_panel/no-data-quality.json
+++ b/tests/integration/expected_test_results/data_quality_knowledge_panel/no-data-quality.json
@@ -332,7 +332,7 @@
{
"element_type" : "text",
"text_element" : {
- "html" : "water, test_ingredient"
+ "html" : "en: water, test_ingredient"
}
},
{
diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006001.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006001.json
index 916b526a792d8..d879330b28b71 100644
--- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006001.json
+++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006001.json
@@ -532,6 +532,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006002.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006002.json
index dd625a7646be8..5496504c1c009 100644
--- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006002.json
+++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006002.json
@@ -347,6 +347,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006003.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006003.json
index 3154d25fd35f8..9fce12608f8b4 100644
--- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006003.json
+++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006003.json
@@ -342,6 +342,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006004.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006004.json
index ff9f665ac6407..d039cfd2e31f2 100644
--- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006004.json
+++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006004.json
@@ -554,6 +554,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "en",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "en",
"lang_imported" : "en",
diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006005.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006005.json
index fb4b6afe1d779..e2c21a14b20f6 100644
--- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006005.json
+++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006005.json
@@ -357,6 +357,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "en",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "en",
"lang_imported" : "en",
diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006006.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006006.json
index 9f89906fd4bc0..f5e53b8b5b8e0 100644
--- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006006.json
+++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006006.json
@@ -351,6 +351,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "en",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "en",
"lang_imported" : "en",
diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006007.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006007.json
index 0a34253048072..905a1a0a80630 100644
--- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006007.json
+++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006007.json
@@ -345,6 +345,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "en",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "en",
"lang_imported" : "en",
diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006001.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006001.json
index 92028afd8a57f..40e235e6b352d 100644
--- a/tests/integration/expected_test_results/import_csv_file/test/2003004006001.json
+++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006001.json
@@ -524,6 +524,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006002.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006002.json
index d94b8597d8466..1ca3dc682fda7 100644
--- a/tests/integration/expected_test_results/import_csv_file/test/2003004006002.json
+++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006002.json
@@ -339,6 +339,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006003.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006003.json
index 8fdf4b38474a0..ad61638c9fb17 100644
--- a/tests/integration/expected_test_results/import_csv_file/test/2003004006003.json
+++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006003.json
@@ -342,6 +342,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "fr",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "fr",
"lang_imported" : "fr",
diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006004.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006004.json
index 28cdee8bc1807..9c52d30661995 100644
--- a/tests/integration/expected_test_results/import_csv_file/test/2003004006004.json
+++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006004.json
@@ -517,6 +517,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "en",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "en",
"lang_imported" : "en",
diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006005.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006005.json
index adc27c716ff6e..5cb71a8847873 100644
--- a/tests/integration/expected_test_results/import_csv_file/test/2003004006005.json
+++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006005.json
@@ -349,6 +349,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "en",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "en",
"lang_imported" : "en",
diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006006.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006006.json
index 492e92e91b1bc..eb5e27154c2aa 100644
--- a/tests/integration/expected_test_results/import_csv_file/test/2003004006006.json
+++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006006.json
@@ -349,6 +349,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "en",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "en",
"lang_imported" : "en",
diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006007.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006007.json
index 59cd2bea06e32..fbd30658d0f79 100644
--- a/tests/integration/expected_test_results/import_csv_file/test/2003004006007.json
+++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006007.json
@@ -345,6 +345,7 @@
"informers_tags" : [
"test-user"
],
+ "ingredients_lc" : "en",
"interface_version_created" : "import_csv_file - version 2019/09/17",
"lang" : "en",
"lang_imported" : "en",
diff --git a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2-moderator.json b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2-moderator.json
index a5e945ced4eb3..38c0a4c3f5c67 100644
--- a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2-moderator.json
+++ b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2-moderator.json
@@ -496,6 +496,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2.json b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2.json
index 1dee3a8851d9f..130d25cb80b1d 100644
--- a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2.json
+++ b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2.json
@@ -495,6 +495,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form-moderator.json b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form-moderator.json
index c2e5f82199a68..1502ede439aa3 100644
--- a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form-moderator.json
+++ b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form-moderator.json
@@ -500,6 +500,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form.json b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form.json
index cd4c78d90baee..7ce5d40263212 100644
--- a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form.json
+++ b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form.json
@@ -499,6 +499,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-api-v2.json b/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-api-v2.json
index ad22bbfc121cc..9d95d1ddd47e5 100644
--- a/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-api-v2.json
+++ b/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-api-v2.json
@@ -494,6 +494,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-web-form.json b/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-web-form.json
index 3f94787fce97e..4d303bd05c645 100644
--- a/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-web-form.json
+++ b/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-web-form.json
@@ -498,6 +498,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/integration/expected_test_results/search_v1/search-no-filter.json b/tests/integration/expected_test_results/search_v1/search-no-filter.json
index 4fc80f6ab43f0..1e691dac19b0e 100644
--- a/tests/integration/expected_test_results/search_v1/search-no-filter.json
+++ b/tests/integration/expected_test_results/search_v1/search-no-filter.json
@@ -471,6 +471,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
@@ -1122,6 +1123,7 @@
"en:fruit",
"en:rice"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 2,
"ingredients_n_tags" : [
"2",
@@ -1775,6 +1777,7 @@
"en:dairy",
"en:egg"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 3,
"ingredients_n_tags" : [
"3",
@@ -2012,11 +2015,17 @@
"snack"
],
"added_countries_tags" : [],
+ "additives_n" : 0,
+ "additives_old_n" : 0,
+ "additives_old_tags" : [],
+ "additives_original_tags" : [],
+ "additives_tags" : [],
"allergens" : "",
"allergens_from_ingredients" : "",
- "allergens_from_user" : "(es) ",
+ "allergens_from_user" : "(en) ",
"allergens_hierarchy" : [],
"allergens_tags" : [],
+ "amino_acids_tags" : [],
"categories" : "snacks",
"categories_hierarchy" : [
"en:snacks"
@@ -2049,7 +2058,7 @@
"2xxxxxxxxxxx"
],
"complete" : 0,
- "completeness" : 0.2,
+ "completeness" : 0.4,
"correctors_tags" : [],
"created_t" : "--ignore--",
"creator" : "tests",
@@ -2057,6 +2066,7 @@
"data_quality_errors_tags" : [],
"data_quality_info_tags" : [
"en:no-packaging-data",
+ "en:ingredients-percent-analysis-ok",
"en:ecoscore-extended-data-not-computed",
"en:food-groups-1-unknown",
"en:food-groups-2-unknown",
@@ -2064,20 +2074,19 @@
],
"data_quality_tags" : [
"en:no-packaging-data",
+ "en:ingredients-percent-analysis-ok",
"en:ecoscore-extended-data-not-computed",
"en:food-groups-1-unknown",
"en:food-groups-2-unknown",
"en:food-groups-3-unknown",
"en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown",
"en:ecoscore-packaging-packaging-data-missing",
- "en:ecoscore-production-system-no-label",
- "en:ecoscore-threatened-species-ingredients-missing"
+ "en:ecoscore-production-system-no-label"
],
"data_quality_warnings_tags" : [
"en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown",
"en:ecoscore-packaging-packaging-data-missing",
- "en:ecoscore-production-system-no-label",
- "en:ecoscore-threatened-species-ingredients-missing"
+ "en:ecoscore-production-system-no-label"
],
"ecoscore_data" : {
"adjustments" : {
@@ -2306,7 +2315,8 @@
"warning" : "no_label"
},
"threatened_species" : {
- "warning" : "ingredients_missing"
+ "ingredient" : "en:palm-oil",
+ "value" : -10
}
},
"agribalyse" : {
@@ -2314,7 +2324,6 @@
},
"missing" : {
"agb_category" : 1,
- "ingredients" : 1,
"labels" : 1,
"origins" : 1,
"packagings" : 1
@@ -2338,10 +2347,100 @@
"informers_tags" : [
"tests"
],
+ "ingredients" : [
+ {
+ "ciqual_food_code" : "13050",
+ "id" : "en:apple",
+ "percent_estimate" : 66.6666666666667,
+ "percent_max" : 100,
+ "percent_min" : 33.3333333333333,
+ "rank" : 1,
+ "text" : "apple",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ },
+ {
+ "ciqual_food_code" : "18066",
+ "id" : "en:water",
+ "percent_estimate" : 16.6666666666667,
+ "percent_max" : 50,
+ "percent_min" : 0,
+ "rank" : 2,
+ "text" : "water",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ },
+ {
+ "ciqual_food_code" : "16129",
+ "from_palm_oil" : "yes",
+ "id" : "en:palm-oil",
+ "percent_estimate" : 16.6666666666667,
+ "percent_max" : 33.3333333333333,
+ "percent_min" : 0,
+ "rank" : 3,
+ "text" : "palm oil",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ }
+ ],
+ "ingredients_analysis" : {
+ "en:palm-oil" : [
+ "en:palm-oil"
+ ]
+ },
+ "ingredients_analysis_tags" : [
+ "en:palm-oil",
+ "en: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:water",
+ "en:palm-oil",
+ "en:oil-and-fat",
+ "en:vegetable-oil-and-fat",
+ "en:palm-oil-and-fat"
+ ],
+ "ingredients_lc" : "en",
+ "ingredients_n" : 3,
+ "ingredients_n_tags" : [
+ "3",
+ "1-10"
+ ],
+ "ingredients_original_tags" : [
+ "en:apple",
+ "en:water",
+ "en:palm-oil"
+ ],
+ "ingredients_percent_analysis" : 1,
+ "ingredients_tags" : [
+ "en:apple",
+ "en:fruit",
+ "en:water",
+ "en:palm-oil",
+ "en:oil-and-fat",
+ "en:vegetable-oil-and-fat",
+ "en:palm-oil-and-fat"
+ ],
+ "ingredients_text" : "apple, water, palm oil",
"ingredients_text_en" : "apple, water, palm oil",
+ "ingredients_text_with_allergens" : "apple, water, palm oil",
"ingredients_text_with_allergens_en" : "apple, water, 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" : 3,
+ "ingredients_with_unspecified_percent_sum" : 100,
+ "ingredients_without_ciqual_codes" : [],
+ "ingredients_without_ciqual_codes_n" : 0,
"interface_version_created" : "20150316.jqm2",
"interface_version_modified" : "20150316.jqm2",
+ "known_ingredients_n" : 7,
"lang" : "es",
"languages" : {
"en:english" : 4
@@ -2363,6 +2462,7 @@
"lc" : "es",
"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",
@@ -2373,9 +2473,12 @@
"en:nutriscore-missing-nutrition-data-sodium",
"en:nutriscore-missing-nutrition-data-proteins",
"en:nutrition-no-fiber",
- "en:nutriscore-not-computed",
- "en:nutrition-no-fruits-vegetables-nuts",
- "en:nutrition-no-fiber-or-fruits-vegetables-nuts",
+ "en:nutriscore-using-estimated-nutrition-facts",
+ "en:nutriscore-computed",
+ "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients",
+ "en:nutrition-all-nutriscore-values-known",
+ "en:nutriscore-2021-same-as-2023",
+ "en:nutriscore-2021-d-2023-d",
"en:packagings-number-of-components-0",
"en:packagings-not-complete",
"en:packagings-empty",
@@ -2383,79 +2486,212 @@
"en:ecoscore-not-computed",
"en:main-countries-new-product"
],
- "nova_group_debug" : "no nova group when the product does not have ingredients",
- "nova_group_error" : "missing_ingredients",
+ "nova_group" : 1,
+ "nova_group_debug" : "",
+ "nova_groups" : "1",
+ "nova_groups_markers" : {},
"nova_groups_tags" : [
- "unknown"
+ "en:1-unprocessed-or-minimally-processed-foods"
],
+ "nucleotides_tags" : [],
"nutrient_levels" : {},
"nutrient_levels_tags" : [],
- "nutriments" : {},
+ "nutriments" : {
+ "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 33.3333333333333,
+ "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 33.3333333333333,
+ "nova-group" : 1,
+ "nova-group_100g" : 1,
+ "nova-group_serving" : 1,
+ "nutrition-score-fr" : 11,
+ "nutrition-score-fr_100g" : 11
+ },
+ "nutriments_estimated" : {
+ "alcohol_100g" : 0,
+ "beta-carotene_100g" : 1.13333333333333e-05,
+ "calcium_100g" : 0.00452166666666667,
+ "carbohydrates_100g" : 7.13333333333333,
+ "cholesterol_100g" : 0,
+ "copper_100g" : 2.35e-05,
+ "energy-kcal_100g" : 182.6,
+ "energy-kj_100g" : 754.666666666666,
+ "energy_100g" : 754.666666666666,
+ "fat_100g" : 16.7533333333333,
+ "fiber_100g" : 0.866666666666667,
+ "fructose_100g" : 4.02,
+ "galactose_100g" : 0,
+ "glucose_100g" : 2.16666666666667,
+ "iodine_100g" : 9.66666666666666e-07,
+ "iron_100g" : 5.33333333333333e-05,
+ "lactose_100g" : 0,
+ "magnesium_100g" : 0.00283166666666667,
+ "maltose_100g" : 0,
+ "manganese_100g" : 2.5595e-05,
+ "pantothenic-acid_100g" : 4.73333333333333e-05,
+ "phosphorus_100g" : 0.00733333333333333,
+ "phylloquinone_100g" : 1.73333333333333e-06,
+ "polyols_100g" : 0.393333333333333,
+ "potassium_100g" : 0.0601216666666667,
+ "proteins_100g" : 0.18,
+ "salt_100g" : 0.00126666666666667,
+ "saturated-fat_100g" : 8.23066666666666,
+ "selenium_100g" : 1.43333333333333e-06,
+ "sodium_100g" : 0.0004,
+ "starch_100g" : 0,
+ "sucrose_100g" : 0.546666666666667,
+ "sugars_100g" : 6.73333333333333,
+ "vitamin-a_100g" : 0,
+ "vitamin-b12_100g" : 0,
+ "vitamin-b1_100g" : 1.26666666666667e-05,
+ "vitamin-b2_100g" : 1.86666666666667e-05,
+ "vitamin-b6_100g" : 2.46666666666667e-05,
+ "vitamin-b9_100g" : 0,
+ "vitamin-c_100g" : 0.00266666666666667,
+ "vitamin-d_100g" : 0,
+ "vitamin-e_100g" : 0.00268333333333333,
+ "vitamin-pp_100g" : 6.06666666666667e-05,
+ "water_100g" : 74.4666666666667,
+ "zinc_100g" : 3.51666666666667e-05
+ },
"nutriscore" : {
"2021" : {
"category_available" : 1,
"data" : {
- "energy" : null,
- "fiber" : 0,
- "fruits_vegetables_nuts_colza_walnut_olive_oils" : 0,
+ "energy" : 754.666666666666,
+ "energy_points" : 2,
+ "energy_value" : 754.7,
+ "fiber" : 0.866666666666667,
+ "fiber_points" : 0,
+ "fiber_value" : 0.87,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils" : 33.3333333333333,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 0,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 33.3,
"is_beverage" : 0,
"is_cheese" : 0,
"is_fat" : 0,
"is_water" : 0,
- "proteins" : null,
- "saturated_fat" : null,
- "sodium" : null,
- "sugars" : null
+ "negative_points" : 11,
+ "positive_points" : 0,
+ "proteins" : 0.18,
+ "proteins_points" : 0,
+ "proteins_value" : 0.18,
+ "saturated_fat" : 8.23066666666666,
+ "saturated_fat_points" : 8,
+ "saturated_fat_value" : 8.2,
+ "sodium" : 0.4,
+ "sodium_points" : 0,
+ "sodium_value" : 0.4,
+ "sugars" : 6.73333333333333,
+ "sugars_points" : 1,
+ "sugars_value" : 6.73
},
- "grade" : "unknown",
- "nutrients_available" : 0,
+ "grade" : "d",
+ "nutrients_available" : 1,
"nutriscore_applicable" : 1,
- "nutriscore_computed" : 0
+ "nutriscore_computed" : 1,
+ "score" : 11
},
"2023" : {
"category_available" : 1,
"data" : {
- "energy" : null,
- "fiber" : 0,
- "fruits_vegetables_legumes" : 0,
+ "count_proteins" : 0,
+ "count_proteins_reason" : "negative_points_more_than_11",
+ "energy" : 754.666666666666,
+ "energy_points" : 2,
+ "fiber" : 0.866666666666667,
+ "fiber_points" : 0,
+ "fruits_vegetables_legumes" : 33.3333333333333,
+ "fruits_vegetables_legumes_points" : 0,
"is_beverage" : 0,
"is_cheese" : 0,
"is_fat_oil_nuts_seeds" : 0,
"is_water" : 0,
- "proteins" : null,
- "salt" : null,
- "saturated_fat" : null,
- "sugars" : null
+ "negative_nutrients" : [
+ "energy",
+ "sugars",
+ "saturated_fat",
+ "salt",
+ "sweeteners"
+ ],
+ "negative_points" : 11,
+ "positive_nutrients" : [
+ "fruits_vegetables_legumes",
+ "fiber"
+ ],
+ "positive_points" : 0,
+ "proteins" : 0.18,
+ "proteins_points" : 0,
+ "salt" : 0.00126666666666667,
+ "salt_points" : 0,
+ "saturated_fat" : 8.23066666666666,
+ "saturated_fat_points" : 8,
+ "sugars" : 6.73333333333333,
+ "sugars_points" : 1
},
- "grade" : "unknown",
- "nutrients_available" : 0,
+ "grade" : "d",
+ "nutrients_available" : 1,
"nutriscore_applicable" : 1,
- "nutriscore_computed" : 0
+ "nutriscore_computed" : 1,
+ "score" : 11
}
},
"nutriscore_2021_tags" : [
- "unknown"
+ "d"
],
"nutriscore_2023_tags" : [
- "unknown"
+ "d"
],
- "nutriscore_grade" : "unknown",
+ "nutriscore_data" : {
+ "energy" : 754.666666666666,
+ "energy_points" : 2,
+ "energy_value" : 754.7,
+ "fiber" : 0.866666666666667,
+ "fiber_points" : 0,
+ "fiber_value" : 0.87,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils" : 33.3333333333333,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 0,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 33.3,
+ "grade" : "d",
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat" : 0,
+ "is_water" : 0,
+ "negative_points" : 11,
+ "positive_points" : 0,
+ "proteins" : 0.18,
+ "proteins_points" : 0,
+ "proteins_value" : 0.18,
+ "saturated_fat" : 8.23066666666666,
+ "saturated_fat_points" : 8,
+ "saturated_fat_value" : 8.2,
+ "score" : 11,
+ "sodium" : 0.4,
+ "sodium_points" : 0,
+ "sodium_value" : 0.4,
+ "sugars" : 6.73333333333333,
+ "sugars_points" : 1,
+ "sugars_value" : 6.73
+ },
+ "nutriscore_grade" : "d",
+ "nutriscore_score" : 11,
+ "nutriscore_score_opposite" : -11,
"nutriscore_tags" : [
- "unknown"
+ "d"
],
"nutriscore_version" : "2021",
"nutrition_data_per" : "100g",
"nutrition_data_prepared_per" : "100g",
- "nutrition_grade_fr" : "unknown",
- "nutrition_grades" : "unknown",
+ "nutrition_grade_fr" : "d",
+ "nutrition_grades" : "d",
"nutrition_grades_tags" : [
- "unknown"
+ "d"
],
"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_no_fiber" : 1,
- "nutrition_score_warning_no_fruits_vegetables_nuts" : 1,
+ "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1,
+ "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 33.3333333333333,
+ "nutrition_score_warning_nutriments_estimated" : 1,
"origin_en" : "spain",
+ "other_nutritional_substances_tags" : [],
"packaging_materials_tags" : [],
"packaging_recycling_tags" : [],
"packaging_shapes_tags" : [],
@@ -2480,11 +2716,11 @@
"rev" : 1,
"serving_quantity" : 10,
"serving_size" : "10 g",
- "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-to-be-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-to-be-completed, en:photos-to-be-uploaded",
+ "states" : "en:to-be-completed, en:nutrition-facts-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-to-be-completed, en:photos-to-be-uploaded",
"states_hierarchy" : [
"en:to-be-completed",
- "en:nutrition-facts-to-be-completed",
- "en:ingredients-to-be-completed",
+ "en:nutrition-facts-completed",
+ "en:ingredients-completed",
"en:expiration-date-to-be-completed",
"en:packaging-code-to-be-completed",
"en:characteristics-to-be-completed",
@@ -2498,8 +2734,8 @@
],
"states_tags" : [
"en:to-be-completed",
- "en:nutrition-facts-to-be-completed",
- "en:ingredients-to-be-completed",
+ "en:nutrition-facts-completed",
+ "en:ingredients-completed",
"en:expiration-date-to-be-completed",
"en:packaging-code-to-be-completed",
"en:characteristics-to-be-completed",
@@ -2513,11 +2749,13 @@
],
"traces" : "",
"traces_from_ingredients" : "",
- "traces_from_user" : "(es) ",
+ "traces_from_user" : "(en) ",
"traces_hierarchy" : [],
"traces_tags" : [],
+ "unknown_ingredients_n" : 0,
"unknown_nutrients_tags" : [],
"url" : "http://world.openfoodfacts.localhost/product/200000000039/vegan-test-snack-with-palm-oil",
+ "vitamins_tags" : [],
"weighers_tags" : []
},
{
@@ -2527,11 +2765,17 @@
"cereal"
],
"added_countries_tags" : [],
+ "additives_n" : 0,
+ "additives_old_n" : 0,
+ "additives_old_tags" : [],
+ "additives_original_tags" : [],
+ "additives_tags" : [],
"allergens" : "",
"allergens_from_ingredients" : "",
- "allergens_from_user" : "(es) ",
+ "allergens_from_user" : "(en) ",
"allergens_hierarchy" : [],
"allergens_tags" : [],
+ "amino_acids_tags" : [],
"categories" : "breakfast cereals",
"categories_hierarchy" : [
"en:plant-based-foods-and-beverages",
@@ -2580,7 +2824,7 @@
"2xxxxxxxxxxx"
],
"complete" : 0,
- "completeness" : 0.2,
+ "completeness" : 0.4,
"correctors_tags" : [],
"created_t" : "--ignore--",
"creator" : "tests",
@@ -2588,6 +2832,7 @@
"data_quality_errors_tags" : [],
"data_quality_info_tags" : [
"en:no-packaging-data",
+ "en:ingredients-percent-analysis-ok",
"en:ecoscore-extended-data-not-computed",
"en:food-groups-1-known",
"en:food-groups-2-known",
@@ -2595,20 +2840,19 @@
],
"data_quality_tags" : [
"en:no-packaging-data",
+ "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-packaging-packaging-data-missing",
- "en:ecoscore-production-system-no-label",
- "en:ecoscore-threatened-species-ingredients-missing"
+ "en:ecoscore-production-system-no-label"
],
"data_quality_warnings_tags" : [
"en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown",
"en:ecoscore-packaging-packaging-data-missing",
- "en:ecoscore-production-system-no-label",
- "en:ecoscore-threatened-species-ingredients-missing"
+ "en:ecoscore-production-system-no-label"
],
"ecoscore_data" : {
"adjustments" : {
@@ -2836,9 +3080,7 @@
"value" : 0,
"warning" : "no_label"
},
- "threatened_species" : {
- "warning" : "ingredients_missing"
- }
+ "threatened_species" : {}
},
"agribalyse" : {
"agribalyse_proxy_food_code" : "32135",
@@ -2931,7 +3173,6 @@
"xk" : "d"
},
"missing" : {
- "ingredients" : 1,
"labels" : 1,
"origins" : 1,
"packagings" : 1
@@ -3025,10 +3266,75 @@
"informers_tags" : [
"tests"
],
+ "ingredients" : [
+ {
+ "ciqual_food_code" : "13050",
+ "id" : "en:apple",
+ "percent_estimate" : 75,
+ "percent_max" : 100,
+ "percent_min" : 50,
+ "rank" : 1,
+ "text" : "apple",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ },
+ {
+ "ciqual_food_code" : "18066",
+ "id" : "en:water",
+ "percent_estimate" : 25,
+ "percent_max" : 50,
+ "percent_min" : 0,
+ "rank" : 2,
+ "text" : "water",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ }
+ ],
+ "ingredients_analysis" : {},
+ "ingredients_analysis_tags" : [
+ "en:palm-oil-free",
+ "en: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:water"
+ ],
+ "ingredients_lc" : "en",
+ "ingredients_n" : 2,
+ "ingredients_n_tags" : [
+ "2",
+ "1-10"
+ ],
+ "ingredients_original_tags" : [
+ "en:apple",
+ "en:water"
+ ],
+ "ingredients_percent_analysis" : 1,
+ "ingredients_tags" : [
+ "en:apple",
+ "en:fruit",
+ "en:water"
+ ],
+ "ingredients_text" : "apple, water",
"ingredients_text_en" : "apple, water",
+ "ingredients_text_with_allergens" : "apple, water",
"ingredients_text_with_allergens_en" : "apple, water",
+ "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" : 2,
+ "ingredients_with_unspecified_percent_sum" : 100,
+ "ingredients_without_ciqual_codes" : [],
+ "ingredients_without_ciqual_codes_n" : 0,
"interface_version_created" : "20150316.jqm2",
"interface_version_modified" : "20150316.jqm2",
+ "known_ingredients_n" : 3,
"lang" : "es",
"languages" : {
"en:english" : 5
@@ -3050,6 +3356,7 @@
"lc" : "es",
"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",
@@ -3060,9 +3367,13 @@
"en:nutriscore-missing-nutrition-data-sodium",
"en:nutriscore-missing-nutrition-data-proteins",
"en:nutrition-no-fiber",
- "en:nutriscore-not-computed",
- "en:nutrition-no-fruits-vegetables-nuts",
- "en:nutrition-no-fiber-or-fruits-vegetables-nuts",
+ "en:nutriscore-using-estimated-nutrition-facts",
+ "en:nutriscore-computed",
+ "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients",
+ "en:nutrition-all-nutriscore-values-known",
+ "en:nutriscore-2021-different-from-2023",
+ "en:nutriscore-2021-better-than-2023",
+ "en:nutriscore-2021-a-2023-b",
"en:packagings-number-of-components-0",
"en:packagings-not-complete",
"en:packagings-empty",
@@ -3077,79 +3388,213 @@
"en:ecoscore-grade-changed",
"en:main-countries-new-product"
],
- "nova_group_debug" : "no nova group when the product does not have ingredients",
- "nova_group_error" : "missing_ingredients",
+ "nova_group" : 1,
+ "nova_group_debug" : "",
+ "nova_groups" : "1",
+ "nova_groups_markers" : {},
"nova_groups_tags" : [
- "unknown"
+ "en:1-unprocessed-or-minimally-processed-foods"
],
+ "nucleotides_tags" : [],
"nutrient_levels" : {},
"nutrient_levels_tags" : [],
- "nutriments" : {},
+ "nutriments" : {
+ "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 50,
+ "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 50,
+ "nova-group" : 1,
+ "nova-group_100g" : 1,
+ "nova-group_serving" : 1,
+ "nutrition-score-fr" : -1,
+ "nutrition-score-fr_100g" : -1
+ },
+ "nutriments_estimated" : {
+ "alcohol_100g" : 0,
+ "beta-carotene_100g" : 1.275e-05,
+ "calcium_100g" : 0.0055325,
+ "carbohydrates_100g" : 8.025,
+ "cholesterol_100g" : 0,
+ "copper_100g" : 2.75e-05,
+ "energy-kcal_100g" : 36.675,
+ "energy-kj_100g" : 155.25,
+ "energy_100g" : 155.25,
+ "fat_100g" : 0.0975,
+ "fiber_100g" : 0.975,
+ "fructose_100g" : 4.5225,
+ "galactose_100g" : 0,
+ "glucose_100g" : 2.4375,
+ "iodine_100g" : 7.5e-08,
+ "iron_100g" : 6e-05,
+ "lactose_100g" : 0,
+ "magnesium_100g" : 0.0032475,
+ "maltose_100g" : 0,
+ "manganese_100g" : 2.8705e-05,
+ "pantothenic-acid_100g" : 5.325e-05,
+ "phosphorus_100g" : 0.00825,
+ "phylloquinone_100g" : 4.5e-07,
+ "polyols_100g" : 0.4425,
+ "potassium_100g" : 0.0676825,
+ "proteins_100g" : 0.2025,
+ "salt_100g" : 0.0019,
+ "saturated-fat_100g" : 0.01575,
+ "selenium_100g" : 2.375e-07,
+ "sodium_100g" : 0.0006,
+ "starch_100g" : 0,
+ "sucrose_100g" : 0.615,
+ "sugars_100g" : 7.575,
+ "vitamin-a_100g" : 0,
+ "vitamin-b12_100g" : 0,
+ "vitamin-b1_100g" : 1.425e-05,
+ "vitamin-b2_100g" : 2.1e-05,
+ "vitamin-b6_100g" : 2.775e-05,
+ "vitamin-b9_100g" : 0,
+ "vitamin-c_100g" : 0.003,
+ "vitamin-d_100g" : 0,
+ "vitamin-e_100g" : 3.75e-05,
+ "vitamin-pp_100g" : 6.825e-05,
+ "water_100g" : 90.025,
+ "zinc_100g" : 4.025e-05
+ },
"nutriscore" : {
"2021" : {
"category_available" : 1,
"data" : {
- "energy" : null,
- "fiber" : 0,
- "fruits_vegetables_nuts_colza_walnut_olive_oils" : 0,
+ "energy" : 155.25,
+ "energy_points" : 0,
+ "energy_value" : 155.3,
+ "fiber" : 0.975,
+ "fiber_points" : 1,
+ "fiber_value" : 0.98,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils" : 50,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 1,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 50,
"is_beverage" : 0,
"is_cheese" : 0,
"is_fat" : 0,
"is_water" : 0,
- "proteins" : null,
- "saturated_fat" : null,
- "sodium" : null,
- "sugars" : null
+ "negative_points" : 1,
+ "positive_points" : 2,
+ "proteins" : 0.2025,
+ "proteins_points" : 0,
+ "proteins_value" : 0.2,
+ "saturated_fat" : 0.01575,
+ "saturated_fat_points" : 0,
+ "saturated_fat_value" : 0,
+ "sodium" : 0.6,
+ "sodium_points" : 0,
+ "sodium_value" : 0.6,
+ "sugars" : 7.575,
+ "sugars_points" : 1,
+ "sugars_value" : 7.58
},
- "grade" : "unknown",
- "nutrients_available" : 0,
+ "grade" : "a",
+ "nutrients_available" : 1,
"nutriscore_applicable" : 1,
- "nutriscore_computed" : 0
+ "nutriscore_computed" : 1,
+ "score" : -1
},
"2023" : {
"category_available" : 1,
"data" : {
- "energy" : null,
- "fiber" : 0,
- "fruits_vegetables_legumes" : 0,
+ "count_proteins" : 1,
+ "count_proteins_reason" : "negative_points_less_than_11",
+ "energy" : 155.25,
+ "energy_points" : 0,
+ "fiber" : 0.975,
+ "fiber_points" : 0,
+ "fruits_vegetables_legumes" : 50,
+ "fruits_vegetables_legumes_points" : 1,
"is_beverage" : 0,
"is_cheese" : 0,
"is_fat_oil_nuts_seeds" : 0,
"is_water" : 0,
- "proteins" : null,
- "salt" : null,
- "saturated_fat" : null,
- "sugars" : null
+ "negative_nutrients" : [
+ "energy",
+ "sugars",
+ "saturated_fat",
+ "salt",
+ "sweeteners"
+ ],
+ "negative_points" : 2,
+ "positive_nutrients" : [
+ "fruits_vegetables_legumes",
+ "fiber",
+ "proteins"
+ ],
+ "positive_points" : 1,
+ "proteins" : 0.2025,
+ "proteins_points" : 0,
+ "salt" : 0.0019,
+ "salt_points" : 0,
+ "saturated_fat" : 0.01575,
+ "saturated_fat_points" : 0,
+ "sugars" : 7.575,
+ "sugars_points" : 2
},
- "grade" : "unknown",
- "nutrients_available" : 0,
+ "grade" : "b",
+ "nutrients_available" : 1,
"nutriscore_applicable" : 1,
- "nutriscore_computed" : 0
+ "nutriscore_computed" : 1,
+ "score" : 1
}
},
"nutriscore_2021_tags" : [
- "unknown"
+ "a"
],
"nutriscore_2023_tags" : [
- "unknown"
+ "b"
],
- "nutriscore_grade" : "unknown",
+ "nutriscore_data" : {
+ "energy" : 155.25,
+ "energy_points" : 0,
+ "energy_value" : 155.3,
+ "fiber" : 0.975,
+ "fiber_points" : 1,
+ "fiber_value" : 0.98,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils" : 50,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 1,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 50,
+ "grade" : "a",
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat" : 0,
+ "is_water" : 0,
+ "negative_points" : 1,
+ "positive_points" : 2,
+ "proteins" : 0.2025,
+ "proteins_points" : 0,
+ "proteins_value" : 0.2,
+ "saturated_fat" : 0.01575,
+ "saturated_fat_points" : 0,
+ "saturated_fat_value" : 0,
+ "score" : -1,
+ "sodium" : 0.6,
+ "sodium_points" : 0,
+ "sodium_value" : 0.6,
+ "sugars" : 7.575,
+ "sugars_points" : 1,
+ "sugars_value" : 7.58
+ },
+ "nutriscore_grade" : "a",
+ "nutriscore_score" : -1,
+ "nutriscore_score_opposite" : 1,
"nutriscore_tags" : [
- "unknown"
+ "a"
],
"nutriscore_version" : "2021",
"nutrition_data_per" : "100g",
"nutrition_data_prepared_per" : "100g",
- "nutrition_grade_fr" : "unknown",
- "nutrition_grades" : "unknown",
+ "nutrition_grade_fr" : "a",
+ "nutrition_grades" : "a",
"nutrition_grades_tags" : [
- "unknown"
+ "a"
],
"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_no_fiber" : 1,
- "nutrition_score_warning_no_fruits_vegetables_nuts" : 1,
+ "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1,
+ "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 50,
+ "nutrition_score_warning_nutriments_estimated" : 1,
"origin_en" : "China",
+ "other_nutritional_substances_tags" : [],
"packaging_materials_tags" : [],
"packaging_recycling_tags" : [],
"packaging_shapes_tags" : [],
@@ -3175,11 +3620,11 @@
"rev" : 1,
"serving_quantity" : 10,
"serving_size" : "10 g",
- "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-to-be-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-to-be-completed, en:photos-to-be-uploaded",
+ "states" : "en:to-be-completed, en:nutrition-facts-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-to-be-completed, en:photos-to-be-uploaded",
"states_hierarchy" : [
"en:to-be-completed",
- "en:nutrition-facts-to-be-completed",
- "en:ingredients-to-be-completed",
+ "en:nutrition-facts-completed",
+ "en:ingredients-completed",
"en:expiration-date-to-be-completed",
"en:packaging-code-to-be-completed",
"en:characteristics-to-be-completed",
@@ -3193,8 +3638,8 @@
],
"states_tags" : [
"en:to-be-completed",
- "en:nutrition-facts-to-be-completed",
- "en:ingredients-to-be-completed",
+ "en:nutrition-facts-completed",
+ "en:ingredients-completed",
"en:expiration-date-to-be-completed",
"en:packaging-code-to-be-completed",
"en:characteristics-to-be-completed",
@@ -3208,11 +3653,13 @@
],
"traces" : "",
"traces_from_ingredients" : "",
- "traces_from_user" : "(es) ",
+ "traces_from_user" : "(en) ",
"traces_hierarchy" : [],
"traces_tags" : [],
+ "unknown_ingredients_n" : 0,
"unknown_nutrients_tags" : [],
"url" : "http://world.openfoodfacts.localhost/product/200000000045/vegan-breakfast-cereals-without-palm-oil",
+ "vitamins_tags" : [],
"weighers_tags" : []
},
{
@@ -3778,6 +4225,7 @@
"en:fruit",
"en:water"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 2,
"ingredients_n_tags" : [
"2",
diff --git a/tests/integration/expected_test_results/search_v1/search-tags-categories-without-ingredients-from-palm-oil.json b/tests/integration/expected_test_results/search_v1/search-tags-categories-without-ingredients-from-palm-oil.json
index c750fb6a0f816..b31a8bdb0bedf 100644
--- a/tests/integration/expected_test_results/search_v1/search-tags-categories-without-ingredients-from-palm-oil.json
+++ b/tests/integration/expected_test_results/search_v1/search-tags-categories-without-ingredients-from-palm-oil.json
@@ -1,9 +1,913 @@
{
- "count" : 1,
+ "count" : 2,
"page" : 1,
- "page_count" : 1,
+ "page_count" : 2,
"page_size" : 24,
"products" : [
+ {
+ "_id" : "200000000045",
+ "_keywords" : [
+ "breakfast",
+ "cereal"
+ ],
+ "added_countries_tags" : [],
+ "additives_n" : 0,
+ "additives_old_n" : 0,
+ "additives_old_tags" : [],
+ "additives_original_tags" : [],
+ "additives_tags" : [],
+ "allergens" : "",
+ "allergens_from_ingredients" : "",
+ "allergens_from_user" : "(en) ",
+ "allergens_hierarchy" : [],
+ "allergens_tags" : [],
+ "amino_acids_tags" : [],
+ "categories" : "breakfast cereals",
+ "categories_hierarchy" : [
+ "en:plant-based-foods-and-beverages",
+ "en:plant-based-foods",
+ "en:breakfasts",
+ "en:cereals-and-potatoes",
+ "en:cereals-and-their-products",
+ "en:breakfast-cereals"
+ ],
+ "categories_lc" : "en",
+ "categories_properties" : {
+ "agribalyse_proxy_food_code:en" : "32135",
+ "ciqual_food_code:en" : "32003"
+ },
+ "categories_properties_tags" : [
+ "all-products",
+ "categories-known",
+ "agribalyse-food-code-unknown",
+ "agribalyse-proxy-food-code-32135",
+ "agribalyse-proxy-food-code-known",
+ "ciqual-food-code-32003",
+ "ciqual-food-code-known",
+ "agribalyse-known",
+ "agribalyse-32135"
+ ],
+ "categories_tags" : [
+ "en:plant-based-foods-and-beverages",
+ "en:plant-based-foods",
+ "en:breakfasts",
+ "en:cereals-and-potatoes",
+ "en:cereals-and-their-products",
+ "en:breakfast-cereals"
+ ],
+ "checkers_tags" : [],
+ "code" : "200000000045",
+ "codes_tags" : [
+ "code-12",
+ "200000000xxx",
+ "20000000xxxx",
+ "2000000xxxxx",
+ "200000xxxxxx",
+ "20000xxxxxxx",
+ "2000xxxxxxxx",
+ "200xxxxxxxxx",
+ "20xxxxxxxxxx",
+ "2xxxxxxxxxxx"
+ ],
+ "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:no-packaging-data",
+ "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:no-packaging-data",
+ "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-packaging-packaging-data-missing",
+ "en:ecoscore-production-system-no-label"
+ ],
+ "data_quality_warnings_tags" : [
+ "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown",
+ "en:ecoscore-packaging-packaging-data-missing",
+ "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" : 1,
+ "value" : -15,
+ "warning" : "packaging_data_missing"
+ },
+ "production_system" : {
+ "labels" : [],
+ "value" : 0,
+ "warning" : "no_label"
+ },
+ "threatened_species" : {}
+ },
+ "agribalyse" : {
+ "agribalyse_proxy_food_code" : "32135",
+ "co2_agriculture" : 2.2396004,
+ "co2_consumption" : 0,
+ "co2_distribution" : 0.019530673,
+ "co2_packaging" : 0.28159592,
+ "co2_processing" : 0.77051126,
+ "co2_total" : 3.564111983,
+ "co2_transportation" : 0.25287373,
+ "code" : "32135",
+ "dqr" : "4.03",
+ "ef_agriculture" : 0.50064279,
+ "ef_consumption" : 0,
+ "ef_distribution" : 0.0048315303,
+ "ef_packaging" : 0.023715692,
+ "ef_processing" : 0.078716079,
+ "ef_total" : 0.6323498093,
+ "ef_transportation" : 0.024443718,
+ "is_beverage" : 0,
+ "name_en" : "Breakfast cereals, mix of puffed or extruded cereals, fortified with vitamins and chemical elements",
+ "name_fr" : "Multi-céréales soufflées ou extrudées, enrichies en vitamines et minéraux",
+ "score" : 45,
+ "version" : "3.1"
+ },
+ "grade" : "d",
+ "grades" : {
+ "ad" : "d",
+ "al" : "d",
+ "at" : "d",
+ "ax" : "d",
+ "ba" : "d",
+ "be" : "d",
+ "bg" : "d",
+ "ch" : "d",
+ "cy" : "d",
+ "cz" : "d",
+ "de" : "d",
+ "dk" : "d",
+ "dz" : "d",
+ "ee" : "d",
+ "eg" : "d",
+ "es" : "d",
+ "fi" : "d",
+ "fo" : "d",
+ "fr" : "d",
+ "gg" : "d",
+ "gi" : "d",
+ "gr" : "d",
+ "hr" : "d",
+ "hu" : "d",
+ "ie" : "d",
+ "il" : "d",
+ "im" : "d",
+ "is" : "d",
+ "it" : "d",
+ "je" : "d",
+ "lb" : "d",
+ "li" : "d",
+ "lt" : "d",
+ "lu" : "d",
+ "lv" : "d",
+ "ly" : "d",
+ "ma" : "d",
+ "mc" : "d",
+ "md" : "d",
+ "me" : "d",
+ "mk" : "d",
+ "mt" : "d",
+ "nl" : "d",
+ "no" : "d",
+ "pl" : "d",
+ "ps" : "d",
+ "pt" : "d",
+ "ro" : "d",
+ "rs" : "d",
+ "se" : "d",
+ "si" : "d",
+ "sj" : "d",
+ "sk" : "d",
+ "sm" : "d",
+ "sy" : "d",
+ "tn" : "d",
+ "tr" : "d",
+ "ua" : "d",
+ "uk" : "d",
+ "us" : "d",
+ "va" : "d",
+ "world" : "d",
+ "xk" : "d"
+ },
+ "missing" : {
+ "labels" : 1,
+ "origins" : 1,
+ "packagings" : 1
+ },
+ "missing_data_warning" : 1,
+ "missing_key_data" : 1,
+ "score" : 25,
+ "scores" : {
+ "ad" : 25,
+ "al" : 25,
+ "at" : 25,
+ "ax" : 25,
+ "ba" : 25,
+ "be" : 25,
+ "bg" : 25,
+ "ch" : 25,
+ "cy" : 25,
+ "cz" : 25,
+ "de" : 25,
+ "dk" : 25,
+ "dz" : 25,
+ "ee" : 25,
+ "eg" : 25,
+ "es" : 25,
+ "fi" : 25,
+ "fo" : 25,
+ "fr" : 25,
+ "gg" : 25,
+ "gi" : 25,
+ "gr" : 25,
+ "hr" : 25,
+ "hu" : 25,
+ "ie" : 25,
+ "il" : 25,
+ "im" : 25,
+ "is" : 25,
+ "it" : 25,
+ "je" : 25,
+ "lb" : 25,
+ "li" : 25,
+ "lt" : 25,
+ "lu" : 25,
+ "lv" : 25,
+ "ly" : 25,
+ "ma" : 25,
+ "mc" : 25,
+ "md" : 25,
+ "me" : 25,
+ "mk" : 25,
+ "mt" : 25,
+ "nl" : 25,
+ "no" : 25,
+ "pl" : 25,
+ "ps" : 25,
+ "pt" : 25,
+ "ro" : 25,
+ "rs" : 25,
+ "se" : 25,
+ "si" : 25,
+ "sj" : 25,
+ "sk" : 25,
+ "sm" : 25,
+ "sy" : 25,
+ "tn" : 25,
+ "tr" : 25,
+ "ua" : 25,
+ "uk" : 25,
+ "us" : 25,
+ "va" : 25,
+ "world" : 25,
+ "xk" : 25
+ },
+ "status" : "known"
+ },
+ "ecoscore_grade" : "d",
+ "ecoscore_score" : 25,
+ "ecoscore_tags" : [
+ "d"
+ ],
+ "editors_tags" : [
+ "tests"
+ ],
+ "entry_dates_tags" : "--ignore--",
+ "food_groups" : "en:breakfast-cereals",
+ "food_groups_tags" : [
+ "en:cereals-and-potatoes",
+ "en:breakfast-cereals"
+ ],
+ "generic_name_en" : "Tester",
+ "id" : "200000000045",
+ "informers_tags" : [
+ "tests"
+ ],
+ "ingredients" : [
+ {
+ "ciqual_food_code" : "13050",
+ "id" : "en:apple",
+ "percent_estimate" : 75,
+ "percent_max" : 100,
+ "percent_min" : 50,
+ "rank" : 1,
+ "text" : "apple",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ },
+ {
+ "ciqual_food_code" : "18066",
+ "id" : "en:water",
+ "percent_estimate" : 25,
+ "percent_max" : 50,
+ "percent_min" : 0,
+ "rank" : 2,
+ "text" : "water",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ }
+ ],
+ "ingredients_analysis" : {},
+ "ingredients_analysis_tags" : [
+ "en:palm-oil-free",
+ "en: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:water"
+ ],
+ "ingredients_lc" : "en",
+ "ingredients_n" : 2,
+ "ingredients_n_tags" : [
+ "2",
+ "1-10"
+ ],
+ "ingredients_original_tags" : [
+ "en:apple",
+ "en:water"
+ ],
+ "ingredients_percent_analysis" : 1,
+ "ingredients_tags" : [
+ "en:apple",
+ "en:fruit",
+ "en:water"
+ ],
+ "ingredients_text" : "apple, water",
+ "ingredients_text_en" : "apple, water",
+ "ingredients_text_with_allergens" : "apple, water",
+ "ingredients_text_with_allergens_en" : "apple, water",
+ "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" : 2,
+ "ingredients_with_unspecified_percent_sum" : 100,
+ "ingredients_without_ciqual_codes" : [],
+ "ingredients_without_ciqual_codes_n" : 0,
+ "interface_version_created" : "20150316.jqm2",
+ "interface_version_modified" : "20150316.jqm2",
+ "known_ingredients_n" : 3,
+ "lang" : "es",
+ "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" : "es",
+ "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-using-estimated-nutrition-facts",
+ "en:nutriscore-computed",
+ "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients",
+ "en:nutrition-all-nutriscore-values-known",
+ "en:nutriscore-2021-different-from-2023",
+ "en:nutriscore-2021-better-than-2023",
+ "en:nutriscore-2021-a-2023-b",
+ "en:packagings-number-of-components-0",
+ "en:packagings-not-complete",
+ "en:packagings-empty",
+ "en:ecoscore-extended-data-not-computed",
+ "en:ecoscore-missing-data-warning",
+ "en:ecoscore-missing-data-labels",
+ "en:ecoscore-missing-data-origins",
+ "en:ecoscore-missing-data-packagings",
+ "en:ecoscore-missing-data-no-packagings",
+ "en:ecoscore-computed",
+ "en:ecoscore-changed",
+ "en:ecoscore-grade-changed",
+ "en:main-countries-new-product"
+ ],
+ "nova_group" : 1,
+ "nova_group_debug" : "",
+ "nova_groups" : "1",
+ "nova_groups_markers" : {},
+ "nova_groups_tags" : [
+ "en:1-unprocessed-or-minimally-processed-foods"
+ ],
+ "nucleotides_tags" : [],
+ "nutrient_levels" : {},
+ "nutrient_levels_tags" : [],
+ "nutriments" : {
+ "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 50,
+ "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 50,
+ "nova-group" : 1,
+ "nova-group_100g" : 1,
+ "nova-group_serving" : 1,
+ "nutrition-score-fr" : -1,
+ "nutrition-score-fr_100g" : -1
+ },
+ "nutriments_estimated" : {
+ "alcohol_100g" : 0,
+ "beta-carotene_100g" : 1.275e-05,
+ "calcium_100g" : 0.0055325,
+ "carbohydrates_100g" : 8.025,
+ "cholesterol_100g" : 0,
+ "copper_100g" : 2.75e-05,
+ "energy-kcal_100g" : 36.675,
+ "energy-kj_100g" : 155.25,
+ "energy_100g" : 155.25,
+ "fat_100g" : 0.0975,
+ "fiber_100g" : 0.975,
+ "fructose_100g" : 4.5225,
+ "galactose_100g" : 0,
+ "glucose_100g" : 2.4375,
+ "iodine_100g" : 7.5e-08,
+ "iron_100g" : 6e-05,
+ "lactose_100g" : 0,
+ "magnesium_100g" : 0.0032475,
+ "maltose_100g" : 0,
+ "manganese_100g" : 2.8705e-05,
+ "pantothenic-acid_100g" : 5.325e-05,
+ "phosphorus_100g" : 0.00825,
+ "phylloquinone_100g" : 4.5e-07,
+ "polyols_100g" : 0.4425,
+ "potassium_100g" : 0.0676825,
+ "proteins_100g" : 0.2025,
+ "salt_100g" : 0.0019,
+ "saturated-fat_100g" : 0.01575,
+ "selenium_100g" : 2.375e-07,
+ "sodium_100g" : 0.0006,
+ "starch_100g" : 0,
+ "sucrose_100g" : 0.615,
+ "sugars_100g" : 7.575,
+ "vitamin-a_100g" : 0,
+ "vitamin-b12_100g" : 0,
+ "vitamin-b1_100g" : 1.425e-05,
+ "vitamin-b2_100g" : 2.1e-05,
+ "vitamin-b6_100g" : 2.775e-05,
+ "vitamin-b9_100g" : 0,
+ "vitamin-c_100g" : 0.003,
+ "vitamin-d_100g" : 0,
+ "vitamin-e_100g" : 3.75e-05,
+ "vitamin-pp_100g" : 6.825e-05,
+ "water_100g" : 90.025,
+ "zinc_100g" : 4.025e-05
+ },
+ "nutriscore" : {
+ "2021" : {
+ "category_available" : 1,
+ "data" : {
+ "energy" : 155.25,
+ "energy_points" : 0,
+ "energy_value" : 155.3,
+ "fiber" : 0.975,
+ "fiber_points" : 1,
+ "fiber_value" : 0.98,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils" : 50,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 1,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 50,
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat" : 0,
+ "is_water" : 0,
+ "negative_points" : 1,
+ "positive_points" : 2,
+ "proteins" : 0.2025,
+ "proteins_points" : 0,
+ "proteins_value" : 0.2,
+ "saturated_fat" : 0.01575,
+ "saturated_fat_points" : 0,
+ "saturated_fat_value" : 0,
+ "sodium" : 0.6,
+ "sodium_points" : 0,
+ "sodium_value" : 0.6,
+ "sugars" : 7.575,
+ "sugars_points" : 1,
+ "sugars_value" : 7.58
+ },
+ "grade" : "a",
+ "nutrients_available" : 1,
+ "nutriscore_applicable" : 1,
+ "nutriscore_computed" : 1,
+ "score" : -1
+ },
+ "2023" : {
+ "category_available" : 1,
+ "data" : {
+ "count_proteins" : 1,
+ "count_proteins_reason" : "negative_points_less_than_11",
+ "energy" : 155.25,
+ "energy_points" : 0,
+ "fiber" : 0.975,
+ "fiber_points" : 0,
+ "fruits_vegetables_legumes" : 50,
+ "fruits_vegetables_legumes_points" : 1,
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat_oil_nuts_seeds" : 0,
+ "is_water" : 0,
+ "negative_nutrients" : [
+ "energy",
+ "sugars",
+ "saturated_fat",
+ "salt",
+ "sweeteners"
+ ],
+ "negative_points" : 2,
+ "positive_nutrients" : [
+ "fruits_vegetables_legumes",
+ "fiber",
+ "proteins"
+ ],
+ "positive_points" : 1,
+ "proteins" : 0.2025,
+ "proteins_points" : 0,
+ "salt" : 0.0019,
+ "salt_points" : 0,
+ "saturated_fat" : 0.01575,
+ "saturated_fat_points" : 0,
+ "sugars" : 7.575,
+ "sugars_points" : 2
+ },
+ "grade" : "b",
+ "nutrients_available" : 1,
+ "nutriscore_applicable" : 1,
+ "nutriscore_computed" : 1,
+ "score" : 1
+ }
+ },
+ "nutriscore_2021_tags" : [
+ "a"
+ ],
+ "nutriscore_2023_tags" : [
+ "b"
+ ],
+ "nutriscore_data" : {
+ "energy" : 155.25,
+ "energy_points" : 0,
+ "energy_value" : 155.3,
+ "fiber" : 0.975,
+ "fiber_points" : 1,
+ "fiber_value" : 0.98,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils" : 50,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 1,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 50,
+ "grade" : "a",
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat" : 0,
+ "is_water" : 0,
+ "negative_points" : 1,
+ "positive_points" : 2,
+ "proteins" : 0.2025,
+ "proteins_points" : 0,
+ "proteins_value" : 0.2,
+ "saturated_fat" : 0.01575,
+ "saturated_fat_points" : 0,
+ "saturated_fat_value" : 0,
+ "score" : -1,
+ "sodium" : 0.6,
+ "sodium_points" : 0,
+ "sodium_value" : 0.6,
+ "sugars" : 7.575,
+ "sugars_points" : 1,
+ "sugars_value" : 7.58
+ },
+ "nutriscore_grade" : "a",
+ "nutriscore_score" : -1,
+ "nutriscore_score_opposite" : 1,
+ "nutriscore_tags" : [
+ "a"
+ ],
+ "nutriscore_version" : "2021",
+ "nutrition_data_per" : "100g",
+ "nutrition_data_prepared_per" : "100g",
+ "nutrition_grade_fr" : "a",
+ "nutrition_grades" : "a",
+ "nutrition_grades_tags" : [
+ "a"
+ ],
+ "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_nuts_estimate_from_ingredients" : 1,
+ "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 50,
+ "nutrition_score_warning_nutriments_estimated" : 1,
+ "origin_en" : "China",
+ "other_nutritional_substances_tags" : [],
+ "packaging_materials_tags" : [],
+ "packaging_recycling_tags" : [],
+ "packaging_shapes_tags" : [],
+ "packaging_text_en" : "no",
+ "packagings" : [],
+ "packagings_materials" : {},
+ "photographers_tags" : [],
+ "pnns_groups_1" : "Cereals and potatoes",
+ "pnns_groups_1_tags" : [
+ "cereals-and-potatoes",
+ "known"
+ ],
+ "pnns_groups_2" : "Breakfast cereals",
+ "pnns_groups_2_tags" : [
+ "breakfast-cereals",
+ "known"
+ ],
+ "popularity_key" : 0,
+ "product_name_en" : "Vegan breakfast cereals without palm oil",
+ "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-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-to-be-completed, en:photos-to-be-uploaded",
+ "states_hierarchy" : [
+ "en:to-be-completed",
+ "en:nutrition-facts-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-to-be-completed",
+ "en:photos-to-be-uploaded"
+ ],
+ "states_tags" : [
+ "en:to-be-completed",
+ "en:nutrition-facts-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-to-be-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" : [],
+ "url" : "http://world.openfoodfacts.localhost/product/200000000045/vegan-breakfast-cereals-without-palm-oil",
+ "vitamins_tags" : [],
+ "weighers_tags" : []
+ },
{
"_id" : "200000000046",
"_keywords" : [
@@ -567,6 +1471,7 @@
"en:fruit",
"en:water"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 2,
"ingredients_n_tags" : [
"2",
diff --git a/tests/integration/expected_test_results/search_v1/search-without-ingredients-from-palm-oil.json b/tests/integration/expected_test_results/search_v1/search-without-ingredients-from-palm-oil.json
index ee8febf7bf8ef..1e691dac19b0e 100644
--- a/tests/integration/expected_test_results/search_v1/search-without-ingredients-from-palm-oil.json
+++ b/tests/integration/expected_test_results/search_v1/search-without-ingredients-from-palm-oil.json
@@ -1,7 +1,7 @@
{
- "count" : 4,
+ "count" : 6,
"page" : 1,
- "page_count" : 4,
+ "page_count" : 6,
"page_size" : 24,
"products" : [
{
@@ -471,6 +471,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
@@ -1122,6 +1123,7 @@
"en:fruit",
"en:rice"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 2,
"ingredients_n_tags" : [
"2",
@@ -1775,6 +1777,7 @@
"en:dairy",
"en:egg"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 3,
"ingredients_n_tags" : [
"3",
@@ -2006,6 +2009,1659 @@
"vitamins_tags" : [],
"weighers_tags" : []
},
+ {
+ "_id" : "200000000039",
+ "_keywords" : [
+ "snack"
+ ],
+ "added_countries_tags" : [],
+ "additives_n" : 0,
+ "additives_old_n" : 0,
+ "additives_old_tags" : [],
+ "additives_original_tags" : [],
+ "additives_tags" : [],
+ "allergens" : "",
+ "allergens_from_ingredients" : "",
+ "allergens_from_user" : "(en) ",
+ "allergens_hierarchy" : [],
+ "allergens_tags" : [],
+ "amino_acids_tags" : [],
+ "categories" : "snacks",
+ "categories_hierarchy" : [
+ "en:snacks"
+ ],
+ "categories_lc" : "en",
+ "categories_properties" : {},
+ "categories_properties_tags" : [
+ "all-products",
+ "categories-known",
+ "agribalyse-food-code-unknown",
+ "agribalyse-proxy-food-code-unknown",
+ "ciqual-food-code-unknown",
+ "agribalyse-unknown"
+ ],
+ "categories_tags" : [
+ "en:snacks"
+ ],
+ "checkers_tags" : [],
+ "code" : "200000000039",
+ "codes_tags" : [
+ "code-12",
+ "200000000xxx",
+ "20000000xxxx",
+ "2000000xxxxx",
+ "200000xxxxxx",
+ "20000xxxxxxx",
+ "2000xxxxxxxx",
+ "200xxxxxxxxx",
+ "20xxxxxxxxxx",
+ "2xxxxxxxxxxx"
+ ],
+ "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:no-packaging-data",
+ "en:ingredients-percent-analysis-ok",
+ "en:ecoscore-extended-data-not-computed",
+ "en:food-groups-1-unknown",
+ "en:food-groups-2-unknown",
+ "en:food-groups-3-unknown"
+ ],
+ "data_quality_tags" : [
+ "en:no-packaging-data",
+ "en:ingredients-percent-analysis-ok",
+ "en:ecoscore-extended-data-not-computed",
+ "en:food-groups-1-unknown",
+ "en:food-groups-2-unknown",
+ "en:food-groups-3-unknown",
+ "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown",
+ "en:ecoscore-packaging-packaging-data-missing",
+ "en:ecoscore-production-system-no-label"
+ ],
+ "data_quality_warnings_tags" : [
+ "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown",
+ "en:ecoscore-packaging-packaging-data-missing",
+ "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" : 1,
+ "value" : -15,
+ "warning" : "packaging_data_missing"
+ },
+ "production_system" : {
+ "labels" : [],
+ "value" : 0,
+ "warning" : "no_label"
+ },
+ "threatened_species" : {
+ "ingredient" : "en:palm-oil",
+ "value" : -10
+ }
+ },
+ "agribalyse" : {
+ "warning" : "missing_agribalyse_match"
+ },
+ "missing" : {
+ "agb_category" : 1,
+ "labels" : 1,
+ "origins" : 1,
+ "packagings" : 1
+ },
+ "missing_agribalyse_match_warning" : 1,
+ "missing_key_data" : 1,
+ "scores" : {},
+ "status" : "unknown"
+ },
+ "ecoscore_grade" : "unknown",
+ "ecoscore_tags" : [
+ "unknown"
+ ],
+ "editors_tags" : [
+ "tests"
+ ],
+ "entry_dates_tags" : "--ignore--",
+ "food_groups_tags" : [],
+ "generic_name_en" : "Tester",
+ "id" : "200000000039",
+ "informers_tags" : [
+ "tests"
+ ],
+ "ingredients" : [
+ {
+ "ciqual_food_code" : "13050",
+ "id" : "en:apple",
+ "percent_estimate" : 66.6666666666667,
+ "percent_max" : 100,
+ "percent_min" : 33.3333333333333,
+ "rank" : 1,
+ "text" : "apple",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ },
+ {
+ "ciqual_food_code" : "18066",
+ "id" : "en:water",
+ "percent_estimate" : 16.6666666666667,
+ "percent_max" : 50,
+ "percent_min" : 0,
+ "rank" : 2,
+ "text" : "water",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ },
+ {
+ "ciqual_food_code" : "16129",
+ "from_palm_oil" : "yes",
+ "id" : "en:palm-oil",
+ "percent_estimate" : 16.6666666666667,
+ "percent_max" : 33.3333333333333,
+ "percent_min" : 0,
+ "rank" : 3,
+ "text" : "palm oil",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ }
+ ],
+ "ingredients_analysis" : {
+ "en:palm-oil" : [
+ "en:palm-oil"
+ ]
+ },
+ "ingredients_analysis_tags" : [
+ "en:palm-oil",
+ "en: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:water",
+ "en:palm-oil",
+ "en:oil-and-fat",
+ "en:vegetable-oil-and-fat",
+ "en:palm-oil-and-fat"
+ ],
+ "ingredients_lc" : "en",
+ "ingredients_n" : 3,
+ "ingredients_n_tags" : [
+ "3",
+ "1-10"
+ ],
+ "ingredients_original_tags" : [
+ "en:apple",
+ "en:water",
+ "en:palm-oil"
+ ],
+ "ingredients_percent_analysis" : 1,
+ "ingredients_tags" : [
+ "en:apple",
+ "en:fruit",
+ "en:water",
+ "en:palm-oil",
+ "en:oil-and-fat",
+ "en:vegetable-oil-and-fat",
+ "en:palm-oil-and-fat"
+ ],
+ "ingredients_text" : "apple, water, palm oil",
+ "ingredients_text_en" : "apple, water, palm oil",
+ "ingredients_text_with_allergens" : "apple, water, palm oil",
+ "ingredients_text_with_allergens_en" : "apple, water, 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" : 3,
+ "ingredients_with_unspecified_percent_sum" : 100,
+ "ingredients_without_ciqual_codes" : [],
+ "ingredients_without_ciqual_codes_n" : 0,
+ "interface_version_created" : "20150316.jqm2",
+ "interface_version_modified" : "20150316.jqm2",
+ "known_ingredients_n" : 7,
+ "lang" : "es",
+ "languages" : {
+ "en:english" : 4
+ },
+ "languages_codes" : {
+ "en" : 4
+ },
+ "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" : "es",
+ "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-using-estimated-nutrition-facts",
+ "en:nutriscore-computed",
+ "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients",
+ "en:nutrition-all-nutriscore-values-known",
+ "en:nutriscore-2021-same-as-2023",
+ "en:nutriscore-2021-d-2023-d",
+ "en:packagings-number-of-components-0",
+ "en:packagings-not-complete",
+ "en:packagings-empty",
+ "en:ecoscore-extended-data-not-computed",
+ "en:ecoscore-not-computed",
+ "en:main-countries-new-product"
+ ],
+ "nova_group" : 1,
+ "nova_group_debug" : "",
+ "nova_groups" : "1",
+ "nova_groups_markers" : {},
+ "nova_groups_tags" : [
+ "en:1-unprocessed-or-minimally-processed-foods"
+ ],
+ "nucleotides_tags" : [],
+ "nutrient_levels" : {},
+ "nutrient_levels_tags" : [],
+ "nutriments" : {
+ "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 33.3333333333333,
+ "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 33.3333333333333,
+ "nova-group" : 1,
+ "nova-group_100g" : 1,
+ "nova-group_serving" : 1,
+ "nutrition-score-fr" : 11,
+ "nutrition-score-fr_100g" : 11
+ },
+ "nutriments_estimated" : {
+ "alcohol_100g" : 0,
+ "beta-carotene_100g" : 1.13333333333333e-05,
+ "calcium_100g" : 0.00452166666666667,
+ "carbohydrates_100g" : 7.13333333333333,
+ "cholesterol_100g" : 0,
+ "copper_100g" : 2.35e-05,
+ "energy-kcal_100g" : 182.6,
+ "energy-kj_100g" : 754.666666666666,
+ "energy_100g" : 754.666666666666,
+ "fat_100g" : 16.7533333333333,
+ "fiber_100g" : 0.866666666666667,
+ "fructose_100g" : 4.02,
+ "galactose_100g" : 0,
+ "glucose_100g" : 2.16666666666667,
+ "iodine_100g" : 9.66666666666666e-07,
+ "iron_100g" : 5.33333333333333e-05,
+ "lactose_100g" : 0,
+ "magnesium_100g" : 0.00283166666666667,
+ "maltose_100g" : 0,
+ "manganese_100g" : 2.5595e-05,
+ "pantothenic-acid_100g" : 4.73333333333333e-05,
+ "phosphorus_100g" : 0.00733333333333333,
+ "phylloquinone_100g" : 1.73333333333333e-06,
+ "polyols_100g" : 0.393333333333333,
+ "potassium_100g" : 0.0601216666666667,
+ "proteins_100g" : 0.18,
+ "salt_100g" : 0.00126666666666667,
+ "saturated-fat_100g" : 8.23066666666666,
+ "selenium_100g" : 1.43333333333333e-06,
+ "sodium_100g" : 0.0004,
+ "starch_100g" : 0,
+ "sucrose_100g" : 0.546666666666667,
+ "sugars_100g" : 6.73333333333333,
+ "vitamin-a_100g" : 0,
+ "vitamin-b12_100g" : 0,
+ "vitamin-b1_100g" : 1.26666666666667e-05,
+ "vitamin-b2_100g" : 1.86666666666667e-05,
+ "vitamin-b6_100g" : 2.46666666666667e-05,
+ "vitamin-b9_100g" : 0,
+ "vitamin-c_100g" : 0.00266666666666667,
+ "vitamin-d_100g" : 0,
+ "vitamin-e_100g" : 0.00268333333333333,
+ "vitamin-pp_100g" : 6.06666666666667e-05,
+ "water_100g" : 74.4666666666667,
+ "zinc_100g" : 3.51666666666667e-05
+ },
+ "nutriscore" : {
+ "2021" : {
+ "category_available" : 1,
+ "data" : {
+ "energy" : 754.666666666666,
+ "energy_points" : 2,
+ "energy_value" : 754.7,
+ "fiber" : 0.866666666666667,
+ "fiber_points" : 0,
+ "fiber_value" : 0.87,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils" : 33.3333333333333,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 0,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 33.3,
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat" : 0,
+ "is_water" : 0,
+ "negative_points" : 11,
+ "positive_points" : 0,
+ "proteins" : 0.18,
+ "proteins_points" : 0,
+ "proteins_value" : 0.18,
+ "saturated_fat" : 8.23066666666666,
+ "saturated_fat_points" : 8,
+ "saturated_fat_value" : 8.2,
+ "sodium" : 0.4,
+ "sodium_points" : 0,
+ "sodium_value" : 0.4,
+ "sugars" : 6.73333333333333,
+ "sugars_points" : 1,
+ "sugars_value" : 6.73
+ },
+ "grade" : "d",
+ "nutrients_available" : 1,
+ "nutriscore_applicable" : 1,
+ "nutriscore_computed" : 1,
+ "score" : 11
+ },
+ "2023" : {
+ "category_available" : 1,
+ "data" : {
+ "count_proteins" : 0,
+ "count_proteins_reason" : "negative_points_more_than_11",
+ "energy" : 754.666666666666,
+ "energy_points" : 2,
+ "fiber" : 0.866666666666667,
+ "fiber_points" : 0,
+ "fruits_vegetables_legumes" : 33.3333333333333,
+ "fruits_vegetables_legumes_points" : 0,
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat_oil_nuts_seeds" : 0,
+ "is_water" : 0,
+ "negative_nutrients" : [
+ "energy",
+ "sugars",
+ "saturated_fat",
+ "salt",
+ "sweeteners"
+ ],
+ "negative_points" : 11,
+ "positive_nutrients" : [
+ "fruits_vegetables_legumes",
+ "fiber"
+ ],
+ "positive_points" : 0,
+ "proteins" : 0.18,
+ "proteins_points" : 0,
+ "salt" : 0.00126666666666667,
+ "salt_points" : 0,
+ "saturated_fat" : 8.23066666666666,
+ "saturated_fat_points" : 8,
+ "sugars" : 6.73333333333333,
+ "sugars_points" : 1
+ },
+ "grade" : "d",
+ "nutrients_available" : 1,
+ "nutriscore_applicable" : 1,
+ "nutriscore_computed" : 1,
+ "score" : 11
+ }
+ },
+ "nutriscore_2021_tags" : [
+ "d"
+ ],
+ "nutriscore_2023_tags" : [
+ "d"
+ ],
+ "nutriscore_data" : {
+ "energy" : 754.666666666666,
+ "energy_points" : 2,
+ "energy_value" : 754.7,
+ "fiber" : 0.866666666666667,
+ "fiber_points" : 0,
+ "fiber_value" : 0.87,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils" : 33.3333333333333,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 0,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 33.3,
+ "grade" : "d",
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat" : 0,
+ "is_water" : 0,
+ "negative_points" : 11,
+ "positive_points" : 0,
+ "proteins" : 0.18,
+ "proteins_points" : 0,
+ "proteins_value" : 0.18,
+ "saturated_fat" : 8.23066666666666,
+ "saturated_fat_points" : 8,
+ "saturated_fat_value" : 8.2,
+ "score" : 11,
+ "sodium" : 0.4,
+ "sodium_points" : 0,
+ "sodium_value" : 0.4,
+ "sugars" : 6.73333333333333,
+ "sugars_points" : 1,
+ "sugars_value" : 6.73
+ },
+ "nutriscore_grade" : "d",
+ "nutriscore_score" : 11,
+ "nutriscore_score_opposite" : -11,
+ "nutriscore_tags" : [
+ "d"
+ ],
+ "nutriscore_version" : "2021",
+ "nutrition_data_per" : "100g",
+ "nutrition_data_prepared_per" : "100g",
+ "nutrition_grade_fr" : "d",
+ "nutrition_grades" : "d",
+ "nutrition_grades_tags" : [
+ "d"
+ ],
+ "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_nuts_estimate_from_ingredients" : 1,
+ "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 33.3333333333333,
+ "nutrition_score_warning_nutriments_estimated" : 1,
+ "origin_en" : "spain",
+ "other_nutritional_substances_tags" : [],
+ "packaging_materials_tags" : [],
+ "packaging_recycling_tags" : [],
+ "packaging_shapes_tags" : [],
+ "packagings" : [],
+ "packagings_materials" : {},
+ "photographers_tags" : [],
+ "pnns_groups_1" : "unknown",
+ "pnns_groups_1_tags" : [
+ "unknown",
+ "missing-association"
+ ],
+ "pnns_groups_2" : "unknown",
+ "pnns_groups_2_tags" : [
+ "unknown",
+ "missing-association"
+ ],
+ "popularity_key" : 0,
+ "product_name_en" : "Vegan Test Snack with palm oil",
+ "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-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-to-be-completed, en:photos-to-be-uploaded",
+ "states_hierarchy" : [
+ "en:to-be-completed",
+ "en:nutrition-facts-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-to-be-completed",
+ "en:photos-to-be-uploaded"
+ ],
+ "states_tags" : [
+ "en:to-be-completed",
+ "en:nutrition-facts-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-to-be-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" : [],
+ "url" : "http://world.openfoodfacts.localhost/product/200000000039/vegan-test-snack-with-palm-oil",
+ "vitamins_tags" : [],
+ "weighers_tags" : []
+ },
+ {
+ "_id" : "200000000045",
+ "_keywords" : [
+ "breakfast",
+ "cereal"
+ ],
+ "added_countries_tags" : [],
+ "additives_n" : 0,
+ "additives_old_n" : 0,
+ "additives_old_tags" : [],
+ "additives_original_tags" : [],
+ "additives_tags" : [],
+ "allergens" : "",
+ "allergens_from_ingredients" : "",
+ "allergens_from_user" : "(en) ",
+ "allergens_hierarchy" : [],
+ "allergens_tags" : [],
+ "amino_acids_tags" : [],
+ "categories" : "breakfast cereals",
+ "categories_hierarchy" : [
+ "en:plant-based-foods-and-beverages",
+ "en:plant-based-foods",
+ "en:breakfasts",
+ "en:cereals-and-potatoes",
+ "en:cereals-and-their-products",
+ "en:breakfast-cereals"
+ ],
+ "categories_lc" : "en",
+ "categories_properties" : {
+ "agribalyse_proxy_food_code:en" : "32135",
+ "ciqual_food_code:en" : "32003"
+ },
+ "categories_properties_tags" : [
+ "all-products",
+ "categories-known",
+ "agribalyse-food-code-unknown",
+ "agribalyse-proxy-food-code-32135",
+ "agribalyse-proxy-food-code-known",
+ "ciqual-food-code-32003",
+ "ciqual-food-code-known",
+ "agribalyse-known",
+ "agribalyse-32135"
+ ],
+ "categories_tags" : [
+ "en:plant-based-foods-and-beverages",
+ "en:plant-based-foods",
+ "en:breakfasts",
+ "en:cereals-and-potatoes",
+ "en:cereals-and-their-products",
+ "en:breakfast-cereals"
+ ],
+ "checkers_tags" : [],
+ "code" : "200000000045",
+ "codes_tags" : [
+ "code-12",
+ "200000000xxx",
+ "20000000xxxx",
+ "2000000xxxxx",
+ "200000xxxxxx",
+ "20000xxxxxxx",
+ "2000xxxxxxxx",
+ "200xxxxxxxxx",
+ "20xxxxxxxxxx",
+ "2xxxxxxxxxxx"
+ ],
+ "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:no-packaging-data",
+ "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:no-packaging-data",
+ "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-packaging-packaging-data-missing",
+ "en:ecoscore-production-system-no-label"
+ ],
+ "data_quality_warnings_tags" : [
+ "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown",
+ "en:ecoscore-packaging-packaging-data-missing",
+ "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" : 1,
+ "value" : -15,
+ "warning" : "packaging_data_missing"
+ },
+ "production_system" : {
+ "labels" : [],
+ "value" : 0,
+ "warning" : "no_label"
+ },
+ "threatened_species" : {}
+ },
+ "agribalyse" : {
+ "agribalyse_proxy_food_code" : "32135",
+ "co2_agriculture" : 2.2396004,
+ "co2_consumption" : 0,
+ "co2_distribution" : 0.019530673,
+ "co2_packaging" : 0.28159592,
+ "co2_processing" : 0.77051126,
+ "co2_total" : 3.564111983,
+ "co2_transportation" : 0.25287373,
+ "code" : "32135",
+ "dqr" : "4.03",
+ "ef_agriculture" : 0.50064279,
+ "ef_consumption" : 0,
+ "ef_distribution" : 0.0048315303,
+ "ef_packaging" : 0.023715692,
+ "ef_processing" : 0.078716079,
+ "ef_total" : 0.6323498093,
+ "ef_transportation" : 0.024443718,
+ "is_beverage" : 0,
+ "name_en" : "Breakfast cereals, mix of puffed or extruded cereals, fortified with vitamins and chemical elements",
+ "name_fr" : "Multi-céréales soufflées ou extrudées, enrichies en vitamines et minéraux",
+ "score" : 45,
+ "version" : "3.1"
+ },
+ "grade" : "d",
+ "grades" : {
+ "ad" : "d",
+ "al" : "d",
+ "at" : "d",
+ "ax" : "d",
+ "ba" : "d",
+ "be" : "d",
+ "bg" : "d",
+ "ch" : "d",
+ "cy" : "d",
+ "cz" : "d",
+ "de" : "d",
+ "dk" : "d",
+ "dz" : "d",
+ "ee" : "d",
+ "eg" : "d",
+ "es" : "d",
+ "fi" : "d",
+ "fo" : "d",
+ "fr" : "d",
+ "gg" : "d",
+ "gi" : "d",
+ "gr" : "d",
+ "hr" : "d",
+ "hu" : "d",
+ "ie" : "d",
+ "il" : "d",
+ "im" : "d",
+ "is" : "d",
+ "it" : "d",
+ "je" : "d",
+ "lb" : "d",
+ "li" : "d",
+ "lt" : "d",
+ "lu" : "d",
+ "lv" : "d",
+ "ly" : "d",
+ "ma" : "d",
+ "mc" : "d",
+ "md" : "d",
+ "me" : "d",
+ "mk" : "d",
+ "mt" : "d",
+ "nl" : "d",
+ "no" : "d",
+ "pl" : "d",
+ "ps" : "d",
+ "pt" : "d",
+ "ro" : "d",
+ "rs" : "d",
+ "se" : "d",
+ "si" : "d",
+ "sj" : "d",
+ "sk" : "d",
+ "sm" : "d",
+ "sy" : "d",
+ "tn" : "d",
+ "tr" : "d",
+ "ua" : "d",
+ "uk" : "d",
+ "us" : "d",
+ "va" : "d",
+ "world" : "d",
+ "xk" : "d"
+ },
+ "missing" : {
+ "labels" : 1,
+ "origins" : 1,
+ "packagings" : 1
+ },
+ "missing_data_warning" : 1,
+ "missing_key_data" : 1,
+ "score" : 25,
+ "scores" : {
+ "ad" : 25,
+ "al" : 25,
+ "at" : 25,
+ "ax" : 25,
+ "ba" : 25,
+ "be" : 25,
+ "bg" : 25,
+ "ch" : 25,
+ "cy" : 25,
+ "cz" : 25,
+ "de" : 25,
+ "dk" : 25,
+ "dz" : 25,
+ "ee" : 25,
+ "eg" : 25,
+ "es" : 25,
+ "fi" : 25,
+ "fo" : 25,
+ "fr" : 25,
+ "gg" : 25,
+ "gi" : 25,
+ "gr" : 25,
+ "hr" : 25,
+ "hu" : 25,
+ "ie" : 25,
+ "il" : 25,
+ "im" : 25,
+ "is" : 25,
+ "it" : 25,
+ "je" : 25,
+ "lb" : 25,
+ "li" : 25,
+ "lt" : 25,
+ "lu" : 25,
+ "lv" : 25,
+ "ly" : 25,
+ "ma" : 25,
+ "mc" : 25,
+ "md" : 25,
+ "me" : 25,
+ "mk" : 25,
+ "mt" : 25,
+ "nl" : 25,
+ "no" : 25,
+ "pl" : 25,
+ "ps" : 25,
+ "pt" : 25,
+ "ro" : 25,
+ "rs" : 25,
+ "se" : 25,
+ "si" : 25,
+ "sj" : 25,
+ "sk" : 25,
+ "sm" : 25,
+ "sy" : 25,
+ "tn" : 25,
+ "tr" : 25,
+ "ua" : 25,
+ "uk" : 25,
+ "us" : 25,
+ "va" : 25,
+ "world" : 25,
+ "xk" : 25
+ },
+ "status" : "known"
+ },
+ "ecoscore_grade" : "d",
+ "ecoscore_score" : 25,
+ "ecoscore_tags" : [
+ "d"
+ ],
+ "editors_tags" : [
+ "tests"
+ ],
+ "entry_dates_tags" : "--ignore--",
+ "food_groups" : "en:breakfast-cereals",
+ "food_groups_tags" : [
+ "en:cereals-and-potatoes",
+ "en:breakfast-cereals"
+ ],
+ "generic_name_en" : "Tester",
+ "id" : "200000000045",
+ "informers_tags" : [
+ "tests"
+ ],
+ "ingredients" : [
+ {
+ "ciqual_food_code" : "13050",
+ "id" : "en:apple",
+ "percent_estimate" : 75,
+ "percent_max" : 100,
+ "percent_min" : 50,
+ "rank" : 1,
+ "text" : "apple",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ },
+ {
+ "ciqual_food_code" : "18066",
+ "id" : "en:water",
+ "percent_estimate" : 25,
+ "percent_max" : 50,
+ "percent_min" : 0,
+ "rank" : 2,
+ "text" : "water",
+ "vegan" : "yes",
+ "vegetarian" : "yes"
+ }
+ ],
+ "ingredients_analysis" : {},
+ "ingredients_analysis_tags" : [
+ "en:palm-oil-free",
+ "en: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:water"
+ ],
+ "ingredients_lc" : "en",
+ "ingredients_n" : 2,
+ "ingredients_n_tags" : [
+ "2",
+ "1-10"
+ ],
+ "ingredients_original_tags" : [
+ "en:apple",
+ "en:water"
+ ],
+ "ingredients_percent_analysis" : 1,
+ "ingredients_tags" : [
+ "en:apple",
+ "en:fruit",
+ "en:water"
+ ],
+ "ingredients_text" : "apple, water",
+ "ingredients_text_en" : "apple, water",
+ "ingredients_text_with_allergens" : "apple, water",
+ "ingredients_text_with_allergens_en" : "apple, water",
+ "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" : 2,
+ "ingredients_with_unspecified_percent_sum" : 100,
+ "ingredients_without_ciqual_codes" : [],
+ "ingredients_without_ciqual_codes_n" : 0,
+ "interface_version_created" : "20150316.jqm2",
+ "interface_version_modified" : "20150316.jqm2",
+ "known_ingredients_n" : 3,
+ "lang" : "es",
+ "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" : "es",
+ "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-using-estimated-nutrition-facts",
+ "en:nutriscore-computed",
+ "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients",
+ "en:nutrition-all-nutriscore-values-known",
+ "en:nutriscore-2021-different-from-2023",
+ "en:nutriscore-2021-better-than-2023",
+ "en:nutriscore-2021-a-2023-b",
+ "en:packagings-number-of-components-0",
+ "en:packagings-not-complete",
+ "en:packagings-empty",
+ "en:ecoscore-extended-data-not-computed",
+ "en:ecoscore-missing-data-warning",
+ "en:ecoscore-missing-data-labels",
+ "en:ecoscore-missing-data-origins",
+ "en:ecoscore-missing-data-packagings",
+ "en:ecoscore-missing-data-no-packagings",
+ "en:ecoscore-computed",
+ "en:ecoscore-changed",
+ "en:ecoscore-grade-changed",
+ "en:main-countries-new-product"
+ ],
+ "nova_group" : 1,
+ "nova_group_debug" : "",
+ "nova_groups" : "1",
+ "nova_groups_markers" : {},
+ "nova_groups_tags" : [
+ "en:1-unprocessed-or-minimally-processed-foods"
+ ],
+ "nucleotides_tags" : [],
+ "nutrient_levels" : {},
+ "nutrient_levels_tags" : [],
+ "nutriments" : {
+ "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 50,
+ "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 50,
+ "nova-group" : 1,
+ "nova-group_100g" : 1,
+ "nova-group_serving" : 1,
+ "nutrition-score-fr" : -1,
+ "nutrition-score-fr_100g" : -1
+ },
+ "nutriments_estimated" : {
+ "alcohol_100g" : 0,
+ "beta-carotene_100g" : 1.275e-05,
+ "calcium_100g" : 0.0055325,
+ "carbohydrates_100g" : 8.025,
+ "cholesterol_100g" : 0,
+ "copper_100g" : 2.75e-05,
+ "energy-kcal_100g" : 36.675,
+ "energy-kj_100g" : 155.25,
+ "energy_100g" : 155.25,
+ "fat_100g" : 0.0975,
+ "fiber_100g" : 0.975,
+ "fructose_100g" : 4.5225,
+ "galactose_100g" : 0,
+ "glucose_100g" : 2.4375,
+ "iodine_100g" : 7.5e-08,
+ "iron_100g" : 6e-05,
+ "lactose_100g" : 0,
+ "magnesium_100g" : 0.0032475,
+ "maltose_100g" : 0,
+ "manganese_100g" : 2.8705e-05,
+ "pantothenic-acid_100g" : 5.325e-05,
+ "phosphorus_100g" : 0.00825,
+ "phylloquinone_100g" : 4.5e-07,
+ "polyols_100g" : 0.4425,
+ "potassium_100g" : 0.0676825,
+ "proteins_100g" : 0.2025,
+ "salt_100g" : 0.0019,
+ "saturated-fat_100g" : 0.01575,
+ "selenium_100g" : 2.375e-07,
+ "sodium_100g" : 0.0006,
+ "starch_100g" : 0,
+ "sucrose_100g" : 0.615,
+ "sugars_100g" : 7.575,
+ "vitamin-a_100g" : 0,
+ "vitamin-b12_100g" : 0,
+ "vitamin-b1_100g" : 1.425e-05,
+ "vitamin-b2_100g" : 2.1e-05,
+ "vitamin-b6_100g" : 2.775e-05,
+ "vitamin-b9_100g" : 0,
+ "vitamin-c_100g" : 0.003,
+ "vitamin-d_100g" : 0,
+ "vitamin-e_100g" : 3.75e-05,
+ "vitamin-pp_100g" : 6.825e-05,
+ "water_100g" : 90.025,
+ "zinc_100g" : 4.025e-05
+ },
+ "nutriscore" : {
+ "2021" : {
+ "category_available" : 1,
+ "data" : {
+ "energy" : 155.25,
+ "energy_points" : 0,
+ "energy_value" : 155.3,
+ "fiber" : 0.975,
+ "fiber_points" : 1,
+ "fiber_value" : 0.98,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils" : 50,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 1,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 50,
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat" : 0,
+ "is_water" : 0,
+ "negative_points" : 1,
+ "positive_points" : 2,
+ "proteins" : 0.2025,
+ "proteins_points" : 0,
+ "proteins_value" : 0.2,
+ "saturated_fat" : 0.01575,
+ "saturated_fat_points" : 0,
+ "saturated_fat_value" : 0,
+ "sodium" : 0.6,
+ "sodium_points" : 0,
+ "sodium_value" : 0.6,
+ "sugars" : 7.575,
+ "sugars_points" : 1,
+ "sugars_value" : 7.58
+ },
+ "grade" : "a",
+ "nutrients_available" : 1,
+ "nutriscore_applicable" : 1,
+ "nutriscore_computed" : 1,
+ "score" : -1
+ },
+ "2023" : {
+ "category_available" : 1,
+ "data" : {
+ "count_proteins" : 1,
+ "count_proteins_reason" : "negative_points_less_than_11",
+ "energy" : 155.25,
+ "energy_points" : 0,
+ "fiber" : 0.975,
+ "fiber_points" : 0,
+ "fruits_vegetables_legumes" : 50,
+ "fruits_vegetables_legumes_points" : 1,
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat_oil_nuts_seeds" : 0,
+ "is_water" : 0,
+ "negative_nutrients" : [
+ "energy",
+ "sugars",
+ "saturated_fat",
+ "salt",
+ "sweeteners"
+ ],
+ "negative_points" : 2,
+ "positive_nutrients" : [
+ "fruits_vegetables_legumes",
+ "fiber",
+ "proteins"
+ ],
+ "positive_points" : 1,
+ "proteins" : 0.2025,
+ "proteins_points" : 0,
+ "salt" : 0.0019,
+ "salt_points" : 0,
+ "saturated_fat" : 0.01575,
+ "saturated_fat_points" : 0,
+ "sugars" : 7.575,
+ "sugars_points" : 2
+ },
+ "grade" : "b",
+ "nutrients_available" : 1,
+ "nutriscore_applicable" : 1,
+ "nutriscore_computed" : 1,
+ "score" : 1
+ }
+ },
+ "nutriscore_2021_tags" : [
+ "a"
+ ],
+ "nutriscore_2023_tags" : [
+ "b"
+ ],
+ "nutriscore_data" : {
+ "energy" : 155.25,
+ "energy_points" : 0,
+ "energy_value" : 155.3,
+ "fiber" : 0.975,
+ "fiber_points" : 1,
+ "fiber_value" : 0.98,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils" : 50,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 1,
+ "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 50,
+ "grade" : "a",
+ "is_beverage" : 0,
+ "is_cheese" : 0,
+ "is_fat" : 0,
+ "is_water" : 0,
+ "negative_points" : 1,
+ "positive_points" : 2,
+ "proteins" : 0.2025,
+ "proteins_points" : 0,
+ "proteins_value" : 0.2,
+ "saturated_fat" : 0.01575,
+ "saturated_fat_points" : 0,
+ "saturated_fat_value" : 0,
+ "score" : -1,
+ "sodium" : 0.6,
+ "sodium_points" : 0,
+ "sodium_value" : 0.6,
+ "sugars" : 7.575,
+ "sugars_points" : 1,
+ "sugars_value" : 7.58
+ },
+ "nutriscore_grade" : "a",
+ "nutriscore_score" : -1,
+ "nutriscore_score_opposite" : 1,
+ "nutriscore_tags" : [
+ "a"
+ ],
+ "nutriscore_version" : "2021",
+ "nutrition_data_per" : "100g",
+ "nutrition_data_prepared_per" : "100g",
+ "nutrition_grade_fr" : "a",
+ "nutrition_grades" : "a",
+ "nutrition_grades_tags" : [
+ "a"
+ ],
+ "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_nuts_estimate_from_ingredients" : 1,
+ "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 50,
+ "nutrition_score_warning_nutriments_estimated" : 1,
+ "origin_en" : "China",
+ "other_nutritional_substances_tags" : [],
+ "packaging_materials_tags" : [],
+ "packaging_recycling_tags" : [],
+ "packaging_shapes_tags" : [],
+ "packaging_text_en" : "no",
+ "packagings" : [],
+ "packagings_materials" : {},
+ "photographers_tags" : [],
+ "pnns_groups_1" : "Cereals and potatoes",
+ "pnns_groups_1_tags" : [
+ "cereals-and-potatoes",
+ "known"
+ ],
+ "pnns_groups_2" : "Breakfast cereals",
+ "pnns_groups_2_tags" : [
+ "breakfast-cereals",
+ "known"
+ ],
+ "popularity_key" : 0,
+ "product_name_en" : "Vegan breakfast cereals without palm oil",
+ "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-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-to-be-completed, en:photos-to-be-uploaded",
+ "states_hierarchy" : [
+ "en:to-be-completed",
+ "en:nutrition-facts-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-to-be-completed",
+ "en:photos-to-be-uploaded"
+ ],
+ "states_tags" : [
+ "en:to-be-completed",
+ "en:nutrition-facts-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-to-be-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" : [],
+ "url" : "http://world.openfoodfacts.localhost/product/200000000045/vegan-breakfast-cereals-without-palm-oil",
+ "vitamins_tags" : [],
+ "weighers_tags" : []
+ },
{
"_id" : "200000000046",
"_keywords" : [
@@ -2569,6 +4225,7 @@
"en:fruit",
"en:water"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 2,
"ingredients_n_tags" : [
"2",
diff --git a/tests/unit/expected_test_results/attributes/en-attributes.json b/tests/unit/expected_test_results/attributes/en-attributes.json
index 0067d2cf06100..cd339395a269f 100644
--- a/tests/unit/expected_test_results/attributes/en-attributes.json
+++ b/tests/unit/expected_test_results/attributes/en-attributes.json
@@ -1003,6 +1003,7 @@
"en:e102",
"en:e120"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 11,
"ingredients_n_tags" : [
"11",
diff --git a/tests/unit/expected_test_results/attributes/en-ecoscore-score-at-20-threshold.json b/tests/unit/expected_test_results/attributes/en-ecoscore-score-at-20-threshold.json
index 45d94e4a8f833..d2520f07d0caa 100644
--- a/tests/unit/expected_test_results/attributes/en-ecoscore-score-at-20-threshold.json
+++ b/tests/unit/expected_test_results/attributes/en-ecoscore-score-at-20-threshold.json
@@ -780,6 +780,7 @@
],
"food_groups_tags" : [],
"ingredients_from_palm_oil_tags" : [],
+ "ingredients_lc" : "en",
"ingredients_text" : "",
"ingredients_that_may_be_from_palm_oil_tags" : [],
"languages" : {},
diff --git a/tests/unit/expected_test_results/attributes/en-maybe-vegan.json b/tests/unit/expected_test_results/attributes/en-maybe-vegan.json
index 55040db970069..818bea8c4df97 100644
--- a/tests/unit/expected_test_results/attributes/en-maybe-vegan.json
+++ b/tests/unit/expected_test_results/attributes/en-maybe-vegan.json
@@ -681,6 +681,7 @@
"en:palm-oil-and-fat",
"en:enzyme"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 3,
"ingredients_n_tags" : [
"3",
diff --git a/tests/unit/expected_test_results/attributes/en-no-ingredients.json b/tests/unit/expected_test_results/attributes/en-no-ingredients.json
index 2623b64d8939d..967317df19da4 100644
--- a/tests/unit/expected_test_results/attributes/en-no-ingredients.json
+++ b/tests/unit/expected_test_results/attributes/en-no-ingredients.json
@@ -779,6 +779,7 @@
"en:milk-and-dairy-products",
"en:cheese"
],
+ "ingredients_lc" : "en",
"languages" : {},
"languages_codes" : {},
"languages_hierarchy" : [],
diff --git a/tests/unit/expected_test_results/attributes/en-nova-groups-markers.json b/tests/unit/expected_test_results/attributes/en-nova-groups-markers.json
index db5e2efe88981..02cb3fc898ecf 100644
--- a/tests/unit/expected_test_results/attributes/en-nova-groups-markers.json
+++ b/tests/unit/expected_test_results/attributes/en-nova-groups-markers.json
@@ -896,6 +896,7 @@
"en:corn-syrup",
"en:glucose-fructose-syrup"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 7,
"ingredients_n_tags" : [
"7",
diff --git a/tests/unit/expected_test_results/attributes/en-nutriscore.json b/tests/unit/expected_test_results/attributes/en-nutriscore.json
index c3e386967d423..dd70f9654d2b8 100644
--- a/tests/unit/expected_test_results/attributes/en-nutriscore.json
+++ b/tests/unit/expected_test_results/attributes/en-nutriscore.json
@@ -808,6 +808,7 @@
"ingredients_hierarchy" : [
"en:fruit"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 1,
"ingredients_n_tags" : [
"1",
diff --git a/tests/unit/expected_test_results/attributes/en-unknown-ingredients.json b/tests/unit/expected_test_results/attributes/en-unknown-ingredients.json
index 92173dc0c45ef..2b93e8435586f 100644
--- a/tests/unit/expected_test_results/attributes/en-unknown-ingredients.json
+++ b/tests/unit/expected_test_results/attributes/en-unknown-ingredients.json
@@ -816,6 +816,7 @@
"ingredients_hierarchy" : [
"en:some-ingredient-that-we-do-not-recognize"
],
+ "ingredients_lc" : "en",
"ingredients_n" : 1,
"ingredients_n_tags" : [
"1",
diff --git a/tests/unit/expected_test_results/attributes/fr-palm-kernel-fat.json b/tests/unit/expected_test_results/attributes/fr-palm-kernel-fat.json
index f264047395125..d175b76004d19 100644
--- a/tests/unit/expected_test_results/attributes/fr-palm-kernel-fat.json
+++ b/tests/unit/expected_test_results/attributes/fr-palm-kernel-fat.json
@@ -653,6 +653,7 @@
"en:vegetable-oil-and-fat",
"en:palm-kernel-oil-and-fat"
],
+ "ingredients_lc" : "fr",
"ingredients_n" : 1,
"ingredients_n_tags" : [
"1",
diff --git a/tests/unit/expected_test_results/attributes/fr-palm-oil-free.json b/tests/unit/expected_test_results/attributes/fr-palm-oil-free.json
index 85b28e8e91bb4..addb6a7cedd23 100644
--- a/tests/unit/expected_test_results/attributes/fr-palm-oil-free.json
+++ b/tests/unit/expected_test_results/attributes/fr-palm-oil-free.json
@@ -675,6 +675,7 @@
"en:disaccharide",
"en:chocolate"
],
+ "ingredients_lc" : "fr",
"ingredients_n" : 4,
"ingredients_n_tags" : [
"4",
diff --git a/tests/unit/expected_test_results/attributes/fr-palm-oil.json b/tests/unit/expected_test_results/attributes/fr-palm-oil.json
index 7d3f106dacd60..9e2c9b8ca609a 100644
--- a/tests/unit/expected_test_results/attributes/fr-palm-oil.json
+++ b/tests/unit/expected_test_results/attributes/fr-palm-oil.json
@@ -666,6 +666,7 @@
"en:vegetable-oil-and-fat",
"en:palm-oil-and-fat"
],
+ "ingredients_lc" : "fr",
"ingredients_n" : 2,
"ingredients_n_tags" : [
"2",
diff --git a/tests/unit/expected_test_results/attributes/fr-vegetable-oils.json b/tests/unit/expected_test_results/attributes/fr-vegetable-oils.json
index 23cb5a7f23b27..2d95d393e54eb 100644
--- a/tests/unit/expected_test_results/attributes/fr-vegetable-oils.json
+++ b/tests/unit/expected_test_results/attributes/fr-vegetable-oils.json
@@ -670,6 +670,7 @@
"en:vegetable-oil-and-fat",
"en:salt"
],
+ "ingredients_lc" : "fr",
"ingredients_n" : 3,
"ingredients_n_tags" : [
"3",