withoutVite(); Storage::fake('public'); $this->seed(RolesAndPermissionsSeeder::class); Setting::firstOrCreate([], ['congregazione_nome' => 'Congregazione di prova']); AnnoTeocratico::create(['label' => '2026-2027', 'start_date' => '2026-09-01', 'end_date' => '2027-08-31']); $this->admin = User::create(['name' => 'Admin', 'email' => 'admin@example.test', 'password' => 'password-di-prova']); $this->admin->assignRole('amministratore'); } private function assegna(Proclamatore $proclamatore, Territorio $territorio) { return Livewire::actingAs($this->admin)->test(Assegna::class) ->set('territorio_id', $territorio->id) ->set('proclamatore_id', $proclamatore->id) ->set('assigned_at', now()->format('Y-m-d')) ->call('save'); } private function territorioConPdf(string $numero = '7'): Territorio { Storage::disk('public')->put("territori-pdf/t{$numero}.pdf", '%PDF-1.4'); return Territorio::create(['numero' => $numero, 'attivo' => true, 'pdf_path' => "territori-pdf/t{$numero}.pdf"]); } private function mario(): Proclamatore { return Proclamatore::create(['nome' => 'Mario', 'cognome' => 'Rossi', 'attivo' => true]); } // ─── Niente contatti nei proclamatori ─────────────────────── public function test_i_proclamatori_non_hanno_ne_email_ne_telefono(): void { $this->assertFalse(Schema::hasColumn('proclamatori', 'email')); $this->assertFalse(Schema::hasColumn('proclamatori', 'telefono')); $this->actingAs($this->admin)->get(route('proclamatori.create')) ->assertOk() ->assertDontSee('id="telefono"', false) ->assertDontSee('id="email"', false); Livewire::actingAs($this->admin)->test(ProclamatoreCreate::class) ->set('nome', 'Anna')->set('cognome', 'Verdi') ->call('save') ->assertHasNoErrors(); $this->assertSame(['Verdi Anna'], Proclamatore::all()->map->nome_completo->all()); } public function test_un_xml_vecchio_con_email_e_telefono_si_importa_ignorandoli(): void { $this->actingAs($this->admin); $this->mario(); $xml = (new XmlExchange())->currentXmlBackup(); $vecchio = str_replace('', 'm@example.test3331234567', $xml); $this->assertArrayNotHasKey('error', (new XmlExchange())->importXmlFromContent($vecchio)); $this->assertSame('Rossi Mario', Proclamatore::sole()->nome_completo); $this->assertStringNotContainsString('', (new XmlExchange())->currentXmlBackup()); } // ─── Dopo l'assegnazione ──────────────────────────────────── public function test_dopo_l_assegnazione_si_sceglie_tra_copia_link_e_condividi(): void { $pagina = $this->assegna($this->mario(), $this->territorioConPdf()) ->assertHasNoErrors() ->assertNoRedirect(); $assegnazione = Assegnazione::sole(); $this->assertTrue($assegnazione->link_da_inviare); $this->assertFalse($assegnazione->link_sent); $link = $assegnazione->shortPdfUrl(); $pagina->assertSet('invioId', $assegnazione->id) ->assertSee('Territorio N° 7 assegnato a Rossi Mario') ->assertSee('Come vuoi mandare il link della piantina?') ->assertSee($link) ->assertSee('Copia link') ->assertSee('Condividi…') // Il messaggio per "Condividi", con il link. ->assertSeeHtml('data-messaggio="Ciao Mario, ti è stato assegnato il territorio N° 7. Ecco la piantina: ' . e($link) . '"') ->assertDontSee('wa.me', false) ->assertDontSee('WhatsApp') ->assertSee('Hai inviato il link?'); } public function test_si_dice_inviato_solo_dopo_aver_scelto_un_canale(): void { $mario = $this->mario(); $this->assegna($mario, $this->territorioConPdf()) ->call('concludiInvio', true) ->assertNoRedirect() ->assertSet('erroreInvio', 'Scegli prima come mandare il link.') ->call('canale', 'condividi') ->call('concludiInvio', true) ->assertRedirect(route('assegnazioni.assegna')); $assegnazione = Assegnazione::sole(); $this->assertTrue($assegnazione->link_sent); $this->assertFalse($assegnazione->link_da_inviare); $this->assertSame('condividi', $assegnazione->link_canale); $log = Activity::where('description', 'link_inviato')->sole(); $this->assertSame('condividi', $log->properties['canale']); $this->assertSame($mario->id, $log->properties['proclamatore_id']); $this->assertStringNotContainsString('Rossi', json_encode($log->properties)); } public function test_whatsapp_ed_email_non_sono_piu_canali(): void { $this->assegna($this->mario(), $this->territorioConPdf()) ->call('canale', 'whatsapp') ->assertSet('canaleUsato', null) ->call('canale', 'email') ->assertSet('canaleUsato', null) ->call('canale', 'copia') ->assertSet('canaleUsato', 'copia'); $this->assertSame(['copia', 'condividi'], Assegnazione::CANALI_ATTIVI); } public function test_se_non_si_conclude_l_invio_l_assegnazione_lo_segnala(): void { $this->assegna($this->mario(), $this->territorioConPdf()); $assegnazione = Assegnazione::sole(); // La pagina viene chiusa senza rispondere: l'invio è perso, l'avviso resta // nell'elenco, e "Invia link" chiede alla pagina di riaprirlo. Livewire::withoutLazyLoading()->actingAs($this->admin)->test(ElencoAssegnati::class) ->assertSee('Link ancora da inviare') ->assertSeeHtml("\$dispatch('apri-invio', { assegnazioneId: {$assegnazione->id} })"); Livewire::actingAs($this->admin)->test(Assegna::class) ->assertSet('invioId', null) ->dispatch('apri-invio', assegnazioneId: $assegnazione->id) ->assertSee('Hai inviato il link?') ->call('concludiInvio', false) ->assertRedirect(route('assegnazioni.assegna')); // "No, non ancora": la procedura è finita, ma il link resta da inviare. $this->assertTrue($assegnazione->fresh()->link_in_sospeso); $this->get(route('territori.show', $assegnazione->territorio_id)) ->assertSee('Il link della piantina è ancora da inviare'); // Segnato come inviato dall'elenco: l'avviso sparisce. Livewire::withoutLazyLoading()->actingAs($this->admin)->test(ElencoAssegnati::class) ->call('toggleLinkSent', $assegnazione->id) ->assertDontSee('Link ancora da inviare'); $this->assertFalse($assegnazione->fresh()->link_in_sospeso); } public function test_condividere_dall_elenco_segna_il_link_come_inviato(): void { $this->assegna($this->mario(), $this->territorioConPdf()); $assegnazione = Assegnazione::sole(); Livewire::withoutLazyLoading()->actingAs($this->admin)->test(ElencoAssegnati::class) ->assertSeeHtml('data-id="' . $assegnazione->id . '"') ->assertDontSee('wa.me', false) ->call('segnaCondiviso', $assegnazione->id) ->assertDontSee('Link ancora da inviare'); $this->assertTrue($assegnazione->fresh()->link_sent); $this->assertSame('condividi', $assegnazione->fresh()->link_canale); } public function test_dalla_scheda_territorio_si_riprende_l_invio(): void { $this->assegna($this->mario(), $this->territorioConPdf()); $assegnazione = Assegnazione::sole(); $this->actingAs($this->admin) ->get(route('assegnazioni.assegna', ['invia' => $assegnazione->id])) ->assertOk() ->assertSee('Hai inviato il link?'); } public function test_senza_pdf_non_c_e_un_link_da_inviare(): void { $territorio = Territorio::create(['numero' => '9', 'attivo' => true]); $this->assegna($this->mario(), $territorio) ->assertSee('non ha un PDF') ->call('concludiInvio', false); $this->assertFalse(Assegnazione::sole()->link_in_sospeso); } public function test_le_assegnazioni_gia_esistenti_non_vengono_segnalate(): void { $vecchia = Assegnazione::create([ 'territorio_id' => $this->territorioConPdf()->id, 'proclamatore_id' => $this->mario()->id, 'anno_teocratico_id' => AnnoTeocratico::sole()->id, 'assigned_at' => now(), 'created_by' => $this->admin->id, ]); $this->assertFalse($vecchia->fresh()->link_in_sospeso); } public function test_l_xml_porta_con_se_lo_stato_dell_invio(): void { $this->actingAs($this->admin); $this->assegna($this->mario(), $this->territorioConPdf())->call('canale', 'copia')->call('concludiInvio', true); $xml = (new XmlExchange())->currentXmlBackup(); $this->assertArrayNotHasKey('error', (new XmlExchange())->importXmlFromContent($xml)); $assegnazione = Assegnazione::sole(); $this->assertTrue($assegnazione->link_sent); $this->assertFalse($assegnazione->link_da_inviare); $this->assertSame('copia', $assegnazione->link_canale); } // ─── Nuovo territorio dal designer ────────────────────────── public function test_nuovo_territorio_porta_al_designer_delle_piantine(): void { $this->actingAs($this->admin) ->get(route('territori.index')) ->assertSee(route('piantine.editor', ['nuovo' => 1]), false); } public function test_dall_elenco_degli_assegnati_si_va_al_rientro(): void { $this->assegna($this->mario(), $this->territorioConPdf('7')); $a = Assegnazione::sole(); Livewire::withoutLazyLoading()->actingAs($this->admin)->test(ElencoAssegnati::class) ->assertSee('Rientro') // Relativo: l'elenco ha un peso massimo per riga (AssegnaPrestazioniTest). ->assertSee('href="' . route('assegnazioni.rientra', $a, false) . '"', false); } }