Skip to content

Commit

Permalink
feature/#104 - support for the new "Image Refresh" API (#289)
Browse files Browse the repository at this point in the history
Impacted files:
* `Product.dart`: added a dedicated field and its computing method
* `ProductFields.dart`: added a dedicated field belonging to the "in languages" category
* `api_getProduct_test.dart`: added a dedicated test
  • Loading branch information
monsieurtanuki committed Nov 10, 2021
1 parent ad4d829 commit be74dd4
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 10 deletions.
29 changes: 29 additions & 0 deletions lib/model/Product.dart
Expand Up @@ -179,6 +179,13 @@ class Product extends JsonObject {
includeIfNull: false)
Map<OpenFoodFactsLanguage, List<String>>? ingredientsTagsInLanguages;

/// Images Freshness in seconds
///
/// 0 seconds means we don't have the picture at all.
/// Read-only
/// cf. https://github.com/openfoodfacts/openfoodfacts-dart/issues/104
Map<OpenFoodFactsLanguage, Map<ImageField, int>>? imagesFreshnessInLanguages;

@JsonKey(
name: 'ingredients_analysis_tags',
includeIfNull: false,
Expand Down Expand Up @@ -412,6 +419,16 @@ class Product extends JsonObject {
result.ingredientsTagsInLanguages ??= {};
result.ingredientsTagsInLanguages![lang] = values;
}
} else if (key
.startsWith(ProductField.IMAGES_FRESHNESS_IN_LANGUAGES.key)) {
final OpenFoodFactsLanguage lang =
_langFrom(key, ProductField.IMAGES_FRESHNESS_IN_LANGUAGES.key);
if (lang != OpenFoodFactsLanguage.UNDEFINED) {
final Map<ImageField, int> values =
_jsonValueToImagesFreshness(json[key], lang);
result.imagesFreshnessInLanguages ??= {};
result.imagesFreshnessInLanguages![lang] = values;
}
} else if (key.startsWith(ProductField.LABELS_TAGS_IN_LANGUAGES.key)) {
OpenFoodFactsLanguage lang =
_langFrom(key, ProductField.LABELS_TAGS_IN_LANGUAGES.key);
Expand Down Expand Up @@ -449,6 +466,18 @@ class Product extends JsonObject {
return (value as List?)?.map((e) => e as String).toList();
}

static Map<ImageField, int> _jsonValueToImagesFreshness(
Map value, OpenFoodFactsLanguage language) {
final Map<ImageField, int> result = {};
for (final ImageField imageField in ImageField.values) {
final int? timestamp = value['${imageField.value}_${language.code}'];
if (timestamp != null) {
result[imageField] = timestamp;
}
}
return result;
}

Map<String, String> toServerData() {
final json = toJson();
return JsonObject.toDataStatic(json);
Expand Down
3 changes: 3 additions & 0 deletions lib/utils/ProductFields.dart
Expand Up @@ -30,6 +30,7 @@ enum ProductField {
INGREDIENTS,
INGREDIENTS_TAGS,
INGREDIENTS_TAGS_IN_LANGUAGES,
IMAGES_FRESHNESS_IN_LANGUAGES,
NUTRIMENTS,
ADDITIVES,
NUTRIENT_LEVELS,
Expand Down Expand Up @@ -87,6 +88,7 @@ extension ProductFieldExtension on ProductField {
ProductField.INGREDIENTS: 'ingredients',
ProductField.INGREDIENTS_TAGS: 'ingredients_tags',
ProductField.INGREDIENTS_TAGS_IN_LANGUAGES: 'ingredients_tags_',
ProductField.IMAGES_FRESHNESS_IN_LANGUAGES: 'images_to_update_',
ProductField.NUTRIMENTS: 'nutriments',
ProductField.ADDITIVES: 'additives_tags',
ProductField.NUTRIENT_LEVELS: 'nutrient_levels',
Expand Down Expand Up @@ -130,6 +132,7 @@ List<String> convertFieldsToStrings(
ProductField.COUNTRIES_TAGS_IN_LANGUAGES,
ProductField.INGREDIENTS_TEXT_IN_LANGUAGES,
ProductField.INGREDIENTS_TAGS_IN_LANGUAGES,
ProductField.IMAGES_FRESHNESS_IN_LANGUAGES,
];

for (final field in fields) {
Expand Down
29 changes: 29 additions & 0 deletions test/api_getProduct_test.dart
Expand Up @@ -1560,4 +1560,33 @@ void main() {
assert(invalidBarcodes.isBlacklisted('15600703'));
assert(!invalidBarcodes.isBlacklisted(_BARCODE_DANISH_BUTTER_COOKIES));
});

test('get images freshness', () async {
final List<OpenFoodFactsLanguage> languages = [
OpenFoodFactsLanguage.ENGLISH,
OpenFoodFactsLanguage.RUSSIAN,
OpenFoodFactsLanguage.GERMAN,
OpenFoodFactsLanguage.FRENCH,
];
final ProductResult productResult = await OpenFoodAPIClient.getProduct(
ProductQueryConfiguration(
_BARCODE_DANISH_BUTTER_COOKIES,
languages: languages,
fields: [ProductField.IMAGES_FRESHNESS_IN_LANGUAGES],
),
);
final Product product = productResult.product!;
const int TEN_YEARS = 10 * 365 * 24 * 3600;
for (final OpenFoodFactsLanguage language in languages) {
final Map<ImageField, int> freshnesses =
product.imagesFreshnessInLanguages![language]!;
for (final ImageField imageField in ImageField.values) {
final int? freshness = freshnesses[imageField];
if (freshness != null) {
expect(freshness >= 0, isTrue);
expect(freshness < TEN_YEARS, isTrue);
}
}
}
});
}
17 changes: 7 additions & 10 deletions test/api_saveProduct_test.dart
Expand Up @@ -148,9 +148,8 @@ void main() {
var frenchResult = await OpenFoodAPIClient.getProduct(
frenchConfig,
);
assert(frenchResult.product != null);
assert(frenchResult.product!.productName != null);
assert(frenchResult.product!.productName == frenchProductName);
expect(frenchResult.product, isNotNull);
expect(frenchResult.product!.productName, frenchProductName);

// get german fields for product
ProductQueryConfiguration germanConfig = ProductQueryConfiguration(
Expand All @@ -165,9 +164,8 @@ void main() {
germanConfig,
);

assert(germanResult.product != null);
assert(germanResult.product!.productName != null);
assert(germanResult.product!.productName == germanProductName);
expect(germanResult.product, isNotNull);
expect(germanResult.product!.productName, germanProductName);

// get preferably French, then German fields for product
ProductQueryConfiguration frenchGermanConfig =
Expand All @@ -183,9 +181,8 @@ void main() {
frenchGermanConfig,
);

assert(frenchGermanResult.product != null);
assert(frenchGermanResult.product!.productName != null);
assert(frenchGermanResult.product!.productName == frenchProductName);
expect(frenchGermanResult.product, isNotNull);
expect(frenchGermanResult.product!.productName, frenchProductName);
});

test('add new product test 2', () async {
Expand Down Expand Up @@ -421,7 +418,7 @@ void main() {
),
product,
);
assert(status.isWrongUsernameOrPassword());
expect(status.isWrongUsernameOrPassword(), isTrue);
});
});
}

0 comments on commit be74dd4

Please sign in to comment.