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