ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
CapabilityTest.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
31 
32 class CapabilityTest extends TestCase
33 {
37  public \PHPUnit\Framework\MockObject\MockObject $workspace_access_handler;
38  public \PHPUnit\Framework\MockObject\MockObject|TypeResolver $type_resolver;
40  private ilAccessHandler|MockObject $access;
41  private ilCtrlInterface|MockObject $ctrl;
43  private Services|MockObject $http;
44  private URIBuilder|MockObject $static_url;
46 
47  private static array $readme_infos = [];
48 
49  private static bool $update_readme = false;
50 
51  protected function setUp(): void
52  {
53  if (!defined('ILIAS_HTTP_PATH')) {
54  define('ILIAS_HTTP_PATH', 'https://ilias.unit.test');
55  }
56 
57  $this->file_info_repository = $this->createMock(\ilObjFileInfoRepository::class);
58  $this->access = $this->createMock(\ilAccessHandler::class);
59  $this->ctrl = $this->createMock(\ilCtrlInterface::class);
60  $this->action_repository = $this->createMock(ActionRepository::class);
61  $this->http = $this->createMock(Services::class);
62  $this->static_url = $this->createMock(URIBuilder::class);
63  $this->type_resolver = $this->createMock(TypeResolver::class);
64  $this->workspace_access_handler = $this->createMock(ilWorkspaceAccessHandler::class);
65 
66  $this->type_resolver->method('resolveTypeByObjectId')
67  ->withAnyParameters()
68  ->willReturn('file');
69 
70  $this->capability_builder = new CapabilityBuilder(
71  $this->file_info_repository,
72  $this->access,
73  $this->ctrl,
74  $this->action_repository,
75  $this->http,
76  $this->static_url,
77  $this->type_resolver,
78  $this->workspace_access_handler
79  );
80  }
81 
82  protected function tearDown(): void
83  {
84  }
85 
86  public static function tearDownAfterClass(): void
87  {
88  if (!self::$update_readme) {
89  return;
90  }
91  self::updateREADME();
92  }
93 
94  public static function environmentProvider(): array
95  {
96  return [
97  'testerei' => [
98  'wopi_view' => true,
99  'wopi_edit' => true,
100  'infopage_first' => true,
101  'user_permissions' => [
102  Permissions::READ,
103  Permissions::WRITE,
104  Permissions::VISIBLE,
105  Permissions::EDIT_CONTENT,
106  Permissions::VIEW_CONTENT
107  ],
108  'expected_best' => Capabilities::FORCED_INFO_PAGE
109  ],
110  [
111  'wopi_view' => true,
112  'wopi_edit' => true,
113  'infopage_first' => false,
114  'user_permissions' => [
115  Permissions::READ,
116  Permissions::WRITE,
117  Permissions::VISIBLE,
118  Permissions::EDIT_CONTENT,
119  Permissions::VIEW_CONTENT
120  ],
121  'expected_best' => Capabilities::VIEW_EXTERNAL
122  ],
123  [
124  'wopi_view' => true,
125  'wopi_edit' => true,
126  'infopage_first' => false,
127  'user_permissions' => [
128  Permissions::EDIT_CONTENT,
129  Permissions::VIEW_CONTENT
130  ],
131  'expected_best' => Capabilities::VIEW_EXTERNAL
132  ],
133  [
134  'wopi_view' => false,
135  'wopi_edit' => false,
136  'infopage_first' => true,
137  'user_permissions' => [
138  Permissions::READ,
139  Permissions::VISIBLE
140  ],
141  'expected_best' => Capabilities::FORCED_INFO_PAGE
142  ],
143  [
144  'wopi_view' => true,
145  'wopi_edit' => true,
146  'infopage_first' => false,
147  'user_permissions' => [
148  Permissions::EDIT_CONTENT,
149  ],
150  'expected_best' => Capabilities::EDIT_EXTERNAL
151  ],
152  [
153  'wopi_view' => true,
154  'wopi_edit' => true,
155  'infopage_first' => false,
156  'user_permissions' => [
157  Permissions::READ,
158  ],
159  'expected_best' => Capabilities::DOWNLOAD
160  ],
161  [
162  'wopi_view' => true,
163  'wopi_edit' => true,
164  'infopage_first' => false,
165  'user_permissions' => [
166  Permissions::WRITE,
167  Permissions::READ,
168  ],
169  'expected_best' => Capabilities::DOWNLOAD
170  ],
171  [
172  'wopi_view' => true,
173  'wopi_edit' => true,
174  'infopage_first' => false,
175  'user_permissions' => [
176  Permissions::WRITE,
177  ],
178  'expected_best' => Capabilities::MANAGE_VERSIONS
179  ],
180  [
181  'wopi_view' => true,
182  'wopi_edit' => true,
183  'infopage_first' => false,
184  'user_permissions' => [
185  Permissions::VISIBLE,
186  ],
187  'expected_best' => Capabilities::INFO_PAGE
188  ],
189  [
190  'wopi_view' => true,
191  'wopi_edit' => true,
192  'infopage_first' => true,
193  'user_permissions' => [
194  Permissions::WRITE,
195  Permissions::READ,
196  ],
197  'expected_best' => Capabilities::FORCED_INFO_PAGE
198  ],
199  [
200  'wopi_view' => true,
201  'wopi_edit' => true,
202  'infopage_first' => false,
203  'user_permissions' => [
204  Permissions::NONE,
205  ],
206  'expected_best' => Capabilities::NONE
207  ],
208  'docu_case' => [
209  'wopi_view' => true,
210  'wopi_edit' => true,
211  'infopage_first' => true,
212  'user_permissions' => [
213  Permissions::READ,
214  Permissions::VISIBLE,
215  ],
216  'expected_best' => Capabilities::FORCED_INFO_PAGE
217  ],
218  ];
219  }
220 
221  #[DataProvider('environmentProvider')]
222  public function testCapabilityPriority(
223  bool $wopi_view,
224  bool $wopi_edit,
225  bool $infopage_first,
226  array $user_permissions,
227  Capabilities $expected_best
228  ): void {
229  static $id;
230  $permissions = $user_permissions;
231 
232  $id++;
233 
234  $context = new Context(
235  $id,
236  $id,
237  Context::CONTEXT_REPO
238  );
239 
240  $this->access->method('checkAccess')
241  ->willReturnCallback(
242  function (string $permission) use ($permissions): bool {
243  $checked_permissions = explode(',', $permission);
244  $common_permissions = array_intersect(
245  array_map(static fn(Permissions $p): string => $p->value, $permissions),
246  $checked_permissions
247  );
248  return $common_permissions !== [];
249  }
250  );
251 
252  $file_info = $this->createMock(\ilObjFileInfo::class);
253  $file_info->method('shouldDownloadDirectly')
254  ->willReturn(!$infopage_first);
255 
256  $this->file_info_repository->method('getByObjectId')
257  ->with($context->getObjectId())
258  ->willReturn($file_info);
259 
260  $this->action_repository->method('hasEditActionForSuffix')
261  ->willReturn($wopi_edit);
262 
263  $this->action_repository->method('hasViewActionForSuffix')
264  ->willReturn($wopi_view);
265 
266  $capabilities = $this->capability_builder->get($context);
267  $best = $capabilities->getBest();
268 
269  $this->assertEquals($expected_best, $best->getCapability());
270 
271  self::$readme_infos[] = [
272  implode(', ', array_map(fn(Permissions $p): string => $p->value, $permissions)), // permissions
273  ($wopi_view ? 'Yes' : 'No'),
274  ($wopi_edit ? 'Yes' : 'No'),
275  ($infopage_first ? 'Info-Page' : 'Open'),
276  $best->getCapability()->name
277  ];
278  }
279 
280  private static function updateREADME(): void
281  {
282  // UPDATE README
283  $readme_file = __DIR__ . '/../../docs/README.md';
284  $readme_content = file_get_contents($readme_file);
285 
286  $table = [
287  [
288  'User\'s Permissions',
289  'WOPI View Action av.',
290  'WOPI Edit Action av.',
291  'Click-Setting',
292  'Expected Capability'
293  ]
294  ];
295  $readme_infos = self::$readme_infos;
296  // sort $readme_infos by last column
297  usort($readme_infos, static function ($a, $b): int {
298  $a_string = implode('', array_reverse($a));
299  $b_string = implode('', array_reverse($b));
300 
301  return strcmp((string) $a_string, (string) $b_string);
302  });
303 
304  $table = array_merge($table, $readme_infos);
305 
306  // Define the markers for the block
307  $start_marker = "<!-- START CAPABILITY_TABLE -->";
308  $end_marker = "<!-- END CAPABILITY_TABLE -->";
309 
310  // Prepare the new block content
311  $new_block = $start_marker . "\n\n" . self::arrayToMarkdownTable($table) . "\n\n" . $end_marker;
312 
313  // Replace the content between the markers
314  $pattern = '/' . preg_quote($start_marker, '/') . '.*?' . preg_quote($end_marker, '/') . '/s';
315  $readme_content = preg_replace($pattern, $new_block, $readme_content);
316 
317  file_put_contents($readme_file, $readme_content);
318  }
319 
320  private static function arrayToMarkdownTable(array $data): string
321  {
322  // Check if the input array is valid
323  if (empty($data) || !is_array($data[0])) {
324  throw new InvalidArgumentException("Input must be a non-empty array of arrays.");
325  }
326 
327  // Calculate the maximum width of each column
328  $col_widths = array_map(
329  static fn($col_index): int => max(
330  array_map(
331  static fn($row): int => isset($row[$col_index]) ? mb_strlen((string) $row[$col_index]) : 0,
332  $data
333  )
334  ),
335  array_keys($data[0])
336  );
337 
338  // Function to pad a row's columns to match the maximum width
339  $pad_row = static fn($row): array => array_map(static function ($value, $index) use ($col_widths): string {
340  $value ??= ''; // Handle missing values
341  return str_pad($value, $col_widths[$index], " ", STR_PAD_RIGHT);
342  }, $row, array_keys($col_widths));
343 
344  // Format the header and rows
345  $header = $pad_row($data[0]);
346  $rows = array_map($pad_row, array_slice($data, 1));
347 
348  // Build the Markdown table
349  $header_row = "| "
350  . implode(" | ", $header)
351  . " |";
352  $sep_row = "| "
353  . implode(" | ", array_map(static fn($width): string => str_repeat("-", $width), $col_widths))
354  . " |";
355  $data_rows = array_map(static fn($row): string => "| " . implode(" | ", $row) . " |", $rows);
356 
357  // Combine all parts
358  return implode("\n", array_merge([$header_row, $sep_row], $data_rows));
359  }
360 
361 }
ActionRepository MockObject $action_repository
CapabilityBuilder $capability_builder
$context
Definition: webdav.php:31
static updateREADME()
ilObjFileInfoRepository MockObject $file_info_repository
ilAccessHandler MockObject $access
static array $readme_infos
PHPUnit Framework MockObject MockObject $workspace_access_handler
static environmentProvider()
static bool $update_readme
static http()
Fetches the global http state from ILIAS.
testCapabilityPriority(bool $wopi_view, bool $wopi_edit, bool $infopage_first, array $user_permissions, Capabilities $expected_best)
static arrayToMarkdownTable(array $data)
Services MockObject $http
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
URIBuilder MockObject $static_url
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
PHPUnit Framework MockObject MockObject TypeResolver $type_resolver
ilCtrlInterface MockObject $ctrl
static tearDownAfterClass()