Skip to content

Commit 400ae9e

Browse files
committed
Add tests to ensure environment ID is propagated for all methods.
1 parent 5cf21f9 commit 400ae9e

File tree

1 file changed

+137
-1
lines changed

1 file changed

+137
-1
lines changed

packages/common_client/test/hooks/ld_common_client_hooks_test.dart

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import 'dart:async';
12
import 'dart:collection';
23
import 'package:test/test.dart';
34
import 'package:launchdarkly_common_client/launchdarkly_common_client.dart';
5+
import 'package:launchdarkly_common_client/src/data_sources/data_source.dart';
46

57
import '../ld_dart_client_test.dart' show TestConfig;
68

@@ -71,6 +73,44 @@ final class TestHook extends Hook {
7173
}
7274
}
7375

76+
final class TestDataSourceWithEnvironmentId implements DataSource {
77+
final StreamController<DataSourceEvent> _eventController = StreamController();
78+
final String environmentId;
79+
80+
TestDataSourceWithEnvironmentId(this.environmentId);
81+
82+
@override
83+
Stream<DataSourceEvent> get events => _eventController.stream;
84+
85+
@override
86+
void restart() {}
87+
88+
@override
89+
void start() {
90+
Timer(Duration(milliseconds: 10), () {
91+
_eventController.sink.add(DataEvent(
92+
'put',
93+
'{"test-flag":{'
94+
'"version":1,'
95+
'"flagVersion":1,'
96+
'"value":"test-value",'
97+
'"variation":0,'
98+
'"reason":{"kind":"FALLTHROUGH"}'
99+
'}}',
100+
environmentId: environmentId));
101+
});
102+
}
103+
104+
@override
105+
void stop() {
106+
_eventController.close();
107+
}
108+
109+
void close() {
110+
_eventController.close();
111+
}
112+
}
113+
74114
void main() {
75115
group('LDCommonClient Hooks Integration', () {
76116
late LDCommonClient client;
@@ -239,7 +279,7 @@ void main() {
239279
expect(evalContext.method, equals('jsonVariation'));
240280
expect(evalContext.context, isNotNull);
241281
expect(evalContext.environmentId,
242-
isNull); // Environment ID not implemented yet
282+
isNull); // Environment ID null when in offline mode
243283
});
244284

245285
test('should handle hooks when client is not started', () async {
@@ -251,4 +291,100 @@ void main() {
251291
expect(initialHook.callLog, contains('afterEvaluation'));
252292
});
253293
});
294+
295+
group('LDCommonClient Hooks with Environment ID', () {
296+
late LDCommonClient client;
297+
late TestHook testHook;
298+
late LDContext testContext;
299+
late TestDataSourceWithEnvironmentId dataSource;
300+
301+
setUp(() {
302+
testHook = TestHook('test-hook');
303+
testContext = LDContextBuilder().kind('user', 'test-user').build();
304+
dataSource = TestDataSourceWithEnvironmentId('test-env-123');
305+
306+
final config = TestConfig('test-sdk-key', AutoEnvAttributes.disabled,
307+
offline: false);
308+
309+
client = LDCommonClient(
310+
config,
311+
CommonPlatform(),
312+
testContext,
313+
DiagnosticSdkData(name: 'test-sdk', version: '1.0.0'),
314+
hooks: [testHook],
315+
dataSourceFactories: (LDCommonConfig config, LDLogger logger,
316+
HttpProperties properties) {
317+
return {
318+
ConnectionMode.streaming: (LDContext context) {
319+
return dataSource;
320+
},
321+
ConnectionMode.polling: (LDContext context) {
322+
return dataSource;
323+
},
324+
};
325+
},
326+
);
327+
});
328+
329+
tearDown(() async {
330+
await client.close();
331+
dataSource.close();
332+
});
333+
334+
test('should pass environment ID to hooks when available from data source',
335+
() async {
336+
await client.start();
337+
338+
// Wait for data source to initialize
339+
await Future.delayed(Duration(milliseconds: 50));
340+
341+
// Test all variation methods with environment ID
342+
client.boolVariation('test-flag', false);
343+
client.boolVariationDetail('test-flag', false);
344+
client.intVariation('test-flag', 0);
345+
client.intVariationDetail('test-flag', 0);
346+
client.doubleVariation('test-flag', 0.0);
347+
client.doubleVariationDetail('test-flag', 0.0);
348+
client.stringVariation('test-flag', 'default');
349+
client.stringVariationDetail('test-flag', 'default');
350+
client.jsonVariation('test-flag', LDValue.ofNull());
351+
client.jsonVariationDetail('test-flag', LDValue.ofNull());
352+
353+
// Should have calls for all variation methods
354+
final beforeEvaluationCalls =
355+
testHook.callLog.where((call) => call == 'beforeEvaluation').length;
356+
final afterEvaluationCalls =
357+
testHook.callLog.where((call) => call == 'afterEvaluation').length;
358+
359+
expect(beforeEvaluationCalls, equals(10));
360+
expect(afterEvaluationCalls, equals(10));
361+
362+
// All evaluation contexts should have the environment ID
363+
for (final evalContext in testHook.evaluationContexts) {
364+
expect(evalContext.environmentId, equals('test-env-123'),
365+
reason:
366+
'Environment ID should be passed to hooks for method: ${evalContext.method}');
367+
expect(evalContext.flagKey, equals('test-flag'));
368+
expect(evalContext.context, isNotNull);
369+
}
370+
371+
// Check that all variation methods are represented
372+
final methods =
373+
testHook.evaluationContexts.map((ctx) => ctx.method).toSet();
374+
expect(
375+
methods,
376+
containsAll([
377+
'boolVariation',
378+
'boolVariationDetail',
379+
'intVariation',
380+
'intVariationDetail',
381+
'doubleVariation',
382+
'doubleVariationDetail',
383+
'stringVariation',
384+
'stringVariationDetail',
385+
'jsonVariation',
386+
'jsonVariationDetail',
387+
]));
388+
});
389+
});
254390
}

0 commit comments

Comments
 (0)