Publication initiale de RelaisSMS : documentation et sources nettoyees
This commit is contained in:
@@ -0,0 +1,440 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Contact;
|
||||
use App\Models\ContactGroup;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ContactManagementTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_authenticated_user_can_create_group_and_local_contact(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user)
|
||||
->post('/contact-groups', [
|
||||
'name' => 'Benevoles',
|
||||
'description' => 'Equipe locale',
|
||||
'is_favorite' => '1',
|
||||
])
|
||||
->assertRedirect('/contacts');
|
||||
|
||||
$group = ContactGroup::query()->where('name', 'Benevoles')->firstOrFail();
|
||||
|
||||
$response = $this->actingAs($user)
|
||||
->post('/contacts', [
|
||||
'first_name' => 'Marie',
|
||||
'last_name' => 'Durand',
|
||||
'organization' => 'AFPMA',
|
||||
'email' => 'marie@example.test',
|
||||
'raw_phone_number' => '06 11 11 00 03',
|
||||
'phone_label' => 'Mobile',
|
||||
'group_ids' => [$group->id],
|
||||
'sms_opt_out' => '1',
|
||||
'is_favorite' => '1',
|
||||
]);
|
||||
|
||||
$contact = Contact::query()->where('email', 'marie@example.test')->firstOrFail();
|
||||
|
||||
$response->assertRedirect(route('contacts.show', $contact));
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'source' => 'local',
|
||||
'sms_opt_out' => true,
|
||||
'is_favorite' => true,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('contact_contact_group', [
|
||||
'contact_id' => $contact->id,
|
||||
'contact_group_id' => $group->id,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('contact_phone_numbers', [
|
||||
'contact_id' => $contact->id,
|
||||
'raw_number' => '06 11 11 00 03',
|
||||
'normalized_number' => '+33611110003',
|
||||
'country' => 'FR',
|
||||
'is_valid' => true,
|
||||
'is_mobile' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_contacts_can_be_searched_by_name_and_phone_number(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$contact = Contact::query()->create([
|
||||
'source' => 'local',
|
||||
'first_name' => 'Jean',
|
||||
'last_name' => 'Martin',
|
||||
'email' => 'jean@example.test',
|
||||
]);
|
||||
|
||||
$contact->phoneNumbers()->create([
|
||||
'raw_number' => '06 11 11 00 01',
|
||||
'normalized_number' => '+33611110001',
|
||||
'country' => 'FR',
|
||||
'is_valid' => true,
|
||||
'is_mobile' => true,
|
||||
'is_primary' => true,
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->get('/contacts?q=Martin')
|
||||
->assertOk()
|
||||
->assertSee('Jean Martin')
|
||||
->assertSee('+33611110001');
|
||||
|
||||
$this->actingAs($user)
|
||||
->get('/contacts?q=11110001')
|
||||
->assertOk()
|
||||
->assertSee('Jean Martin');
|
||||
}
|
||||
|
||||
public function test_contacts_default_mobile_filter_includes_stale_normalized_mobile_numbers(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$contact = Contact::query()->create([
|
||||
'source' => 'carddav',
|
||||
'external_id' => 'uid-yveline',
|
||||
'first_name' => 'Yveline',
|
||||
'last_name' => 'Mobile',
|
||||
]);
|
||||
$contact->phoneNumbers()->create([
|
||||
'raw_number' => '064-201-4207',
|
||||
'normalized_number' => '+33642014207',
|
||||
'country' => 'FR',
|
||||
'is_valid' => true,
|
||||
'is_mobile' => false,
|
||||
'is_primary' => true,
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->get('/contacts')
|
||||
->assertOk()
|
||||
->assertSee('Yveline Mobile')
|
||||
->assertSee('Mobile detecte');
|
||||
}
|
||||
|
||||
public function test_authenticated_user_can_update_contact(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$oldGroup = ContactGroup::query()->create([
|
||||
'source' => 'local',
|
||||
'name' => 'Anciens',
|
||||
'slug' => 'anciens',
|
||||
]);
|
||||
$newGroup = ContactGroup::query()->create([
|
||||
'source' => 'local',
|
||||
'name' => 'Membres',
|
||||
'slug' => 'membres',
|
||||
]);
|
||||
$contact = Contact::query()->create([
|
||||
'source' => 'local',
|
||||
'first_name' => 'Jean',
|
||||
'last_name' => 'Martin',
|
||||
'email' => 'jean@example.test',
|
||||
]);
|
||||
$contact->groups()->attach($oldGroup);
|
||||
$contact->phoneNumbers()->create([
|
||||
'label' => 'Mobile',
|
||||
'raw_number' => '06 11 11 00 01',
|
||||
'normalized_number' => '+33611110001',
|
||||
'country' => 'FR',
|
||||
'is_valid' => true,
|
||||
'is_mobile' => true,
|
||||
'is_primary' => true,
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->put(route('contacts.update', $contact), [
|
||||
'first_name' => 'Jeanne',
|
||||
'last_name' => 'Martin',
|
||||
'email' => 'jeanne@example.test',
|
||||
'raw_phone_number' => '07 55 55 00 04',
|
||||
'phone_label' => 'Portable',
|
||||
'group_ids' => [$newGroup->id],
|
||||
'is_favorite' => '1',
|
||||
])
|
||||
->assertRedirect(route('contacts.show', $contact));
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'first_name' => 'Jeanne',
|
||||
'email' => 'jeanne@example.test',
|
||||
'sms_opt_out' => false,
|
||||
'is_favorite' => true,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseMissing('contact_contact_group', [
|
||||
'contact_id' => $contact->id,
|
||||
'contact_group_id' => $oldGroup->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('contact_contact_group', [
|
||||
'contact_id' => $contact->id,
|
||||
'contact_group_id' => $newGroup->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('contact_phone_numbers', [
|
||||
'contact_id' => $contact->id,
|
||||
'label' => 'Portable',
|
||||
'raw_number' => '07 55 55 00 04',
|
||||
'normalized_number' => '+33755550004',
|
||||
'is_mobile' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_imported_contacts_cannot_be_edited_or_deleted(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$contact = Contact::query()->create([
|
||||
'source' => 'carddav',
|
||||
'external_id' => 'remote-1',
|
||||
'first_name' => 'Jean',
|
||||
'last_name' => 'Importe',
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('contacts.edit', $contact))
|
||||
->assertForbidden();
|
||||
|
||||
$this->actingAs($user)
|
||||
->put(route('contacts.update', $contact), [
|
||||
'last_name' => 'Modifie',
|
||||
])
|
||||
->assertForbidden();
|
||||
|
||||
$this->actingAs($user)
|
||||
->delete(route('contacts.destroy', $contact))
|
||||
->assertForbidden();
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'last_name' => 'Importe',
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_authenticated_user_can_toggle_favorite_on_imported_contact(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$contact = Contact::query()->create([
|
||||
'source' => 'carddav',
|
||||
'external_id' => 'remote-favorite',
|
||||
'first_name' => 'Yveline',
|
||||
'last_name' => 'Importee',
|
||||
'is_favorite' => false,
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->patch(route('contacts.favorite', $contact), [
|
||||
'is_favorite' => '1',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'source' => 'carddav',
|
||||
'is_favorite' => true,
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->patch(route('contacts.favorite', $contact), [
|
||||
'is_favorite' => '0',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'source' => 'carddav',
|
||||
'is_favorite' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_authenticated_user_can_toggle_sms_opt_out_on_imported_contact(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$contact = Contact::query()->create([
|
||||
'source' => 'galette',
|
||||
'external_id' => 'remote-opt-out',
|
||||
'first_name' => 'Claire',
|
||||
'last_name' => 'Importee',
|
||||
'sms_opt_out' => false,
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->patch(route('contacts.opt-out', $contact), [
|
||||
'sms_opt_out' => '1',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'source' => 'galette',
|
||||
'sms_opt_out' => true,
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->patch(route('contacts.opt-out', $contact), [
|
||||
'sms_opt_out' => '0',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'source' => 'galette',
|
||||
'sms_opt_out' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_authenticated_user_can_delete_contact(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$contact = Contact::query()->create([
|
||||
'source' => 'local',
|
||||
'first_name' => 'Jean',
|
||||
'last_name' => 'Martin',
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->delete(route('contacts.destroy', $contact))
|
||||
->assertRedirect(route('contacts.index'));
|
||||
|
||||
$this->assertSoftDeleted('contacts', [
|
||||
'id' => $contact->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_authenticated_user_can_update_and_delete_group(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$group = ContactGroup::query()->create([
|
||||
'source' => 'local',
|
||||
'name' => 'Benevoles',
|
||||
'slug' => 'benevoles',
|
||||
]);
|
||||
$contact = Contact::query()->create([
|
||||
'source' => 'local',
|
||||
'first_name' => 'Marie',
|
||||
'last_name' => 'Durand',
|
||||
]);
|
||||
$contact->groups()->attach($group);
|
||||
|
||||
$this->actingAs($user)
|
||||
->put(route('contact-groups.update', $group), [
|
||||
'name' => 'Equipe accueil',
|
||||
'description' => 'Permanences',
|
||||
'is_favorite' => '1',
|
||||
])
|
||||
->assertRedirect(route('contacts.index', ['group' => $group->id]));
|
||||
|
||||
$this->assertDatabaseHas('contact_groups', [
|
||||
'id' => $group->id,
|
||||
'name' => 'Equipe accueil',
|
||||
'slug' => 'equipe-accueil',
|
||||
'description' => 'Permanences',
|
||||
'is_favorite' => true,
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->delete(route('contact-groups.destroy', $group))
|
||||
->assertRedirect(route('contacts.index'));
|
||||
|
||||
$this->assertSoftDeleted('contact_groups', [
|
||||
'id' => $group->id,
|
||||
]);
|
||||
$this->assertDatabaseMissing('contact_contact_group', [
|
||||
'contact_id' => $contact->id,
|
||||
'contact_group_id' => $group->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_authenticated_user_can_update_local_group_members(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$group = ContactGroup::query()->create([
|
||||
'source' => 'local',
|
||||
'name' => 'Benevoles',
|
||||
'slug' => 'benevoles',
|
||||
]);
|
||||
$kept = Contact::query()->create([
|
||||
'source' => 'local',
|
||||
'first_name' => 'Marie',
|
||||
'last_name' => 'Durand',
|
||||
]);
|
||||
$removed = Contact::query()->create([
|
||||
'source' => 'local',
|
||||
'first_name' => 'Paul',
|
||||
'last_name' => 'Ancien',
|
||||
]);
|
||||
$addedImported = Contact::query()->create([
|
||||
'source' => 'carddav',
|
||||
'external_id' => 'remote-added',
|
||||
'first_name' => 'Claire',
|
||||
'last_name' => 'Importee',
|
||||
]);
|
||||
$group->contacts()->attach([$kept->id, $removed->id]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->put(route('contact-groups.update', $group), [
|
||||
'name' => 'Benevoles',
|
||||
'members_submitted' => '1',
|
||||
'contact_ids' => [$kept->id, $addedImported->id],
|
||||
])
|
||||
->assertRedirect(route('contacts.index', ['group' => $group->id]));
|
||||
|
||||
$this->assertDatabaseHas('contact_contact_group', [
|
||||
'contact_id' => $kept->id,
|
||||
'contact_group_id' => $group->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('contact_contact_group', [
|
||||
'contact_id' => $addedImported->id,
|
||||
'contact_group_id' => $group->id,
|
||||
]);
|
||||
$this->assertDatabaseMissing('contact_contact_group', [
|
||||
'contact_id' => $removed->id,
|
||||
'contact_group_id' => $group->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_imported_groups_cannot_be_edited_or_deleted(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$group = ContactGroup::query()->create([
|
||||
'source' => 'galette',
|
||||
'external_id' => 'remote-group',
|
||||
'name' => 'Groupe importe',
|
||||
'slug' => 'galette-groupe-importe',
|
||||
]);
|
||||
|
||||
$this->actingAs($user)
|
||||
->get(route('contact-groups.edit', $group))
|
||||
->assertForbidden();
|
||||
|
||||
$this->actingAs($user)
|
||||
->put(route('contact-groups.update', $group), [
|
||||
'name' => 'Modifie',
|
||||
])
|
||||
->assertForbidden();
|
||||
|
||||
$this->actingAs($user)
|
||||
->delete(route('contact-groups.destroy', $group))
|
||||
->assertForbidden();
|
||||
|
||||
$this->assertDatabaseHas('contact_groups', [
|
||||
'id' => $group->id,
|
||||
'name' => 'Groupe importe',
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_guest_cannot_access_contacts(): void
|
||||
{
|
||||
$this->get('/contacts')
|
||||
->assertRedirect('/login');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user