Publication initiale de RelaisSMS : documentation et sources nettoyees
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Calendar;
|
||||
|
||||
use App\Services\Calendar\ICalendarParser;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ICalendarParserTest extends TestCase
|
||||
{
|
||||
public function test_it_parses_event_attendees_organizer_and_display_alarm(): void
|
||||
{
|
||||
Carbon::setTestNow(Carbon::parse('2026-06-12 12:00:00', 'Europe/Paris'));
|
||||
|
||||
$events = (new ICalendarParser)->parse(<<<'ICS'
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:event-test
|
||||
SUMMARY:test
|
||||
DTSTART;TZID=Europe/Paris:20260613T100000
|
||||
DTEND;TZID=Europe/Paris:20260613T110000
|
||||
ORGANIZER;CN=Alex Martin:mailto:alex@example.test
|
||||
ATTENDEE;CN=Marie Durand:mailto:marie@example.test
|
||||
BEGIN:VALARM
|
||||
ACTION:DISPLAY
|
||||
TRIGGER:-PT1H
|
||||
DESCRIPTION:Rappel
|
||||
END:VALARM
|
||||
BEGIN:VALARM
|
||||
ACTION:EMAIL
|
||||
TRIGGER:-PT2H
|
||||
DESCRIPTION:Rappel email
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
ICS);
|
||||
|
||||
$this->assertCount(1, $events);
|
||||
$this->assertSame('event-test', $events[0]->uid);
|
||||
$this->assertSame('test', $events[0]->summary);
|
||||
$this->assertSame([
|
||||
['email' => 'alex@example.test', 'name' => 'Alex Martin'],
|
||||
['email' => 'marie@example.test', 'name' => 'Marie Durand'],
|
||||
], $events[0]->attendees);
|
||||
$this->assertSame('DISPLAY', $events[0]->alarms[0]->action);
|
||||
$this->assertSame(-60, $events[0]->alarms[0]->triggerMinutes);
|
||||
$this->assertSame('EMAIL', $events[0]->alarms[1]->action);
|
||||
}
|
||||
|
||||
public function test_it_parses_an_attendee_invited_through_a_circle(): void
|
||||
{
|
||||
$events = (new ICalendarParser)->parse(<<<'ICS'
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:circle-event
|
||||
SUMMARY:Circle test
|
||||
DTSTART;TZID=Europe/Paris:20260918T000000
|
||||
DTEND;TZID=Europe/Paris:20260918T003000
|
||||
ORGANIZER;CN=Camille Test:mailto:camille@example.test
|
||||
ATTENDEE;CN=EquipeTest;CUTYPE=GROUP:mailto:circle+team@example.test
|
||||
ATTENDEE;CN="Martin; Alex";CUTYPE=INDIVIDUAL;MEMBER="mailto:circle+team@example.test";PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.1:mailto:alex@example.test
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
ICS);
|
||||
|
||||
$this->assertCount(1, $events);
|
||||
$this->assertSame([
|
||||
['email' => 'camille@example.test', 'name' => 'Camille Test'],
|
||||
['email' => 'circle+team@example.test', 'name' => 'EquipeTest'],
|
||||
['email' => 'alex@example.test', 'name' => 'Martin; Alex'],
|
||||
], $events[0]->attendees);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\CardDav;
|
||||
|
||||
use App\Services\CardDav\VCardParser;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class VCardParserTest extends TestCase
|
||||
{
|
||||
public function test_it_parses_contact_fields_phone_numbers_and_categories(): void
|
||||
{
|
||||
$vcard = <<<'VCF'
|
||||
BEGIN:VCARD
|
||||
VERSION:3.0
|
||||
UID:contact-123
|
||||
FN:Marie Durand
|
||||
N:Durand;Marie;;;
|
||||
ORG:AFPMA
|
||||
EMAIL;TYPE=HOME:marie@example.test
|
||||
TEL;TYPE=CELL,VOICE:06 11 11 00 03
|
||||
TEL;TYPE=HOME:04 00 00 00 00
|
||||
CATEGORIES:Benevoles,Conseil\, bureau
|
||||
END:VCARD
|
||||
VCF;
|
||||
|
||||
$contact = (new VCardParser)->parse($vcard);
|
||||
|
||||
$this->assertSame('contact-123', $contact->uid);
|
||||
$this->assertSame('Marie Durand', $contact->fullName);
|
||||
$this->assertSame('Marie', $contact->firstName);
|
||||
$this->assertSame('Durand', $contact->lastName);
|
||||
$this->assertSame('AFPMA', $contact->organization);
|
||||
$this->assertSame('marie@example.test', $contact->email);
|
||||
$this->assertCount(2, $contact->phoneNumbers);
|
||||
$this->assertSame('Cell, Voice', $contact->phoneNumbers[0]->label);
|
||||
$this->assertSame(['Benevoles', 'Conseil, bureau'], $contact->categories);
|
||||
}
|
||||
|
||||
public function test_it_unfolds_multiline_values(): void
|
||||
{
|
||||
$vcard = "BEGIN:VCARD\r\nVERSION:3.0\r\nUID:folded\r\nFN:Association des amis\r\n du lac\r\nTEL:0611110001\r\nEND:VCARD\r\n";
|
||||
|
||||
$contact = (new VCardParser)->parse($vcard);
|
||||
|
||||
$this->assertSame('Association des amis du lac', $contact->fullName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ExampleTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* A basic test example.
|
||||
*/
|
||||
public function test_that_true_is_true(): void
|
||||
{
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Services\Sms\OvhShortCodeMessage;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class OvhShortCodeMessageTest extends TestCase
|
||||
{
|
||||
#[DataProvider('messages')]
|
||||
public function test_it_removes_links_and_preserves_useful_text(string $input, string $expected): void
|
||||
{
|
||||
$this->assertSame($expected, (new OvhShortCodeMessage)->prepare($input));
|
||||
}
|
||||
|
||||
public static function messages(): array
|
||||
{
|
||||
return [
|
||||
'production reminder' => ["Rappel : Réunion Communication\n30/09/2026 10:00\nParticiper à la réunion Zoom https://us06web.zoom.us/j/12345 ID de réunion: 123 456", "Rappel : Réunion Communication\n30/09/2026 10:00\nParticiper à la réunion Zoom ID de réunion: 123 456"],
|
||||
'schemes and www' => ['Voir HTTPS://example.org/x?a=b et www.example.fr/test merci', 'Voir et merci'],
|
||||
'bare domain' => ['Zoom zoom.us/j/123 puis exemple.fr', 'Zoom puis'],
|
||||
'markdown' => ['Rejoindre [la réunion](https://zoom.us/j/123)', 'Rejoindre la réunion'],
|
||||
'html' => ['Rejoindre <a href="https://zoom.us/j/123">la réunion</a>', 'Rejoindre la réunion'],
|
||||
'email phones and date' => ['Contact prenom.nom@example.fr +33 6 12 34 56 78 le 30.09.2026 à 10:00', 'Contact prenom.nom@example.fr +33 6 12 34 56 78 le 30.09.2026 à 10:00'],
|
||||
'url only' => ['https://example.org', ''],
|
||||
'unicode domain' => ['Voir https://exemple.fr/été et réunion.fr/a', 'Voir et'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Contracts\PhoneNumberNormalizerInterface;
|
||||
use Tests\TestCase;
|
||||
|
||||
class PhoneNumberNormalizerTest extends TestCase
|
||||
{
|
||||
public function test_it_normalizes_french_mobile_numbers_to_e164(): void
|
||||
{
|
||||
$result = app(PhoneNumberNormalizerInterface::class)->normalize('(+33) 6 11 11 00 02', 'FR');
|
||||
|
||||
$this->assertTrue($result->isValid);
|
||||
$this->assertTrue($result->isMobile);
|
||||
$this->assertSame('+33611110002', $result->normalizedNumber);
|
||||
$this->assertSame('FR', $result->country);
|
||||
$this->assertNull($result->error);
|
||||
}
|
||||
|
||||
public function test_it_keeps_fixed_line_numbers_valid_but_not_mobile(): void
|
||||
{
|
||||
$result = app(PhoneNumberNormalizerInterface::class)->normalize('01 23 45 67 89', 'FR');
|
||||
|
||||
$this->assertTrue($result->isValid);
|
||||
$this->assertFalse($result->isMobile);
|
||||
$this->assertSame('+33123456789', $result->normalizedNumber);
|
||||
}
|
||||
|
||||
public function test_it_detects_mobile_numbers_with_libphonenumber_when_regex_does_not_match(): void
|
||||
{
|
||||
config(['relais_sms.default_settings.mobile_phone_regex' => '/^never-matches$/']);
|
||||
|
||||
$result = app(PhoneNumberNormalizerInterface::class)->normalize('tel:+33611110002', 'FR');
|
||||
|
||||
$this->assertTrue($result->isValid);
|
||||
$this->assertTrue($result->isMobile);
|
||||
$this->assertSame('+33611110002', $result->normalizedNumber);
|
||||
}
|
||||
|
||||
public function test_it_detects_dash_separated_french_mobile_numbers(): void
|
||||
{
|
||||
$result = app(PhoneNumberNormalizerInterface::class)->normalize('064-201-4207', 'FR');
|
||||
|
||||
$this->assertTrue($result->isValid);
|
||||
$this->assertTrue($result->isMobile);
|
||||
$this->assertSame('+33642014207', $result->normalizedNumber);
|
||||
}
|
||||
|
||||
public function test_it_reports_invalid_numbers(): void
|
||||
{
|
||||
$result = app(PhoneNumberNormalizerInterface::class)->normalize('not a phone', 'FR');
|
||||
|
||||
$this->assertFalse($result->isValid);
|
||||
$this->assertFalse($result->isMobile);
|
||||
$this->assertNull($result->normalizedNumber);
|
||||
$this->assertNotNull($result->error);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Services\Sms\SmsMessageLength;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class SmsMessageLengthTest extends TestCase
|
||||
{
|
||||
public function test_gsm_message_is_limited_to_160_units(): void
|
||||
{
|
||||
$length = new SmsMessageLength;
|
||||
|
||||
$this->assertTrue($length->fitsInOneSms(str_repeat('a', 160)));
|
||||
$this->assertFalse($length->fitsInOneSms(str_repeat('a', 161)));
|
||||
$this->assertSame(160, $length->units(str_repeat('^', 80)));
|
||||
}
|
||||
|
||||
public function test_unicode_message_is_limited_to_70_units(): void
|
||||
{
|
||||
$length = new SmsMessageLength;
|
||||
|
||||
$this->assertTrue($length->fitsInOneSms(str_repeat('ê', 70)));
|
||||
$this->assertFalse($length->fitsInOneSms(str_repeat('ê', 71)));
|
||||
}
|
||||
|
||||
public function test_value_is_truncated_with_marker_inside_one_sms(): void
|
||||
{
|
||||
$length = new SmsMessageLength;
|
||||
$value = $length->truncateBetween('Rappel : ', str_repeat('a', 200), "\n17/09/2026 14:00");
|
||||
$message = 'Rappel : '.$value."\n17/09/2026 14:00";
|
||||
|
||||
$this->assertStringEndsWith('[...]', $value);
|
||||
$this->assertTrue($length->fitsInOneSms($message));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user