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