Skip to content

Commit

Permalink
fix: #407 - getProductList now works with unlimited number of barcodes (
Browse files Browse the repository at this point in the history
#413)

Impacted files:
* `api_searchProducts_test.dart`: additional test; refactored
* `openfoodfacts.dart`: changed method `getProductList` from GET to POST
* `ProductListQueryConfiguration.dart`: overrode `getParametersMap` in order to add barcodes as POST parameters
  • Loading branch information
monsieurtanuki authored Mar 15, 2022
1 parent dc77db3 commit fd7ddbc
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 69 deletions.
8 changes: 4 additions & 4 deletions lib/openfoodfacts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -324,14 +324,14 @@ class OpenFoodAPIClient {
QueryType? queryType,
}) async {
final Uri uri = UriHelper.getUri(
path: 'products/${configuration.barcodes.join(',')}.json',
queryParameters: configuration.getParametersMap(),
path: 'api/v2/search/',
queryType: queryType,
);

final Response response = await HttpHelper().doGetRequest(
final Response response = await HttpHelper().doPostRequest(
uri,
user: user,
configuration.getParametersMap(),
user,
queryType: queryType,
);

Expand Down
9 changes: 9 additions & 0 deletions lib/utils/ProductListQueryConfiguration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,13 @@ class ProductListQueryConfiguration extends AbstractQueryConfiguration {
}
return result;
}

@override
Map<String, String> getParametersMap() {
final Map<String, String> result = super.getParametersMap();

result['code'] = barcodes.join(',') + '.json';

return result;
}
}
118 changes: 53 additions & 65 deletions test/api_searchProducts_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@ void main() {
OpenFoodAPIConfiguration.globalQueryType = QueryType.TEST;

group('$OpenFoodAPIClient search products', () {
const String UNKNOWN_BARCODE = '1111111111111111111111111111111';
const List<String> BARCODES = [
'8024884500403',
'3263855093192',
'3045320001570',
'3021762383344',
'4008400402222',
'3330720237255',
'3608580823513',
'3700278403936',
'3302747010029',
'3608580823490',
'3250391660995',
'3760020506605',
'8722700202387',
'3330720237330',
'3535800940005',
'20000691',
'3270190127512',
UNKNOWN_BARCODE,
];

test('search favorite products', () async {
final parameters = <Parameter>[
const Page(page: 1),
Expand Down Expand Up @@ -383,28 +405,6 @@ void main() {
});

test('multiple products', () async {
const String UNKNOWN_BARCODE = '1111111111111111111111111111111';
const List<String> BARCODES = [
'8024884500403',
'3263855093192',
'3045320001570',
'3021762383344',
'4008400402222',
'3330720237255',
'3608580823513',
'3700278403936',
'3302747010029',
'3608580823490',
'3250391660995',
'3760020506605',
'8722700202387',
'3330720237330',
'3535800940005',
'20000691',
'3270190127512',
UNKNOWN_BARCODE,
];

final ProductListQueryConfiguration configuration =
ProductListQueryConfiguration(
BARCODES,
Expand All @@ -430,28 +430,6 @@ void main() {
});

test('product freshness', () async {
const String UNKNOWN_BARCODE = '1111111111111111111111111111111';
const List<String> BARCODES = [
'8024884500403',
'3263855093192',
'3045320001570',
'3021762383344',
'4008400402222',
'3330720237255',
'3608580823513',
'3700278403936',
'3302747010029',
'3608580823490',
'3250391660995',
'3760020506605',
'8722700202387',
'3330720237330',
'3535800940005',
'20000691',
'3270190127512',
UNKNOWN_BARCODE,
];

final Map<String, ProductFreshness> result =
await OpenFoodAPIClient.getProductFreshness(
barcodes: BARCODES,
Expand All @@ -472,26 +450,6 @@ void main() {
});

test('multiple products and pagination', () async {
const BARCODES = [
'8024884500403',
'3263855093192',
'3045320001570',
'3021762383344',
'4008400402222',
'3330720237255',
'3608580823513',
'3700278403936',
'3302747010029',
'3608580823490',
'3250391660995',
'3760020506605',
'8722700202387',
'3330720237330',
'3535800940005',
'20000691',
'3270190127512',
];

final obtainedBarcodes = <String>[];
var page = 1;
while (true) {
Expand All @@ -516,7 +474,9 @@ void main() {
}
// We want to test pagination mechanism so we expect >1 pages
expect(page, greaterThan(1));
expect(obtainedBarcodes.toSet(), BARCODES.toSet());
final Set<String> knownBarcodes = BARCODES.toSet();
knownBarcodes.remove(UNKNOWN_BARCODE);
expect(obtainedBarcodes.toSet(), knownBarcodes);
});

test('query potatoes products', () async {
Expand All @@ -542,5 +502,33 @@ void main() {
expect(result.products![0].runtimeType, Product);
expect(result.count, greaterThan(1500));
});

test('many many products', () async {
final List<String> manyBarcodes = <String>[];
// for a GET, the limit seems to be around 8000 characters
// but here we don't care anymore as now it's a POST
for (int i = 0; i < 100; i++) {
manyBarcodes.addAll(BARCODES);
}

final ProductListQueryConfiguration configuration =
ProductListQueryConfiguration(
manyBarcodes,
fields: [ProductField.BARCODE, ProductField.NAME],
language: OpenFoodFactsLanguage.FRENCH,
);

final SearchResult result = await OpenFoodAPIClient.getProductList(
TestConstants.PROD_USER,
configuration,
queryType: QueryType.PROD,
);

expect(result.page, 1);
expect(result.pageSize, 24);
expect(result.count, BARCODES.length - 1);
expect(result.products, isNotNull);
expect(result.products!.length, BARCODES.length - 1);
});
});
}

0 comments on commit fd7ddbc

Please sign in to comment.