Skip to content

Commit

Permalink
feat: openfoodfacts#596 - implemented autocomplete for ORIGINS
Browse files Browse the repository at this point in the history
Impacted files:
* `api_get_autocompleted_suggestions_test.dart`: added tests for ORIGINS autocomplete
* `api_getProduct_test.dart`: minor refactoring
* `openfoodfacts.dart`: minor refactoring
* `TagType.dart`: added ORIGINS; refactored "à la 2.17"
* `TaxonomyQueryConfiguration.dart`: minor refactoring
  • Loading branch information
monsieurtanuki committed Oct 23, 2022
1 parent 89c5b79 commit cffa5f4
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 68 deletions.
4 changes: 2 additions & 2 deletions lib/openfoodfacts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ class OpenFoodAPIClient {
throw Exception('No taxonomy translation for $taxonomyTagType');
}
final Uri uri = UriHelper.getUri(
path: taxonomyTagType.key,
path: taxonomyTagType.offTag,
queryType: queryType,
queryParameters: {'translate': '1'},
addUserAgentParameters: false,
Expand Down Expand Up @@ -773,7 +773,7 @@ class OpenFoodAPIClient {
queryType: queryType,
);
final Map<String, String> queryParameters = <String, String>{
'tagtype': taxonomyType.key,
'tagtype': taxonomyType.offTag,
'term': input,
'lc': language.code,
'limit': limit.toString(),
Expand Down
57 changes: 29 additions & 28 deletions lib/utils/TagType.dart
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
enum TagType {
STATES,
LANGUAGES,
LABELS,
CATEGORIES,
COUNTRIES,
INGREDIENTS,
TRACES,
ADDITIVES,
ALLERGENS,
PACKAGING,
EMB_CODES
}
import 'package:openfoodfacts/model/OffTagged.dart';

enum TagType implements OffTagged {
STATES(offTag: 'states'),
LANGUAGES(offTag: 'languages'),
LABELS(offTag: 'labels'),
CATEGORIES(offTag: 'categories'),
COUNTRIES(offTag: 'countries'),
INGREDIENTS(offTag: 'ingredients'),
TRACES(offTag: 'traces'),
ADDITIVES(offTag: 'additives'),
ALLERGENS(offTag: 'allergens'),
PACKAGING(offTag: 'packaging'),
ORIGINS(offTag: 'origins'),
EMB_CODES(offTag: 'emb_codes');

const TagType({
required this.offTag,
});

@override
final String offTag;

/// Returns the first [TagType] that matches the [offTag].
static TagType? fromOffTag(final String? offTag) =>
OffTagged.fromOffTag(offTag, TagType.values) as TagType?;

extension TaxonomyTypeExtension on TagType {
static const Map<TagType, String> _TAXONOMIES = {
TagType.STATES: 'states',
TagType.LABELS: 'labels',
TagType.CATEGORIES: 'categories',
TagType.COUNTRIES: 'countries',
TagType.INGREDIENTS: 'ingredients',
TagType.TRACES: 'traces',
TagType.ADDITIVES: 'additives',
TagType.ALLERGENS: 'allergens',
TagType.PACKAGING: 'packaging',
TagType.LANGUAGES: 'languages',
TagType.EMB_CODES: 'emb_codes',
};
String get key => _TAXONOMIES[this] ?? '';
// TODO: deprecated from 2022-10-23; remove when old enough
@Deprecated('Use offTag instead')
String get key => offTag;
}
2 changes: 1 addition & 1 deletion lib/utils/TaxonomyQueryConfiguration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ abstract class TaxonomyQueryConfiguration<T extends JsonObject,
Map<String, String> getParametersMap() {
final Map<String, String> result = {};

result['tagtype'] = tagType.key;
result['tagtype'] = tagType.offTag;
if (_isRootConfiguration) {
result['include_root_entries'] = '1';
} else {
Expand Down
2 changes: 1 addition & 1 deletion test/api_getProduct_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1799,7 +1799,7 @@ void main() {
expect(
url,
'https://world-${language.code}.openfoodfacts.net/'
'${tagType.key}'
'${tagType.offTag}'
'?translate=1',
);
} catch (e) {
Expand Down
110 changes: 74 additions & 36 deletions test/api_get_autocompleted_suggestions_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,59 +15,97 @@ void main() {
}

group('$OpenFoodAPIClient Suggestions and autocompletion', () {
test('Suggestions for countries', () async {
List<dynamic> result =
await OpenFoodAPIClient.getAutocompletedSuggestions(
test('Suggestions for countries and origins', () async {
late List<dynamic> result;

final List<TagType> tagTypes = <TagType>[
TagType.COUNTRIES,
language: OpenFoodFactsLanguage.FRENCH,
input: 't',
);
TagType.ORIGINS,
];
for (final TagType tagType in tagTypes) {
result = await OpenFoodAPIClient.getAutocompletedSuggestions(
tagType,
language: OpenFoodFactsLanguage.FRENCH,
input: 't',
);
listContains(result, 't');

result = await OpenFoodAPIClient.getAutocompletedSuggestions(
tagType,
language: OpenFoodFactsLanguage.FRENCH,
input: 'TUN',
);
listContains(result, 'tun');

result = await OpenFoodAPIClient.getAutocompletedSuggestions(
tagType,
language: OpenFoodFactsLanguage.ENGLISH,
input: 'TUN',
);
listContains(result, 'tun');

result = await OpenFoodAPIClient.getAutocompletedSuggestions(
tagType,
language: OpenFoodFactsLanguage.ARABIC,
input: 'تو',
);
listContains(result, 'تو');

result = await OpenFoodAPIClient.getAutocompletedSuggestions(
tagType,
language: OpenFoodFactsLanguage.GEORGIAN,
input: 'TUN',
);
expect(result, isEmpty);

expect(
await OpenFoodAPIClient.getAutocompletedSuggestions(
tagType,
language: OpenFoodFactsLanguage.FRENCH,
input: 'TUN',
),
await OpenFoodAPIClient.getAutocompletedSuggestions(
tagType,
language: OpenFoodFactsLanguage.FRENCH,
input: 'tun',
));
}
});

listContains(result, 't');
test('Suggestions for countries only', () async {
late List<dynamic> result;

result = await OpenFoodAPIClient.getAutocompletedSuggestions(
TagType.COUNTRIES,
language: OpenFoodFactsLanguage.FRENCH,
input: 'TUN',
input: 'provence',
);
expect(result, isEmpty); // "provence" is not a country
});

listContains(result, 'tun');
test('Suggestions for origins only', () async {
late List<dynamic> result;

result = await OpenFoodAPIClient.getAutocompletedSuggestions(
TagType.COUNTRIES,
language: OpenFoodFactsLanguage.ENGLISH,
input: 'TUN',
TagType.ORIGINS,
language: OpenFoodFactsLanguage.FRENCH,
input: 'provence',
);

listContains(result, 'tun');
expect(result, isNotEmpty);

result = await OpenFoodAPIClient.getAutocompletedSuggestions(
TagType.COUNTRIES,
language: OpenFoodFactsLanguage.ARABIC,
input: 'تو',
TagType.ORIGINS,
language: OpenFoodFactsLanguage.FRENCH,
input: 'prove',
);

listContains(result, 'تو');
expect(result, isNotEmpty);

result = await OpenFoodAPIClient.getAutocompletedSuggestions(
TagType.COUNTRIES,
language: OpenFoodFactsLanguage.GEORGIAN,
input: 'TUN',
TagType.ORIGINS,
language: OpenFoodFactsLanguage.FRENCH,
input: 'pyré',
);

expect(result.isEmpty, true);

expect(
await OpenFoodAPIClient.getAutocompletedSuggestions(
TagType.COUNTRIES,
language: OpenFoodFactsLanguage.FRENCH,
input: 'TUN',
),
await OpenFoodAPIClient.getAutocompletedSuggestions(
TagType.COUNTRIES,
language: OpenFoodFactsLanguage.FRENCH,
input: 'tun',
));
expect(result, isNotEmpty); // something about Pyrénées
});

test('Suggestions for state', () async {
Expand Down

0 comments on commit cffa5f4

Please sign in to comment.