schermate di configurazione complete: razze disponibili, mio pollaio, registro galline, clienti, backup/ripristino nel formato dell'app Android, lingua a runtime, introduzione e informazioni
- datastore: export/import JSON con le chiavi camelCase dell'app Android (breedSettings/reservations/customers), scorte e ultimo aggiornamento preservati al ripristino - settings: flag 'introduzione vista' - desktop: permesso Documents (dove finisce il backup) - nuovi controlli: tools/check_qml.py (chiavi di traduzione, simboli JS, pagine, componenti) e qmllint nella suite - versione 0.2.0
This commit is contained in:
+75
-12
@@ -123,17 +123,74 @@ int main(int argc, char *argv[])
|
||||
check("chiave last_production_update_v1", root.contains("last_production_update_v1"));
|
||||
}
|
||||
|
||||
// --- backup / ripristino ----------------------------------------------
|
||||
// --- backup nel formato dell'app Android -------------------------------
|
||||
QString exported;
|
||||
{
|
||||
const QString backup = QDir(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation))
|
||||
.filePath("backup-test.json");
|
||||
check("export", store.exportTo(backup));
|
||||
check("clearAll", store.clearAll());
|
||||
check("dopo clearAll: vuoto", store.reservations().isEmpty() && store.customers().isEmpty());
|
||||
check("import", store.importFrom(backup));
|
||||
check("dopo import: prenotazioni ripristinate", store.reservations().size() == 1);
|
||||
check("dopo import: clienti ripristinati", store.customers().size() == 1);
|
||||
QFile::remove(backup);
|
||||
exported = store.exportBackup();
|
||||
check("export: percorso restituito", !exported.isEmpty(), exported);
|
||||
check("export: file scritto in Documenti",
|
||||
exported.contains(QStringLiteral("/Documents/")), exported);
|
||||
check("export: file esistente", QFile::exists(exported));
|
||||
|
||||
QFile f(exported);
|
||||
f.open(QIODevice::ReadOnly);
|
||||
const QJsonObject root = QJsonDocument::fromJson(f.readAll()).object();
|
||||
f.close();
|
||||
check("backup: chiave breedSettings (come l'app Android)", root.contains("breedSettings"));
|
||||
check("backup: chiave reservations", root.contains("reservations"));
|
||||
check("backup: chiave customers", root.contains("customers"));
|
||||
check("backup: nessuna chiave interna (breed_settings_v2)",
|
||||
!root.contains("breed_settings_v2"));
|
||||
check("backup: esattamente 3 chiavi", root.size() == 3);
|
||||
}
|
||||
|
||||
// backup prodotto dall'app Android (scritto a mano come lo esporta lei):
|
||||
// deve essere accettato e sostituire i dati.
|
||||
{
|
||||
const QString android = QStringLiteral(
|
||||
"{\n"
|
||||
" \"breedSettings\": [\n"
|
||||
" {\"breedId\": \"livorno\", \"hens\": [\n"
|
||||
" {\"id\": \"h9\", \"name\": \"Gina\", \"birthDate\": \"2024-03-01T00:00:00.000\", \"isLaying\": true}\n"
|
||||
" ]}\n"
|
||||
" ],\n"
|
||||
" \"reservations\": [\n"
|
||||
" {\"id\": \"r9\", \"customerName\": \"Luca\", \"breedId\": \"livorno\", \"eggsRequested\": 6,\n"
|
||||
" \"createdAt\": \"2026-10-01T08:00:00.000\", \"deliveryDate\": \"2026-10-03\", \"isDelivered\": false}\n"
|
||||
" ],\n"
|
||||
" \"customers\": [\n"
|
||||
" {\"id\": \"c9\", \"firstName\": \"Luca\", \"lastName\": \"Bianchi\", \"phoneNumber\": \"333\"}\n"
|
||||
" ]\n"
|
||||
"}\n");
|
||||
check("backup Android riconosciuto valido", store.isValidBackup(android));
|
||||
check("import del backup Android", store.importBackup(android));
|
||||
check("import: razze sostituite", store.breedSettings().size() == 1
|
||||
&& store.breedSettings().at(0).toMap().value("breedId").toString() == "livorno");
|
||||
check("import: gallina annidata letta", store.breedSettings().at(0).toMap()
|
||||
.value("hens").toList().at(0).toMap().value("name").toString() == "Gina");
|
||||
check("import: prenotazioni sostituite", store.reservations().size() == 1
|
||||
&& store.reservations().at(0).toMap().value("eggsRequested").toInt() == 6);
|
||||
check("import: clienti sostituiti", store.customers().size() == 1
|
||||
&& store.customers().at(0).toMap().value("lastName").toString() == "Bianchi");
|
||||
|
||||
// il backup Android non porta scorte ne' ultima produzione: si tengono
|
||||
check("import: magazzino preservato", !store.warehouseStock().isEmpty());
|
||||
check("import: data aggiornamento preservata",
|
||||
store.lastProductionUpdate() == "2026-10-09");
|
||||
|
||||
// rilettura da disco: l'import e' stato salvato
|
||||
DataStore reopened;
|
||||
check("import: salvato su disco", reopened.reservations().size() == 1
|
||||
&& reopened.breedSettings().at(0).toMap().value("breedId").toString() == "livorno");
|
||||
}
|
||||
|
||||
// backup senza 'customers' (le versioni vecchie non lo avevano)
|
||||
{
|
||||
const QString old = QStringLiteral("{\"breedSettings\": [], \"reservations\": []}");
|
||||
check("backup senza clienti: valido", store.isValidBackup(old));
|
||||
check("backup senza clienti: importato", store.importBackup(old));
|
||||
check("backup senza clienti: liste vuote", store.breedSettings().isEmpty()
|
||||
&& store.customers().isEmpty());
|
||||
}
|
||||
|
||||
// --- file corrotto: non deve crashare e non deve perdere i dati ---------
|
||||
@@ -147,10 +204,16 @@ int main(int argc, char *argv[])
|
||||
check("file corrotto: non crasha", true);
|
||||
check("file corrotto: stato vuoto", broken.reservations().isEmpty());
|
||||
|
||||
// il backup di un file corrotto viene rifiutato
|
||||
check("import di un file non valido rifiutato", !broken.importFrom(store.dataFilePath()));
|
||||
check("import di un JSON non valido rifiutato", !broken.importBackup("{ rotto"));
|
||||
check("import di un oggetto senza le chiavi richieste rifiutato",
|
||||
!broken.importBackup("{\"altro\": 1}"));
|
||||
check("import di un array (non oggetto) rifiutato", !broken.importBackup("[]"));
|
||||
check("import di testo vuoto rifiutato", !broken.importBackup(" "));
|
||||
check("isValidBackup su testo vuoto", !broken.isValidBackup(""));
|
||||
}
|
||||
|
||||
QFile::remove(exported);
|
||||
|
||||
qInfo().noquote() << (failures == 0 ? "\ntutti i controlli superati"
|
||||
: QString("\n%1 controlli falliti").arg(failures));
|
||||
return failures == 0 ? 0 : 1;
|
||||
|
||||
Reference in New Issue
Block a user