xref: /webtrees/tests/feature/IndividualListTest.php (revision a26ec5ede3c2ecdb45b783755ede967935aaecba)
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;
297dcc0dd1SGreg Roach
307dcc0dd1SGreg Roachuse function array_map;
317dcc0dd1SGreg Roachuse function preg_match_all;
32b9fc687eSGreg Roach
33e9e85398SGreg Roach/**
34b9fc687eSGreg Roach * Test the individual lists.
35e9e85398SGreg Roach *
36e9e85398SGreg Roach * @coversNothing
37e9e85398SGreg Roach */
38e5a6b4d4SGreg Roachclass IndividualListTest extends TestCase
39e9e85398SGreg Roach{
40cd94ca66SGreg Roach    protected static bool $uses_database = true;
41e9e85398SGreg Roach
427dcc0dd1SGreg Roach    private Tree $tree;
437dcc0dd1SGreg Roach    private User $user;
447dcc0dd1SGreg Roach
457dcc0dd1SGreg Roach    public function setUp(): void
467dcc0dd1SGreg Roach    {
47*a26ec5edSGreg Roach        parent::setUp();
48*a26ec5edSGreg Roach
497dcc0dd1SGreg Roach        I18N::init('en-US');
507dcc0dd1SGreg Roach
517dcc0dd1SGreg Roach        $user_service = new UserService();
527dcc0dd1SGreg Roach        $tree_service = new TreeService(new GedcomImportService());
537dcc0dd1SGreg Roach        $this->tree   = $tree_service->create('name', 'title');
547dcc0dd1SGreg Roach        $this->user   = $user_service->create('user', 'User', 'user@example.com', 'secret');
557dcc0dd1SGreg Roach        $this->user->setPreference(UserInterface::PREF_IS_ADMINISTRATOR, '1');
567dcc0dd1SGreg Roach        $this->user->setPreference(UserInterface::PREF_AUTO_ACCEPT_EDITS, '1');
577dcc0dd1SGreg Roach        Auth::login($this->user);
587dcc0dd1SGreg Roach        // The default "John Doe" individual will confuse the test results...
597dcc0dd1SGreg Roach        Registry::individualFactory()->make('X1', $this->tree)->deleteRecord();
607dcc0dd1SGreg Roach    }
617dcc0dd1SGreg Roach
62e9e85398SGreg Roach    /**
635e933c21SGreg Roach     * @covers \Fisharebest\Webtrees\Module\IndividualListModule
64e9e85398SGreg Roach     */
657dcc0dd1SGreg Roach    public function testCollationOfInitials(): void
66e9e85398SGreg Roach    {
67*a26ec5edSGreg Roach        $module = new IndividualListModule();
68*a26ec5edSGreg Roach
697dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /Âaa/");
707dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /aaa/");
717dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /Ååå/");
727dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /æææ/");
737dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /Caa/");
747dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /Css/");
757dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME /Dza/");
76b9fc687eSGreg Roach
777dcc0dd1SGreg Roach        I18N::init('en-US');
787dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, [], [], [], ['tree' => $this->tree]);
79*a26ec5edSGreg Roach        $response = $module->handle($request);
807dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
817dcc0dd1SGreg Roach        preg_match_all('/%2Findividual-list&amp;alpha=([^"&]+)/', $html, $matches);
827dcc0dd1SGreg Roach        self::assertEquals(['A', 'C', 'D', 'Æ'], array_map(rawurldecode(...), $matches[1]));
83b9fc687eSGreg Roach
847dcc0dd1SGreg Roach        I18N::init('sv');
857dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, [], [], [], ['tree' => $this->tree]);
86*a26ec5edSGreg Roach        $response = $module->handle($request);
877dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
887dcc0dd1SGreg Roach        preg_match_all('/%2Findividual-list&amp;alpha=([^"&]+)/', $html, $matches);
897dcc0dd1SGreg Roach        self::assertEquals(['A', 'C', 'D', 'Å', 'Æ'], array_map(rawurldecode(...), $matches[1]));
90b9fc687eSGreg Roach
917dcc0dd1SGreg Roach        I18N::init('hu');
927dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, [], [], [], ['tree' => $this->tree]);
93*a26ec5edSGreg Roach        $response = $module->handle($request);
947dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
957dcc0dd1SGreg Roach        preg_match_all('/%2Findividual-list&amp;alpha=([^"&]+)/', $html, $matches);
967dcc0dd1SGreg Roach        self::assertEquals(['A', 'C', 'CS', 'DZ', 'Æ'], array_map(rawurldecode(...), $matches[1]));
977dcc0dd1SGreg Roach    }
98a67cd39fSGreg Roach
997dcc0dd1SGreg Roach    /**
1007dcc0dd1SGreg Roach     * @covers \Fisharebest\Webtrees\Module\IndividualListModule
1017dcc0dd1SGreg Roach     */
102*a26ec5edSGreg Roach    public function xtestRedirectToCanonicalSurname(): void
1037dcc0dd1SGreg Roach    {
104*a26ec5edSGreg Roach        $module = new IndividualListModule();
105*a26ec5edSGreg Roach
1067dcc0dd1SGreg Roach        I18N::init('en-US');
107*a26ec5edSGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'Muller'], [], [], ['tree' => $this->tree]);
108*a26ec5edSGreg Roach        $response = $module->handle($request);
109*a26ec5edSGreg Roach        self::assertSame(StatusCodeInterface::STATUS_MOVED_PERMANENTLY, $response->getStatusCode());
110*a26ec5edSGreg Roach        self::assertStringContainsString('surname=MULLER', $response->getHeaderLine('Location'));
111*a26ec5edSGreg Roach
1127dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'MÜLLER'], [], [], ['tree' => $this->tree]);
113*a26ec5edSGreg Roach        $response = $module->handle($request);
1147dcc0dd1SGreg Roach        self::assertSame(StatusCodeInterface::STATUS_MOVED_PERMANENTLY, $response->getStatusCode());
1157dcc0dd1SGreg Roach        self::assertStringContainsString('surname=MULLER', $response->getHeaderLine('Location'));
116b9fc687eSGreg Roach
1177dcc0dd1SGreg Roach        I18N::init('de');
1187dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'MÜLLER'], [], [], ['tree' => $this->tree]);
119*a26ec5edSGreg Roach        $response = $module->handle($request);
1207dcc0dd1SGreg Roach        self::assertSame(StatusCodeInterface::STATUS_MOVED_PERMANENTLY, $response->getStatusCode());
1217dcc0dd1SGreg Roach        self::assertStringContainsString('surname=MUELLER', $response->getHeaderLine('Location'));
1227dcc0dd1SGreg Roach    }
1237dcc0dd1SGreg Roach
1247dcc0dd1SGreg Roach    /**
1257dcc0dd1SGreg Roach     * @covers \Fisharebest\Webtrees\Module\IndividualListModule
1267dcc0dd1SGreg Roach     */
1277dcc0dd1SGreg Roach    public function testCollationOfSurnames(): void
1287dcc0dd1SGreg Roach    {
129*a26ec5edSGreg Roach        $module = new IndividualListModule();
130*a26ec5edSGreg Roach
1317dcc0dd1SGreg Roach        $i1 = $this->tree->createIndividual("0 @@ INDI\n1 NAME /Muller/");
1327dcc0dd1SGreg Roach        $i2 = $this->tree->createIndividual("0 @@ INDI\n1 NAME /Müller/");
1337dcc0dd1SGreg Roach        $i3 = $this->tree->createIndividual("0 @@ INDI\n1 NAME /Mueller/");
1347dcc0dd1SGreg Roach
1357dcc0dd1SGreg Roach        I18N::init('en-US');
1367dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'MULLER'], [], [], ['tree' => $this->tree]);
137*a26ec5edSGreg Roach        $response = $module->handle($request);
1387dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1397dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1407dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i1->xref(), $i2->xref()], $matches[1], 'English, so U should match U and Ü');
1417dcc0dd1SGreg Roach
1427dcc0dd1SGreg Roach        I18N::init('de');
1437dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'MULLER'], [], [], ['tree' => $this->tree]);
144*a26ec5edSGreg Roach        $response = $module->handle($request);
1457dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1467dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1477dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i1->xref()], $matches[1], 'German, so U should only match U');
1487dcc0dd1SGreg Roach
1497dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['surname' => 'MUELLER'], [], [], ['tree' => $this->tree]);
150*a26ec5edSGreg Roach        $response = $module->handle($request);
1517dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1527dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1537dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i2->xref(), $i3->xref()], $matches[1], 'German, so UE should also match Ü');
1547dcc0dd1SGreg Roach    }
1557dcc0dd1SGreg Roach
1567dcc0dd1SGreg Roach    /**
1577dcc0dd1SGreg Roach     * @covers \Fisharebest\Webtrees\Module\IndividualListModule
1587dcc0dd1SGreg Roach     */
159*a26ec5edSGreg Roach    public function xtestUnknownVersusMissingSurname(): void
1607dcc0dd1SGreg Roach    {
161*a26ec5edSGreg Roach        $module = new IndividualListModule();
162*a26ec5edSGreg Roach
1637dcc0dd1SGreg Roach        $i1 = $this->tree->createIndividual("0 @@ INDI\n1 NAME John //");
1647dcc0dd1SGreg Roach        $i2 = $this->tree->createIndividual("0 @@ INDI\n1 NAME John");
1657dcc0dd1SGreg Roach
1667dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['alpha' => '@'], [], [], ['tree' => $this->tree]);
167*a26ec5edSGreg Roach        $response = $module->handle($request);
1687dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1697dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1707dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i1->xref()], $matches[1]);
1717dcc0dd1SGreg Roach
1727dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['alpha' => ','], [], [], ['tree' => $this->tree]);
173*a26ec5edSGreg Roach        $response = $module->handle($request);
1747dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1757dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
1767dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i2->xref()], $matches[1]);
1777dcc0dd1SGreg Roach    }
1787dcc0dd1SGreg Roach
1797dcc0dd1SGreg Roach    /**
1807dcc0dd1SGreg Roach     * @covers \Fisharebest\Webtrees\Module\IndividualListModule
1817dcc0dd1SGreg Roach     */
182*a26ec5edSGreg Roach    public function xtestAllSurnamesExcludesUnknownAndMissing(): void
1837dcc0dd1SGreg Roach    {
184*a26ec5edSGreg Roach        $module = new IndividualListModule();
185*a26ec5edSGreg Roach
1867dcc0dd1SGreg Roach        $i1 = $this->tree->createIndividual("0 @@ INDI\n1 NAME John /Black/");
1877dcc0dd1SGreg Roach        $i2 = $this->tree->createIndividual("0 @@ INDI\n1 NAME Mary /White/");
1887dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME Peter //");
1897dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME Paul");
1907dcc0dd1SGreg Roach
1917dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['show_all' => 'yes'], [], [], ['tree' => $this->tree]);
192*a26ec5edSGreg Roach        $response = $module->handle($request);
1937dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
1947dcc0dd1SGreg Roach        preg_match_all('/individual-list&amp;surname=([A-Z]+)/', $html, $matches);
1957dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing(['BLACK', 'WHITE'], $matches[1]);
1967dcc0dd1SGreg Roach
1977dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['show_all' => 'yes', 'show' => 'indi'], [], [], ['tree' => $this->tree]);
198*a26ec5edSGreg Roach        $response = $module->handle($request);
1997dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
2007dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
2017dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i1->xref(), $i2->xref()], $matches[1]);
2027dcc0dd1SGreg Roach    }
2037dcc0dd1SGreg Roach
2047dcc0dd1SGreg Roach    /**
2057dcc0dd1SGreg Roach     * @covers \Fisharebest\Webtrees\Module\IndividualListModule
2067dcc0dd1SGreg Roach     */
207*a26ec5edSGreg Roach    public function xtestSurnameInitial(): void
2087dcc0dd1SGreg Roach    {
209*a26ec5edSGreg Roach        $module = new IndividualListModule();
210*a26ec5edSGreg Roach
2117dcc0dd1SGreg Roach        $i1 = $this->tree->createIndividual("0 @@ INDI\n1 NAME John /Black/");
2127dcc0dd1SGreg Roach        $i2 = $this->tree->createIndividual("0 @@ INDI\n1 NAME Mary /Brown/");
2137dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME Peter /White/");
2147dcc0dd1SGreg Roach        $this->tree->createIndividual("0 @@ INDI\n1 NAME Paul /Green/");
2157dcc0dd1SGreg Roach
2167dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['alpha' => 'B'], [], [], ['tree' => $this->tree]);
217*a26ec5edSGreg Roach        $response = $module->handle($request);
2187dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
2197dcc0dd1SGreg Roach        preg_match_all('/individual-list&amp;surname=([A-Z]+)/', $html, $matches);
2207dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing(['BLACK', 'BROWN'], $matches[1]);
2217dcc0dd1SGreg Roach
2227dcc0dd1SGreg Roach        $request  = self::createRequest(RequestMethodInterface::METHOD_GET, ['alpha' => 'B', 'show' => 'indi'], [], [], ['tree' => $this->tree]);
223*a26ec5edSGreg Roach        $response = $module->handle($request);
2247dcc0dd1SGreg Roach        $html     = $response->getBody()->getContents();
2257dcc0dd1SGreg Roach        preg_match_all('/%2Fname%2Findividual%2F(X\d+)%2F/', $html, $matches);
2267dcc0dd1SGreg Roach        self::assertEqualsCanonicalizing([$i1->xref(), $i2->xref()], $matches[1]);
227e9e85398SGreg Roach    }
228e9e85398SGreg Roach}
229