afform/core - Add property 'is_dashlet'
[civicrm-core.git] / ext / afform / mock / tests / phpunit / api / v4 / AfformTest.php
1 <?php
2
3 /**
4 * Afform.Get API Test Case
5 * This is a generic test class implemented with PHPUnit.
6 * @group headless
7 */
8 class api_v4_AfformTest extends api_v4_AfformTestCase {
9 use \Civi\Test\Api3TestTrait;
10 use \Civi\Test\ContactTestTrait;
11
12 /**
13 * DOMDocument outputs some tags a little different than they were input.
14 * It's not really a problem but can trip up tests.
15 *
16 * @param array|string $markup
17 * @return array|string
18 */
19 private function fudgeMarkup($markup) {
20 if (is_array($markup)) {
21 foreach ($markup as $idx => $item) {
22 $markup[$idx] = $this->fudgeMarkup($item);
23 }
24 return $markup;
25 }
26 else {
27 return str_replace([' />', '/>'], ['/>', ' />'], $markup);
28 }
29 }
30
31 public function getBasicDirectives() {
32 return [
33 ['mockPage', ['title' => '', 'description' => '', 'server_route' => 'civicrm/mock-page', 'permission' => 'access Foobar', 'is_dashlet' => TRUE]],
34 ['mockBareFile', ['title' => '', 'description' => '', 'permission' => 'access CiviCRM', 'is_dashlet' => FALSE]],
35 ['mockFoo', ['title' => '', 'description' => '', 'permission' => 'access CiviCRM']],
36 ['mock-weird-name', ['title' => 'Weird Name', 'description' => '', 'permission' => 'access CiviCRM']],
37 ];
38 }
39
40 /**
41 * This takes the bundled `example-page` and performs some API calls on it.
42 *
43 * @param string $formName
44 * The symbolic name of the form.
45 * @param array $originalMetadata
46 * @dataProvider getBasicDirectives
47 */
48 public function testGetUpdateRevert($formName, $originalMetadata) {
49 $get = function($arr, $key) {
50 return isset($arr[$key]) ? $arr[$key] : NULL;
51 };
52
53 Civi\Api4\Afform::revert()->addWhere('name', '=', $formName)->execute();
54
55 $message = 'The initial Afform.get should return default data';
56 $result = Civi\Api4\Afform::get()->addWhere('name', '=', $formName)->execute();
57 $this->assertEquals($formName, $result[0]['name'], $message);
58 $this->assertEquals($get($originalMetadata, 'title'), $get($result[0], 'title'), $message);
59 $this->assertEquals($get($originalMetadata, 'description'), $get($result[0], 'description'), $message);
60 $this->assertEquals($get($originalMetadata, 'server_route'), $get($result[0], 'server_route'), $message);
61 $this->assertEquals($get($originalMetadata, 'is_dashlet'), $get($result[0], 'is_dashlet'), $message);
62 $this->assertEquals($get($originalMetadata, 'permission'), $get($result[0], 'permission'), $message);
63 $this->assertTrue(is_array($result[0]['layout']), $message);
64 $this->assertEquals(TRUE, $get($result[0], 'has_base'), $message);
65 $this->assertEquals(FALSE, $get($result[0], 'has_local'), $message);
66
67 $message = 'After updating with Afform.create, the revised data should be returned';
68 $result = Civi\Api4\Afform::update()
69 ->addWhere('name', '=', $formName)
70 ->addValue('description', 'The temporary description')
71 ->addValue('permission', 'access foo')
72 ->addValue('is_dashlet', TRUE)
73 ->execute();
74 $this->assertEquals($formName, $result[0]['name'], $message);
75 $this->assertEquals('The temporary description', $result[0]['description'], $message);
76
77 $message = 'After updating, the Afform.get API should return blended data';
78 $result = Civi\Api4\Afform::get()->addWhere('name', '=', $formName)->execute();
79 $this->assertEquals($formName, $result[0]['name'], $message);
80 $this->assertEquals($get($originalMetadata, 'title'), $get($result[0], 'title'), $message);
81 $this->assertEquals('The temporary description', $get($result[0], 'description'), $message);
82 $this->assertEquals(TRUE, $get($result[0], 'is_dashlet'), $message);
83 $this->assertEquals($get($originalMetadata, 'server_route'), $get($result[0], 'server_route'), $message);
84 $this->assertEquals('access foo', $get($result[0], 'permission'), $message);
85 $this->assertTrue(is_array($result[0]['layout']), $message);
86 $this->assertEquals(TRUE, $get($result[0], 'has_base'), $message);
87 $this->assertEquals(TRUE, $get($result[0], 'has_local'), $message);
88
89 Civi\Api4\Afform::revert()->addWhere('name', '=', $formName)->execute();
90 $message = 'After reverting, the final Afform.get should return default data';
91 $result = Civi\Api4\Afform::get()->addWhere('name', '=', $formName)->execute();
92 $this->assertEquals($formName, $result[0]['name'], $message);
93 $this->assertEquals($get($originalMetadata, 'title'), $get($result[0], 'title'), $message);
94 $this->assertEquals($get($originalMetadata, 'description'), $get($result[0], 'description'), $message);
95 $this->assertEquals($get($originalMetadata, 'server_route'), $get($result[0], 'server_route'), $message);
96 $this->assertEquals($get($originalMetadata, 'permission'), $get($result[0], 'permission'), $message);
97 $this->assertTrue(is_array($result[0]['layout']), $message);
98 $this->assertEquals(TRUE, $get($result[0], 'has_base'), $message);
99 $this->assertEquals(FALSE, $get($result[0], 'has_local'), $message);
100 }
101
102 public function getFormatExamples() {
103 $ex = [];
104 $formats = ['html', 'shallow', 'deep'];
105 foreach (glob(__DIR__ . '/formatExamples/*.php') as $exampleFile) {
106 $example = require $exampleFile;
107 if (isset($example['deep'])) {
108 foreach ($formats as $updateFormat) {
109 foreach ($formats as $readFormat) {
110 $ex[] = ['mockBareFile', $updateFormat, $example[$updateFormat], $readFormat, $example[$readFormat], $exampleFile];
111 }
112 }
113 }
114 }
115 return $ex;
116 }
117
118 /**
119 * In this test, we update the layout and in one format and then read it back
120 * in another format.
121 *
122 * @param string $formName
123 * The symbolic name of the form.
124 * @param string $updateFormat
125 * The format with which to write the data.
126 * 'html' or 'array'
127 * @param mixed $updateLayout
128 * The new value to set
129 * @param string $readFormat
130 * The format with which to read the data.
131 * 'html' or 'array'
132 * @param mixed $readLayout
133 * The value that we expect to read.
134 * @param string $exampleName
135 * (For debug messages) A symbolic name of the example data-set being tested.
136 * @dataProvider getFormatExamples
137 */
138 public function testUpdateAndGetFormat($formName, $updateFormat, $updateLayout, $readFormat, $readLayout, $exampleName) {
139 Civi\Api4\Afform::revert()->addWhere('name', '=', $formName)->execute();
140
141 Civi\Api4\Afform::update()
142 ->addWhere('name', '=', $formName)
143 ->setLayoutFormat($updateFormat)
144 ->setValues(['layout' => $updateLayout])
145 ->execute();
146
147 $result = Civi\Api4\Afform::get()
148 ->addWhere('name', '=', $formName)
149 ->setLayoutFormat($readFormat)
150 ->execute();
151
152 $this->assertEquals($readLayout, $this->fudgeMarkup($result[0]['layout']), "Based on \"$exampleName\", writing content as \"$updateFormat\" and reading back as \"$readFormat\".");
153
154 Civi\Api4\Afform::revert()->addWhere('name', '=', $formName)->execute();
155 }
156
157 public function getWhitespaceExamples() {
158 $ex = [];
159 foreach (glob(__DIR__ . '/formatExamples/*.php') as $exampleFile) {
160 $example = require $exampleFile;
161 if (isset($example['pretty'])) {
162 $ex[] = ['mockBareFile', $example, $exampleFile];
163 }
164 }
165 return $ex;
166 }
167
168 /**
169 * This tests that a non-pretty html string will have its whitespace stripped & reformatted
170 * when using the "formatWhitespace" option.
171 *
172 * @dataProvider getWhitespaceExamples
173 */
174 public function testWhitespaceFormat($directiveName, $example, $exampleName) {
175 Civi\Api4\Afform::save()
176 ->addRecord(['name' => $directiveName, 'layout' => $example['html']])
177 ->setLayoutFormat('html')
178 ->execute();
179
180 $result = Civi\Api4\Afform::get()
181 ->addWhere('name', '=', $directiveName)
182 ->setLayoutFormat('shallow')
183 ->setFormatWhitespace(TRUE)
184 ->execute()
185 ->first();
186
187 $this->assertEquals($example['stripped'] ?? $example['shallow'], $this->fudgeMarkup($result['layout']));
188
189 Civi\Api4\Afform::save()
190 ->addRecord(['name' => $directiveName, 'layout' => $result['layout']])
191 ->setLayoutFormat('shallow')
192 ->setFormatWhitespace(TRUE)
193 ->execute();
194
195 $result = Civi\Api4\Afform::get()
196 ->addWhere('name', '=', $directiveName)
197 ->setLayoutFormat('html')
198 ->execute()
199 ->first();
200
201 $this->assertEquals($example['pretty'], $this->fudgeMarkup($result['layout']));
202 }
203
204 public function testAutoRequires() {
205 $formName = 'mockPage';
206 $this->createLoggedInUser();
207
208 // The default mockPage has 1 explicit requirement + 2 automatic requirements.
209 Civi\Api4\Afform::revert()->addWhere('name', '=', $formName)->execute();
210 $angModule = Civi::service('angular')->getModule($formName);
211 $this->assertEquals(['afCore', 'mockBespoke', 'mockBareFile', 'mockFoo'], $angModule['requires']);
212 $storedRequires = Civi\Api4\Afform::get()->addWhere('name', '=', $formName)->addSelect('requires')->execute();
213 $this->assertEquals(['mockBespoke'], $storedRequires[0]['requires']);
214
215 // Knock down to 1 explicit + 1 automatic.
216 Civi\Api4\Afform::update()
217 ->addWhere('name', '=', $formName)
218 ->setLayoutFormat('html')
219 ->setValues(['layout' => '<div>The bare file says "<span mock-bare-file/>"</div>'])
220 ->execute();
221 $angModule = Civi::service('angular')->getModule($formName);
222 $this->assertEquals(['afCore', 'mockBespoke', 'mockBareFile'], $angModule['requires']);
223 $storedRequires = Civi\Api4\Afform::get()->addWhere('name', '=', $formName)->addSelect('requires')->execute();
224 $this->assertEquals(['mockBespoke'], $storedRequires[0]['requires']);
225
226 // Remove the last explict and implicit requirements.
227 Civi\Api4\Afform::update()
228 ->addWhere('name', '=', $formName)
229 ->setLayoutFormat('html')
230 ->setValues([
231 'layout' => '<div>The file has nothing! <strong>NOTHING!</strong> <em>JUST RANTING!</em></div>',
232 'requires' => [],
233 ])
234 ->execute();
235 $angModule = Civi::service('angular')->getModule($formName);
236 $this->assertEquals(['afCore'], $angModule['requires']);
237 $storedRequires = Civi\Api4\Afform::get()->addWhere('name', '=', $formName)->addSelect('requires')->execute();
238 $this->assertEquals([], $storedRequires[0]['requires']);
239
240 Civi\Api4\Afform::revert()->addWhere('name', '=', $formName)->execute();
241 $angModule = Civi::service('angular')->getModule($formName);
242 $this->assertEquals(['afCore', 'mockBespoke', 'mockBareFile', 'mockFoo'], $angModule['requires']);
243 }
244
245 }