Publication initiale de RelaisSMS : documentation et sources nettoyees

This commit is contained in:
2026-10-21 09:29:39 +02:00
commit ac186b03b1
158 changed files with 24818 additions and 0 deletions
@@ -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);
}
}
+47
View File
@@ -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);
}
}
+16
View File
@@ -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);
}
}
+30
View File
@@ -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'],
];
}
}
+59
View File
@@ -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);
}
}
+36
View File
@@ -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));
}
}