Files
ignis_app/test/wiz_provisioning_notifier_test.dart
2026-05-16 17:24:28 +07:00

219 lines
6.9 KiB
Dart

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,
);
}