test(#74): lock observer provider wiring -- shared connector + gate reactivity (P1)
main.dart wiring verified correct (no change): the singleton MeshCoreConnector (main.dart:38 -> field -> provided by value) is the SAME instance passed to ObserverConfigService, so the service watches the live transport. Plain ChangeNotifierProvider (not a proxy) is right -- the connector instance is stable; only its state changes, which the service reads live. Lazy-safe: the constructor has no side effects. This test pins that contract: the service is reachable through Provider and a mutation to the shared connector's caps flips the Observer gate (supported). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>pull/99/head
parent
be33f4ff5f
commit
81c5b4e72f
@ -0,0 +1,60 @@
|
|||||||
|
// Provider wiring lock for the Observer config feature (#64 P1).
|
||||||
|
//
|
||||||
|
// main.dart provides the singleton MeshCoreConnector by value and creates
|
||||||
|
// ObserverConfigService with THAT SAME connector (main.dart:38 -> field -> the
|
||||||
|
// two providers). This pins the contract the feature depends on: the service is
|
||||||
|
// reachable through Provider AND shares the live connector, so the Observer
|
||||||
|
// settings gate (`supported`) reacts to device-info caps. A fresh-connector
|
||||||
|
// rewire (create: (_) => ObserverConfigService(MeshCoreConnector())) breaks it.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:meshcore_open/connector/meshcore_connector.dart';
|
||||||
|
import 'package:meshcore_open/connector/observer_config_client.dart';
|
||||||
|
import 'package:meshcore_open/services/observer_config_service.dart';
|
||||||
|
|
||||||
|
class _CapsConnector extends MeshCoreConnector {
|
||||||
|
int? ver;
|
||||||
|
int? caps;
|
||||||
|
@override
|
||||||
|
int? get firmwareVerCode => ver;
|
||||||
|
@override
|
||||||
|
int? get offbandCaps => caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
testWidgets(
|
||||||
|
'ObserverConfigService is provided and shares the live connector',
|
||||||
|
(tester) async {
|
||||||
|
final connector = _CapsConnector();
|
||||||
|
late ObserverConfigService svc;
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MultiProvider(
|
||||||
|
providers: [
|
||||||
|
ChangeNotifierProvider<MeshCoreConnector>.value(value: connector),
|
||||||
|
ChangeNotifierProvider(
|
||||||
|
create: (_) => ObserverConfigService(connector),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
svc = context.read<ObserverConfigService>();
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Unsupported until the shared connector reports a v14+ observer build.
|
||||||
|
expect(svc.supported, isFalse);
|
||||||
|
|
||||||
|
connector.ver = ObserverConfigClient.minVerCode;
|
||||||
|
connector.caps = ObserverConfigClient.capWifiObserver;
|
||||||
|
|
||||||
|
// The gate flips because the service reads through the SAME connector.
|
||||||
|
expect(svc.supported, isTrue);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in new issue