Refactor PVC models and update tests
- Updated the PVC models in the database and adjusted the tests accordingly to reflect the new model counts and codes. - Removed deprecated models from the JSON data for PVC systems. - Added new GLB models for "scorrevole_sf_3_ante" and "scorrevole_sf_4_ante". - Enhanced the development scripts to streamline the build process for both frontends. - Updated documentation to reflect changes in the development environment and deployment process. - Improved the styling of texture radio options for better visibility. - Fixed URL handling in the configurator to ensure proper routing and API calls.
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
/auth.json
|
||||
node_modules
|
||||
/public/build
|
||||
/public/configuratore
|
||||
/public/preventivo
|
||||
/public/fonts-manifest.dev.json
|
||||
/public/hot
|
||||
/public/storage
|
||||
|
||||
+12
-24
@@ -18,7 +18,7 @@ riassuntivo e invia le email a cliente e amministratore.
|
||||
2. `starter.js` invia `POST /api/carrello/aggiungi` (con `sistema`, `type`, dimensioni, prezzo, payload,
|
||||
screenshot PNG). Il backend crea/aggiorna un `preventivo` (stato `bozza`) identificato da un `token`
|
||||
salvato in `localStorage`.
|
||||
3. Il pulsante "Vai al preventivo" apre l'app cliente passando il token: `…/?token=XXX`.
|
||||
3. Il pulsante "Vai al preventivo" apre l'app cliente passando il token: `/preventivo/?token=XXX`.
|
||||
4. L'app cliente mostra il carrello, l'utente compila i dati e conferma → `POST /api/carrello/{token}/conferma`.
|
||||
5. Il backend crea il `cliente`, imposta lo stato a `inviato`, genera il PDF e invia le email
|
||||
(cliente con PDF allegato + notifica admin). Il preventivo è visibile nel backoffice.
|
||||
@@ -33,20 +33,14 @@ php artisan migrate --seed # crea le tabelle + utente admin
|
||||
php artisan storage:link
|
||||
php artisan serve --port=8000 # API + admin su http://localhost:8000
|
||||
|
||||
# 2. App cliente (cartella cliente/)
|
||||
cd cliente
|
||||
pnpm install
|
||||
pnpm dev # http://localhost:5199
|
||||
|
||||
# 3. Configuratore (root del repo)
|
||||
# 2. Frontend: configuratore + app cliente, compilati in public/ (dalla root del repo)
|
||||
cd ..
|
||||
pnpm dev # http://localhost:5173
|
||||
./build.sh # -> public/configuratore e public/preventivo
|
||||
```
|
||||
|
||||
Le tre porte (8000 / 5199 / 5173) sono fisse (`strictPort: true` nei rispettivi `vite.config.js`): se una è
|
||||
già occupata l'avvio fallisce con un errore esplicito invece di spostarsi silenziosamente su un'altra porta
|
||||
— evita che il configuratore e l'app cliente finiscano per caso sulla stessa porta (successo in passato,
|
||||
dato che entrambi avevano `5174` come default).
|
||||
Configuratore e app cliente sono serviti da questo backend: <http://localhost:8000/configuratore/?sistema=pvc&type=finestra_2_ante>
|
||||
e <http://localhost:8000/preventivo/>. In sviluppo `./dev.sh` (root) avvia Laravel e ricompila i frontend
|
||||
a ogni modifica. Dettagli in `../docs/PREVENTIVI_BACKOFFICE.md`.
|
||||
|
||||
### Credenziali admin (seed di default)
|
||||
- URL: <http://localhost:8000/admin>
|
||||
@@ -62,19 +56,13 @@ In produzione configurare SMTP nel `.env`.
|
||||
|---|---|
|
||||
| `DB_*` | MySQL: `127.0.0.1`, `root`, no password, `kreios_preventivi` |
|
||||
| `ADMIN_NOTIFY_EMAIL` | Email che riceve la notifica di nuovo preventivo |
|
||||
| `APP_FRONTEND_CLIENTE_URL` | URL dell'app cliente (per i link) |
|
||||
| `CORS_ALLOWED_ORIGINS` | Origini autorizzate all'API (default `*` in dev) |
|
||||
| `APP_FRONTEND_CLIENTE_URL` | URL dell'app cliente, solo se non servita da qui (default `APP_URL/preventivo`) |
|
||||
| `CORS_ALLOWED_ORIGINS` | Origini esterne autorizzate all'API (default `*`; i frontend serviti da qui non ne hanno bisogno) |
|
||||
|
||||
### Configuratore (`../src/js/starter.js`)
|
||||
`PREVENTIVI_API_BASE` è l'unico indirizzo che il configuratore deve conoscere a priori (default
|
||||
`http://localhost:8000/api`, sovrascrivibile con `window.PREVENTIVI_API_BASE` prima del bundle). L'URL
|
||||
dell'app cliente **non è hardcoded**: all'avvio il configuratore chiama `GET /api/config` e usa il
|
||||
`frontend_cliente_url` restituito da Laravel (letto da `APP_FRONTEND_CLIENTE_URL` nel `.env`) — così non c'è
|
||||
da tenere sincronizzati due URL se la porta Vite dell'app cliente cambia (es. per conflitto con altre porte
|
||||
occupate). `window.APP_CLIENTE_URL` resta come fallback locale se il backend non è raggiungibile.
|
||||
|
||||
### App cliente (`cliente/.env`)
|
||||
`VITE_API_BASE` — URL base dell'API Laravel (default `http://localhost:8000/api`).
|
||||
### Frontend
|
||||
Configuratore e app cliente chiamano l'API sulla stessa origine (`${location.origin}/api`): nessuna
|
||||
variabile da impostare. `VITE_PREVENTIVI_API_BASE` (root) / `VITE_API_BASE` (`cliente/`) servono solo per
|
||||
un'API su un altro dominio. Il link "Vai al preventivo" usa `frontend_cliente_url` da `GET /api/config`.
|
||||
|
||||
## Modello dati
|
||||
|
||||
|
||||
Vendored
-14
@@ -1,14 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/jpeg" href="/kreios-logo.jpg" />
|
||||
<title>Il tuo preventivo · Krèios</title>
|
||||
<script type="module" crossorigin src="/assets/index-CmMOSSq4.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-C_ir1rDB.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -2,6 +2,9 @@
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { api, resolveToken, resolveReturnUrl, resolveClienteToken, clearToken, formatEuro } from './api.js'
|
||||
|
||||
// Servita sotto /preventivo/: i file di public/ vanno risolti rispetto alla base della build.
|
||||
const logoUrl = `${import.meta.env.BASE_URL}kreios-logo.jpg`
|
||||
|
||||
const step = ref('cart') // cart | checkout | done
|
||||
const loading = ref(true)
|
||||
const submitting = ref(false)
|
||||
@@ -158,7 +161,7 @@ onMounted(loadCarrello)
|
||||
|
||||
<template>
|
||||
<header class="app-header">
|
||||
<img src="/kreios-logo.jpg" alt="Krèios" />
|
||||
<img :src="logoUrl" alt="Krèios" />
|
||||
<h1>Il tuo preventivo</h1>
|
||||
</header>
|
||||
|
||||
@@ -340,7 +343,7 @@ onMounted(loadCarrello)
|
||||
<!-- STEP CONFERMA -->
|
||||
<template v-else-if="step === 'done'">
|
||||
<div class="card center">
|
||||
<img class="done-logo" src="/kreios-logo.jpg" alt="Krèios" />
|
||||
<img class="done-logo" :src="logoUrl" alt="Krèios" />
|
||||
<div class="success-icon">✅</div>
|
||||
<h2>Grazie!</h2>
|
||||
<p>La tua richiesta di preventivo <b>n. {{ numeroConfermato }}</b> è stata inviata.</p>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const BASE = import.meta.env.VITE_API_BASE || 'http://localhost:8000/api'
|
||||
// L'app cliente è servita dal backend stesso (/preventivo/): l'API è sulla stessa origine.
|
||||
const BASE = import.meta.env.VITE_API_BASE || `${window.location.origin}/api`
|
||||
|
||||
async function request(path, options = {}) {
|
||||
const res = await fetch(`${BASE}${path}`, {
|
||||
|
||||
@@ -3,9 +3,11 @@ import vue from '@vitejs/plugin-vue'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
server: {
|
||||
host: true,
|
||||
port: 5199,
|
||||
strictPort: true,
|
||||
// L'app cliente è servita da Laravel sotto /preventivo/ (stessa origine dell'API):
|
||||
// la build finisce direttamente in backoffice/public/preventivo.
|
||||
base: '/preventivo/',
|
||||
build: {
|
||||
outDir: '../public/preventivo',
|
||||
emptyOutDir: true,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -4,11 +4,13 @@ return [
|
||||
// Email a cui inviare la notifica di nuovo preventivo.
|
||||
'admin_email' => env('ADMIN_NOTIFY_EMAIL'),
|
||||
|
||||
// URL base dell'app cliente (per link nelle email admin).
|
||||
'frontend_cliente_url' => env('APP_FRONTEND_CLIENTE_URL', 'http://localhost:5199'),
|
||||
// URL base dell'app cliente (per link nelle email admin). Di default è servita da questo
|
||||
// backend sotto /preventivo (build in public/preventivo, vedi routes/web.php).
|
||||
'frontend_cliente_url' => env('APP_FRONTEND_CLIENTE_URL', rtrim((string) env('APP_URL', 'http://localhost'), '/').'/preventivo'),
|
||||
|
||||
// URL del configuratore 3D (linkato dal menu del backoffice).
|
||||
'configuratore_url' => env('APP_CONFIGURATORE_URL', 'http://localhost:5173'),
|
||||
// URL del configuratore 3D (linkato dal menu del backoffice). Di default è servito da questo
|
||||
// backend sotto /configuratore/ (build in public/configuratore).
|
||||
'configuratore_url' => env('APP_CONFIGURATORE_URL', rtrim((string) env('APP_URL', 'http://localhost'), '/').'/configuratore/'),
|
||||
|
||||
// Regola base di scontistica (in %), valida per tutti i clienti salvo personalizzazione:
|
||||
// imponibile = totale parziale x (1 - 1° sconto) x (1 - 2° sconto extra).
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Modello;
|
||||
use App\Models\Sistema;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
/**
|
||||
* Scorrevoli SF PVC: i modelli 3 e 4 ante hanno ora il file 3D e vanno nel
|
||||
* configuratore (listino, regole vetro e opzioni ci sono già); 1 anta SF e parallelo
|
||||
* 1 anta escono dalla gamma (non hanno listino né opzioni proprie).
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
private const NUOVI = [
|
||||
'scorrevole_sf_3_ante' => 'SCORREVOLE 3 ANTE SF PVC - SALAMANDER',
|
||||
'scorrevole_sf_4_ante' => 'SCORREVOLE 4 ANTE SF PVC - SALAMANDER',
|
||||
];
|
||||
|
||||
private const ELIMINATI = ['scorrevole_sf_1_anta', 'scorrevole_parallelo_1_anta'];
|
||||
|
||||
/** Moduli che il 2 ante ha in più rispetto ai modelli senza configurazione 3D. */
|
||||
private const MODULI_3D = ['listino', 'maniglia', 'modello', 'vetro'];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$pvc = Sistema::where('codice', 'pvc')->first();
|
||||
if (! $pvc) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (self::NUOVI as $codice => $titolo) {
|
||||
$modello = $pvc->modelli()->where('codice', $codice)->first();
|
||||
$modello?->update([
|
||||
'attivo' => true,
|
||||
'cartella' => $codice,
|
||||
'file_modello' => "{$codice}.glb",
|
||||
'cartella_texture' => 'finestra_2_ante',
|
||||
'titolo' => $modello->titolo ?: $titolo,
|
||||
'moduli' => array_values(array_unique([...self::MODULI_3D, ...($modello->moduli ?? [])])),
|
||||
]);
|
||||
}
|
||||
|
||||
// Una alla volta: l'evento deleted rimuove anche l'icona dal disco.
|
||||
$pvc->modelli()->whereIn('codice', self::ELIMINATI)->get()->each->delete();
|
||||
|
||||
$this->dopoIl2Ante($pvc);
|
||||
}
|
||||
|
||||
/** Attivandosi finirebbero in fondo agli attivi: li mette subito dopo lo scorrevole SF 2 ante. */
|
||||
private function dopoIl2Ante(Sistema $pvc): void
|
||||
{
|
||||
$codici = $pvc->modelli()->orderBy('ordine')->orderBy('id')->pluck('codice')
|
||||
->diff(array_keys(self::NUOVI))->values()->all();
|
||||
$posizione = array_search('scorrevole_sf_2_ante', $codici, true);
|
||||
if ($posizione !== false) {
|
||||
array_splice($codici, $posizione + 1, 0, array_keys(self::NUOVI));
|
||||
}
|
||||
|
||||
foreach ($codici as $i => $codice) {
|
||||
$pvc->modelli()->where('codice', $codice)->update(['ordine' => $i + 1]);
|
||||
}
|
||||
|
||||
Modello::normalizzaOrdine($pvc->id);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// I modelli eliminati non vengono ricreati: si recuperano con il CatalogoSeeder
|
||||
// da una versione precedente di database/seeders/data/modelli_pvc.php.
|
||||
$pvc = Sistema::where('codice', 'pvc')->first();
|
||||
if (! $pvc) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (array_keys(self::NUOVI) as $codice) {
|
||||
$modello = $pvc->modelli()->where('codice', $codice)->first();
|
||||
$modello?->update([
|
||||
'attivo' => false,
|
||||
'cartella' => null,
|
||||
'file_modello' => null,
|
||||
'cartella_texture' => null,
|
||||
'moduli' => array_values(array_diff($modello->moduli ?? [], self::MODULI_3D)),
|
||||
]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -107,8 +107,6 @@ return [
|
||||
'scorrevole_hst_2_ante' => ['ALZ2', ['finitura_esterna', 'apertura']],
|
||||
'scorrevole_hst_4_ante' => ['ALZ4', ['finitura_esterna', 'apertura']],
|
||||
// Non presenti nella specifica vetri: nessuna variazione di prezzo per il vetro.
|
||||
'scorrevole_sf_1_anta' => [null, ['finitura_esterna', 'apertura']],
|
||||
'scorrevole_parallelo_1_anta' => [null, ['finitura_esterna', 'apertura']],
|
||||
'scorrevole_sf_2_ante' => ['SC2', ['finitura_esterna', 'apertura']],
|
||||
'scorrevole_sf_3_ante' => ['SC3', ['finitura_esterna', 'apertura']],
|
||||
'scorrevole_sf_4_ante' => ['SC4', ['finitura_esterna', 'apertura']],
|
||||
|
||||
@@ -636,9 +636,9 @@ return [
|
||||
'portafinestra_3_ante' => 'PORTAFINESTRA 3 ANTE PVC - SALAMANDER BE 82',
|
||||
'scorrevole_hst_1_anta' => 'SCORREVOLE 1 ANTA HTS PVC - SALAMANDER',
|
||||
'scorrevole_hst_2_ante' => 'SCORREVOLE 2 ANTE HTS PVC - SALAMANDER',
|
||||
'scorrevole_parallelo_1_anta' => 'SCORREVOLE PARALLELO 1 ANTA PVC - SALAMANDER',
|
||||
'scorrevole_sf_1_anta' => 'SCORREVOLE 1 ANTA SF PVC - SALAMANDER',
|
||||
'scorrevole_sf_2_ante' => 'SCORREVOLE 2 ANTE SF PVC - SALAMANDER',
|
||||
'scorrevole_sf_3_ante' => 'SCORREVOLE 3 ANTE SF PVC - SALAMANDER',
|
||||
'scorrevole_sf_4_ante' => 'SCORREVOLE 4 ANTE SF PVC - SALAMANDER',
|
||||
'scuretto_base' => 'SCURETTO BASE PVC - SALAMANDER',
|
||||
'scuretto_pannello_alessandrite' => 'SCURETTO ALESSANDRITE PVC - SALAMANDER',
|
||||
'scuretto_pannello_malachite' => 'SCURETTO MALACHITE PVC - SALAMANDER',
|
||||
|
||||
@@ -171,17 +171,6 @@ return [
|
||||
'cartella_texture' => null,
|
||||
'moduli' => null,
|
||||
],
|
||||
[
|
||||
'codice' => 'scorrevole_sf_1_anta',
|
||||
'nome' => 'Scorrevole SF 1 Anta',
|
||||
'descrizione' => null,
|
||||
'attivo' => true,
|
||||
'cartella' => 'scorrevole_sf_1_anta',
|
||||
'file_modello' => 'scorrevole_sf_1_anta.glb',
|
||||
'categoria' => 'scorrevoli',
|
||||
'cartella_texture' => 'finestra_2_ante',
|
||||
'moduli' => ['cerniere', 'listino', 'maniglia', 'modello', 'vetro'],
|
||||
],
|
||||
[
|
||||
'codice' => 'scorrevole_sf_2_ante',
|
||||
'nome' => 'Scorrevole SF 2 Ante',
|
||||
@@ -197,23 +186,23 @@ return [
|
||||
'codice' => 'scorrevole_sf_3_ante',
|
||||
'nome' => 'Scorrevole SF 3 Ante',
|
||||
'descrizione' => 'SCORREVOLE IN LINEA A 3 ANTE',
|
||||
'attivo' => false,
|
||||
'cartella' => null,
|
||||
'file_modello' => null,
|
||||
'attivo' => true,
|
||||
'cartella' => 'scorrevole_sf_3_ante',
|
||||
'file_modello' => 'scorrevole_sf_3_ante.glb',
|
||||
'categoria' => 'scorrevoli',
|
||||
'cartella_texture' => null,
|
||||
'moduli' => null,
|
||||
'cartella_texture' => 'finestra_2_ante',
|
||||
'moduli' => ['cerniere', 'listino', 'maniglia', 'modello', 'vetro'],
|
||||
],
|
||||
[
|
||||
'codice' => 'scorrevole_sf_4_ante',
|
||||
'nome' => 'Scorrevole SF 4 Ante',
|
||||
'descrizione' => 'SCORREVOLE IN LINEA A 4 ANTE',
|
||||
'attivo' => false,
|
||||
'cartella' => null,
|
||||
'file_modello' => null,
|
||||
'attivo' => true,
|
||||
'cartella' => 'scorrevole_sf_4_ante',
|
||||
'file_modello' => 'scorrevole_sf_4_ante.glb',
|
||||
'categoria' => 'scorrevoli',
|
||||
'cartella_texture' => null,
|
||||
'moduli' => null,
|
||||
'cartella_texture' => 'finestra_2_ante',
|
||||
'moduli' => ['cerniere', 'listino', 'maniglia', 'modello', 'vetro'],
|
||||
],
|
||||
[
|
||||
'codice' => 'traslante_scorrevole_1_anta',
|
||||
@@ -237,17 +226,6 @@ return [
|
||||
'cartella_texture' => null,
|
||||
'moduli' => null,
|
||||
],
|
||||
[
|
||||
'codice' => 'scorrevole_parallelo_1_anta',
|
||||
'nome' => 'Scorrevole Parallelo 1 Anta',
|
||||
'descrizione' => null,
|
||||
'attivo' => true,
|
||||
'cartella' => 'scorrevole_parallelo_1_anta',
|
||||
'file_modello' => 'scorrevole_parallelo_1_anta.glb',
|
||||
'categoria' => 'scorrevoli',
|
||||
'cartella_texture' => 'finestra_2_ante',
|
||||
'moduli' => ['cerniere', 'listino', 'maniglia', 'modello', 'vetro'],
|
||||
],
|
||||
[
|
||||
'codice' => 'bilico',
|
||||
'nome' => 'Bilico Orizzontale',
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use App\Models\Preventivo;
|
||||
use App\Support\PreventivoPdf;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
@@ -20,3 +21,21 @@ Route::get('/admin/preventivi/{preventivo}/pdf', function (Preventivo $preventiv
|
||||
'preventivo-'.($preventivo->numero ?? $preventivo->id).'.pdf'
|
||||
);
|
||||
})->middleware(['auth'])->name('preventivi.pdf.show');
|
||||
|
||||
// Configuratore 3D e app cliente (preventivo) sono build Vite statiche dentro public/ (vedi build.sh):
|
||||
// i file (js, css, assets) li serve direttamente il web server, qui gestiamo solo l'index.
|
||||
// Lo slash finale è obbligatorio perché i path runtime sono relativi (./assets/...).
|
||||
foreach (['configuratore', 'preventivo'] as $frontend) {
|
||||
Route::get($frontend, function (Request $request) use ($frontend) {
|
||||
if (! str_ends_with($request->getPathInfo(), '/')) {
|
||||
$query = $request->getQueryString();
|
||||
|
||||
return redirect('/'.$frontend.'/'.($query ? '?'.$query : ''), 301);
|
||||
}
|
||||
|
||||
$index = public_path($frontend.'/index.html');
|
||||
abort_unless(is_file($index), 404, "Build di {$frontend} assente: eseguire build.sh.");
|
||||
|
||||
return response()->file($index, ['Cache-Control' => 'no-cache']);
|
||||
})->name($frontend);
|
||||
}
|
||||
|
||||
@@ -62,12 +62,9 @@ class CatalogoAdminTest extends TestCase
|
||||
{
|
||||
$codici = fn () => Modello::orderBy('ordine')->pluck('codice')->all();
|
||||
|
||||
// Ordine di OrdineSerramenti per gli attivi, poi i 4 disattivi nello stesso ordine.
|
||||
// Ordine di OrdineSerramenti per gli attivi, poi i 2 disattivi nello stesso ordine.
|
||||
$this->assertSame(['finestra_1_anta', 'finestra_2_ante', 'finestra_3_ante'], array_slice($codici(), 0, 3));
|
||||
$this->assertSame(
|
||||
['scorrevole_hst_4_ante', 'scorrevole_sf_3_ante', 'scorrevole_sf_4_ante', 'traslante_scorrevole_1_anta_f'],
|
||||
array_slice($codici(), -4)
|
||||
);
|
||||
$this->assertSame(['scorrevole_hst_4_ante', 'traslante_scorrevole_1_anta_f'], array_slice($codici(), -2));
|
||||
|
||||
// Disattivando un modello passa nel gruppo in fondo (dopo i 25 attivi rimasti),
|
||||
// mantenendo l'ordine relativo con gli altri disattivi; riattivandolo resta
|
||||
@@ -81,7 +78,7 @@ class CatalogoAdminTest extends TestCase
|
||||
$this->assertSame(['celino', 'bilico', 'scorrevole_hst_4_ante'], array_slice($codici(), 24, 3));
|
||||
|
||||
// In tabella i disattivi stanno in fondo anche se l'ordine salvato li metterebbe in mezzo.
|
||||
Modello::where('codice', 'scorrevole_sf_3_ante')->update(['ordine' => 2]);
|
||||
Modello::where('codice', 'scorrevole_hst_4_ante')->update(['ordine' => 2]);
|
||||
Livewire::test(ListModelli::class)
|
||||
->set('tableRecordsPerPage', 50)
|
||||
->assertCanSeeTableRecords(
|
||||
|
||||
@@ -26,14 +26,14 @@ class CatalogoApiTest extends TestCase
|
||||
$this->seed(CatalogoSeeder::class);
|
||||
|
||||
$pvc = Sistema::where('codice', 'pvc')->firstOrFail();
|
||||
$this->assertSame(30, $pvc->modelli()->count());
|
||||
$this->assertSame(28, $pvc->modelli()->count());
|
||||
|
||||
$finestra = $pvc->modelli()->where('codice', 'finestra_1_anta')->firstOrFail();
|
||||
$this->assertSame('FINESTRA 1 ANTA, A/R', $finestra->descrizione);
|
||||
Storage::disk('public')->assertExists($finestra->icona);
|
||||
|
||||
// Modelli presenti solo nell'Excel: senza asset 3D, quindi disattivi.
|
||||
$this->assertFalse($pvc->modelli()->where('codice', 'scorrevole_sf_3_ante')->value('attivo'));
|
||||
$this->assertFalse($pvc->modelli()->where('codice', 'scorrevole_hst_4_ante')->value('attivo'));
|
||||
}
|
||||
|
||||
public function test_il_seeder_non_sovrascrive_le_modifiche_admin(): void
|
||||
@@ -44,7 +44,7 @@ class CatalogoApiTest extends TestCase
|
||||
$this->seed(CatalogoSeeder::class);
|
||||
|
||||
$this->assertSame('Bilico modificato', Modello::where('codice', 'bilico')->value('nome'));
|
||||
$this->assertSame(30, Modello::count());
|
||||
$this->assertSame(28, Modello::count());
|
||||
}
|
||||
|
||||
public function test_api_sistemi_espone_solo_modelli_attivi_e_con_listino_in_ordine(): void
|
||||
@@ -63,7 +63,7 @@ class CatalogoApiTest extends TestCase
|
||||
$this->assertSame(25, $modelli->count());
|
||||
$this->assertNotContains('bilico', $modelli->pluck('id'));
|
||||
$this->assertSame('finestra_1_anta', $modelli->first()['id']);
|
||||
$this->assertNotContains('scorrevole_sf_3_ante', $modelli->pluck('id'));
|
||||
$this->assertNotContains('scorrevole_hst_4_ante', $modelli->pluck('id'));
|
||||
$this->assertStringEndsWith('/storage/modelli/icone/pvc/finestra_1_anta.jpg', $modelli->first()['icona']);
|
||||
$this->assertSame('finestra_1_anta.glb', $modelli->first()['modello']);
|
||||
}
|
||||
|
||||
@@ -230,6 +230,6 @@ class ImportazioneListiniTest extends TestCase
|
||||
]);
|
||||
|
||||
// Modello disattivo (senza asset 3D): non esposto.
|
||||
$this->getJson('/api/sistemi/pvc/modelli/scorrevole_sf_3_ante/listino')->assertNotFound();
|
||||
$this->getJson('/api/sistemi/pvc/modelli/scorrevole_hst_4_ante/listino')->assertNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user