Commit | Line | Data |
---|---|---|
d89d2545 TO |
1 | <?php |
2 | ||
3 | namespace Civi\Core; | |
4 | ||
5 | /** | |
6 | * Class CRM_Core_RegionTest | |
7 | * | |
8 | * @group headless | |
9 | */ | |
10 | class 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 | } |