Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: suggestions for packaging codes / EMB codes #10113

Merged
merged 3 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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" : []
}
Loading