Skip to content

Commit

Permalink
fix: suggestions for packaging codes / EMB codes (#10113)
Browse files Browse the repository at this point in the history
fixes #10049
  • Loading branch information
stephanegigandet authored Apr 15, 2024
1 parent 8326999 commit 0503521
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 44 deletions.
4 changes: 1 addition & 3 deletions lib/ProductOpener/APITaxonomySuggestions.pm
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,8 @@ sub taxonomy_suggestions_api ($request_ref) {
}
# Generate suggestions
else {
my $options_relavant = {%$options_ref};
delete $options_relavant->{get_synonyms};
my @suggestions
= get_taxonomy_suggestions_with_synonyms($tagtype, $search_lc, $string, $context_ref, $options_relavant);
= get_taxonomy_suggestions_with_synonyms($tagtype, $search_lc, $string, $context_ref, $options_ref);
$log->debug("taxonomy_suggestions_api", @suggestions) if $log->is_debug();
$response_ref->{suggestions} = [map {$_->{tag}} @suggestions];
if ($options_ref->{get_synonyms}) {
Expand Down
21 changes: 16 additions & 5 deletions lib/ProductOpener/TaxonomySuggestions.pm
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,12 @@ By priority, the function returns:
- limit: limit of number of results
- format (not yet defined and implemented)
=head3 Return value
An array of suggestions hashes with the following fields:
- tag: the tag to suggest
- matched_synonym: the synonym that matched the input string
=cut

sub filter_suggestions_matching_string_with_synonyms ($tags_ref, $tagtype, $search_lc, $string, $options_ref) {
Expand Down Expand Up @@ -424,7 +430,12 @@ sub filter_suggestions_matching_string_with_synonyms ($tags_ref, $tagtype, $sear
my $stringid = get_string_id_for_lang("no_language", normalize_packager_codes($string));
foreach my $canon_tagid (@$tags_ref) {
next if $canon_tagid !~ /^$stringid/;
push @suggestions, normalize_packager_codes($canon_tagid);
my $normalized_tag = normalize_packager_codes($canon_tagid);
my $suggestion_ref = {
tag => $normalized_tag,
matched_synonym => $normalized_tag
};
push @suggestions, $suggestion_ref;
last if ++$suggestions_count >= $limit;
}
}
Expand Down Expand Up @@ -467,24 +478,24 @@ sub filter_suggestions_matching_string_with_synonyms ($tags_ref, $tagtype, $sear
}
) if $log->is_debug();

my $to_add = {
my $suggestion_ref = {
tag => $tag,
matched_synonym => $best_match->{match}
};
# matching at start, best matches
if ($best_match->{type} eq "start") {
push @suggestions, $to_add;
push @suggestions, $suggestion_ref;
# count matches at start so that we can return only if we have enough matches
$suggestions_count++;
last if $suggestions_count >= $limit;
}
# matching inside
elsif ($best_match->{type} eq "inside") {
push @suggestions_c, $to_add;
push @suggestions_c, $suggestion_ref;
}
# fuzzy match
elsif ($best_match->{type} eq "fuzzy") {
push @suggestions_f, $to_add;
push @suggestions_f, $suggestion_ref;
}
}
}
Expand Down
49 changes: 13 additions & 36 deletions tests/integration/api_v3_taxonomy_suggestions.t
Original file line number Diff line number Diff line change
Expand Up @@ -35,188 +35,165 @@ my $tests_ref = [
test_case => 'categories-no-string',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=categories',
expected_status_code => 200,
},
{
test_case => 'categories-string-strawberry',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=categories&string=strawberry',
expected_status_code => 200,
},
{
test_case => 'categories-term-strawberry',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=categories&term=strawberry',
expected_status_code => 200,
},
{
test_case => 'categories-string-fraise',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=categories&string=fraise',
expected_status_code => 200,
},
{
test_case => 'categories-string-fr-fraise',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=categories&string=fraise&lc=fr',
expected_status_code => 200,
},
{
test_case => 'categories-string-fr-frais',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=categories&string=frais&lc=fr',
expected_status_code => 200,
},
{
test_case => 'categories-string-fr-cafe-accent',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=categories&string=Café&lc=fr',
expected_status_code => 200,
},
{
test_case => 'categories-string-fr-cafe-accent',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=categories&string=Café&lc=fr',
expected_status_code => 200,
path => '/api/v3/taxonomy_suggestions?tagtype=categories&string=caf%C3%A9&lc=fr',
},
{
test_case => 'allergens-string-fr-o-get-synonyms',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=allergens&string=o&lc=fr&get_synonyms=1',
expected_status_code => 200,
},
# Packaging suggestions return most popular suggestions first
{
test_case => 'packaging-shapes',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_shapes',
expected_status_code => 200,
},
{
test_case => 'packaging-shapes-fr',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_shapes&lc=fr',
expected_status_code => 200,
},
{
test_case => 'packaging-shapes-string-po',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_shapes&string=po',
expected_status_code => 200,
},
{
test_case => 'packaging-shapes-string-fr-po',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_shapes&string=po&lc=fr',
expected_status_code => 200,
},
# Packaging shape suggestions can be specific to a country and categories, and shape
{
test_case => 'packaging-shapes-cc-fr',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_shapes&cc=fr',
expected_status_code => 200,
},
# categories can contain a comma separated list of taxonomy entry ids, entry name or synonym in the lc language
{
test_case => 'packaging-shapes-categories-mango-nectars-beverages',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_shapes&categories=mango%20nectars,beverages',
expected_status_code => 200,
},
{
test_case => 'packaging-shapes-cc-fr-categories-yogurt',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_shapes&cc=fr&categories=yogurt',
expected_status_code => 200,
},
{
test_case => 'packaging-shapes-cc-fr-categories-en-yogurts',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_shapes&cc=fr&categories=en:yogurts',
expected_status_code => 200,
},
{
test_case => 'packaging-shapes-cc-fr-categories-yaourt-fr',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_shapes&cc=fr&categories=yaourt&lc=fr',
expected_status_code => 200,
},
# Packaging materials suggestions can be specific to a country and categories, and shape
{
test_case => 'packaging-materials',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_materials',
expected_status_code => 200,
},
{
test_case => 'packaging-materials-cc-fr',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_materials&cc=fr',
expected_status_code => 200,
},
{
test_case => 'packaging-materials-cc-fr-shape-pot',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_materials&cc=fr&shape=pot',
expected_status_code => 200,
},
{
test_case => 'packaging-materials-cc-fr-categories-yaourt-shape-pot',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_materials&cc=fr&categories=yogurts&shape=pot',
expected_status_code => 200,
},
# match with xx: synonyms
{
test_case => 'packaging-materials-1',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_materials&string=1',
expected_status_code => 200,
},
{
test_case => 'packaging-materials-01',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_materials&string=01',
expected_status_code => 200,
},
{
test_case => 'packaging-materials-1-pet',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_materials&string=1-pet',
expected_status_code => 200,
},
{
test_case => 'packaging-materials-pet-1',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_materials&string=pet-1',
expected_status_code => 200,
},
# Packaging recycling
{
test_case => 'packaging-recycling-fr-recy',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_recycling&cc=fr&string=recy',
expected_status_code => 200,
},
{
test_case => 'packaging-recycling-fr-bac-ver',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_recycling&cc=fr&string=bac-ver',
expected_status_code => 200,
},
{
test_case => 'packaging-recycling-fr-bac-verre',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_recycling&cc=fr&string=bac-verre',
expected_status_code => 200,
},
{
test_case => 'packaging-recycling-fr-bac-tri',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=packaging_recycling&cc=fr&string=bac-tri',
expected_status_code => 200,
},
# packaging codes / EMB codes: not a taxonomy, but can have suggestions too
{
test_case => 'emb-codes',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=emb_codes&string=fr%2056',
},
# suggestions with synonyms
{
test_case => 'categories-string-fr-tart-get-synonyms',
method => 'GET',
path => '/api/v3/taxonomy_suggestions?tagtype=categories&string=tart&lc=fr&get_synonyms=1',
}
];

execute_api_tests(__FILE__, $tests_ref);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"errors" : [],
"matched_synonyms" : {
"Flammekueches" : "Tarte flambée",
"Produits à tartiner" : "Tartinables",
"Quiches au poireau" : "Tartes aux poireaux",
"Quiches au poisson" : "Tartes au poisson",
"Quiches au saumon" : "Tartes au saumon",
"Quiches aux épinards" : "Tartes aux épinards",
"Salades d'œufs" : "Tartinades d'œufs",
"Tartares d'algues" : "Tartares d'algues",
"Tartares de boeuf" : "Tartares de boeuf",
"Tartares de viande" : "Tartares de viande",
"Tarte au vin" : "Tarte au vin",
"Tarte aux fruits rouges" : "Tarte aux fruits rouges",
"Tarte aux groseilles" : "Tarte aux groseilles",
"Tarte aux noix de Saint-Jacques" : "Tarte aux noix de Saint-Jacques",
"Tarte aux poires amandine" : "Tarte aux poires amandine",
"Tarte à l'oignon" : "Tarte à l'oignon",
"Tarte à la provençale" : "Tarte à la provençale",
"Tarte épinard chèvre" : "Tarte épinard chèvre",
"Tartelettes" : "Tartelettes",
"Tartelettes au caramel" : "Tartelettes au caramel",
"Tartelettes au chocolat" : "Tartelettes au chocolat",
"Tartelettes au citron" : "Tartelettes au citron",
"Tartelettes aux fruits entiers ou coupés" : "Tartelettes aux fruits entiers ou coupés",
"Tartelettes à l'abricot" : "Tartelettes à l'abricot",
"Tartelettes à la fraise" : "Tartelettes à la fraise"
},
"status" : "success",
"suggestions" : [
"Flammekueches",
"Produits à tartiner",
"Quiches au poireau",
"Quiches au poisson",
"Quiches au saumon",
"Quiches aux épinards",
"Salades d'œufs",
"Tartares d'algues",
"Tartares de boeuf",
"Tartares de viande",
"Tarte au vin",
"Tarte aux fruits rouges",
"Tarte aux groseilles",
"Tarte aux noix de Saint-Jacques",
"Tarte aux poires amandine",
"Tarte à l'oignon",
"Tarte à la provençale",
"Tarte épinard chèvre",
"Tartelettes",
"Tartelettes au caramel",
"Tartelettes au chocolat",
"Tartelettes au citron",
"Tartelettes aux fruits entiers ou coupés",
"Tartelettes à l'abricot",
"Tartelettes à la fraise"
],
"warnings" : []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"errors" : [],
"status" : "success",
"suggestions" : [
"FR 56.003.001 EC",
"FR 56.003.002 EC",
"FR 56.003.003 EC",
"FR 56.003.004 EC",
"FR 56.003.005 EC",
"FR 56.003.006 EC",
"FR 56.003.007 EC",
"FR 56.003.015 EC",
"FR 56.003.801 EC",
"FR 56.005.002 EC",
"FR 56.005.801 EC",
"FR 56.007.002 EC",
"FR 56.007.017 EC",
"FR 56.007.032 EC",
"FR 56.007.045 EC",
"FR 56.007.051 EC",
"FR 56.007.057 EC",
"FR 56.007.059 EC",
"FR 56.007.061 EC",
"FR 56.007.066 EC",
"FR 56.007.068 EC",
"FR 56.007.069 EC",
"FR 56.007.076 EC",
"FR 56.007.078 EC",
"FR 56.007.079 EC"
],
"warnings" : []
}

0 comments on commit 0503521

Please sign in to comment.