diff --git a/tests/php/Unit/Collaboration/Collaborators/ManualPhonePluginTest.php b/tests/php/Unit/Collaboration/Collaborators/ManualPhonePluginTest.php index 965487a72b..6f00def38f 100644 --- a/tests/php/Unit/Collaboration/Collaborators/ManualPhonePluginTest.php +++ b/tests/php/Unit/Collaboration/Collaborators/ManualPhonePluginTest.php @@ -17,14 +17,16 @@ use PHPUnit\Framework\TestCase; class ManualPhonePluginTest extends TestCase { - #[DataProvider('providerSearchScenarios')] - public function testSearchReturnsManualEntryOnlyWhenValid( + #[DataProvider('providerValidPhoneNumbers')] + public function testSearchAddsAnExactManualEntryForAValidPhoneNumber( string $method, + string $search, string $rawSearch, - ?string $normalized, + string $expectedRawSearch, string $defaultRegion, - ?string $expectedRegionParam, - int $expectedCount, + ?string $expectedRegion, + string $standardFormat, + string $expectedShareWith, ): void { $config = $this->createMock(IConfig::class); $config->method('getSystemValueString') @@ -32,60 +34,150 @@ public function testSearchReturnsManualEntryOnlyWhenValid( ->willReturn($defaultRegion); $phoneUtil = $this->createMock(IPhoneNumberUtil::class); - $phoneUtil->method('convertToStandardFormat') - ->with($rawSearch, $expectedRegionParam) - ->willReturn($normalized); + $phoneUtil->expects($this->once()) + ->method('convertToStandardFormat') + ->with($expectedRawSearch, $expectedRegion) + ->willReturn($standardFormat); $context = new SignerSearchContext(); - $context->set($method, $normalized ?? '', $rawSearch); + $context->set($method, $search, $rawSearch); $plugin = new ManualPhonePlugin($config, $phoneUtil, $context); $searchResult = new SearchResult(); - $plugin->search($normalized ?? '', 10, 0, $searchResult); + $hasMore = $plugin->search($search, 10, 0, $searchResult); $results = $searchResult->asArray(); - $items = array_merge($results['manual-phone'] ?? [], $results['exact']['manual-phone'] ?? []); - $this->assertCount($expectedCount, $items); - if ($expectedCount > 0) { - $this->assertSame(ManualPhonePlugin::TYPE_SIGNER_MANUAL_PHONE, $items[0]['value']['shareType']); - $this->assertSame($normalized, $items[0]['value']['shareWith']); - } + $exact = $results['exact']['manual-phone'] ?? []; + $wide = $results['manual-phone'] ?? []; + + $this->assertFalse($hasMore, 'The manual entry is the only result this plugin can offer'); + $this->assertEmpty($wide, 'A manual entry is always an exact match'); + $this->assertCount(1, $exact); + $this->assertSame($expectedShareWith, $exact[0]['label']); + $this->assertSame($expectedShareWith, $exact[0]['shareWithDisplayNameUnique']); + $this->assertSame($method, $exact[0]['method']); + $this->assertSame($expectedShareWith, $exact[0]['value']['shareWith']); + $this->assertSame(ManualPhonePlugin::TYPE_SIGNER_MANUAL_PHONE, $exact[0]['value']['shareType']); + } + + #[DataProvider('providerSearchesWithoutAPhoneNumberToValidate')] + public function testSearchDoesNotValidateWhenThereIsNoPhoneNumberToOffer( + string $method, + string $search, + string $contextSearch, + string $rawSearch, + ): void { + $config = $this->createMock(IConfig::class); + $config->expects($this->never()) + ->method('getSystemValueString'); + + $phoneUtil = $this->createMock(IPhoneNumberUtil::class); + $phoneUtil->expects($this->never()) + ->method('convertToStandardFormat'); + + $context = new SignerSearchContext(); + $context->set($method, $contextSearch, $rawSearch); + + $plugin = new ManualPhonePlugin($config, $phoneUtil, $context); + + $searchResult = new SearchResult(); + $hasMore = $plugin->search($search, 10, 0, $searchResult); + + $results = $searchResult->asArray(); + + $this->assertFalse($hasMore); + $this->assertEmpty($results['exact']['manual-phone'] ?? []); + $this->assertEmpty($results['manual-phone'] ?? []); + } + + public function testSearchDoesNotOfferANumberRejectedByThePhoneNumberUtil(): void { + $config = $this->createMock(IConfig::class); + $config->method('getSystemValueString') + ->with('default_phone_region', '') + ->willReturn('BR'); + + $phoneUtil = $this->createMock(IPhoneNumberUtil::class); + $phoneUtil->expects($this->once()) + ->method('convertToStandardFormat') + ->with('123', 'BR') + ->willReturn(null); + + $context = new SignerSearchContext(); + $context->set('sms', '123', '123'); + + $plugin = new ManualPhonePlugin($config, $phoneUtil, $context); + + $searchResult = new SearchResult(); + $hasMore = $plugin->search('123', 10, 0, $searchResult); + + $results = $searchResult->asArray(); + + $this->assertFalse($hasMore); + $this->assertEmpty($results['exact']['manual-phone'] ?? []); + $this->assertEmpty($results['manual-phone'] ?? []); } - public static function providerSearchScenarios(): array { + public static function providerValidPhoneNumbers(): array { return [ - 'non phone method' => [ - 'method' => 'email', + 'national number with a default region' => [ + 'method' => 'whatsapp', + 'search' => '+5521987654321', 'rawSearch' => '21987654321', - 'normalized' => '+5521987654321', + 'expectedRawSearch' => '21987654321', 'defaultRegion' => 'BR', - 'expectedRegionParam' => 'BR', - 'expectedCount' => 0, + 'expectedRegion' => 'BR', + 'standardFormat' => '+5521987654321', + 'expectedShareWith' => '+5521987654321', ], - 'invalid number' => [ + 'e164 number without a default region' => [ 'method' => 'sms', - 'rawSearch' => '123', - 'normalized' => null, + 'search' => '+12025551234', + 'rawSearch' => '+12025551234', + 'expectedRawSearch' => '+12025551234', + 'defaultRegion' => '', + 'expectedRegion' => null, + 'standardFormat' => '+12025551234', + 'expectedShareWith' => '+12025551234', + ], + 'surrounding whitespace is discarded' => [ + 'method' => 'signal', + 'search' => ' +5521987654321 ', + 'rawSearch' => "\t21987654321 ", + 'expectedRawSearch' => '21987654321', 'defaultRegion' => 'BR', - 'expectedRegionParam' => 'BR', - 'expectedCount' => 0, + 'expectedRegion' => 'BR', + 'standardFormat' => '+55 21 98765-4321', + 'expectedShareWith' => '+5521987654321', ], - 'valid number' => [ - 'method' => 'whatsapp', + ]; + } + + public static function providerSearchesWithoutAPhoneNumberToValidate(): array { + return [ + 'method that does not use a phone number' => [ + 'method' => 'email', + 'search' => '+5521987654321', + 'contextSearch' => '+5521987654321', 'rawSearch' => '21987654321', - 'normalized' => '+5521987654321', - 'defaultRegion' => 'BR', - 'expectedRegionParam' => 'BR', - 'expectedCount' => 1, ], - 'valid e164 without default region' => [ + 'empty search' => [ 'method' => 'sms', - 'rawSearch' => '+12025551234', - 'normalized' => '+12025551234', - 'defaultRegion' => '', - 'expectedRegionParam' => null, - 'expectedCount' => 1, + 'search' => '', + 'contextSearch' => '', + 'rawSearch' => '21987654321', + ], + 'search made only of whitespace' => [ + 'method' => 'sms', + 'search' => ' ', + 'contextSearch' => ' ', + 'rawSearch' => '21987654321', + ], + 'context without the raw search typed by the user' => [ + 'method' => 'sms', + 'search' => '+5521987654321', + 'contextSearch' => '', + 'rawSearch' => '', ], ]; }