Merge pull request #17144 from lcdservices/dev-core-1716
[civicrm-core.git] / tests / phpunit / Civi / Core / ThemesTest.php
CommitLineData
d89d2545
TO
1<?php
2
3namespace Civi\Core;
4
5/**
6 * Class CRM_Core_RegionTest
7 *
8 * @group headless
9 */
10class ThemesTest extends \CiviUnitTestCase {
11
12 protected function setUp() {
13 $this->useTransaction();
14 parent::setUp();
15 }
16
17 public function getThemeExamples() {
18 $cases = [];
19
20 // --- Library of example themes which we can include in tests. ---
21
22 $hookJudy = [
23 'judy' => [
24 'title' => 'Judy Garland',
25 'ext' => 'civicrm',
26 'prefix' => 'tests/phpunit/Civi/Core/Theme/judy/',
27 'excludes' => ['test.extension.uitest-files/ignoreme.css'],
28 ],
29 ];
30 $hookLiza = [
31 'liza' => [
32 'title' => 'Liza Minnelli',
33 'prefix' => 'tests/phpunit/Civi/Core/Theme/liza/',
34 'ext' => 'civicrm',
35 ],
36 ];
37 $hookBlueMarine = [
38 'bluemarine' => [
39 'title' => 'Blue Marine',
40 'url_callback' => [__CLASS__, 'fakeCallback'],
41 'ext' => 'civicrm',
42 ],
43 ];
44 $hookAquaMarine = [
45 'aquamarine' => [
46 'title' => 'Aqua Marine',
47 'url_callback' => [__CLASS__, 'fakeCallback'],
48 'ext' => 'civicrm',
49 'search_order' => ['aquamarine', 'bluemarine', '_fallback_'],
50 ],
51 ];
52
737ff8e3 53 $civicrmBaseUrl = rtrim(\Civi::paths()->getVariable('civicrm.root', 'url'), '/');
d89d2545
TO
54
55 // --- Library of tests ---
56
57 // Use the default theme, Greenwich.
58 $cases[] = [
59 [],
60 'default',
61 'Greenwich',
62 [
63 'civicrm-css/civicrm.css' => ["$civicrmBaseUrl/css/civicrm.css"],
64 'civicrm-css/joomla.css' => ["$civicrmBaseUrl/css/joomla.css"],
737ff8e3 65 'test.extension.uitest-files/foo.css' => ["$civicrmBaseUrl/tests/extensions/test.extension.uitest/files/foo.css"],
d89d2545
TO
66 ],
67 ];
68
69 // judy is defined. Let's use judy.
70 $cases[] = [
71 // Example hook data
72 $hookJudy,
73 'judy',
74 // Example theme to inspect
75 'Judy Garland',
76 [
77 'civicrm-css/civicrm.css' => ["$civicrmBaseUrl/tests/phpunit/Civi/Core/Theme/judy/css/civicrm.css"],
78 'civicrm-css/joomla.css' => ["$civicrmBaseUrl/css/joomla.css"],
737ff8e3 79 'test.extension.uitest-files/foo.css' => ["$civicrmBaseUrl/tests/extensions/test.extension.uitest/files/foo.css"],
d89d2545
TO
80 // excluded
81 'test.extension.uitest-files/ignoreme.css' => [],
82 ],
83 ];
84
85 // Misconfiguration: liza was previously used but then disappeared. Fallback to default, Greenwich.
86 $cases[] = [
87 $hookJudy,
88 'liza',
89 'Greenwich',
90 [
91 'civicrm-css/civicrm.css' => ["$civicrmBaseUrl/css/civicrm.css"],
92 'civicrm-css/joomla.css' => ["$civicrmBaseUrl/css/joomla.css"],
737ff8e3 93 'test.extension.uitest-files/foo.css' => ["$civicrmBaseUrl/tests/extensions/test.extension.uitest/files/foo.css"],
d89d2545
TO
94 ],
95 ];
96
97 // We have some themes available, but the admin opted out.
98 $cases[] = [
99 $hookJudy,
100 'none',
101 'None (Unstyled)',
102 [
103 'civicrm-css/civicrm.css' => [],
104 'civicrm-css/joomla.css' => ["$civicrmBaseUrl/css/joomla.css"],
737ff8e3 105 'test.extension.uitest-files/foo.css' => ["$civicrmBaseUrl/tests/extensions/test.extension.uitest/files/foo.css"],
d89d2545
TO
106 ],
107 ];
108
109 // Theme which overrides an extension's CSS file.
110 $cases[] = [
111 $hookJudy + $hookLiza,
112 'liza',
113 'Liza Minnelli',
114 [
115 // Warning: If your local system has overrides for the `debug_enabled`, these results may vary.
116 'civicrm-css/civicrm.css' => ["$civicrmBaseUrl/tests/phpunit/Civi/Core/Theme/liza/css/civicrm.css"],
117 'civicrm-css/civicrm.min.css' => ["$civicrmBaseUrl/tests/phpunit/Civi/Core/Theme/liza/css/civicrm.min.css"],
118 'civicrm-css/joomla.css' => ["$civicrmBaseUrl/css/joomla.css"],
737ff8e3 119 'test.extension.uitest-files/foo.css' => ["$civicrmBaseUrl/tests/phpunit/Civi/Core/Theme/liza/test.extension.uitest-files/foo.css"],
d89d2545
TO
120 ],
121 ];
122
123 // Theme has a custom URL-lookup function.
124 $cases[] = [
125 $hookBlueMarine + $hookAquaMarine,
126 'bluemarine',
127 'Blue Marine',
128 [
129 'civicrm-css/civicrm.css' => ['http://example.com/blue/civicrm.css'],
130 'civicrm-css/joomla.css' => ["$civicrmBaseUrl/css/joomla.css"],
131 'test.extension.uitest-files/foo.css' => ['http://example.com/blue/foobar/foo.css'],
132 ],
133 ];
134
135 // Theme is derived from another.
136 $cases[] = [
137 $hookBlueMarine + $hookAquaMarine,
138 'aquamarine',
139 'Aqua Marine',
140 [
141 'civicrm-css/civicrm.css' => ['http://example.com/aqua/civicrm.css'],
142 'civicrm-css/joomla.css' => ["$civicrmBaseUrl/css/joomla.css"],
143 'test.extension.uitest-files/foo.css' => ['http://example.com/blue/foobar/foo.css'],
144 ],
145 ];
146
147 return $cases;
148 }
149
150 /**
151 * Test theme.
152 *
153 * @param array $inputtedHook
154 * @param string $themeKey
155 * @param string $expectedTitle
156 * @param array $expectedUrls
157 * List of files to lookup plus the expected URLs.
158 * Array("{$extName}-{$fileName}" => "{$expectUrl}").
159 *
160 * @dataProvider getThemeExamples
161 */
162 public function testTheme($inputtedHook, $themeKey, $expectedTitle, $expectedUrls) {
163 $this->hookClass->setHook('civicrm_themes', function (&$themes) use ($inputtedHook) {
164 foreach ($inputtedHook as $key => $value) {
165 $themes[$key] = $value;
166 }
167 });
168
169 \Civi::settings()->set('theme_frontend', $themeKey);
170 \Civi::settings()->set('theme_backend', $themeKey);
171
172 /** @var \Civi\Core\Themes $themeSvc */
173 $themeSvc = \Civi::service('themes');
174 $theme = $themeSvc->get($themeSvc->getActiveThemeKey());
175 if ($expectedTitle) {
176 $this->assertEquals($expectedTitle, $theme['title']);
177 }
178
179 foreach ($expectedUrls as $inputFile => $expectedUrl) {
180 list ($ext, $file) = explode('-', $inputFile, 2);
181 $actualUrl = $themeSvc->resolveUrls($themeSvc->getActiveThemeKey(), $ext, $file);
182 foreach (array_keys($actualUrl) as $k) {
183 // Ignore cache revision key (`?r=abcd1234`).
184 list ($actualUrl[$k]) = explode('?', $actualUrl[$k], 2);
185 }
186 $this->assertEquals($expectedUrl, $actualUrl, "Check URL for $inputFile");
187 }
188 }
189
190 public static function fakeCallback($themes, $themeKey, $cssExt, $cssFile) {
191 $map['bluemarine']['civicrm']['css/bootstrap.css'] = ['http://example.com/blue/bootstrap.css'];
192 $map['bluemarine']['civicrm']['css/civicrm.css'] = ['http://example.com/blue/civicrm.css'];
193 $map['bluemarine']['test.extension.uitest']['files/foo.css'] = ['http://example.com/blue/foobar/foo.css'];
194 $map['aquamarine']['civicrm']['css/civicrm.css'] = ['http://example.com/aqua/civicrm.css'];
511e9a21 195 return $map[$themeKey][$cssExt][$cssFile] ?? Themes::PASSTHRU;
d89d2545
TO
196 }
197
198 public function testGetAll() {
199 $all = \Civi::service('themes')->getAll();
200 $this->assertTrue(isset($all['greenwich']));
201 $this->assertTrue(isset($all['_fallback_']));
202 }
203
204 public function testGetAvailable() {
205 $all = \Civi::service('themes')->getAvailable();
206 $this->assertTrue(isset($all['greenwich']));
207 $this->assertFalse(isset($all['_fallback_']));
208 }
209
210 public function testApiOptions() {
211 $result = $this->callAPISuccess('Setting', 'getoptions', [
212 'field' => 'theme_backend',
213 ]);
214 $this->assertTrue(isset($result['values']['greenwich']));
215 $this->assertFalse(isset($result['values']['_fallback_']));
216 }
217
218}