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: Added missing product fields to ProductField enum #331

Merged
merged 4 commits into from Dec 19, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 26 additions & 6 deletions lib/model/Product.dart
@@ -1,10 +1,13 @@
import 'dart:convert';

import 'package:json_annotation/json_annotation.dart';
import 'package:openfoodfacts/model/AttributeGroup.dart';
import 'package:openfoodfacts/model/Attribute.dart';
import 'package:openfoodfacts/model/AttributeGroup.dart';
import 'package:openfoodfacts/model/ProductImage.dart';
import 'package:openfoodfacts/utils/JsonHelper.dart';
import 'package:openfoodfacts/utils/LanguageHelper.dart';
import 'package:openfoodfacts/utils/ProductFields.dart';

import '../interface/JsonObject.dart';
import 'Additives.dart';
import 'Allergens.dart';
Expand Down Expand Up @@ -102,6 +105,11 @@ class Product extends JsonObject {
includeIfNull: false)
Map<OpenFoodFactsLanguage, String>? productNameInLanguages;

///Common name
///Example: Chocolate bar with milk and hazelnuts
@JsonKey(name: 'generic_name', includeIfNull: false)
String? genericName;

Comment on lines +108 to +112
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comment and the example!

Beyond that good start will come later painful questions like: is that always in English? ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just looked into a response and it has generic_name, generic_name_fr as well as a generic_name_fr_debug_tags list, interesting

@JsonKey(name: 'brands', includeIfNull: false)
String? brands;
@JsonKey(name: 'brands_tags', includeIfNull: false)
Expand Down Expand Up @@ -156,13 +164,20 @@ class Product extends JsonObject {

@JsonKey(name: 'serving_size', includeIfNull: false)
String? servingSize;

@JsonKey(
name: 'serving_quantity',
fromJson: JsonHelper.servingQuantityFromJson,
includeIfNull: false)
name: 'serving_quantity',
fromJson: JsonHelper.quantityFromJson,
includeIfNull: false,
)
double? servingQuantity;
@JsonKey(name: 'product_quantity', includeIfNull: false)
dynamic packagingQuantity;

@JsonKey(
name: 'product_quantity',
fromJson: JsonHelper.quantityFromJson,
includeIfNull: false,
)
double? packagingQuantity;

/// cause nesting is sooo cool ;)
@JsonKey(
Expand Down Expand Up @@ -292,6 +307,9 @@ class Product extends JsonObject {
@JsonKey(name: 'stores_tags', includeIfNull: false)
List<String>? storesTags;

@JsonKey(name: 'stores', includeIfNull: false)
String? stores;

@JsonKey(
name: 'attribute_groups',
includeIfNull: false,
Expand Down Expand Up @@ -322,6 +340,7 @@ class Product extends JsonObject {
{this.barcode,
this.productName,
this.productNameInLanguages,
this.genericName,
this.brands,
this.brandsTags,
this.countries,
Expand Down Expand Up @@ -369,6 +388,7 @@ class Product extends JsonObject {
this.statesTags,
this.tracesTags,
this.storesTags,
this.stores,
this.attributeGroups,
this.lastModified,
this.ecoscoreGrade,
Expand Down
6 changes: 5 additions & 1 deletion lib/model/Product.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions lib/utils/JsonHelper.dart
@@ -1,8 +1,8 @@
import 'package:openfoodfacts/interface/JsonObject.dart';
import 'package:openfoodfacts/model/AttributeGroup.dart';
import 'package:openfoodfacts/utils/LanguageHelper.dart';
import 'package:openfoodfacts/model/Ingredient.dart';
import 'package:openfoodfacts/model/ProductImage.dart';
import 'package:openfoodfacts/utils/LanguageHelper.dart';

/// Helper class around product field conversion to/from JSON
class JsonHelper {
Expand Down Expand Up @@ -127,7 +127,7 @@ class JsonHelper {
}

/// Returns a double from a JSON-encoded int or double
static double? servingQuantityFromJson(dynamic data) {
static double? quantityFromJson(dynamic data) {
if (data == null || data is double) {
return data;
}
Expand Down
14 changes: 14 additions & 0 deletions lib/utils/ProductFields.dart
Expand Up @@ -15,6 +15,7 @@ enum ProductField {
LANGUAGE,
QUANTITY,
SERVING_SIZE,
SERVING_QUANTITY,
PACKAGING_QUANTITY,
FRONT_IMAGE,
SELECTED_IMAGE,
Expand Down Expand Up @@ -43,15 +44,21 @@ enum ProductField {
CATEGORIES,
CATEGORIES_TAGS,
CATEGORIES_TAGS_IN_LANGUAGES,
LABELS,
LABELS_TAGS,
LABELS_TAGS_IN_LANGUAGES,
PACKAGING,
PACKAGING_TAGS,
MISC_TAGS,
STATES_TAGS,
TRACES_TAGS,
STORES_TAGS,
STORES,
INGREDIENTS_ANALYSIS_TAGS,
ALLERGENS,
ENVIRONMENT_IMPACT_LEVELS,
ATTRIBUTE_GROUPS,
LAST_MODIFIED,
ECOSCORE_GRADE,
ECOSCORE_SCORE,
ECOSCORE_DATA,
Expand All @@ -73,6 +80,7 @@ extension ProductFieldExtension on ProductField {
ProductField.LANGUAGE: 'lang',
ProductField.QUANTITY: 'quantity',
ProductField.SERVING_SIZE: 'serving_size',
ProductField.SERVING_QUANTITY: 'serving_quantity',
ProductField.PACKAGING_QUANTITY: 'product_quantity',
ProductField.FRONT_IMAGE: 'image_small_url',
ProductField.IMAGE_FRONT_URL: 'image_front_url',
Expand Down Expand Up @@ -101,15 +109,21 @@ extension ProductFieldExtension on ProductField {
ProductField.CATEGORIES: 'categories',
ProductField.CATEGORIES_TAGS: 'categories_tags',
ProductField.CATEGORIES_TAGS_IN_LANGUAGES: 'categories_tags_',
ProductField.LABELS: 'labels',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably would be worth checking in a test that when we ask for those fields in a get product query, we actually get them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On it

ProductField.LABELS_TAGS: 'labels_tags',
ProductField.LABELS_TAGS_IN_LANGUAGES: 'labels_tags_',
ProductField.PACKAGING: 'packaging',
ProductField.PACKAGING_TAGS: 'packaging_tags',
ProductField.MISC_TAGS: 'misc',
ProductField.STATES_TAGS: 'states_tags',
ProductField.TRACES_TAGS: 'traces_tags',
ProductField.STORES_TAGS: 'stores_tags',
ProductField.STORES: 'stores',
ProductField.INGREDIENTS_ANALYSIS_TAGS: 'ingredients_analysis_tags',
ProductField.ALLERGENS: 'allergens_tags',
ProductField.ENVIRONMENT_IMPACT_LEVELS: 'environment_impact_level_tags',
ProductField.ATTRIBUTE_GROUPS: 'attribute_groups',
ProductField.LAST_MODIFIED: 'last_modified_t',
ProductField.ECOSCORE_GRADE: 'ecoscore_grade',
ProductField.ECOSCORE_SCORE: 'ecoscore_score',
ProductField.ECOSCORE_DATA: 'ecoscore_data',
Expand Down
47 changes: 47 additions & 0 deletions test/api_getProduct_test.dart
Expand Up @@ -35,6 +35,7 @@ void main() {
Product product = Product(
barcode: barcode,
productName: 'Coca Cola Light',
genericName: 'Softdrink',
lang: OpenFoodFactsLanguage.GERMAN,
countries: 'Frankreich,Deutschland',
brands: 'Coca Cola',
Expand Down Expand Up @@ -77,6 +78,8 @@ void main() {
expect(result.product!.barcode, barcode);
expect(result.product!.lastModified != null, true);

expect(result.product!.genericName, 'Softdrink');

// only german ingredients
expect(result.product!.ingredientsText != null, true);

Expand Down Expand Up @@ -1647,4 +1650,48 @@ void main() {
'de-es.openfoodfacts.net',
);
});

test('get minified product', () async {
String barcode = '111111555555';

//First add the product to the Test DB
Product product = Product(
barcode: barcode,
lang: OpenFoodFactsLanguage.GERMAN,
genericName: 'Softdrink',
labels: 'MyTestLabel',
packaging: 'de:In einer Plastikflasche',
quantity: '5.5 Liter',
);

await OpenFoodAPIClient.saveProduct(
TestConstants.TEST_USER,
product,
);

ProductQueryConfiguration configurations = ProductQueryConfiguration(
barcode,
language: OpenFoodFactsLanguage.GERMAN,
fields: [
ProductField.GENERIC_NAME,
ProductField.LABELS,
ProductField.PACKAGING,
ProductField.PACKAGING_TAGS,
ProductField.QUANTITY,
],
);

ProductResult result = await OpenFoodAPIClient.getProduct(
configurations,
user: TestConstants.TEST_USER,
);

expect(result.status, 1);
expect(result.product?.barcode, null);
expect(result.product?.genericName, 'Softdrink');
expect(result.product?.labels, 'MyTestLabel');
expect(result.product?.packaging, 'de:In einer Plastikflasche');
expect(result.product?.packagingTags, ['de-in-einer-plastikflasche']);
expect(result.product?.quantity, '5.5 Liter');
});
}