219 lines
6.9 KiB
Dart
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,
|
|
);
|
|
}
|