# Collaudo dell'integrazione delle applicazioni

> Le verifiche in modalità account ottengono ora attestazioni di identità di breve durata. Uno stato negativo dell'acquisto in Launch costituisce soltanto una prova relativa all'acquisto, non una prova del rifiuto dell'esecuzione da parte di Licentivo. Per dimostrare il comportamento in esecuzione è necessaria la verifica con l'SDK ufficiale; non sono implicate distribuzioni in produzione o pubblicazioni dell'SDK. Consultare i [limiti dell'account](/it/launch-documents/account-purchase-boundary/).

Esistono due livelli di prova separati: controlli automatici locali controllati e verifiche esterne nella sandbox del commerciante. Un sostituto di test, una lettura riuscita del catalogo, una configurazione generata o una verifica dello stato superata non dimostrano mai un pagamento reale, il rilascio di una licenza o un'attivazione. La configurazione dei servizi esterni è stata esplicitamente rinviata per questa iterazione di sviluppo.

## Controlli automatici locali

Eseguire dalla directory radice del repository:

```powershell
go test ./...
go vet ./...
node --check internal/httpapi/web/app.js
node --check internal/httpapi/web/integration.js
node --check internal/httpapi/web/integration-prompts.js
node --test scripts/integration-prompts.test.mjs scripts/integration-state.test.mjs
python scripts/test_acceptance.py
./scripts/test-mysql.ps1
```

Lo strumento ausiliario MySQL crea un nuovo server isolato e database in `.cache`; non deve essere indirizzato a un database di clienti. Un semplice `go test ./...` salta gli scenari del database se non vengono forniti i DSN isolati. I test e le compilazioni dell'SDK/dei pacchetti sono descritti in [integration-packages.md](/it/launch-documents/integration-packages/). Conservare l'output dei test e le versioni degli strumenti con il registro della release.

La matrice locale include autenticazione, verifica condizionale dell'email, titolarità di prodotto/ambiente, stati in sospeso/scaduti/sospesi, riproduzione degli eventi di pagamento, riconciliazione delle licenze, rinnovi/rimborsi, cambio di account, persistenza protetta delle sessioni e decisioni di ripiego offline. I test del ciclo di vita usano runtime controllati; la verifica crittografica effettiva in esecuzione rimane responsabilità dell'SDK ufficiale e viene esercitata separatamente prima della release.

Per **Strumenti operativi → Integrazione rapida con IA**, verificare tutte le nove opzioni dei linguaggi, la selezione di piattaforma/progetto/funzionalità, una bozza non configurata e un prompt generato da una configurazione pubblica convalidata. Confrontare copia e download con il prompt visibile e verificare che il cambio di prodotto o ambiente non conservi una precedente configurazione convalidata. I prompt devono escludere sessioni, password, credenziali di esecuzione di licenze/dispositivi e chiavi amministrative; la generazione o la copia di un prompt non deve chiamare servizi di IA. Il comando di test Node del bundle sorgente riportato sopra verifica il generatore puro. Un prompt generato, o il codice successivamente prodotto da uno strumento di IA, richiede comunque i test del linguaggio e i passaggi di collaudo esterno indicati di seguito.

## Preparare il collaudo nella sandbox esterna

1. Distribuire un'istanza di test Launch dedicata con un'origine HTTPS raggiungibile e i webhook del fornitore. Mantenere disabilitate le vendite live.
2. Configurare le credenziali sandbox di **un solo** fornitore di pagamento e una connessione Licentivo in lettura/scrittura. I record della sandbox di pagamento sono isolati, ma usano comunque il servizio Licentivo configurato e possono creare licenze di test/record di dispositivi reali. Usare un prodotto/una politica di test dedicati e clienti di test.
3. Pubblicare un piano sandbox e usare **Integrazione del programma** per esportare `launch-config.json` e il file `product.json` convalidato in `.local/acceptance/`.
4. Installare localmente soltanto il pacchetto Python Launch revisionato: `python -m pip install ./sdk/python`, oppure installarne il wheel. La sua implementazione SDK privata è inclusa.
5. Usare una funzionalità di test non a consumo come `export`. `--activate` avvia l'SDK ufficiale, chiama `refresh_online()` in modo sincrono, richiede uno stato online attivo e invoca la sua API per le operazioni protette. Una sola autorizzazione offline in cache non può superare questa verifica; questa verifica non esercita la misurazione dei consumi.

Le credenziali vengono richieste senza visualizzarle. L'automazione può fornire `LAUNCH_ACCEPTANCE_EMAIL` e `LAUNCH_ACCEPTANCE_PASSWORD` nell'ambiente privato del processo. Non inserire password negli argomenti dei comandi, nei report, negli screenshot o nei file inclusi nei commit. Lo strumento revoca la propria sessione desktop temporanea dopo ogni verifica autenticata, ma non disattiva i dispositivi durante l'uscita ordinaria.

```powershell
python scripts/acceptance.py preflight --config .local/acceptance/launch-config.json --report .local/acceptance/01-preflight.json
python scripts/acceptance.py verify --config .local/acceptance/launch-config.json --expect not_purchased --report .local/acceptance/02-no-purchase.json
```

Lo strumento rifiuta configurazioni dell'ambiente live, HTTP non su loopback, reindirizzamenti con credenziali, prodotti non corrispondenti e configurazioni pubbliche contenenti segreti di esecuzione. Prima di effettuare richieste, rifiuta le asserzioni di attivazione/ordine al di fuori di `verify` e le opzioni di creazione del checkout al di fuori di `checkout`. I report esistenti non vengono mai sovrascritti. I report contengono prove consentite da un elenco esplicito, non risposte grezze, token di accesso o chiavi di licenza. Un server o SDK mancante produce una verifica fallita, non un successo artificiale.

Le verifiche locali del commerciante usano `scope: local_sandbox_probe` e `licensing_scope: not_called`. `verify --activate` contatta il servizio ufficiale esterno di licenze anche quando il commerciante opera su localhost; tale combinazione viene registrata come `local_merchant_external_licensing_probe` con `licensing_scope: official_external_service`.

## Primo pagamento e attivazione

Creare un checkout di test sul sito del commerciante oppure crearne uno con un UUID stabile dell'operazione:

```powershell
$operation = [guid]::NewGuid().ToString()
python scripts/acceptance.py checkout --config .local/acceptance/launch-config.json --provider stripe --plan-version-id PLAN_VERSION_UUID --operation-id $operation --report .local/acceptance/03-checkout.json
```

Sostituire il fornitore e la versione del piano con il proprio piano sandbox pubblicato. Conservare e riutilizzare lo stesso UUID dell'operazione quando si riprova una creazione di checkout dall'esito incerto. Lo strumento stampa l'ID dell'ordine. Completare l'ordine di cui si è titolari nel centro account del commerciante usando il checkout sandbox ufficiale del fornitore. Le interazioni con l'interfaccia del fornitore non vengono intenzionalmente simulate dalla verifica.

Dopo la conferma del pagamento da parte del fornitore e la ricezione del webhook:

```powershell
python scripts/acceptance.py verify --config .local/acceptance/launch-config.json --order-id ORDER_UUID --expect-order paid --expect active --activate --product-config .local/acceptance/product.json --feature export --report .local/acceptance/04-activation.json
```

Verifica l'account autenticato, l'ordine sandbox di cui si è titolari, il diritto, la corrispondenza tra credenziali e prodotto e un'effettiva operazione protetta dell'SDK ufficiale. Un'autorizzazione in sospeso viene ritentata al massimo cinque volte entro una finestra limitata (30 secondi per impostazione predefinita, massimo 120), rispettando `Retry-After`. Un errore di autorizzazione inatteso viene registrato senza esporre il testo grezzo dell'errore dell'SDK.

## Matrice di collaudo del ciclo di vita

Per ogni coppia linguaggio/sistema operativo rilasciata, salvare un record datato con revisione del sorgente, versioni di Launch/client/SDK, ambiente del fornitore, etichetta anonimizzata del cliente, ID degli ordini, risultato atteso, risultato osservato e nome del file del report pertinente. Contrassegnare le righe non eseguite come **non eseguite**. Non considerare superata l'intera matrice sulla base della sola verifica del primo pagamento.

| Scenario | Procedura | Prove richieste |
| --- | --- | --- |
| Registrazione / verifica | Registrarsi senza acquistare; ripetere con la verifica abilitata e disabilitata | La verifica disabilitata non blocca; la verifica abilitata produce `EMAIL_VERIFICATION_REQUIRED` fino al completamento |
| Nessun acquisto | Eseguire `verify --expect not_purchased` | Credenziale rifiutata; nessuna operazione protetta viene eseguita |
| Primo acquisto | Completare il pagamento sandbox, quindi eseguire la verifica di attivazione | Il fornitore conferma il pagamento; un diritto pagato, una licenza sincronizzata, operazione SDK riuscita |
| Riavvio | Chiudere l'esempio del linguaggio scelto con l'accesso ricordato, avviare un nuovo processo e ripristinare | Nessuna richiesta di password; stessa cache account/prodotto e autorizzazione firmata valida |
| Avvio offline | Dopo un'attivazione riuscita con accesso ricordato, disabilitare la rete per quel processo/computer di test e riavviare | L'autorizzazione firmata in cache consente soltanto le operazioni ammesse dalla politica; le politiche che vietano l'uso offline o flottanti rifiutano l'avvio |
| Scadenza offline / arretramento dell'orologio | Usare una politica di test di breve durata e un computer di test eliminabile | L'SDK rifiuta lo stato scaduto/con orologio arretrato; il callback della funzionalità non viene eseguito |
| Rinnovo / upgrade | Acquistare un rinnovo o un upgrade con preventivo nel negozio sandbox | Ordine/copertura corretti; nuova validità e nuove funzionalità visibili dopo la sincronizzazione e l'aggiornamento dell'SDK |
| Rimborso | Richiedere/approvare un rimborso sandbox completo; attendere la conferma del fornitore | Il rimborso del fornitore e la copertura locale corrispondono; `verify --expect suspended` oppure `--expect expired` secondo il caso; l'altra copertura pagata rimane utilizzabile |
| Disconnessione / cambio di account | Disconnettere A, accedere come B senza un acquisto; riavviare e verificare il comportamento | Sessione/cache salvate di A rimosse; B non può usare la licenza, i dispositivi o le funzionalità di A |
| Isolamento di prodotto / ambiente | Usare un altro prodotto e cambiare separatamente le configurazioni sandbox/live | Le credenziali e le cache non possono attraversare gli ambiti di identità; la verifica esterna stessa rifiuta live |
| Limite di dispositivi raggiunto / rilascio | Attivare sul numero massimo di dispositivi di test distinti consentito dalla politica; tentare un dispositivo aggiuntivo, quindi rilasciarne esplicitamente uno | L'SDK rifiuta il dispositivo in eccesso e consente la sostituzione dopo il rilascio confermato; la chiusura ordinaria non consuma la quota di rilascio |
| Ripristino | Riavviare Launch durante un rilascio in sospeso e riprodurre un webhook sandbox firmato | Una sola copertura dell'ordine/licenza, riconciliazione finale; nessun checkout o addebito duplicato |

Gli effetti di rimborsi e sospensioni su un'autorizzazione offline già emessa rimangono vincolati alla politica offline firmata dell'SDK ufficiale. Non viene garantita una revoca immediata durante la disconnessione dalla rete. Un'interruzione prolungata di Launch alla scadenza del contratto può ritardare la sospensione a monte; consultare le [limitazioni del contratto](/it/launch-documents/licentivo-contract/).

## Completamento e prove conservate

Ogni report di verifica imposta deliberatamente `acceptance_complete: false`: registra soltanto i controlli effettivamente eseguiti in quella chiamata. Esaminare la matrice e i record del fornitore prima di accettare una release. Configurare successivamente i servizi esterni e riprendere i comandi precedenti; non sostituire i risultati mancanti con un indicatore di successo né abilitare le vendite live soltanto perché i test locali sono superati.
