Skip to content

Commit 1661987

Browse files
Merge pull request #63402 from nextcloud/backport/60463/stable34
[stable34] test(carddav): refactor testSearch to use clearer assertions and unique UIDs
2 parents efe1cb0 + 53ae9d4 commit 1661987

1 file changed

Lines changed: 110 additions & 86 deletions

File tree

apps/dav/tests/unit/CardDAV/CardDavBackendTest.php

Lines changed: 110 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -681,18 +681,20 @@ public function testGetCardIdFailed(): void {
681681
}
682682

683683
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'dataTestSearch')]
684-
public function testSearch(string $pattern, array $properties, array $options, array $expected): void {
685-
/** @var VCard $vCards */
684+
public function testSearch(string $pattern, array $properties, array $options, array $expectedUris, array $expectedNeedles): void {
686685
$vCards = [];
686+
687687
$vCards[0] = new VCard();
688-
$vCards[0]->add(new Text($vCards[0], 'UID', 'uid'));
688+
$vCards[0]->add(new Text($vCards[0], 'UID', 'uid-0'));
689689
$vCards[0]->add(new Text($vCards[0], 'FN', 'John Doe'));
690690
$vCards[0]->add(new Text($vCards[0], 'CLOUD', 'john@nextcloud.com'));
691+
691692
$vCards[1] = new VCard();
692-
$vCards[1]->add(new Text($vCards[1], 'UID', 'uid'));
693+
$vCards[1]->add(new Text($vCards[1], 'UID', 'uid-1'));
693694
$vCards[1]->add(new Text($vCards[1], 'FN', 'John M. Doe'));
695+
694696
$vCards[2] = new VCard();
695-
$vCards[2]->add(new Text($vCards[2], 'UID', 'uid'));
697+
$vCards[2]->add(new Text($vCards[2], 'UID', 'uid-2'));
696698
$vCards[2]->add(new Text($vCards[2], 'FN', 'find without options'));
697699
$vCards[2]->add(new Text($vCards[2], 'CLOUD', 'peter_pan@nextcloud.com'));
698700

@@ -714,95 +716,117 @@ public function testSearch(string $pattern, array $properties, array $options, a
714716
$vCardIds[] = $query->getLastInsertId();
715717
}
716718

717-
$query = $this->db->getQueryBuilder();
718-
$query->insert($this->dbCardsPropertiesTable)
719-
->values(
720-
[
721-
'addressbookid' => $query->createNamedParameter(0),
722-
'cardid' => $query->createNamedParameter($vCardIds[0]),
723-
'name' => $query->createNamedParameter('FN'),
724-
'value' => $query->createNamedParameter('John Doe'),
725-
'preferred' => $query->createNamedParameter(0)
726-
]
727-
);
728-
$query->executeStatement();
729-
$query = $this->db->getQueryBuilder();
730-
$query->insert($this->dbCardsPropertiesTable)
731-
->values(
732-
[
733-
'addressbookid' => $query->createNamedParameter(0),
734-
'cardid' => $query->createNamedParameter($vCardIds[0]),
735-
'name' => $query->createNamedParameter('CLOUD'),
736-
'value' => $query->createNamedParameter('John@nextcloud.com'),
737-
'preferred' => $query->createNamedParameter(0)
738-
]
739-
);
740-
$query->executeStatement();
741-
$query = $this->db->getQueryBuilder();
742-
$query->insert($this->dbCardsPropertiesTable)
743-
->values(
744-
[
745-
'addressbookid' => $query->createNamedParameter(0),
746-
'cardid' => $query->createNamedParameter($vCardIds[1]),
747-
'name' => $query->createNamedParameter('FN'),
748-
'value' => $query->createNamedParameter('John M. Doe'),
749-
'preferred' => $query->createNamedParameter(0)
750-
]
751-
);
752-
$query->executeStatement();
753-
$query = $this->db->getQueryBuilder();
754-
$query->insert($this->dbCardsPropertiesTable)
755-
->values(
756-
[
757-
'addressbookid' => $query->createNamedParameter(0),
758-
'cardid' => $query->createNamedParameter($vCardIds[2]),
759-
'name' => $query->createNamedParameter('FN'),
760-
'value' => $query->createNamedParameter('find without options'),
761-
'preferred' => $query->createNamedParameter(0)
762-
]
763-
);
764-
$query->executeStatement();
765-
$query = $this->db->getQueryBuilder();
766-
$query->insert($this->dbCardsPropertiesTable)
767-
->values(
768-
[
769-
'addressbookid' => $query->createNamedParameter(0),
770-
'cardid' => $query->createNamedParameter($vCardIds[2]),
771-
'name' => $query->createNamedParameter('CLOUD'),
772-
'value' => $query->createNamedParameter('peter_pan@nextcloud.com'),
773-
'preferred' => $query->createNamedParameter(0)
774-
]
775-
);
776-
$query->executeStatement();
719+
$propertyRows = [
720+
[$vCardIds[0], 'FN', 'John Doe'],
721+
[$vCardIds[0], 'CLOUD', 'John@nextcloud.com'],
722+
[$vCardIds[1], 'FN', 'John M. Doe'],
723+
[$vCardIds[2], 'FN', 'find without options'],
724+
[$vCardIds[2], 'CLOUD', 'peter_pan@nextcloud.com'],
725+
];
726+
727+
foreach ($propertyRows as [$cardId, $name, $value]) {
728+
$query = $this->db->getQueryBuilder();
729+
$query->insert($this->dbCardsPropertiesTable)
730+
->values(
731+
[
732+
'addressbookid' => $query->createNamedParameter(0),
733+
'cardid' => $query->createNamedParameter($cardId),
734+
'name' => $query->createNamedParameter($name),
735+
'value' => $query->createNamedParameter($value),
736+
'preferred' => $query->createNamedParameter(0),
737+
]
738+
);
739+
$query->executeStatement();
740+
}
777741

778742
$result = $this->backend->search(0, $pattern, $properties, $options);
779743

780-
// check result
781-
$this->assertSame(count($expected), count($result));
782-
$found = [];
783-
foreach ($result as $r) {
784-
foreach ($expected as $exp) {
785-
if ($r['uri'] === $exp[0] && strpos($r['carddata'], $exp[1]) > 0) {
786-
$found[$exp[1]] = true;
787-
break;
788-
}
789-
}
790-
}
744+
$this->assertCount(count($expectedUris), $result);
745+
746+
$actualUris = array_map(static fn (array $row): string => $row['uri'], $result);
747+
sort($actualUris);
748+
$expectedSortedUris = $expectedUris;
749+
sort($expectedSortedUris);
750+
751+
$this->assertSame($expectedSortedUris, $actualUris, 'Search returned unexpected URIs');
791752

792-
$this->assertSame(count($expected), count($found));
753+
$expectedByUri = array_combine($expectedUris, $expectedNeedles);
754+
$this->assertIsArray($expectedByUri);
755+
756+
foreach ($result as $row) {
757+
$this->assertArrayHasKey($row['uri'], $expectedByUri, 'Unexpected URI in search result');
758+
$this->assertNotFalse(
759+
strpos($row['carddata'], $expectedByUri[$row['uri']]),
760+
'Returned carddata does not contain expected fragment for ' . $row['uri']
761+
);
762+
}
793763
}
794764

795765
public static function dataTestSearch(): array {
796766
return [
797-
['John', ['FN'], [], [['uri0', 'John Doe'], ['uri1', 'John M. Doe']]],
798-
['M. Doe', ['FN'], [], [['uri1', 'John M. Doe']]],
799-
['Do', ['FN'], [], [['uri0', 'John Doe'], ['uri1', 'John M. Doe']]],
800-
'check if duplicates are handled correctly' => ['John', ['FN', 'CLOUD'], [], [['uri0', 'John Doe'], ['uri1', 'John M. Doe']]],
801-
'case insensitive' => ['john', ['FN'], [], [['uri0', 'John Doe'], ['uri1', 'John M. Doe']]],
802-
'limit' => ['john', ['FN'], ['limit' => 1], [['uri0', 'John Doe']]],
803-
'limit and offset' => ['john', ['FN'], ['limit' => 1, 'offset' => 1], [['uri1', 'John M. Doe']]],
804-
'find "_" escaped' => ['_', ['CLOUD'], [], [['uri2', 'find without options']]],
805-
'find not empty CLOUD' => ['%_%', ['CLOUD'], ['escape_like_param' => false], [['uri0', 'John Doe'], ['uri2', 'find without options']]],
767+
'basic FN match' => [
768+
'pattern' => 'John',
769+
'properties' => ['FN'],
770+
'options' => [],
771+
'expectedUris' => ['uri0', 'uri1'],
772+
'expectedNeedles' => ['John Doe', 'John M. Doe'],
773+
],
774+
'partial FN match' => [
775+
'pattern' => 'M. Doe',
776+
'properties' => ['FN'],
777+
'options' => [],
778+
'expectedUris' => ['uri1'],
779+
'expectedNeedles' => ['John M. Doe'],
780+
],
781+
'substring FN match' => [
782+
'pattern' => 'Do',
783+
'properties' => ['FN'],
784+
'options' => [],
785+
'expectedUris' => ['uri0', 'uri1'],
786+
'expectedNeedles' => ['John Doe', 'John M. Doe'],
787+
],
788+
'search across multiple properties returns one result per card' => [
789+
'pattern' => 'John',
790+
'properties' => ['FN', 'CLOUD'],
791+
'options' => [],
792+
'expectedUris' => ['uri0', 'uri1'],
793+
'expectedNeedles' => ['John Doe', 'John M. Doe'],
794+
],
795+
'case-insensitive search' => [
796+
'pattern' => 'john',
797+
'properties' => ['FN'],
798+
'options' => [],
799+
'expectedUris' => ['uri0', 'uri1'],
800+
'expectedNeedles' => ['John Doe', 'John M. Doe'],
801+
],
802+
'limit' => [
803+
'pattern' => 'john',
804+
'properties' => ['FN'],
805+
'options' => ['limit' => 1],
806+
'expectedUris' => ['uri0'],
807+
'expectedNeedles' => ['John Doe'],
808+
],
809+
'limit with offset' => [
810+
'pattern' => 'john',
811+
'properties' => ['FN'],
812+
'options' => ['limit' => 1, 'offset' => 1],
813+
'expectedUris' => ['uri1'],
814+
'expectedNeedles' => ['John M. Doe'],
815+
],
816+
'underscore is escaped by default' => [
817+
'pattern' => '_',
818+
'properties' => ['CLOUD'],
819+
'options' => [],
820+
'expectedUris' => ['uri2'],
821+
'expectedNeedles' => ['find without options'],
822+
],
823+
'underscore wildcard search when escape_like_param is false' => [
824+
'pattern' => '%_%',
825+
'properties' => ['CLOUD'],
826+
'options' => ['escape_like_param' => false],
827+
'expectedUris' => ['uri0', 'uri2'],
828+
'expectedNeedles' => ['John Doe', 'find without options'],
829+
],
806830
];
807831
}
808832

0 commit comments

Comments
 (0)