xref: /webtrees/tests/feature/IndividualListTest.php (revision b50dba3a86d260384d07c30bedf82d8e78ab49f7)
1e9e85398SGreg Roach<?php
23976b470SGreg Roach
3e9e85398SGreg Roach/**
4e9e85398SGreg Roach * webtrees: online genealogy
5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team
6e9e85398SGreg Roach * This program is free software: you can redistribute it and/or modify
7e9e85398SGreg Roach * it under the terms of the GNU General Public License as published by
8e9e85398SGreg Roach * the Free Software Foundation, either version 3 of the License, or
9e9e85398SGreg Roach * (at your option) any later version.
10e9e85398SGreg Roach * This program is distributed in the hope that it will be useful,
11e9e85398SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
12e9e85398SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13e9e85398SGreg Roach * GNU General Public License for more details.
14e9e85398SGreg Roach * You should have received a copy of the GNU General Public License
1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
16e9e85398SGreg Roach */
17fcfa147eSGreg Roach
18e9e85398SGreg Roachdeclare(strict_types=1);
19e9e85398SGreg Roach
20e9e85398SGreg Roachnamespace Fisharebest\Webtrees;
21e9e85398SGreg Roach
2271378461SGreg Roachuse Fig\Http\Message\RequestMethodInterface;
2371378461SGreg Roachuse Fig\Http\Message\StatusCodeInterface;
247dcc0dd1SGreg Roachuse Fisharebest\Webtrees\Contracts\UserInterface;
2587cca37cSGreg Roachuse Fisharebest\Webtrees\Module\IndividualListModule;
267dcc0dd1SGreg Roachuse Fisharebest\Webtrees\Services\GedcomImportService;
277dcc0dd1SGreg Roachuse Fisharebest\Webtrees\Services\TreeService;
287dcc0dd1SGreg Roachuse Fisharebest\Webtrees\Services\UserService;
29*202c018bSGreg Roachuse PHPUnit\Framework\Attributes\CoversClass;
30*202c018bSGreg Roach
317dcc0dd1SGreg Roachuse function array_map;
327dcc0dd1SGreg Roachuse function preg_match_all;
33b9fc687eSGreg Roach
34*202c018bSGreg Roach#[CoversClass(IndividualListModule::class)]
35e5a6b4d4SGreg Roachclass IndividualListTest extends TestCase
36e9e85398SGreg Roach{
37cd94ca66SGreg Roach    protected static bool $uses_database = true;
38e9e85398SGreg Roach
397dcc0dd1SGreg Roach    private Tree $tree;
407dcc0dd1SGreg Roach    private User $user;
417dcc0dd1SGreg Roach
427dcc0dd1SGreg Roach    public function setUp(): void
437dcc0dd1SGreg Roach    {
44a26ec5edSGreg Roach        parent::setUp();
45a26ec5edSGreg Roach
467dcc0dd1SGreg Roach        I18N::init('en-US');
477dcc0dd1SGreg Roach
487dcc0dd1SGreg Roach        $user_service = new UserService();
497dcc0dd1SGreg Roach        $tree_service = new TreeService(new GedcomImportService());
507dcc0dd1SGreg Roach        $this->tree   = $tree_service->create('name', 'title');
517dcc0dd1SGreg Roach        $this->user   = $user_service->create('user', 'User', 'user@example.com', 'secret');
527dcc0dd1SGreg Roach        $this->user->setPreference(UserInterface::PREF_IS_ADMINISTRATOR, '1');
537dcc0dd1SGreg Roach        $this->user->setPreference(UserInterface::PREF_AUTO_ACCEPT_EDITS, '1');
547dcc0dd1SGreg Roach        Auth::login($this->user);
557dcc0dd1SGreg Roach        // The default "John Doe" individual will confuse the test results...
567dcc0dd1SGreg Roach        Registry::individualFactory()->make('X1', $this->tree)->deleteRecord();
577dcc0dd1SGreg Roach    }
587dcc0dd1SGreg Roach
597dcc0dd1SGreg Roach    public function testCollationOfInitials(): void
60e9e85398SGreg Roach    {
61a26ec5edSGreg Roach        $module = new IndividualListModule();
62a26ec5edSGreg Roach
637dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /Âaa/");
647dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /aaa/");
657dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /Ååå/");
667dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /æææ/");
677dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /Caa/");
687dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /Css/");
697dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /Dza/");
70b9fc687eSGreg Roach
717dcc0dd1SGreg Roach        I18N::init('en-US');
727dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, [], [], [], ['tree' => $this->tree]);
73a26ec5edSGreg Roach        $response = $module->handle($request);
747dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
757dcc0dd1SGreg Roach        preg_match_all('/%2Findividual-list&amp;alpha=([^"&]+)/', $html, $matches);
767dcc0dd1SGreg Roach        self::assertEquals(['A', 'C', 'D', 'Æ'], array_map(rawurldecode(...), $matches[1]));
77b9fc687eSGreg Roach
787dcc0dd1SGreg Roach        I18N::init('sv');
797dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, [], [], [], ['tree' => $this->tree]);
80a26ec5edSGreg Roach        $response = $module->handle($request);
817dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
827dcc0dd1SGreg Roach        preg_match_all('/%2Findividual-list&amp;alpha=([^"&]+)/', $html, $matches);
837dcc0dd1SGreg Roach        self::assertEquals(['A', 'C', 'D', 'Å', 'Æ'], array_map(rawurldecode(...), $matches[1]));
84b9fc687eSGreg Roach
857dcc0dd1SGreg Roach        I18N::init('hu');
867dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, [], [], [], ['tree' => $this->tree]);
87a26ec5edSGreg Roach        $response = $module->handle($request);
887dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
897dcc0dd1SGreg Roach        preg_match_all('/%2Findividual-list&amp;alpha=([^"&]+)/', $html, $matches);
907dcc0dd1SGreg Roach        self::assertEquals(['A', 'C', 'CS', 'DZ', 'Æ'], array_map(rawurldecode(...), $matches[1]));
917dcc0dd1SGreg Roach    }
92a67cd39fSGreg Roach
93a26ec5edSGreg Roach    public function xtestRedirectToCanonicalSurname(): void
947dcc0dd1SGreg Roach    {
95a26ec5edSGreg Roach        $module = new IndividualListModule();
96a26ec5edSGreg Roach
977dcc0dd1SGreg Roach        I18N::init('en-US');
98a26ec5edSGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'Muller'], [], [], ['tree' => $this->tree]);
99a26ec5edSGreg Roach        $response = $module->handle($request);
100a26ec5edSGreg Roach        self::assertSame(StatusCodeInterface::STATUS_MOVED_PERMANENTLY, $response->getStatusCode());
101a26ec5edSGreg Roach        self::assertStringContainsString('surname=MULLER', $response->getHeaderLine('Location'));
102a26ec5edSGreg Roach
1037dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'MÜLLER'], [], [], ['tree' => $this->tree]);
104a26ec5edSGreg Roach        $response = $module->handle($request);
1057dcc0dd1SGreg Roach        self::assertSame(StatusCodeInterface::STATUS_MOVED_PERMANENTLY, $response->getStatusCode());
1067dcc0dd1SGreg Roach        self::assertStringContainsString('surname=MULLER', $response->getHeaderLine('Location'));
107b9fc687eSGreg Roach
1087dcc0dd1SGreg Roach        I18N::init('de');
1097dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'MÜLLER'], [], [], ['tree' => $this->tree]);
110a26ec5edSGreg Roach        $response = $module->handle($request);
1117dcc0dd1SGreg Roach        self::assertSame(StatusCodeInterface::STATUS_MOVED_PERMANENTLY, $response->getStatusCode());
1127dcc0dd1SGreg Roach        self::assertStringContainsString('surname=MUELLER', $response->getHeaderLine('Location'));
1137dcc0dd1SGreg Roach    }
1147dcc0dd1SGreg Roach
1157dcc0dd1SGreg Roach    public function testCollationOfSurnames(): void
1167dcc0dd1SGreg Roach    {
117a26ec5edSGreg Roach        $module = new IndividualListModule();
118a26ec5edSGreg Roach
1197dcc0dd1SGreg Roach        $i1 = $this->tree->createIndividual("0 @@ INDI\n1 NAME /Muller/");
1207dcc0dd1SGreg Roach        $i2 = $this->tree->createIndividual("0 @@ INDI\n1 NAME /Müller/");
1217dcc0dd1SGreg Roach        $i3 = $this->tree->createIndividual("0 @@ INDI\n1 NAME /Mueller/");
1227dcc0dd1SGreg Roach
1237dcc0dd1SGreg Roach        I18N::init('en-US');
1247dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'MULLER'], [], [], ['tree' => $this->tree]);
125a26ec5edSGreg Roach        $response = $module->handle($request);
1267dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1277dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1287dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i1->xref(), $i2->xref()], $matches[1], 'English, so U should match U and Ü');
1297dcc0dd1SGreg Roach
1307dcc0dd1SGreg Roach        I18N::init('de');
1317dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'MULLER'], [], [], ['tree' => $this->tree]);
132a26ec5edSGreg Roach        $response = $module->handle($request);
1337dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1347dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1357dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i1->xref()], $matches[1], 'German, so U should only match U');
1367dcc0dd1SGreg Roach
1377dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'MUELLER'], [], [], ['tree' => $this->tree]);
138a26ec5edSGreg Roach        $response = $module->handle($request);
1397dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1407dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1417dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i2->xref(), $i3->xref()], $matches[1], 'German, so UE should also match Ü');
1427dcc0dd1SGreg Roach    }
1437dcc0dd1SGreg Roach
144a26ec5edSGreg Roach    public function xtestUnknownVersusMissingSurname(): void
1457dcc0dd1SGreg Roach    {
146a26ec5edSGreg Roach        $module = new IndividualListModule();
147a26ec5edSGreg Roach
1487dcc0dd1SGreg Roach        $i1 = $this->tree->createIndividual("0 @@ INDI\n1 NAME John //");
1497dcc0dd1SGreg Roach        $i2 = $this->tree->createIndividual("0 @@ INDI\n1 NAME John");
1507dcc0dd1SGreg Roach
1517dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['alpha' => '@'], [], [], ['tree' => $this->tree]);
152a26ec5edSGreg Roach        $response = $module->handle($request);
1537dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1547dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1557dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i1->xref()], $matches[1]);
1567dcc0dd1SGreg Roach
1577dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['alpha' => ','], [], [], ['tree' => $this->tree]);
158a26ec5edSGreg Roach        $response = $module->handle($request);
1597dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1607dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1617dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i2->xref()], $matches[1]);
1627dcc0dd1SGreg Roach    }
1637dcc0dd1SGreg Roach
164a26ec5edSGreg Roach    public function xtestAllSurnamesExcludesUnknownAndMissing(): void
1657dcc0dd1SGreg Roach    {
166a26ec5edSGreg Roach        $module = new IndividualListModule();
167a26ec5edSGreg Roach
1687dcc0dd1SGreg Roach        $i1 = $this->tree->createIndividual("0 @@ INDI\n1 NAME John /Black/");
1697dcc0dd1SGreg Roach        $i2 = $this->tree->createIndividual("0 @@ INDI\n1 NAME Mary /White/");
1707dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME Peter //");
1717dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME Paul");
1727dcc0dd1SGreg Roach
1737dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['show_all' => 'yes'], [], [], ['tree' => $this->tree]);
174a26ec5edSGreg Roach        $response = $module->handle($request);
1757dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1767dcc0dd1SGreg Roach        preg_match_all('/individual-list&amp;surname=([A-Z]+)/', $html, $matches);
1777dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing(['BLACK', 'WHITE'], $matches[1]);
1787dcc0dd1SGreg Roach
1797dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['show_all' => 'yes', 'show' => 'indi'], [], [], ['tree' => $this->tree]);
180a26ec5edSGreg Roach        $response = $module->handle($request);
1817dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1827dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1837dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i1->xref(), $i2->xref()], $matches[1]);
1847dcc0dd1SGreg Roach    }
1857dcc0dd1SGreg Roach
186a26ec5edSGreg Roach    public function xtestSurnameInitial(): void
1877dcc0dd1SGreg Roach    {
188a26ec5edSGreg Roach        $module = new IndividualListModule();
189a26ec5edSGreg Roach
1907dcc0dd1SGreg Roach        $i1 = $this->tree->createIndividual("0 @@ INDI\n1 NAME John /Black/");
1917dcc0dd1SGreg Roach        $i2 = $this->tree->createIndividual("0 @@ INDI\n1 NAME Mary /Brown/");
1927dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME Peter /White/");
1937dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME Paul /Green/");
1947dcc0dd1SGreg Roach
1957dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['alpha' => 'B'], [], [], ['tree' => $this->tree]);
196a26ec5edSGreg Roach        $response = $module->handle($request);
1977dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1987dcc0dd1SGreg Roach        preg_match_all('/individual-list&amp;surname=([A-Z]+)/', $html, $matches);
1997dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing(['BLACK', 'BROWN'], $matches[1]);
2007dcc0dd1SGreg Roach
2017dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['alpha' => 'B', 'show' => 'indi'], [], [], ['tree' => $this->tree]);
202a26ec5edSGreg Roach        $response = $module->handle($request);
2037dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
2047dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
2057dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i1->xref(), $i2->xref()], $matches[1]);
206e9e85398SGreg Roach    }
207e9e85398SGreg Roach}
208