From a70840765d3efbdd5c5e0c16a109def010748c8e Mon Sep 17 00:00:00 2001 From: monsieurtanuki Date: Wed, 10 Nov 2021 16:17:56 +0100 Subject: [PATCH] feature_2/#210 - add nutrient order and list (#272) Impacted files: * `openfoodfacts.dart`: created method `getOrderedNutrients` * `ordered_nutrient_test.dart`: used new method `OpenFoodAPIClient.getOrderedNutrients`; refactored --- lib/openfoodfacts.dart | 26 +++++++++ test/ordered_nutrient_test.dart | 96 ++++++++++++++++----------------- 2 files changed, 73 insertions(+), 49 deletions(-) diff --git a/lib/openfoodfacts.dart b/lib/openfoodfacts.dart index 5d7f214641..52520d8c96 100644 --- a/lib/openfoodfacts.dart +++ b/lib/openfoodfacts.dart @@ -8,6 +8,7 @@ import 'package:http/http.dart'; import 'package:openfoodfacts/interface/JsonObject.dart'; import 'package:openfoodfacts/model/KnowledgePanels.dart'; import 'package:openfoodfacts/model/OcrIngredientsResult.dart'; +import 'package:openfoodfacts/model/OrderedNutrients.dart'; import 'package:openfoodfacts/model/TaxonomyAdditive.dart'; import 'package:openfoodfacts/model/TaxonomyAllergen.dart'; import 'package:openfoodfacts/model/TaxonomyCategory.dart'; @@ -855,4 +856,29 @@ class OpenFoodAPIClient { return KnowledgePanels.empty(); } } + + /// Returns the nutrient hierarchy specific to a country, localized. + /// + /// [cc] is the country code, as ISO 3166-1 alpha-2 + static Future getOrderedNutrients({ + required final String cc, + required final OpenFoodFactsLanguage language, + final QueryType? queryType, + }) async { + final Uri uri = UriHelper.getUri( + path: 'cgi/nutrients.pl', + queryType: queryType, + queryParameters: {'cc': cc, 'lc': language.code}, + ); + + final Response response = await HttpHelper().doGetRequest( + uri, + userAgent: OpenFoodAPIConfiguration.userAgent, + ); + if (response.statusCode != 200) { + throw Exception('Could not retrieve ordered nutrients!'); + } + final json = jsonDecode(response.body); + return OrderedNutrients.fromJson(json); + } } diff --git a/test/ordered_nutrient_test.dart b/test/ordered_nutrient_test.dart index 57572713fc..830277d3be 100644 --- a/test/ordered_nutrient_test.dart +++ b/test/ordered_nutrient_test.dart @@ -1,18 +1,34 @@ -import 'dart:convert'; - import 'package:openfoodfacts/model/OrderedNutrient.dart'; import 'package:openfoodfacts/model/OrderedNutrients.dart'; import 'package:openfoodfacts/openfoodfacts.dart'; import 'package:openfoodfacts/utils/OpenFoodAPIConfiguration.dart'; import 'package:openfoodfacts/utils/QueryType.dart'; import 'package:test/test.dart'; -import 'package:http/http.dart' as http; -import 'package:openfoodfacts/utils/HttpHelper.dart'; /// Tests related to [OrderedNutrient] and [OrderedNutrients] void main() { OpenFoodAPIConfiguration.globalQueryType = QueryType.TEST; + OrderedNutrient? _findOrderedNutrient( + final List? list, + final String nutrientId, + ) { + if (list == null) { + return null; + } + for (final OrderedNutrient item in list) { + if (item.id == nutrientId) { + return item; + } + final OrderedNutrient? found = + _findOrderedNutrient(item.subNutrients, nutrientId); + if (found != null) { + return found; + } + } + return null; + } + group('$OpenFoodAPIClient ordered nutrients', () { test('find expected nutrients', () async { // Very long list, experimentally created from the 3 initial URLs. @@ -126,22 +142,20 @@ void main() { 'zinc', }; - const List urls = [ - 'https://fr.openfoodfacts.org/cgi/nutrients.pl', - 'https://us.openfoodfacts.org/cgi/nutrients.pl', - 'https://us-es.openfoodfacts.org/cgi/nutrients.pl', - ]; - for (final String url in urls) { - final http.Response response = - await HttpHelper().doGetRequest(Uri.parse(url)); - final json = jsonDecode(response.body); + const Set countries = {'fr', 'br', 'us'}; + const OpenFoodFactsLanguage language = OpenFoodFactsLanguage.AFRIKAANS; + for (final String country in countries) { final OrderedNutrients orderedNutrients = - OrderedNutrients.fromJson(json); + await OpenFoodAPIClient.getOrderedNutrients( + cc: country, + language: language, + ); for (final String expectedNutrient in expectedNutrients) { expect( _findOrderedNutrient(orderedNutrients.nutrients, expectedNutrient), isNotNull, - reason: 'Could not find $expectedNutrient in $url', + reason: + 'Could not find nutrient $expectedNutrient for country $country', ); } } @@ -149,42 +163,26 @@ void main() { test('check localized "energy"', () async { const String nutrientId = 'energy'; - const Map energies = { - 'https://fr.openfoodfacts.org/cgi/nutrients.pl': 'Énergie', - 'https://us.openfoodfacts.org/cgi/nutrients.pl': 'Energy', - 'https://us-es.openfoodfacts.org/cgi/nutrients.pl': 'Energía', + const Map energies = { + OpenFoodFactsLanguage.FRENCH: 'Énergie', + OpenFoodFactsLanguage.SPANISH: 'Energía', + OpenFoodFactsLanguage.ENGLISH: 'Energy', + OpenFoodFactsLanguage.PORTUGUESE: 'Energia', }; - for (final String url in energies.keys) { - final http.Response response = - await HttpHelper().doGetRequest(Uri.parse(url)); - final json = jsonDecode(response.body); - final OrderedNutrients orderedNutrients = - OrderedNutrients.fromJson(json); - final OrderedNutrient? found = - _findOrderedNutrient(orderedNutrients.nutrients, nutrientId); - expect(found, isNotNull); - expect(found!.name, energies[url]); + const Set countries = {'us', 'it', 'br'}; + for (final OpenFoodFactsLanguage language in energies.keys) { + for (final String country in countries) { + final OrderedNutrients orderedNutrients = + await OpenFoodAPIClient.getOrderedNutrients( + cc: country, + language: language, + ); + final OrderedNutrient? found = + _findOrderedNutrient(orderedNutrients.nutrients, nutrientId); + expect(found, isNotNull); + expect(found!.name, energies[language]); + } } }); }); } - -OrderedNutrient? _findOrderedNutrient( - final List? list, - final String nutrientId, -) { - if (list == null) { - return null; - } - for (final OrderedNutrient item in list) { - if (item.id == nutrientId) { - return item; - } - final OrderedNutrient? found = - _findOrderedNutrient(item.subNutrients, nutrientId); - if (found != null) { - return found; - } - } - return null; -}