Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
25.00% |
26 / 104 |
|
33.33% |
4 / 12 |
CRAP | |
0.00% |
0 / 1 |
TestEnvironment | |
25.00% |
26 / 104 |
|
33.33% |
4 / 12 |
436.42 | |
0.00% |
0 / 1 |
setup | |
0.00% |
0 / 32 |
|
0.00% |
0 / 1 |
56 | |||
makeRandomStatic | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setUpVirtualFilesystem | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
createTestFiles | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
createTestData | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
2 | |||
overwriteModificationDatesVfs | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
4 | |||
buildTestDB | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
updateDataBaseScheme | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 | |||
rollback | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
bailOut | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
defineTestDataDir | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
overwriteModificationDatesTestDataDir | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
30 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | use JetBrains\PhpStorm\NoReturn; |
6 | use org\bovigo\vfs\vfsStream; |
7 | use org\bovigo\vfs\vfsStreamContent; |
8 | use org\bovigo\vfs\vfsStreamWrapper; |
9 | |
10 | class TestEnvironment { |
11 | const int staticDate = 1627545600; |
12 | const array testModes = ['prepare', 'api', 'integration', 'prepare-integration']; |
13 | static string | null $testMode = null; |
14 | |
15 | |
16 | public static function setup(string $testMode, ?string $testClock = null): void { |
17 | self::$testMode = in_array($testMode, self::testModes) ? $testMode : 'api'; |
18 | $testClock = $testClock ?? self::staticDate; |
19 | |
20 | try { |
21 | SystemConfig::$debug_useStaticTime = '@' . (int) $testClock; |
22 | SystemConfig::$debug_useStaticTokens = true; |
23 | SystemConfig::$debug_useInsecurePasswords = true; |
24 | SystemConfig::$debug_allowExternalXmlSchema = false; |
25 | SystemConfig::$debug_fastLoginReuse = true; |
26 | self::makeRandomStatic(); |
27 | DB::connectToTestDB(); |
28 | |
29 | if (self::$testMode == 'integration') { |
30 | // this is called every single call from integration tests |
31 | self::defineTestDataDir(false); |
32 | } |
33 | |
34 | if (self::$testMode == 'prepare-integration') { |
35 | // this is called one time before each integration test (cypress) |
36 | self::defineTestDataDir(true); |
37 | self::createTestFiles(true); |
38 | self::overwriteModificationDatesTestDataDir(); |
39 | self::buildTestDB(); |
40 | self::createTestData(); |
41 | } |
42 | |
43 | if (self::$testMode == 'prepare') { |
44 | // this is called once before the api tests (dredd) |
45 | self::setUpVirtualFilesystem(); |
46 | self::createTestFiles(false); |
47 | self::overwriteModificationDatesVfs(); |
48 | self::buildTestDB(); |
49 | self::createTestData(); |
50 | } |
51 | |
52 | if (self::$testMode == 'api') { |
53 | // api tests can use vfs for more speed |
54 | self::setUpVirtualFilesystem(); |
55 | self::createTestFiles(false); |
56 | self::overwriteModificationDatesVfs(); |
57 | // in api-tests every call is atomic and the test db gets restored afterwards |
58 | // the test db must be set up before with $testMode == 'prepare' |
59 | $initDAO = new InitDAO(); |
60 | $initDAO->beginTransaction(); |
61 | register_shutdown_function([self::class, "rollback"]); |
62 | } |
63 | } catch (Throwable $exception) { |
64 | TestEnvironment::bailOut($exception); |
65 | } |
66 | } |
67 | |
68 | public static function makeRandomStatic(): void { |
69 | srand(1); |
70 | } |
71 | |
72 | private static function setUpVirtualFilesystem(): void { |
73 | $vfs = vfsStream::setup('root', 0777); |
74 | vfsStream::newDirectory('data', 0777)->at($vfs); |
75 | vfsStream::newDirectory('data/ws_1', 0777)->at($vfs); |
76 | |
77 | define('DATA_DIR', vfsStream::url('root/data')); |
78 | } |
79 | |
80 | private static function createTestFiles(bool $includeSystemTestFiles): void { |
81 | $initializer = new WorkspaceInitializer(); |
82 | $initializer->importSampleFiles(1, 'default'); |
83 | Folder::createPath(DATA_DIR . "/ws_1/UnitAttachments"); |
84 | $initializer->createSampleScanImage("UnitAttachments/h5ki-bd-va4dg-jc2to2mp_6tga4teiw.png", 1); |
85 | if ($includeSystemTestFiles) { |
86 | $initializer->importSampleFiles(1, 'system-test'); |
87 | $initializer->importSampleFiles(2, 'default'); |
88 | } |
89 | } |
90 | |
91 | private static function createTestData(): void { |
92 | $initDAO = new InitDAO(); |
93 | |
94 | $initDAO->createWorkspace('sample_workspace'); |
95 | $initDAO->createWorkspace('second_workspace'); |
96 | |
97 | $adminId = $initDAO->createAdmin('super', 'user123'); |
98 | $initDAO->addWorkspacesToAdmin($adminId, [1, 2]); |
99 | |
100 | (new Workspace(1))->storeAllFiles(); |
101 | (new Workspace(2))->storeAllFiles(); |
102 | |
103 | $initDAO->createSampleLoginsReviewsLogs(); |
104 | $initDAO->createSampleExpiredSessions(); |
105 | $initDAO->createSampleWorkspaceAdmins(); |
106 | $initDAO->createSampleMetaData(); |
107 | $personSessions = $initDAO->createSampleMonitorSessions(); |
108 | $groupMonitor = $personSessions['test-group-monitor']; |
109 | /* @var $groupMonitor PersonSession */ |
110 | $initDAO->createSampleCommands($groupMonitor->getPerson()->getId()); |
111 | |
112 | $initializer = new WorkspaceInitializer(); |
113 | $initializer->createSampleScanImage('sample_scanned_image.png', 1); |
114 | $initDAO->importScanImage(1, 'sample_scanned_image.png'); |
115 | } |
116 | |
117 | public static function overwriteModificationDatesVfs(vfsStreamContent $dir = null): void { |
118 | if (!$dir) { |
119 | $dir = vfsStreamWrapper::getRoot()->getChild('data'); |
120 | } |
121 | $dir->lastModified(TestEnvironment::staticDate); |
122 | foreach ($dir->getChildren() as $child) { |
123 | $child->lastModified(TestEnvironment::staticDate); |
124 | if (is_dir($child->url())) { |
125 | TestEnvironment::overwriteModificationDatesVfs($child); |
126 | } |
127 | } |
128 | } |
129 | |
130 | static function buildTestDB(): void { |
131 | $initDAO = new InitDAO(); |
132 | $nextPatchPath = ROOT_DIR . '/scripts/database/patches.d/next.sql'; |
133 | $fullSchemePath = ROOT_DIR . '/scripts/database/full.sql'; |
134 | $patchFileChanged = (file_exists($nextPatchPath) and (filemtime($nextPatchPath) > filemtime($fullSchemePath))); |
135 | |
136 | if (!file_exists($fullSchemePath) or $patchFileChanged) { |
137 | TestEnvironment::updateDataBaseScheme(); |
138 | return; |
139 | } |
140 | $initDAO->clearDB(); |
141 | $initDAO->runFile(ROOT_DIR . '/scripts/database/full.sql'); |
142 | } |
143 | |
144 | private static function updateDataBaseScheme(): void { |
145 | $initDAO = new InitDAO(); |
146 | $initDAO->clearDB(); |
147 | $initDAO->runFile(ROOT_DIR . "/scripts/database/base.sql"); |
148 | $initDAO->installPatches(ROOT_DIR . "/scripts/database/patches.d", false); |
149 | |
150 | $scheme = '-- IQB-Testcenter DB --'; |
151 | foreach ($initDAO::tables as $table) { |
152 | $scheme .= "\n\n" . $initDAO->_("show create table $table")['Create Table'] . ";"; |
153 | $scheme .= "\n" . "truncate $table; -- to reset auto-increment"; |
154 | } |
155 | file_put_contents(ROOT_DIR . '/scripts/database/full.sql', $scheme); |
156 | } |
157 | |
158 | private static function rollback(): void { |
159 | $initDAO = new InitDAO(); |
160 | $initDAO->rollBack(); |
161 | } |
162 | |
163 | #[NoReturn] |
164 | private static function bailOut(Throwable $exception): void { |
165 | // TestEnvironment::debugVirtualEnvironment(); |
166 | $errorUniqueId = ErrorHandler::logException($exception, true); |
167 | http_response_code(500); |
168 | header("Error-ID:$errorUniqueId"); |
169 | throw new RuntimeException("Could not create environment: " . $exception->getMessage()); |
170 | } |
171 | |
172 | private static function defineTestDataDir(bool $shouldReset): void { |
173 | define('DATA_DIR', ROOT_DIR . '/data-TEST'); |
174 | if (!$shouldReset) { |
175 | return; |
176 | } |
177 | Folder::createPath(DATA_DIR); |
178 | Folder::deleteContentsRecursive(DATA_DIR); |
179 | } |
180 | |
181 | private static function overwriteModificationDatesTestDataDir(?string $dir = DATA_DIR): void { |
182 | touch($dir, TestEnvironment::staticDate); |
183 | foreach (new DirectoryIterator($dir) as $child) { |
184 | if ($child->isDot() or $child->isLink()) { |
185 | continue; |
186 | } |
187 | touch($child->getPathname(), TestEnvironment::staticDate); |
188 | if ($child->isDir()) { |
189 | self::overwriteModificationDatesTestDataDir($child->getPathname()); |
190 | } |
191 | } |
192 | } |
193 | } |