Skip to content

Commit 4abc03b

Browse files
Add getTreatments[WithConfig] methods
1 parent c420659 commit 4abc03b

File tree

3 files changed

+234
-1
lines changed

3 files changed

+234
-1
lines changed

splitio_web/lib/splitio_web.dart

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,4 +413,68 @@ class SplitioWeb extends SplitioPlatform {
413413
_convertEvaluationOptions(evaluationOptions)) as JSString;
414414
return result.toDart;
415415
}
416+
417+
@override
418+
Future<Map<String, String>> getTreatments({
419+
required String matchingKey,
420+
required String? bucketingKey,
421+
required List<String> splitNames,
422+
Map<String, dynamic> attributes = const {},
423+
EvaluationOptions evaluationOptions = const EvaluationOptions.empty(),
424+
}) async {
425+
final client = await _getClient(
426+
matchingKey: matchingKey,
427+
bucketingKey: bucketingKey,
428+
);
429+
430+
final result = client.getTreatments.callAsFunction(
431+
null,
432+
splitNames.jsify(),
433+
_convertMap(attributes, true),
434+
_convertEvaluationOptions(evaluationOptions)) as JSObject;
435+
return jsTreatmentsToMap(result);
436+
}
437+
438+
@override
439+
Future<SplitResult> getTreatmentWithConfig({
440+
required String matchingKey,
441+
required String? bucketingKey,
442+
required String splitName,
443+
Map<String, dynamic> attributes = const {},
444+
EvaluationOptions evaluationOptions = const EvaluationOptions.empty(),
445+
}) async {
446+
await this._initFuture;
447+
final client = await _getClient(
448+
matchingKey: matchingKey,
449+
bucketingKey: bucketingKey,
450+
);
451+
452+
final result = client.getTreatmentWithConfig.callAsFunction(
453+
null,
454+
splitName.toJS,
455+
_convertMap(attributes, true),
456+
_convertEvaluationOptions(evaluationOptions)) as JSObject;
457+
return jsTreatmentWithConfigToSplitResult(result);
458+
}
459+
460+
@override
461+
Future<Map<String, SplitResult>> getTreatmentsWithConfig({
462+
required String matchingKey,
463+
required String? bucketingKey,
464+
required List<String> splitNames,
465+
Map<String, dynamic> attributes = const {},
466+
EvaluationOptions evaluationOptions = const EvaluationOptions.empty(),
467+
}) async {
468+
final client = await _getClient(
469+
matchingKey: matchingKey,
470+
bucketingKey: bucketingKey,
471+
);
472+
473+
final result = client.getTreatmentsWithConfig.callAsFunction(
474+
null,
475+
splitNames.jsify(),
476+
_convertMap(attributes, true),
477+
_convertEvaluationOptions(evaluationOptions)) as JSObject;
478+
return jsTreatmentsWithConfigToMap(result);
479+
}
416480
}

splitio_web/lib/src/js_interop.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dart:js_interop';
2+
import 'package:splitio_platform_interface/split_result.dart';
23

34
// JS SDK types
45

@@ -15,6 +16,13 @@ extension type JS_ISettings._(JSObject _) implements JSObject {
1516
@JS()
1617
extension type JS_IBrowserClient._(JSObject _) implements JSObject {
1718
external JSFunction getTreatment;
19+
external JSFunction getTreatments;
20+
external JSFunction getTreatmentWithConfig;
21+
external JSFunction getTreatmentsWithConfig;
22+
external JSFunction getTreatmentsByFlagSet;
23+
external JSFunction getTreatmentsByFlagSets;
24+
external JSFunction getTreatmentWithConfigByFlagSet;
25+
external JSFunction getTreatmentsWithConfigByFlagSets;
1826
}
1927

2028
@JS()
@@ -68,3 +76,18 @@ dynamic jsAnyToDart(JSAny? value) {
6876
return value; // JS null and undefined are null in Dart
6977
}
7078
}
79+
80+
// Conversion utils: JS SDK to Flutter SDK types
81+
82+
Map<String, String> jsTreatmentsToMap(JSObject obj) {
83+
return jsObjectToMap(obj).map((k, v) => MapEntry(k, v as String));
84+
}
85+
86+
Map<String, SplitResult> jsTreatmentsWithConfigToMap(JSObject obj) {
87+
return jsObjectToMap(obj).map((k, v) => MapEntry(k, SplitResult(v['treatment'] as String, v['config'] as String?)));
88+
}
89+
90+
SplitResult jsTreatmentWithConfigToSplitResult(JSObject obj) {
91+
final config = _reflectGet(obj, 'config'.toJS);
92+
return SplitResult((_reflectGet(obj, 'treatment'.toJS) as JSString).toDart, (config is JSString) ? config.toDart : null);
93+
}

splitio_web/test/splitio_web_test.dart

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:splitio_platform_interface/split_certificate_pinning_configurati
88
import 'package:splitio_platform_interface/split_configuration.dart';
99
import 'package:splitio_platform_interface/split_evaluation_options.dart';
1010
import 'package:splitio_platform_interface/split_sync_config.dart';
11+
import 'package:splitio_platform_interface/split_result.dart';
1112
import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart';
1213

1314
extension on web.Window {
@@ -27,6 +28,52 @@ void main() {
2728
));
2829
return 'on'.toJS;
2930
}.toJS;
31+
mockClient['getTreatments'] =
32+
(JSAny? flagNames, JSAny? attributes, JSAny? evaluationOptions) {
33+
calls.add((
34+
methodName: 'getTreatments',
35+
methodArguments: [flagNames, attributes, evaluationOptions]
36+
));
37+
if (flagNames is JSArray) {
38+
return flagNames.toDart.fold(JSObject(), (previousValue, element) {
39+
if (element is JSString) {
40+
previousValue.setProperty(element, 'on'.toJS);
41+
}
42+
return previousValue;
43+
});
44+
}
45+
return JSObject();
46+
}.toJS;
47+
mockClient['getTreatmentWithConfig'] =
48+
(JSAny? flagName, JSAny? attributes, JSAny? evaluationOptions) {
49+
calls.add((
50+
methodName: 'getTreatmentWithConfig',
51+
methodArguments: [flagName, attributes, evaluationOptions]
52+
));
53+
final result = JSObject();
54+
result.setProperty('treatment'.toJS, 'on'.toJS);
55+
result.setProperty('config'.toJS, 'some-config'.toJS);
56+
return result;
57+
}.toJS;
58+
mockClient['getTreatmentsWithConfig'] =
59+
(JSAny? flagNames, JSAny? attributes, JSAny? evaluationOptions) {
60+
calls.add((
61+
methodName: 'getTreatmentsWithConfig',
62+
methodArguments: [flagNames, attributes, evaluationOptions]
63+
));
64+
if (flagNames is JSArray) {
65+
return flagNames.toDart.fold(JSObject(), (previousValue, element) {
66+
if (element is JSString) {
67+
final result = JSObject();
68+
result.setProperty('treatment'.toJS, 'on'.toJS);
69+
result.setProperty('config'.toJS, 'some-config'.toJS);
70+
previousValue.setProperty(element, result);
71+
}
72+
return previousValue;
73+
});
74+
}
75+
return JSObject();
76+
}.toJS;
3077

3178
final mockLog = JSObject();
3279
mockLog['warn'] = (JSAny? arg1) {
@@ -170,6 +217,106 @@ void main() {
170217
'Invalid property value: [value1, 100, false], for key: propList, will be ignored'));
171218
});
172219

220+
test('getTreatments without attributes', () async {
221+
final result = await _platform.getTreatments(
222+
matchingKey: 'matching-key',
223+
bucketingKey: 'bucketing-key',
224+
splitNames: ['split1', 'split2']);
225+
226+
expect(result, {'split1': 'on', 'split2': 'on'});
227+
expect(calls.last.methodName, 'getTreatments');
228+
expect(calls.last.methodArguments.map(jsAnyToDart), [
229+
['split1', 'split2'],
230+
{},
231+
{}
232+
]);
233+
});
234+
235+
test('getTreatments with attributes and evaluation properties', () async {
236+
final result = await _platform.getTreatments(
237+
matchingKey: 'matching-key',
238+
bucketingKey: 'bucketing-key',
239+
splitNames: ['split1', 'split2'],
240+
attributes: {'attr1': true});
241+
242+
expect(result, {'split1': 'on', 'split2': 'on'});
243+
expect(calls.last.methodName, 'getTreatments');
244+
expect(calls.last.methodArguments.map(jsAnyToDart), [
245+
['split1', 'split2'],
246+
{'attr1': true},
247+
{}
248+
]);
249+
});
250+
251+
test('getTreatmentWithConfig with attributes', () async {
252+
final result = await _platform.getTreatmentWithConfig(
253+
matchingKey: 'matching-key',
254+
bucketingKey: 'bucketing-key',
255+
splitName: 'split1',
256+
attributes: {'attr1': true});
257+
258+
expect(result.toString(), SplitResult('on', 'some-config').toString());
259+
expect(calls.last.methodName, 'getTreatmentWithConfig');
260+
expect(calls.last.methodArguments.map(jsAnyToDart), [
261+
'split1',
262+
{'attr1': true},
263+
{}
264+
]);
265+
});
266+
267+
test('getTreatmentWithConfig without attributes', () async {
268+
final result = await _platform.getTreatmentWithConfig(
269+
matchingKey: 'matching-key',
270+
bucketingKey: 'bucketing-key',
271+
splitName: 'split1');
272+
273+
expect(result.toString(), SplitResult('on', 'some-config').toString());
274+
expect(calls.last.methodName, 'getTreatmentWithConfig');
275+
expect(calls.last.methodArguments.map(jsAnyToDart), ['split1', {}, {}]);
276+
});
277+
278+
test('getTreatmentsWithConfig without attributes', () async {
279+
final result = await _platform.getTreatmentsWithConfig(
280+
matchingKey: 'matching-key',
281+
bucketingKey: 'bucketing-key',
282+
splitNames: ['split1', 'split2']);
283+
284+
expect(result, predicate<Map<String, SplitResult>>((result) {
285+
return result.length == 2 &&
286+
result['split1'].toString() ==
287+
SplitResult('on', 'some-config').toString() &&
288+
result['split2'].toString() ==
289+
SplitResult('on', 'some-config').toString();
290+
}));
291+
expect(calls.last.methodName, 'getTreatmentsWithConfig');
292+
expect(calls.last.methodArguments.map(jsAnyToDart), [
293+
['split1', 'split2'],
294+
{},
295+
{}
296+
]);
297+
});
298+
299+
test('getTreatmentsWithConfig with attributes', () async {
300+
final result = await _platform.getTreatmentsWithConfig(
301+
matchingKey: 'matching-key',
302+
bucketingKey: 'bucketing-key',
303+
splitNames: ['split1', 'split2'],
304+
attributes: {'attr1': true});
305+
306+
expect(result, predicate<Map<String, SplitResult>>((result) {
307+
return result.length == 2 &&
308+
result['split1'].toString() ==
309+
SplitResult('on', 'some-config').toString() &&
310+
result['split2'].toString() ==
311+
SplitResult('on', 'some-config').toString();
312+
}));
313+
expect(calls.last.methodName, 'getTreatmentsWithConfig');
314+
expect(calls.last.methodArguments.map(jsAnyToDart), [
315+
['split1', 'split2'],
316+
{'attr1': true},
317+
{}
318+
]);
319+
});
173320
});
174321

175322
group('initialization', () {
@@ -429,5 +576,4 @@ void main() {
429576
]);
430577
});
431578
});
432-
433579
}

0 commit comments

Comments
 (0)