xref: /webtrees/tests/app/TreeTest.php (revision 803193fe6835fa954147d30cdf6ce1a1da6103ff)
1a25f0a04SGreg Roach<?php
2a25f0a04SGreg Roach/**
3a25f0a04SGreg Roach * webtrees: online genealogy
48fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team
5a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify
6a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by
7a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or
8a25f0a04SGreg Roach * (at your option) any later version.
9a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful,
10a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
11a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12a25f0a04SGreg Roach * GNU General Public License for more details.
13a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License
14a25f0a04SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
15a25f0a04SGreg Roach */
16e7f56f2aSGreg Roachdeclare(strict_types=1);
17e7f56f2aSGreg Roach
1884e2cf4eSGreg Roachnamespace Fisharebest\Webtrees;
19a25f0a04SGreg Roach
20e5a6b4d4SGreg Roachuse Fisharebest\Webtrees\Services\UserService;
2194026f20SGreg Roachuse function stream_get_contents;
2294026f20SGreg Roach
23a25f0a04SGreg Roach/**
24a25f0a04SGreg Roach * Test harness for the class Tree
25a25f0a04SGreg Roach */
26e5a6b4d4SGreg Roachclass TreeTest extends TestCase
27c1010edaSGreg Roach{
28126654d7SGreg Roach    protected static $uses_database = true;
29126654d7SGreg Roach
30a25f0a04SGreg Roach    /**
31126654d7SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::__construct
32126654d7SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::create
33126654d7SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::id
34126654d7SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::name
35126654d7SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::title
3652348eb8SGreg Roach     *
3752348eb8SGreg Roach     * @return void
38a25f0a04SGreg Roach     */
39126654d7SGreg Roach    public function testConstructor(): void
40c1010edaSGreg Roach    {
41126654d7SGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
42126654d7SGreg Roach
43126654d7SGreg Roach        $this->assertSame(1, $tree->id());
44126654d7SGreg Roach        $this->assertSame('tree-name', $tree->name());
45126654d7SGreg Roach        $this->assertSame('Tree title', $tree->title());
46126654d7SGreg Roach    }
47126654d7SGreg Roach
48126654d7SGreg Roach    /**
49126654d7SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::getPreference
50126654d7SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::setPreference
51126654d7SGreg Roach     *
52126654d7SGreg Roach     * @return void
53126654d7SGreg Roach     */
54af343084SGreg Roach    public function testTreePreferences(): void
55126654d7SGreg Roach    {
56126654d7SGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
57126654d7SGreg Roach
58126654d7SGreg Roach        $pref = $tree->getPreference('foo', 'default');
59126654d7SGreg Roach        $this->assertSame('default', $pref);
60126654d7SGreg Roach
61126654d7SGreg Roach        $tree->setPreference('foo', 'bar');
62126654d7SGreg Roach        $pref = $tree->getPreference('foo', 'default');
63126654d7SGreg Roach        $this->assertSame('bar', $pref);
64a25f0a04SGreg Roach    }
65af343084SGreg Roach
66af343084SGreg Roach    /**
67af343084SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::getUserPreference
68000dd58cSGreg Roach     * @covers \Fisharebest\Webtrees\Tree::setUserPreference
69af343084SGreg Roach     *
70af343084SGreg Roach     * @return void
71af343084SGreg Roach     */
72af343084SGreg Roach    public function testUserTreePreferences(): void
73af343084SGreg Roach    {
74e5a6b4d4SGreg Roach        $user_service = new UserService();
75af343084SGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
76e5a6b4d4SGreg Roach        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
77af343084SGreg Roach
78af343084SGreg Roach        $pref = $tree->getUserPreference($user, 'foo', 'default');
79af343084SGreg Roach        $this->assertSame('default', $pref);
80af343084SGreg Roach
81af343084SGreg Roach        $tree->setUserPreference($user, 'foo', 'bar');
82af343084SGreg Roach        $pref = $tree->getUserPreference($user, 'foo', 'default');
83af343084SGreg Roach        $this->assertSame('bar', $pref);
84af343084SGreg Roach    }
85963fbaeeSGreg Roach
86963fbaeeSGreg Roach    /**
877d76853dSGreg Roach     * @covers \Fisharebest\Webtrees\Tree::getNewXref
887d76853dSGreg Roach     *
897d76853dSGreg Roach     * @return void
907d76853dSGreg Roach     */
917d76853dSGreg Roach    public function testGetNewXref(): void
927d76853dSGreg Roach    {
937d76853dSGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
947d76853dSGreg Roach
957d76853dSGreg Roach        $this->assertSame('X1', $tree->getNewXref());
967d76853dSGreg Roach        $this->assertSame('X2', $tree->getNewXref());
977d76853dSGreg Roach        $this->assertSame('X3', $tree->getNewXref());
987d76853dSGreg Roach        $this->assertSame('X4', $tree->getNewXref());
997d76853dSGreg Roach        $this->assertSame('X5', $tree->getNewXref());
1007d76853dSGreg Roach    }
1017d76853dSGreg Roach
1027d76853dSGreg Roach    /**
1037d76853dSGreg Roach     * @covers \Fisharebest\Webtrees\Tree::createIndividual
1047d76853dSGreg Roach     * @expectedException \InvalidArgumentException
1057d76853dSGreg Roach     *
1067d76853dSGreg Roach     * @return void
1077d76853dSGreg Roach     */
1087d76853dSGreg Roach    public function testCreateInvalidIndividual(): void
1097d76853dSGreg Roach    {
110e5a6b4d4SGreg Roach        $user_service = new UserService();
1117d76853dSGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
112e5a6b4d4SGreg Roach        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
1137d76853dSGreg Roach        $user->setPreference('canadmin', '1');
1147d76853dSGreg Roach        Auth::login($user);
1157d76853dSGreg Roach
1167d76853dSGreg Roach        $tree->createIndividual("0 @@ FOO\n1 SEX U");
1177d76853dSGreg Roach    }
1187d76853dSGreg Roach
1197d76853dSGreg Roach    /**
120963fbaeeSGreg Roach     * @covers \Fisharebest\Webtrees\Tree::createIndividual
121963fbaeeSGreg Roach     *
122963fbaeeSGreg Roach     * @return void
123963fbaeeSGreg Roach     */
124963fbaeeSGreg Roach    public function testCreateIndividual(): void
125963fbaeeSGreg Roach    {
126e5a6b4d4SGreg Roach        $user_service = new UserService();
127963fbaeeSGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
128e5a6b4d4SGreg Roach        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
129963fbaeeSGreg Roach        $user->setPreference('canadmin', '1');
130963fbaeeSGreg Roach        Auth::login($user);
131963fbaeeSGreg Roach
1328f9b0fb2SGreg Roach        $record = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
1338f9b0fb2SGreg Roach        $this->assertTrue($record->isPendingAddition());
134963fbaeeSGreg Roach
135963fbaeeSGreg Roach        $user->setPreference('auto_accept', '1');
1368f9b0fb2SGreg Roach        $record = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
1378f9b0fb2SGreg Roach        $this->assertFalse($record->isPendingAddition());
1388f9b0fb2SGreg Roach    }
139963fbaeeSGreg Roach
1408f9b0fb2SGreg Roach    /**
1417d76853dSGreg Roach     * @covers \Fisharebest\Webtrees\Tree::createFamily
1427d76853dSGreg Roach     * @expectedException \InvalidArgumentException
1438f9b0fb2SGreg Roach     *
1448f9b0fb2SGreg Roach     * @return void
1458f9b0fb2SGreg Roach     */
1467d76853dSGreg Roach    public function testCreateInvalidFamily(): void
1478f9b0fb2SGreg Roach    {
148e5a6b4d4SGreg Roach        $user_service = new UserService();
1498f9b0fb2SGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
150e5a6b4d4SGreg Roach        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
1517d76853dSGreg Roach        $user->setPreference('canadmin', '1');
1527d76853dSGreg Roach        Auth::login($user);
153963fbaeeSGreg Roach
1547d76853dSGreg Roach        $tree->createFamily("0 @@ FOO\n1 MARR Y");
1558f9b0fb2SGreg Roach    }
156963fbaeeSGreg Roach
1578f9b0fb2SGreg Roach    /**
1588f9b0fb2SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::createFamily
1598f9b0fb2SGreg Roach     *
1608f9b0fb2SGreg Roach     * @return void
1618f9b0fb2SGreg Roach     */
1628f9b0fb2SGreg Roach    public function testCreateFamily(): void
1638f9b0fb2SGreg Roach    {
164e5a6b4d4SGreg Roach        $user_service = new UserService();
1658f9b0fb2SGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
166e5a6b4d4SGreg Roach        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
1678f9b0fb2SGreg Roach        $user->setPreference('canadmin', '1');
1688f9b0fb2SGreg Roach        Auth::login($user);
1698f9b0fb2SGreg Roach
1708f9b0fb2SGreg Roach        $record = $tree->createFamily("0 @@ FAM\n1 MARR Y");
1718f9b0fb2SGreg Roach        $this->assertTrue($record->isPendingAddition());
1728f9b0fb2SGreg Roach
1738f9b0fb2SGreg Roach        $user->setPreference('auto_accept', '1');
1748f9b0fb2SGreg Roach        $record = $tree->createFamily("0 @@ FAM\n1 MARR Y");
1758f9b0fb2SGreg Roach        $this->assertFalse($record->isPendingAddition());
1768f9b0fb2SGreg Roach    }
1778f9b0fb2SGreg Roach
1788f9b0fb2SGreg Roach    /**
1797d76853dSGreg Roach     * @covers \Fisharebest\Webtrees\Tree::createMediaObject
1807d76853dSGreg Roach     * @expectedException \InvalidArgumentException
1817d76853dSGreg Roach     *
1827d76853dSGreg Roach     * @return void
1837d76853dSGreg Roach     */
1847d76853dSGreg Roach    public function testCreateInvalidMediaObject(): void
1857d76853dSGreg Roach    {
186e5a6b4d4SGreg Roach        $user_service = new UserService();
1877d76853dSGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
188e5a6b4d4SGreg Roach        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
1897d76853dSGreg Roach        $user->setPreference('canadmin', '1');
1907d76853dSGreg Roach        Auth::login($user);
1917d76853dSGreg Roach
1927d76853dSGreg Roach        $tree->createMediaObject("0 @@ FOO\n1 MARR Y");
1937d76853dSGreg Roach    }
1947d76853dSGreg Roach
1957d76853dSGreg Roach    /**
1967d76853dSGreg Roach     * @covers \Fisharebest\Webtrees\Tree::createMediaObject
1977d76853dSGreg Roach     *
1987d76853dSGreg Roach     * @return void
1997d76853dSGreg Roach     */
2007d76853dSGreg Roach    public function testCreateMediaObject(): void
2017d76853dSGreg Roach    {
202e5a6b4d4SGreg Roach        $user_service = new UserService();
2037d76853dSGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
204e5a6b4d4SGreg Roach        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
2057d76853dSGreg Roach        $user->setPreference('canadmin', '1');
2067d76853dSGreg Roach        Auth::login($user);
2077d76853dSGreg Roach
2087d76853dSGreg Roach        $record = $tree->createMediaObject("0 @@ OBJE\n1 FILE foo.jpeg");
2097d76853dSGreg Roach        $this->assertTrue($record->isPendingAddition());
2107d76853dSGreg Roach
2117d76853dSGreg Roach        $user->setPreference('auto_accept', '1');
2127d76853dSGreg Roach        $record = $tree->createMediaObject("0 @@ OBJE\n1 FILE foo.jpeg");
2137d76853dSGreg Roach        $this->assertFalse($record->isPendingAddition());
2147d76853dSGreg Roach    }
2157d76853dSGreg Roach
2167d76853dSGreg Roach    /**
217bec87e94SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::createRecord
218bec87e94SGreg Roach     * @expectedException \InvalidArgumentException
219bec87e94SGreg Roach     *
220bec87e94SGreg Roach     * @return void
221bec87e94SGreg Roach     */
222bec87e94SGreg Roach    public function testCreateInvalidRecord(): void
223bec87e94SGreg Roach    {
224e5a6b4d4SGreg Roach        $user_service = new UserService();
225bec87e94SGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
226e5a6b4d4SGreg Roach        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
227bec87e94SGreg Roach        $user->setPreference('canadmin', '1');
228bec87e94SGreg Roach        Auth::login($user);
229bec87e94SGreg Roach
230bec87e94SGreg Roach        $tree->createRecord("0 @@FOO\n1 NOTE noted");
231bec87e94SGreg Roach    }
232bec87e94SGreg Roach
233bec87e94SGreg Roach    /**
234bec87e94SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::createRecord
235bec87e94SGreg Roach     *
236bec87e94SGreg Roach     * @return void
237bec87e94SGreg Roach     */
238bec87e94SGreg Roach    public function testCreateRecord(): void
239bec87e94SGreg Roach    {
240e5a6b4d4SGreg Roach        $user_service = new UserService();
241bec87e94SGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
242e5a6b4d4SGreg Roach        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
243bec87e94SGreg Roach        $user->setPreference('canadmin', '1');
244bec87e94SGreg Roach        Auth::login($user);
245bec87e94SGreg Roach
246bec87e94SGreg Roach        $record = $tree->createRecord("0 @@ FOO\n1 NOTE noted");
247bec87e94SGreg Roach        $this->assertTrue($record->isPendingAddition());
248bec87e94SGreg Roach
249bec87e94SGreg Roach        $user->setPreference('auto_accept', '1');
250bec87e94SGreg Roach        $record = $tree->createRecord("0 @@ FOO\n1 NOTE noted");
251bec87e94SGreg Roach        $this->assertFalse($record->isPendingAddition());
252bec87e94SGreg Roach    }
253bec87e94SGreg Roach
254bec87e94SGreg Roach    /**
2558f9b0fb2SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::significantIndividual
2568f9b0fb2SGreg Roach     *
2578f9b0fb2SGreg Roach     * @return void
2588f9b0fb2SGreg Roach     */
2598f9b0fb2SGreg Roach    public function testSignificantIndividual(): void
2608f9b0fb2SGreg Roach    {
261e5a6b4d4SGreg Roach        $user_service = new UserService();
2628f9b0fb2SGreg Roach        $tree = Tree::create('tree-name', 'Tree title');
263e5a6b4d4SGreg Roach        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
2648f9b0fb2SGreg Roach        $user->setPreference('auto_accept', '1');
2658f9b0fb2SGreg Roach        Auth::login($user);
2668f9b0fb2SGreg Roach
2678f9b0fb2SGreg Roach        // No individuals in tree?  Dummy individual
2688f9b0fb2SGreg Roach        $this->assertSame('I', $tree->significantIndividual($user)->xref());
2698f9b0fb2SGreg Roach
2708f9b0fb2SGreg Roach        $record1 = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
2718f9b0fb2SGreg Roach        $record2 = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
2728f9b0fb2SGreg Roach        $record3 = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
2738f9b0fb2SGreg Roach        $record4 = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
2748f9b0fb2SGreg Roach
2758f9b0fb2SGreg Roach        // Individuals exist?  First one (lowest XREF).
2768f9b0fb2SGreg Roach        $this->assertSame($record1->xref(), $tree->significantIndividual($user)->xref());
2778f9b0fb2SGreg Roach
2788f9b0fb2SGreg Roach        // Preference for tree?
2798f9b0fb2SGreg Roach        $tree->setPreference('PEDIGREE_ROOT_ID', $record2->xref());
2808f9b0fb2SGreg Roach        $this->assertSame($record2->xref(), $tree->significantIndividual($user)->xref());
2818f9b0fb2SGreg Roach
2828f9b0fb2SGreg Roach        // User preference
2838f9b0fb2SGreg Roach        $tree->setUserPreference($user, 'gedcomid', $record3->xref());
2848f9b0fb2SGreg Roach        $this->assertSame($record3->xref(), $tree->significantIndividual($user)->xref());
2858f9b0fb2SGreg Roach
2868f9b0fb2SGreg Roach        // User record
2878f9b0fb2SGreg Roach        $tree->setUserPreference($user, 'rootid', $record4->xref());
2888f9b0fb2SGreg Roach        $this->assertSame($record4->xref(), $tree->significantIndividual($user)->xref());
289963fbaeeSGreg Roach    }
290a7890280SGreg Roach
291a7890280SGreg Roach    /**
292a7890280SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::importGedcomFile
293a7890280SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::deleteGenealogyData
294a7890280SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::delete
295a7890280SGreg Roach     *
296a7890280SGreg Roach     * @return void
297a7890280SGreg Roach     */
298a7890280SGreg Roach    public function testImportAndDeleteGedcomFile(): void
299a7890280SGreg Roach    {
300a7890280SGreg Roach        $tree = $this->importTree('demo.ged');
301a7890280SGreg Roach        $this->assertNotNull(Tree::findByName('demo.ged'));
302432ff88aSGreg Roach        Site::setPreference('DEFAULT_GEDCOM', $tree->name());
303a7890280SGreg Roach
304a7890280SGreg Roach        $tree->delete();
305432ff88aSGreg Roach
306a7890280SGreg Roach        $this->assertNull(Tree::findByName('demo.ged'));
307432ff88aSGreg Roach        $this->assertSame('', Site::getPreference('DEFAULT_GEDCOM'));
308a7890280SGreg Roach    }
30915a3f100SGreg Roach
31015a3f100SGreg Roach    /**
31115a3f100SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::hasPendingEdit
31215a3f100SGreg Roach     *
31315a3f100SGreg Roach     * @return void
31415a3f100SGreg Roach     */
31515a3f100SGreg Roach    public function testHasPendingEdits(): void
31615a3f100SGreg Roach    {
317e5a6b4d4SGreg Roach        $user_service = new UserService();
31815a3f100SGreg Roach        $tree = $this->importTree('demo.ged');
319e5a6b4d4SGreg Roach        $user = $user_service->create('admin', 'Administrator', 'admin@example.com', 'secret');
32015a3f100SGreg Roach        $user->setPreference('canadmin', '1');
32115a3f100SGreg Roach        Auth::login($user);
32215a3f100SGreg Roach
32315a3f100SGreg Roach        $user->setPreference('auto_accept', '1');
32415a3f100SGreg Roach        $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
32515a3f100SGreg Roach        $this->assertFalse($tree->hasPendingEdit());
32615a3f100SGreg Roach
32715a3f100SGreg Roach        $user->setPreference('auto_accept', '0');
32815a3f100SGreg Roach        $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
32915a3f100SGreg Roach        $this->assertTrue($tree->hasPendingEdit());
33015a3f100SGreg Roach    }
33194026f20SGreg Roach
33294026f20SGreg Roach    /**
33394026f20SGreg Roach     * @covers \Fisharebest\Webtrees\Tree::exportGedcom
33494026f20SGreg Roach     *
33594026f20SGreg Roach     * @return void
33694026f20SGreg Roach     */
33794026f20SGreg Roach    public function testExportGedcom(): void
33894026f20SGreg Roach    {
33994026f20SGreg Roach        $tree = $this->importTree('demo.ged');
34094026f20SGreg Roach
341*803193feSGreg Roach        $fp = fopen('php://memory', 'wb');
34294026f20SGreg Roach
34394026f20SGreg Roach        $tree->exportGedcom($fp);
34494026f20SGreg Roach
34594026f20SGreg Roach        rewind($fp);
34694026f20SGreg Roach
34794026f20SGreg Roach        $original = file_get_contents(__DIR__ . '/../data/demo.ged');
34894026f20SGreg Roach        $export   = stream_get_contents($fp);
34994026f20SGreg Roach
35094026f20SGreg Roach        // The date and time in the HEAD record will be different.
35194026f20SGreg Roach        $original = preg_replace('/\n1 DATE .. ... ..../', '', $original, 1);
35294026f20SGreg Roach        $export   = preg_replace('/\n1 DATE .. ... ..../', '', $export, 1);
35394026f20SGreg Roach        $original = preg_replace('/\n2 TIME ..:..:../', '', $original, 1);
35494026f20SGreg Roach        $export   = preg_replace('/\n2 TIME ..:..:../', '', $export, 1);
35594026f20SGreg Roach
35694026f20SGreg Roach        $this->assertSame($original, $export);
35794026f20SGreg Roach    }
358a25f0a04SGreg Roach}
359