Add WiZ provisioning wizard
This commit is contained in:
218
test/wiz_provisioning_notifier_test.dart
Normal file
218
test/wiz_provisioning_notifier_test.dart
Normal file
@@ -0,0 +1,218 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:ignis_app/features/homes/providers/homes_providers.dart';
|
||||
import 'package:ignis_app/features/provisioning/models/wiz_provisioning_device.dart';
|
||||
import 'package:ignis_app/features/provisioning/models/wiz_provisioning_environment.dart';
|
||||
import 'package:ignis_app/features/provisioning/models/wiz_provisioning_failure.dart';
|
||||
import 'package:ignis_app/features/provisioning/models/wiz_provisioning_state.dart';
|
||||
import 'package:ignis_app/features/provisioning/models/wiz_provisioning_timing.dart';
|
||||
import 'package:ignis_app/features/provisioning/providers/wiz_provisioning_providers.dart';
|
||||
import 'package:ignis_app/features/provisioning/services/wiz_provisioning_platform_service.dart';
|
||||
import 'package:ignis_app/features/provisioning/services/wiz_smart_pairing_service.dart';
|
||||
import 'package:ignis_app/features/shared/providers/core_providers.dart';
|
||||
import 'package:ignis_app/models/home_config.dart';
|
||||
|
||||
import 'test_support.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
test('initialize reports missing active home', () async {
|
||||
final container = ProviderContainer(
|
||||
overrides: [
|
||||
wizProvisioningPlatformServiceProvider.overrideWithValue(
|
||||
FakeWizProvisioningPlatformService(environment: _readyEnvironment()),
|
||||
),
|
||||
],
|
||||
);
|
||||
addTearDown(container.dispose);
|
||||
|
||||
await container.read(wizProvisioningProvider.notifier).initialize();
|
||||
|
||||
final state = container.read(wizProvisioningProvider);
|
||||
expect(state.status, WizProvisioningStatus.failure);
|
||||
expect(state.failure?.kind, WizProvisioningFailureKind.noActiveHome);
|
||||
});
|
||||
|
||||
test(
|
||||
'initialize asks for permissions when Wi-Fi access is not granted',
|
||||
() async {
|
||||
final home = HomeConfig(id: 'home-1', name: 'Дом', url: 'https://ignis');
|
||||
final container = ProviderContainer(
|
||||
overrides: [
|
||||
currentHomeProvider.overrideWith(() => FakeCurrentHomeNotifier(home)),
|
||||
wizProvisioningPlatformServiceProvider.overrideWithValue(
|
||||
FakeWizProvisioningPlatformService(
|
||||
environment: _readyEnvironment(
|
||||
permissionStatus: WizProvisioningPermissionStatus.requestable,
|
||||
connectedToWifi: false,
|
||||
ssid: null,
|
||||
bssid: null,
|
||||
frequencyMhz: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
addTearDown(container.dispose);
|
||||
|
||||
await container.read(wizProvisioningProvider.notifier).initialize();
|
||||
|
||||
final state = container.read(wizProvisioningProvider);
|
||||
expect(state.status, WizProvisioningStatus.attentionRequired);
|
||||
expect(
|
||||
state.failure?.kind,
|
||||
WizProvisioningFailureKind.missingPermissions,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test('successful smart pairing ends with rescan success', () async {
|
||||
final home = HomeConfig(id: 'home-1', name: 'Дом', url: 'https://ignis');
|
||||
final api = FakeIgnisApi()
|
||||
..rescanNetworkData = {
|
||||
'status': 'ok',
|
||||
'found': 1,
|
||||
'added': 1,
|
||||
'updated': 0,
|
||||
'removed_offline': 0,
|
||||
'pending_removal': 0,
|
||||
'online': 1,
|
||||
};
|
||||
final smartPairing = FakeWizSmartPairingService(
|
||||
streamFactory: () {
|
||||
final controller = StreamController<WizProvisioningDevice>();
|
||||
Future<void>.microtask(() {
|
||||
controller.add(
|
||||
const WizProvisioningDevice(
|
||||
bssid: 'aa:bb:cc:dd:ee:ff',
|
||||
ipAddress: '192.168.1.44',
|
||||
),
|
||||
);
|
||||
});
|
||||
return controller.stream;
|
||||
},
|
||||
);
|
||||
final container = ProviderContainer(
|
||||
overrides: [
|
||||
currentHomeProvider.overrideWith(() => FakeCurrentHomeNotifier(home)),
|
||||
apiProvider.overrideWithValue(api),
|
||||
wizProvisioningPlatformServiceProvider.overrideWithValue(
|
||||
FakeWizProvisioningPlatformService(environment: _readyEnvironment()),
|
||||
),
|
||||
wizSmartPairingServiceProvider.overrideWithValue(smartPairing),
|
||||
wizProvisioningTimingProvider.overrideWithValue(
|
||||
const WizProvisioningTiming(
|
||||
provisioningTimeout: Duration(milliseconds: 200),
|
||||
settleAfterFirstResponse: Duration.zero,
|
||||
initialRescanDelay: Duration.zero,
|
||||
retryRescanDelay: Duration.zero,
|
||||
maxRescanAttempts: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
addTearDown(container.dispose);
|
||||
|
||||
await container.read(wizProvisioningProvider.notifier).initialize();
|
||||
await container
|
||||
.read(wizProvisioningProvider.notifier)
|
||||
.startProvisioning(
|
||||
ssid: 'Home-2G',
|
||||
password: 'secret',
|
||||
bssid: '11:22:33:44:55:66',
|
||||
);
|
||||
|
||||
final state = container.read(wizProvisioningProvider);
|
||||
expect(state.status, WizProvisioningStatus.success);
|
||||
expect(state.provisionedDevices, hasLength(1));
|
||||
expect(state.rescanSummary?.added, 1);
|
||||
expect(api.rescanCalls, 1);
|
||||
});
|
||||
}
|
||||
|
||||
class FakeCurrentHomeNotifier extends CurrentHomeNotifier {
|
||||
FakeCurrentHomeNotifier(this._home);
|
||||
|
||||
final HomeConfig? _home;
|
||||
|
||||
@override
|
||||
HomeConfig? build() => _home;
|
||||
}
|
||||
|
||||
class FakeWizProvisioningPlatformService
|
||||
implements WizProvisioningPlatformService {
|
||||
FakeWizProvisioningPlatformService({required this.environment});
|
||||
|
||||
final WizProvisioningEnvironment environment;
|
||||
int requestCalls = 0;
|
||||
int openWifiSettingsCalls = 0;
|
||||
int openAppSettingsCalls = 0;
|
||||
|
||||
@override
|
||||
Future<WizProvisioningEnvironment> inspectEnvironment() async => environment;
|
||||
|
||||
@override
|
||||
Future<void> requestPermissions() async {
|
||||
requestCalls += 1;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> openAppSettings() async {
|
||||
openAppSettingsCalls += 1;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> openWifiSettings() async {
|
||||
openWifiSettingsCalls += 1;
|
||||
}
|
||||
}
|
||||
|
||||
class FakeWizSmartPairingService implements WizSmartPairingService {
|
||||
FakeWizSmartPairingService({required this.streamFactory});
|
||||
|
||||
final Stream<WizProvisioningDevice> Function() streamFactory;
|
||||
int startCalls = 0;
|
||||
int stopCalls = 0;
|
||||
|
||||
@override
|
||||
Stream<WizProvisioningDevice> startProvisioning({
|
||||
required String ssid,
|
||||
required String password,
|
||||
String? bssid,
|
||||
}) {
|
||||
startCalls += 1;
|
||||
return streamFactory();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> stopProvisioning() async {
|
||||
stopCalls += 1;
|
||||
}
|
||||
}
|
||||
|
||||
WizProvisioningEnvironment _readyEnvironment({
|
||||
WizProvisioningPermissionStatus permissionStatus =
|
||||
WizProvisioningPermissionStatus.granted,
|
||||
bool connectedToWifi = true,
|
||||
bool locationServicesEnabled = true,
|
||||
String? ssid = 'Home-2G',
|
||||
String? bssid = '11:22:33:44:55:66',
|
||||
int? frequencyMhz = 2437,
|
||||
}) {
|
||||
return WizProvisioningEnvironment(
|
||||
platform: 'android',
|
||||
androidApiLevel: 35,
|
||||
smartPairingSupported: true,
|
||||
wifiSettingsSupported: true,
|
||||
appSettingsSupported: true,
|
||||
permissionStatus: permissionStatus,
|
||||
locationServicesEnabled: locationServicesEnabled,
|
||||
connectedToWifi: connectedToWifi,
|
||||
ssid: ssid,
|
||||
bssid: bssid,
|
||||
frequencyMhz: frequencyMhz,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user