| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- import 'dart:convert';
- import 'package:flutter_test/flutter_test.dart';
- import 'package:http/http.dart' as http;
- import 'package:http/testing.dart';
- import 'package:rackpeek_mobile/data/api_client.dart';
- import 'package:rackpeek_mobile/data/settings_store.dart';
- import 'package:rackpeek_mobile/state/inventory_store.dart';
- import 'support/memory_storage.dart';
- void main() {
- test(
- 'offline edits persist across store restarts and preserve unknown fields',
- () async {
- final storage = MemoryKeyValueStorage();
- final settings = SettingsStore(storage: storage);
- await settings.saveOfflineState({
- 'document': {
- 'version': 5,
- 'resources': [
- {
- 'kind': 'Service',
- 'name': 'media',
- 'customField': {'owner': 'lab'},
- 'network': {
- 'ip': '192.168.1.20',
- 'port': 8096,
- 'protocol': 'TCP',
- },
- },
- ],
- 'connections': [],
- },
- 'pendingChanges': <Map<String, dynamic>>[],
- });
- final first = InventoryStore(null, settings: settings);
- await first.refresh();
- await first.applyPatch({
- 'kind': 'Service',
- 'name': 'media',
- 'network': {'port': 8920},
- });
- expect(first.document!.byName('media')!.network!.ip, '192.168.1.20');
- expect(
- first.document!.toJson()['resources'][0]['customField']['owner'],
- 'lab',
- );
- expect(first.pendingChangeCount, 1);
- first.dispose();
- final reopened = InventoryStore(null, settings: settings);
- await reopened.refresh();
- expect(reopened.document!.byName('media')!.network!.port, 8920);
- expect(reopened.pendingChangeCount, 1);
- reopened.dispose();
- },
- );
- test(
- 'a pending offline change uploads when the configured server returns',
- () async {
- final storage = MemoryKeyValueStorage();
- final settings = SettingsStore(storage: storage);
- await settings.saveOfflineState({
- 'document': {
- 'version': 5,
- 'resources': [
- {'kind': 'Server', 'name': 'nas01'},
- ],
- 'connections': [],
- },
- 'pendingChanges': [
- {'kind': 'Server', 'name': 'nas01', 'model': 'NAS'},
- ],
- });
- var uploaded = false;
- final client = MockClient((request) async {
- if (request.method == 'POST' && request.url.path == '/api/inventory') {
- uploaded = true;
- return http.Response('{}', 200);
- }
- if (request.url.path == '/api/inventory') {
- return http.Response(
- jsonEncode({
- 'version': 5,
- 'resources': [
- {'kind': 'Server', 'name': 'nas01', 'model': 'NAS'},
- ],
- 'connections': [],
- }),
- 200,
- );
- }
- if (request.url.path == '/api/inventory/summary') {
- return http.Response('{}', 200);
- }
- return http.Response('{}', 404);
- });
- final store = InventoryStore(
- RackPeekApi(
- baseUrl: 'https://server.example.test',
- apiKey: 'key',
- client: client,
- ),
- settings: settings,
- );
- await store.refresh();
- expect(uploaded, isTrue);
- expect(store.isOnline, isTrue);
- expect(store.hasPendingChanges, isFalse);
- expect(store.document!.byName('nas01')!.model, 'NAS');
- store.dispose();
- },
- );
- test('a failed upload keeps local edits and refresh retries them', () async {
- final storage = MemoryKeyValueStorage();
- final settings = SettingsStore(storage: storage);
- var failFirstPost = true;
- var postCount = 0;
- final client = MockClient((request) async {
- if (request.method == 'POST') {
- postCount++;
- if (failFirstPost) {
- failFirstPost = false;
- return http.Response('{"error":"offline"}', 503);
- }
- return http.Response('{}', 200);
- }
- if (request.url.path == '/api/inventory') {
- return http.Response(
- jsonEncode({
- 'version': 5,
- 'resources': [
- {'kind': 'Server', 'name': 'nas01', 'model': 'NAS'},
- ],
- 'connections': [],
- }),
- 200,
- );
- }
- return http.Response('{}', 200);
- });
- final store = InventoryStore(
- RackPeekApi(
- baseUrl: 'https://server.example.test',
- apiKey: 'key',
- client: client,
- ),
- settings: settings,
- );
- await store.refresh();
- await store.addResource({
- 'kind': 'Server',
- 'name': 'nas01',
- 'model': 'NAS',
- });
- expect(store.pendingChangeCount, 1);
- expect(store.document!.byName('nas01')!.model, 'NAS');
- expect(store.isOnline, isFalse);
- await store.refresh();
- expect(postCount, 2);
- expect(store.pendingChangeCount, 0);
- expect(store.isOnline, isTrue);
- store.dispose();
- });
- }
|