Skip to content

Commit

Permalink
feat: 719 - Suggestion Manager with suggestions for the latest input (#…
Browse files Browse the repository at this point in the history
…720)

* feat: 719 - Suggestion Manager with suggestions for the latest input

New files:
* `api_suggestion_manager_test.dart`: Unit tests for `SuggestionManager`
* `suggestion_manager.dart`: Manager that returns the suggestions for the latest input.

Impacted files:
* `open_food_api_client.dart`: added a comment mentioning `SuggestionManager`.
* `openfoodfacts.dart`: exported new file `suggestion_manager.dart`

* feat: 719 - fixed tests and added a verbose jsonDecode method

Deleted file:
* `api_get_autocompleted_suggestions_test.dart`: based on a deprecated method

Impacted files:
* `api_get_suggestions_test.dart`: fixed test
* `available_attribute_groups.dart`: now uses `HttpHelper().jsonDecode`
* `available_preference_importances.dart`: now uses `HttpHelper().jsonDecode`
* `events.dart`: now uses `HttpHelper().jsonDecode`
* `folksonomy.dart`: now uses `HttpHelper().jsonDecode`
* `http_helper.dart`: new `jsonDecode` method that deals with typical OFF server html error pages
* `invalid_barcodes.dart`: now uses `HttpHelper().jsonDecode`
* `open_food_api_client.dart`: now uses `HttpHelper().jsonDecode`
* `ordered_nutrient_test.dart`: now uses `HttpHelper().jsonDecode`
* `product_from_json_test.dart`: now uses `HttpHelper().jsonDecode`
* `status.dart`: now uses `HttpHelper().jsonDecode`

* feat: 719 - added the "software error" case

Impacted file:
* `http_helper.dart`: added the "software error" case to `jsonDecode` method
  • Loading branch information
monsieurtanuki committed Apr 1, 2023
1 parent 4953709 commit 5a31a09
Show file tree
Hide file tree
Showing 15 changed files with 310 additions and 432 deletions.
1 change: 1 addition & 0 deletions lib/openfoodfacts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export 'src/utils/product_helper.dart';
export 'src/utils/product_query_configurations.dart';
export 'src/utils/product_search_query_configuration.dart';
export 'src/utils/query_type.dart';
export 'src/utils/suggestion_manager.dart';
export 'src/utils/tag_type.dart';
export 'src/utils/unit_helper.dart';
export 'src/utils/uri_helper.dart';
Expand Down
16 changes: 9 additions & 7 deletions lib/src/events.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:convert';

import 'package:http/http.dart';
import 'model/badge_base.dart';
Expand Down Expand Up @@ -47,7 +46,8 @@ class EventsAPIClient {
);
_checkResponse(response);
final List<EventsBase> result = <EventsBase>[];
final List<dynamic> json = jsonDecode(response.body) as List<dynamic>;
final List<dynamic> json =
HttpHelper().jsonDecode(response.body) as List<dynamic>;
for (var element in json) {
result.add(EventsBase.fromJson(element));
}
Expand Down Expand Up @@ -78,7 +78,7 @@ class EventsAPIClient {
_checkResponse(response);
final Map<String, int> result = <String, int>{};
final Map<String, dynamic> json =
jsonDecode(response.body) as Map<String, dynamic>;
HttpHelper().jsonDecode(response.body) as Map<String, dynamic>;
for (final String key in json.keys) {
result[key] = json[key] as int;
}
Expand Down Expand Up @@ -112,7 +112,7 @@ class EventsAPIClient {
);
_checkResponse(response);
final Map<String, dynamic> json =
jsonDecode(response.body) as Map<String, dynamic>;
HttpHelper().jsonDecode(response.body) as Map<String, dynamic>;
return json['score'] as int;
}

Expand All @@ -139,7 +139,8 @@ class EventsAPIClient {
);
_checkResponse(response);
final List<BadgeBase> result = <BadgeBase>[];
final List<dynamic> json = jsonDecode(response.body) as List<dynamic>;
final List<dynamic> json =
HttpHelper().jsonDecode(response.body) as List<dynamic>;
for (var element in json) {
result.add(BadgeBase.fromJson(element));
}
Expand All @@ -165,7 +166,8 @@ class EventsAPIClient {
);
_checkResponse(response);
final List<LeaderboardEntry> result = <LeaderboardEntry>[];
final List<dynamic> json = jsonDecode(response.body) as List<dynamic>;
final List<dynamic> json =
HttpHelper().jsonDecode(response.body) as List<dynamic>;
for (var element in json) {
result.add(LeaderboardEntry.fromJson(element));
}
Expand All @@ -179,7 +181,7 @@ class EventsAPIClient {
String? exception;
try {
final Map<String, dynamic> json =
jsonDecode(response.body) as Map<String, dynamic>;
HttpHelper().jsonDecode(response.body) as Map<String, dynamic>;
exception = json['detail'];
} catch (e) {
//
Expand Down
21 changes: 13 additions & 8 deletions lib/src/folksonomy.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:convert';

import 'package:http/http.dart';

Expand Down Expand Up @@ -69,7 +68,8 @@ class FolksonomyAPIClient {
// not found
return result;
}
final List<dynamic> json = jsonDecode(response.body) as List<dynamic>;
final List<dynamic> json =
HttpHelper().jsonDecode(response.body) as List<dynamic>;
for (var element in json) {
result.add(ProductStats.fromJson(element));
}
Expand Down Expand Up @@ -104,7 +104,8 @@ class FolksonomyAPIClient {
);
_checkResponse(response);
final Map<String, String> result = <String, String>{};
final List<dynamic> json = jsonDecode(response.body) as List<dynamic>;
final List<dynamic> json =
HttpHelper().jsonDecode(response.body) as List<dynamic>;
for (var element in json) {
final ProductList productList = ProductList.fromJson(element);
if (productList.key != key) {
Expand Down Expand Up @@ -142,7 +143,8 @@ class FolksonomyAPIClient {
// not found
return result;
}
final List<dynamic> json = jsonDecode(response.body) as List<dynamic>;
final List<dynamic> json =
HttpHelper().jsonDecode(response.body) as List<dynamic>;
for (var element in json) {
final ProductTag productTag = ProductTag.fromJson(element);
result[productTag.key] = productTag;
Expand Down Expand Up @@ -178,7 +180,7 @@ class FolksonomyAPIClient {
return null;
}
final Map<String, dynamic> json =
jsonDecode(response.body) as Map<String, dynamic>;
HttpHelper().jsonDecode(response.body) as Map<String, dynamic>;
return ProductTag.fromJson(json);
}

Expand Down Expand Up @@ -210,7 +212,8 @@ class FolksonomyAPIClient {
// not found
return result;
}
final List<dynamic> json = jsonDecode(response.body) as List<dynamic>;
final List<dynamic> json =
HttpHelper().jsonDecode(response.body) as List<dynamic>;
for (var element in json) {
final ProductTag productTag = ProductTag.fromJson(element);
result[productTag.key] = productTag;
Expand Down Expand Up @@ -269,7 +272,8 @@ Future<void> deleteProductTag({
// not found
return result;
}
final List<dynamic> json = jsonDecode(response.body) as List<dynamic>;
final List<dynamic> json =
HttpHelper().jsonDecode(response.body) as List<dynamic>;
for (var element in json) {
result.add(ProductTag.fromJson(element));
}
Expand Down Expand Up @@ -349,7 +353,8 @@ Future<void> deleteProductTag({
);
_checkResponse(response);
final Map<String, KeyStats> result = <String, KeyStats>{};
final List<dynamic> json = jsonDecode(response.body) as List<dynamic>;
final List<dynamic> json =
HttpHelper().jsonDecode(response.body) as List<dynamic>;
for (var element in json) {
final KeyStats item = KeyStats.fromJson(element);
result[item.key] = item;
Expand Down
5 changes: 2 additions & 3 deletions lib/src/model/status.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'dart:convert';

import 'package:json_annotation/json_annotation.dart';

import '../interface/json_object.dart';
import '../utils/http_helper.dart';

part 'status.g.dart';

Expand Down Expand Up @@ -66,7 +65,7 @@ class Status extends JsonObject {
/// Constructs a [Status] from an API response
factory Status.fromApiResponse(String responseBody) {
try {
return Status.fromJson(json.decode(responseBody));
return Status.fromJson(HttpHelper().jsonDecode(responseBody));
} catch (e) {
return Status(
body: responseBody,
Expand Down
58 changes: 36 additions & 22 deletions lib/src/open_food_api_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class OpenFoodAPIClient {
user,
queryType: queryType,
);
return ProductResultV3.fromJson(jsonDecode(response.body));
return ProductResultV3.fromJson(HttpHelper().jsonDecode(response.body));
}

/// Send one image to the server.
Expand Down Expand Up @@ -253,7 +253,7 @@ class OpenFoodAPIClient {
user: user,
queryType: queryType,
);
return ProductResult.fromJson(json.decode(productString));
return ProductResult.fromJson(HttpHelper().jsonDecode(productString));
}

/// Returns the product for the given barcode.
Expand All @@ -278,7 +278,9 @@ class OpenFoodAPIClient {
queryType: queryType,
);
final String jsonStr = _replaceQuotes(productString);
final ProductResult result = ProductResult.fromJson(jsonDecode(jsonStr));
final ProductResult result = ProductResult.fromJson(
HttpHelper().jsonDecode(jsonStr),
);
if (result.product != null) {
ProductHelper.removeImages(result.product!, configuration.language);
ProductHelper.createImageUrls(result.product!, queryType: queryType);
Expand Down Expand Up @@ -331,8 +333,9 @@ class OpenFoodAPIClient {
queryType: queryType,
);
final String jsonStr = _replaceQuotes(productString);
final ProductResultV3 result =
ProductResultV3.fromJson(jsonDecode(jsonStr));
final ProductResultV3 result = ProductResultV3.fromJson(
HttpHelper().jsonDecode(jsonStr),
);
if (result.product != null) {
ProductHelper.removeImages(result.product!, configuration.language);
ProductHelper.createImageUrls(result.product!, queryType: queryType);
Expand Down Expand Up @@ -360,7 +363,7 @@ class OpenFoodAPIClient {
queryType: queryType,
);
final String jsonStr = _replaceQuotes(productString);
final json = jsonDecode(jsonStr);
final json = HttpHelper().jsonDecode(jsonStr);
if (json['status'] != 'success') {
throw Exception('Error: ${json['status']}');
}
Expand Down Expand Up @@ -549,7 +552,9 @@ class OpenFoodAPIClient {
}) async {
final Response response = await configuration.getResponse(user, queryType);
final String jsonStr = _replaceQuotes(response.body);
final SearchResult result = SearchResult.fromJson(json.decode(jsonStr));
final SearchResult result = SearchResult.fromJson(
HttpHelper().jsonDecode(jsonStr),
);
_removeImages(result, configuration);
return result;
}
Expand Down Expand Up @@ -609,7 +614,7 @@ class OpenFoodAPIClient {
);
Map<String, dynamic> decodedJson =
json.decode(_replaceQuotes(response.body))
HttpHelper().jsonDecode(_replaceQuotes(response.body))
..removeWhere((String key, dynamic value) {
if (value is Map) {
return value.isEmpty;
Expand Down Expand Up @@ -819,8 +824,9 @@ class OpenFoodAPIClient {
user: user,
queryType: queryType,
);
var result =
InsightsResult.fromJson(json.decode(utf8.decode(response.bodyBytes)));
var result = InsightsResult.fromJson(
HttpHelper().jsonDecode(utf8.decode(response.bodyBytes)),
);
return result;
}
Expand All @@ -842,7 +848,8 @@ class OpenFoodAPIClient {
);
return InsightsResult.fromJson(
json.decode(utf8.decode(response.bodyBytes)));
HttpHelper().jsonDecode(utf8.decode(response.bodyBytes)),
);
}
static Future<RobotoffQuestionResult> getRobotoffQuestionsForProduct(
Expand Down Expand Up @@ -873,7 +880,8 @@ class OpenFoodAPIClient {
queryType: queryType,
);
var result = RobotoffQuestionResult.fromJson(
json.decode(utf8.decode(response.bodyBytes)));
HttpHelper().jsonDecode(utf8.decode(response.bodyBytes)),
);
return result;
}
Expand Down Expand Up @@ -917,7 +925,8 @@ class OpenFoodAPIClient {
queryType: queryType,
);
var result = RobotoffQuestionResult.fromJson(
json.decode(utf8.decode(response.bodyBytes)));
HttpHelper().jsonDecode(utf8.decode(response.bodyBytes)),
);
return result;
}
Expand Down Expand Up @@ -994,7 +1003,8 @@ class OpenFoodAPIClient {
addCredentialsToHeader: true,
);
SpellingCorrection result = SpellingCorrection.fromJson(
json.decode(utf8.decode(response.bodyBytes)));
HttpHelper().jsonDecode(utf8.decode(response.bodyBytes)),
);
return result;
}
Expand Down Expand Up @@ -1043,7 +1053,8 @@ class OpenFoodAPIClient {
addCredentialsToBody: false,
);
return OcrIngredientsResult.fromJson(
json.decode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>,
HttpHelper().jsonDecode(utf8.decode(response.bodyBytes))
as Map<String, dynamic>,
);
}

Expand Down Expand Up @@ -1088,7 +1099,8 @@ class OpenFoodAPIClient {
addCredentialsToBody: false,
);
return OcrPackagingResult.fromJson(
json.decode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>,
HttpHelper().jsonDecode(utf8.decode(response.bodyBytes))
as Map<String, dynamic>,
);
}

Expand Down Expand Up @@ -1131,10 +1143,12 @@ class OpenFoodAPIClient {
queryType: queryType,
addCredentialsToBody: false,
);
return json.decode(response.body);
return HttpHelper().jsonDecode(response.body);
}

/// cf. https://openfoodfacts.github.io/openfoodfacts-server/reference/api-v3/#get-/api/v3/taxonomy_suggestions
///
/// Consider using [SuggestionManager].
static Future<List<String>> getSuggestions(
final TagType taxonomyType, {
final String input = '',
Expand Down Expand Up @@ -1165,7 +1179,7 @@ class OpenFoodAPIClient {
user: user,
queryType: queryType,
);
final Map<String, dynamic> map = json.decode(response.body);
final Map<String, dynamic> map = HttpHelper().jsonDecode(response.body);
final List<String> result = <String>[];
if (map['suggestions'] != null) {
for (dynamic value in map['suggestions']) {
Expand Down Expand Up @@ -1227,7 +1241,7 @@ class OpenFoodAPIClient {
addCredentialsToBody: true,
);
if (response.statusCode == 200 || response.statusCode == 403) {
return LoginStatus.fromJson(jsonDecode(response.body));
return LoginStatus.fromJson(HttpHelper().jsonDecode(response.body));
}

return null;
Expand Down Expand Up @@ -1371,7 +1385,7 @@ class OpenFoodAPIClient {
final QueryType? queryType,
}) async =>
OrderedNutrients.fromJson(
jsonDecode(
HttpHelper().jsonDecode(
await getOrderedNutrientsJsonString(
country: CountryHelper.fromJson(cc)!,
language: language,
Expand Down Expand Up @@ -1512,7 +1526,7 @@ class OpenFoodAPIClient {
'Bad response (${response.statusCode}): ${response.body}');
}
final Map<String, dynamic> json =
jsonDecode(response.body) as Map<String, dynamic>;
HttpHelper().jsonDecode(response.body) as Map<String, dynamic>;
final String status = json['status'];
if (status != 'status ok') {
throw Exception('Status not ok ($status)');
Expand Down Expand Up @@ -1565,7 +1579,7 @@ class OpenFoodAPIClient {
'Bad response (${response.statusCode}): ${response.body}');
}
final Map<String, dynamic> json =
jsonDecode(response.body) as Map<String, dynamic>;
HttpHelper().jsonDecode(response.body) as Map<String, dynamic>;
final String status = json['status'];
if (status != 'status ok') {
throw Exception('Status not ok ($status)');
Expand Down
4 changes: 2 additions & 2 deletions lib/src/personalized_search/available_attribute_groups.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import 'dart:convert';
import '../model/attribute_group.dart';
import '../utils/http_helper.dart';

/// Referential of attribute groups, with loader.
class AvailableAttributeGroups {
/// Load constructor; may throw an exception.
AvailableAttributeGroups.loadFromJSONString(
final String attributeGroupsString,
) {
final dynamic inputJson = json.decode(attributeGroupsString);
final dynamic inputJson = HttpHelper().jsonDecode(attributeGroupsString);
final List<AttributeGroup> attributeGroups = <AttributeGroup>[];
for (final dynamic item in inputJson as List<dynamic>) {
attributeGroups.add(AttributeGroup.fromJson(item));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'dart:convert';
import 'preference_importance.dart';
import '../utils/http_helper.dart';

/// Referential of preference importance, with loader.
class AvailablePreferenceImportances {
Expand All @@ -11,7 +11,8 @@ class AvailablePreferenceImportances {
final Map<String, PreferenceImportance> preferenceImportances =
<String, PreferenceImportance>{};
final Map<String, int> importancesReverseIds = <String, int>{};
final dynamic inputJson = json.decode(preferenceImportancesString);
final dynamic inputJson =
HttpHelper().jsonDecode(preferenceImportancesString);
for (final dynamic item in inputJson as List<dynamic>) {
final PreferenceImportance preferenceImportance =
PreferenceImportance.fromJson(item);
Expand Down

0 comments on commit 5a31a09

Please sign in to comment.