xref: /webtrees/tests/app/TreeTest.php (revision 3976b4703df669696105ed6b024b96d433c8fbdb)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2019 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17declare(strict_types=1);
18
19namespace Fisharebest\Webtrees;
20
21use Fisharebest\Webtrees\Services\UserService;
22
23use function stream_get_contents;
24
25/**
26 * Test harness for the class Tree
27 */
28class TreeTest extends TestCase
29{
30    protected static $uses_database = true;
31
32    /**
33     * @covers \Fisharebest\Webtrees\Tree::__construct
34     * @covers \Fisharebest\Webtrees\Tree::create
35     * @covers \Fisharebest\Webtrees\Tree::id
36     * @covers \Fisharebest\Webtrees\Tree::name
37     * @covers \Fisharebest\Webtrees\Tree::title
38     *
39     * @return void
40     */
41    public function testConstructor(): void
42    {
43        $tree = Tree::create('tree-name', 'Tree title');
44
45        $this->assertSame('tree-name', $tree->name());
46        $this->assertSame('Tree title', $tree->title());
47    }
48
49    /**
50     * @covers \Fisharebest\Webtrees\Tree::getPreference
51     * @covers \Fisharebest\Webtrees\Tree::setPreference
52     *
53     * @return void
54     */
55    public function testTreePreferences(): void
56    {
57        $tree = Tree::create('tree-name', 'Tree title');
58
59        $pref = $tree->getPreference('foo', 'default');
60        $this->assertSame('default', $pref);
61
62        $tree->setPreference('foo', 'bar');
63        $pref = $tree->getPreference('foo', 'default');
64        $this->assertSame('bar', $pref);
65    }
66
67    /**
68     * @covers \Fisharebest\Webtrees\Tree::getUserPreference
69     * @covers \Fisharebest\Webtrees\Tree::setUserPreference
70     *
71     * @return void
72     */
73    public function testUserTreePreferences(): void
74    {
75        $user_service = new UserService();
76        $tree = Tree::create('tree-name', 'Tree title');
77        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
78
79        $pref = $tree->getUserPreference($user, 'foo', 'default');
80        $this->assertSame('default', $pref);
81
82        $tree->setUserPreference($user, 'foo', 'bar');
83        $pref = $tree->getUserPreference($user, 'foo', 'default');
84        $this->assertSame('bar', $pref);
85    }
86
87    /**
88     * @covers \Fisharebest\Webtrees\Tree::getNewXref
89     *
90     * @return void
91     */
92    public function testGetNewXref(): void
93    {
94        $tree = Tree::create('tree-name', 'Tree title');
95
96        $this->assertSame('X1', $tree->getNewXref());
97        $this->assertSame('X2', $tree->getNewXref());
98        $this->assertSame('X3', $tree->getNewXref());
99        $this->assertSame('X4', $tree->getNewXref());
100        $this->assertSame('X5', $tree->getNewXref());
101    }
102
103    /**
104     * @covers \Fisharebest\Webtrees\Tree::createIndividual
105     * @expectedException \InvalidArgumentException
106     *
107     * @return void
108     */
109    public function testCreateInvalidIndividual(): void
110    {
111        $user_service = new UserService();
112        $tree = Tree::create('tree-name', 'Tree title');
113        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
114        $user->setPreference('canadmin', '1');
115        Auth::login($user);
116
117        $tree->createIndividual("0 @@ FOO\n1 SEX U");
118    }
119
120    /**
121     * @covers \Fisharebest\Webtrees\Tree::createIndividual
122     *
123     * @return void
124     */
125    public function testCreateIndividual(): void
126    {
127        $user_service = new UserService();
128        $tree = Tree::create('tree-name', 'Tree title');
129        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
130        $user->setPreference('canadmin', '1');
131        Auth::login($user);
132
133        $record = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
134        $this->assertTrue($record->isPendingAddition());
135
136        $user->setPreference('auto_accept', '1');
137        $record = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
138        $this->assertFalse($record->isPendingAddition());
139    }
140
141    /**
142     * @covers \Fisharebest\Webtrees\Tree::createFamily
143     * @expectedException \InvalidArgumentException
144     *
145     * @return void
146     */
147    public function testCreateInvalidFamily(): void
148    {
149        $user_service = new UserService();
150        $tree = Tree::create('tree-name', 'Tree title');
151        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
152        $user->setPreference('canadmin', '1');
153        Auth::login($user);
154
155        $tree->createFamily("0 @@ FOO\n1 MARR Y");
156    }
157
158    /**
159     * @covers \Fisharebest\Webtrees\Tree::createFamily
160     *
161     * @return void
162     */
163    public function testCreateFamily(): void
164    {
165        $user_service = new UserService();
166        $tree = Tree::create('tree-name', 'Tree title');
167        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
168        $user->setPreference('canadmin', '1');
169        Auth::login($user);
170
171        $record = $tree->createFamily("0 @@ FAM\n1 MARR Y");
172        $this->assertTrue($record->isPendingAddition());
173
174        $user->setPreference('auto_accept', '1');
175        $record = $tree->createFamily("0 @@ FAM\n1 MARR Y");
176        $this->assertFalse($record->isPendingAddition());
177    }
178
179    /**
180     * @covers \Fisharebest\Webtrees\Tree::createMediaObject
181     * @expectedException \InvalidArgumentException
182     *
183     * @return void
184     */
185    public function testCreateInvalidMediaObject(): void
186    {
187        $user_service = new UserService();
188        $tree = Tree::create('tree-name', 'Tree title');
189        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
190        $user->setPreference('canadmin', '1');
191        Auth::login($user);
192
193        $tree->createMediaObject("0 @@ FOO\n1 MARR Y");
194    }
195
196    /**
197     * @covers \Fisharebest\Webtrees\Tree::createMediaObject
198     *
199     * @return void
200     */
201    public function testCreateMediaObject(): void
202    {
203        $user_service = new UserService();
204        $tree = Tree::create('tree-name', 'Tree title');
205        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
206        $user->setPreference('canadmin', '1');
207        Auth::login($user);
208
209        $record = $tree->createMediaObject("0 @@ OBJE\n1 FILE foo.jpeg");
210        $this->assertTrue($record->isPendingAddition());
211
212        $user->setPreference('auto_accept', '1');
213        $record = $tree->createMediaObject("0 @@ OBJE\n1 FILE foo.jpeg");
214        $this->assertFalse($record->isPendingAddition());
215    }
216
217    /**
218     * @covers \Fisharebest\Webtrees\Tree::createRecord
219     * @expectedException \InvalidArgumentException
220     *
221     * @return void
222     */
223    public function testCreateInvalidRecord(): void
224    {
225        $user_service = new UserService();
226        $tree = Tree::create('tree-name', 'Tree title');
227        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
228        $user->setPreference('canadmin', '1');
229        Auth::login($user);
230
231        $tree->createRecord("0 @@FOO\n1 NOTE noted");
232    }
233
234    /**
235     * @covers \Fisharebest\Webtrees\Tree::createRecord
236     *
237     * @return void
238     */
239    public function testCreateRecord(): void
240    {
241        $user_service = new UserService();
242        $tree = Tree::create('tree-name', 'Tree title');
243        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
244        $user->setPreference('canadmin', '1');
245        Auth::login($user);
246
247        $record = $tree->createRecord("0 @@ FOO\n1 NOTE noted");
248        $this->assertTrue($record->isPendingAddition());
249
250        $user->setPreference('auto_accept', '1');
251        $record = $tree->createRecord("0 @@ FOO\n1 NOTE noted");
252        $this->assertFalse($record->isPendingAddition());
253    }
254
255    /**
256     * @covers \Fisharebest\Webtrees\Tree::significantIndividual
257     *
258     * @return void
259     */
260    public function testSignificantIndividual(): void
261    {
262        $user_service = new UserService();
263        $tree = Tree::create('tree-name', 'Tree title');
264        $user = $user_service->create('user', 'User', 'user@example.com', 'secret');
265        $user->setPreference('auto_accept', '1');
266        Auth::login($user);
267
268        // No individuals in tree?  Dummy individual
269        $this->assertSame('I', $tree->significantIndividual($user)->xref());
270
271        $record1 = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
272        $record2 = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
273        $record3 = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
274        $record4 = $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
275
276        // Individuals exist?  First one (lowest XREF).
277        $this->assertSame($record1->xref(), $tree->significantIndividual($user)->xref());
278
279        // Preference for tree?
280        $tree->setPreference('PEDIGREE_ROOT_ID', $record2->xref());
281        $this->assertSame($record2->xref(), $tree->significantIndividual($user)->xref());
282
283        // User preference
284        $tree->setUserPreference($user, 'gedcomid', $record3->xref());
285        $this->assertSame($record3->xref(), $tree->significantIndividual($user)->xref());
286
287        // User record
288        $tree->setUserPreference($user, 'rootid', $record4->xref());
289        $this->assertSame($record4->xref(), $tree->significantIndividual($user)->xref());
290    }
291
292    /**
293     * @covers \Fisharebest\Webtrees\Tree::importGedcomFile
294     * @covers \Fisharebest\Webtrees\Tree::deleteGenealogyData
295     * @covers \Fisharebest\Webtrees\Tree::delete
296     *
297     * @return void
298     */
299    public function testImportAndDeleteGedcomFile(): void
300    {
301        $tree = $this->importTree('demo.ged');
302        $this->assertNotNull(Tree::findByName('demo.ged'));
303        Site::setPreference('DEFAULT_GEDCOM', $tree->name());
304
305        $tree->delete();
306
307        $this->assertNull(Tree::findByName('demo.ged'));
308        $this->assertSame('', Site::getPreference('DEFAULT_GEDCOM'));
309    }
310
311    /**
312     * @covers \Fisharebest\Webtrees\Tree::hasPendingEdit
313     *
314     * @return void
315     */
316    public function testHasPendingEdits(): void
317    {
318        $user_service = new UserService();
319        $tree = $this->importTree('demo.ged');
320        $user = $user_service->create('admin', 'Administrator', 'admin@example.com', 'secret');
321        $user->setPreference('canadmin', '1');
322        Auth::login($user);
323
324        $user->setPreference('auto_accept', '1');
325        $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
326        $this->assertFalse($tree->hasPendingEdit());
327
328        $user->setPreference('auto_accept', '0');
329        $tree->createIndividual("0 @@ INDI\n1 SEX F\n1 NAME Foo /Bar/");
330        $this->assertTrue($tree->hasPendingEdit());
331    }
332
333    /**
334     * @covers \Fisharebest\Webtrees\Tree::exportGedcom
335     *
336     * @return void
337     */
338    public function testExportGedcom(): void
339    {
340        $tree = $this->importTree('demo.ged');
341
342        $fp = fopen('php://memory', 'wb');
343
344        $tree->exportGedcom($fp);
345
346        rewind($fp);
347
348        $original = file_get_contents(__DIR__ . '/../data/demo.ged');
349        $export   = stream_get_contents($fp);
350
351        // The date and time in the HEAD record will be different.
352        $original = preg_replace('/\n1 DATE .. ... ..../', '', $original, 1);
353        $export   = preg_replace('/\n1 DATE .. ... ..../', '', $export, 1);
354        $original = preg_replace('/\n2 TIME ..:..:../', '', $original, 1);
355        $export   = preg_replace('/\n2 TIME ..:..:../', '', $export, 1);
356
357        $this->assertSame($original, $export);
358    }
359}
360