xref: /webtrees/tests/TestCase.php (revision d4c04956282de586ef4b5dcdf193f600967f0366)
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\Http\Controllers\GedcomFileController;
21use Fisharebest\Webtrees\Schema\SeedDatabase;
22use Fisharebest\Webtrees\Services\TimeoutService;
23use Illuminate\Cache\ArrayStore;
24use Illuminate\Cache\Repository;
25use Illuminate\Database\Capsule\Manager as DB;
26use function basename;
27use Symfony\Component\HttpFoundation\Request;
28
29/**
30 * Base class for unit tests
31 */
32class TestCase extends \PHPUnit\Framework\TestCase
33{
34    protected static $uses_database = false;
35
36    /**
37     * Things to run once, before all the tests.
38     */
39    public static function setUpBeforeClass()
40    {
41        parent::setUpBeforeClass();
42
43        if (static::$uses_database) {
44            defined('WT_ROOT') || define('WT_ROOT', dirname(__DIR__) . '/');
45
46            static::createTestDatabase();
47        }
48    }
49
50    /**
51     * Things to run once, AFTER all the tests.
52     */
53    public static function tearDownAfterClass()
54    {
55        if (static::$uses_database) {
56            $pdo = DB::connection()->getPdo();
57            unset($pdo);
58        }
59
60        parent::tearDownAfterClass();
61    }
62
63    /**
64     * Things to run before every test.
65     */
66    protected function setUp()
67    {
68        parent::setUp();
69
70        // Use an array cache for database calls, etc.
71        app()->instance('cache.array', new Repository(new ArrayStore()));
72
73        app()->bind(Tree::class, function () {
74            return null;
75        });
76
77        app()->instance(User::class, User::visitor());
78
79        app()->instance(Request::class, Request::createFromGlobals());
80
81        defined('WT_ROOT') || define('WT_ROOT', dirname(__DIR__) . '/');
82        defined('WT_BASE_URL') || define('WT_BASE_URL', 'http://localhost/');
83        defined('WT_DATA_DIR') || define('WT_DATA_DIR', WT_ROOT . 'data/');
84        defined('WT_LOCALE') || define('WT_LOCALE', I18N::init('en-US'));
85
86        if (static::$uses_database) {
87            DB::connection()->beginTransaction();
88        }
89    }
90
91    /**
92     * Things to run after every test
93     */
94    protected function tearDown()
95    {
96        if (static::$uses_database) {
97            DB::connection()->rollBack();
98        }
99
100        app('cache.array')->flush();
101
102        Site::$preferences = [];
103        Tree::$trees = [];
104        GedcomRecord::$gedcom_record_cache = null;
105        GedcomRecord::$pending_record_cache = null;
106
107        Auth::logout();
108    }
109
110    /**
111     * Create an SQLite in-memory database for testing
112     */
113    protected static function createTestDatabase(): void
114    {
115        $capsule = new DB();
116        $capsule->addConnection([
117            'driver'   => 'sqlite',
118            'database' => ':memory:',
119        ]);
120        $capsule->setAsGlobal();
121        Database::registerMacros();
122
123        // Create tables
124        Database::updateSchema('\Fisharebest\Webtrees\Schema', 'WT_SCHEMA_VERSION', Webtrees::SCHEMA_VERSION);
125
126        // Create config data
127        (new SeedDatabase())->run();
128    }
129
130    /**
131     * Import a GEDCOM file into the test database.
132     *
133     * @param string $gedcom_file
134     *
135     * @return Tree
136     */
137    protected function importTree(string $gedcom_file): Tree
138    {
139        $tree = Tree::create(basename($gedcom_file), basename($gedcom_file));
140        $tree->importGedcomFile(__DIR__ . '/data/' . $gedcom_file, $gedcom_file);
141
142        View::share('tree', $tree);
143        $gedcom_file_controller = new GedcomFileController();
144
145        do {
146            $gedcom_file_controller->import(new TimeoutService(microtime(true)), $tree);
147
148            $imported = $tree->getPreference('imported');
149        } while (!$imported);
150
151        return $tree;
152    }
153}
154