ILIAS  trunk Revision v13.0_alpha-62-g3b72d83f2e5
ilCertificateDateHelperTest.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21use PHPUnit\Framework\Attributes\RunInSeparateProcess;
22use PHPUnit\Framework\Attributes\DataProvider;
23use PHPUnit\Framework\MockObject\Stub;
24
26{
27 private const string USER_TIME_ZONE = 'Europe/Berlin';
28 private const string DEFAULT_TIME_ZONE = 'UTC';
29
30 private int $current_time;
31
32 protected function setUp(): void
33 {
35
36 class_exists('ilDateTime');
37
38 ilTimeZone::_setDefaultTimeZone(self::DEFAULT_TIME_ZONE);
39
41 $logger = $this->createStub(ilLogger::class);
42
44 $logger_factory = $this->getStubBuilder(ilLoggerFactory::class)
45 ->disableOriginalConstructor()
46 ->onlyMethods(['getComponentLogger'])
47 ->getStub();
48 $logger_factory->method('getComponentLogger')->willReturn($logger);
49 $this->setGlobalVariable('ilLoggerFactory', $logger_factory);
50 $this->setGlobalVariable('lng', $this->getSystemLanguageMock());
51 $this->setGlobalVariable('ilUser', $this->getUserMock());
52 $this->setGlobalVariable(
53 'logging.factory',
54 $this->createStub(ILIAS\Logging\Logger\LoggerFactoryInterface::class)
55 );
56 $this->setGlobalVariable(
57 'logging.defaultConfigFactory',
58 $this->createStub(ILIAS\Logging\Logger\DefaultConfigLoggerFactoryInterface::class)
59 );
60 $this->setGlobalVariable(
61 'logging.config',
62 $this->createStub(ILIAS\Logging\Config\ConfigInterface::class)
63 );
64 $this->current_time = time();
65 }
66
67 protected function tearDown(): void
68 {
71 }
72
73 public static function dataProviderFormatDateWithDateFormat(): array
74 {
75 return [
76 [null, 'No date'],
77 ['2001-01-01', '1. Jan 2001'],
78 ['2001-01-01 00:00:00', '1. Jan 2001'],
79 [978307200, '1. Jan 2001'],
80 [0, 'No date'],
81 ['', 'No date'],
82 ];
83 }
84
85 #[DataProvider('dataProviderFormatDateWithDateFormat')]
86 public function testFormatDateWithDefaultFormat($input, $output): void
87 {
88 $helper = new ilCertificateDateHelper();
89 $this->assertEquals($output, $helper->formatDate($input));
90 }
91
92 public static function dataProviderFormatDateTimeWithDateTimeFormat(): array
93 {
94 return [
95 [null, 'No date'],
96 ['2001-01-01 00:00:00', '1. Jan 2001, 01:00'],
97 [978307200, '1. Jan 2001, 01:00'],
98 [0, 'No date'],
99 ['', 'No date'],
100 ];
101 }
102
103 #[DataProvider('dataProviderFormatDateTimeWithDateTimeFormat')]
104 public function testFormatDateTimeWithDefaultFormat($input, $output): void
105 {
106 $helper = new ilCertificateDateHelper();
107 $this->assertEquals($output, $helper->formatDateTime($input));
108 }
109
111 {
112 $used_relative_dates = ilDatePresentation::useRelativeDates();
113
114 $helper = new ilCertificateDateHelper();
115
116 $helper->formatDate('2001-01-01');
117 $this->assertEquals($used_relative_dates, ilDatePresentation::useRelativeDates());
118
120 $helper->formatDate('2001-01-01');
121 $this->assertTrue(ilDatePresentation::useRelativeDates());
122
124 $helper->formatDate('2001-01-01');
125 $this->assertFalse(ilDatePresentation::useRelativeDates());
126
127 ilDatePresentation::setUseRelativeDates($used_relative_dates);
128 }
129
130 public static function provideExplicitFormatCases(): array
131 {
132 $ts = 1757609100; // See snippet in: https://github.com/ILIAS-eLearning/ILIAS/pull/10084
133
134 class_exists('ilDateTime');
135
136 return [
137 'date: unix-int ok' => ['date', $ts, IL_CAL_UNIX, null, 'unix timestamp (int) accepted for date'],
138 'date: unix-string ok' => [
139 'date',
140 (string) $ts,
142 null,
143 'unix timestamp (string) accepted for date'
144 ],
145 'datetime: unix-int ok' => [
146 'datetime',
147 $ts,
149 null,
150 'unix timestamp (int) accepted for datetime'
151 ],
152 'datetime: unix-string ok' => [
153 'datetime',
154 (string) $ts,
156 null,
157 'unix timestamp (string) accepted for datetime'
158 ],
159
160 'date: negative-unix ok' => ['date', -1, IL_CAL_UNIX, null, 'negative unix timestamp accepted as int'],
161 'datetime: negative-unix ok' => [
162 'datetime',
163 -1,
165 null,
166 'negative unix timestamp accepted as int'
167 ],
168
169 'date: date ok' => ['date', '2025-09-12', IL_CAL_DATE, null, 'valid date string'],
170 'datetime: datetime ok' => [
171 'datetime',
172 '2025-09-12 20:30:00',
174 null,
175 'valid date-time string'
176 ],
177 'date: YYYYMMDD ok' => ['date', '20250912', IL_CAL_DATE, null, 'numeric YYYYMMDD is not treated as unix'],
178
179 'date: unix-string with DATE throws' => [
180 'date',
181 (string) $ts,
183 InvalidArgumentException::class,
184 'unix-like string with DATE format should be rejected'
185 ],
186 'datetime: unix-string with DATETIME throws' => [
187 'datetime',
188 (string) $ts,
190 InvalidArgumentException::class,
191 'unix-like string with DATETIME format should be rejected'
192 ],
193 'date: date with UNIX throws' => [
194 'date',
195 '2025-09-12',
197 InvalidArgumentException::class,
198 'non-numeric with UNIX should be rejected'
199 ],
200 'datetime: datetime with UNIX throws' => [
201 'datetime',
202 '2025-09-12 20:30:00',
204 InvalidArgumentException::class,
205 'non-numeric with UNIX should be rejected'
206 ],
207 ];
208 }
209
214 #[DataProvider('provideExplicitFormatCases')]
216 string $method,
217 $input,
218 int $format,
219 ?string $expected_exception,
220 string $why
221 ): void {
222 $helper = new ilCertificateDateHelper();
223
224 $cb = static function () use ($helper, $method, $input, $format) {
225 return $method === 'date'
226 ? $helper->formatDate($input, null, $format)
227 : $helper->formatDateTime($input, null, $format);
228 };
229
230 if ($expected_exception === null) {
231 $this->assertDoesNotThrow($cb, $why);
232 } else {
233 $this->assertThrows($cb, $expected_exception, null);
234 }
235 }
236
240 public static function dateFormattingMethodsProvider(): array
241 {
242 return [
243 'formatDateTime' => ['formatDateTime'],
244 'formatDate' => ['formatDate'],
245 ];
246 }
247
248 #[DataProvider('dateFormattingMethodsProvider')]
249 public function testCannotFormatNonDateString(string $method): void
250 {
251 $helper = new ilCertificateDateHelper();
252 $this->expectExceptionMessage('Cannot parse date: invalid-date');
253 $helper->$method('invalid-date');
254 }
255
256 #[RunInSeparateProcess]
257 public function testFormatDateWithUserLanguage(): void
258 {
259 $this->mockUserLanguageGerman();
260
261 $helper = new ilCertificateDateHelper();
262 $this->assertEquals('1. Mai 2001', $helper->formatDate('2001-05-01 01:30:59', $this->getUserMock()));
263 }
264
265 #[RunInSeparateProcess]
267 {
268 $this->mockUserLanguageGerman();
269
270 $helper = new ilCertificateDateHelper();
271 $this->assertEquals('1. Mai 2001, 03:30', $helper->formatDateTime('2001-05-01 01:30:59', $this->getUserMock()));
272 }
273
274 private function getUserMock(): ilObjUser&Stub
275 {
277 $user = $this->getStubBuilder(ilObjUser::class)
278 ->disableOriginalConstructor()
279 ->onlyMethods(['getTimeFormat', 'getLanguage', 'getTimeZone'])
280 ->getStub();
281 $user->method('getTimeFormat')->willReturn((string) ilCalendarSettings::TIME_FORMAT_24);
282 $user->method('getLanguage')->willReturn('de');
283 $user->method('getTimeZone')->willReturn(self::USER_TIME_ZONE);
284
285 return $user;
286 }
287
288 private function getSystemLanguageMock(): ilLanguage&Stub
289 {
291 $lng = $this->getStubBuilder(ilLanguage::class)
292 ->onlyMethods(['txt', 'loadLanguageModule'])
293 ->disableOriginalConstructor()
294 ->getStub();
295 $lng->method('txt')->willReturnCallback(function (string $topic): string {
296 return match ($topic) {
297 'month_01_short' => 'Jan',
298 'month_01_long' => 'January',
299 'month_02_short' => 'Feb',
300 'month_03_short' => 'Mar',
301 'month_04_short' => 'Apr',
302 'month_05_short' => 'May',
303 'month_06_short' => 'Jun',
304 'month_07_short' => 'Jul',
305 'month_08_short' => 'Aug',
306 'month_09_short' => 'Sep',
307 'month_10_short' => 'Oct',
308 'month_11_short' => 'Nov',
309 'month_12_short' => 'Dec',
310 'no_date' => 'No date',
311 'today' => 'Today',
312 'yesterday' => 'Yesterday',
313 'tomorrow' => 'Tomorrow',
314 default => '-' . $topic . '-'
315 };
316 });
317
318 return $lng;
319 }
320
321 private function mockUserLanguageGerman(): void
322 {
323 if (!defined('ILIAS_LOG_ENABLED')) {
324 define('ILIAS_LOG_ENABLED', false);
325 }
326 if (!defined('ILIAS_ABSOLUTE_PATH')) {
327 define('ILIAS_ABSOLUTE_PATH', dirname(__FILE__, 5));
328 }
329
331 $ilClientIniFile = $this->createStub(ilIniFile::class);
332 $this->setGlobalVariable('ilClientIniFile', $ilClientIniFile);
333
334 // ilDatePresentation builds its own ilLanguage, which serves the shipped build only for installed languages
335 $installed = [['obj_id' => 1, 'title' => 'de', 'description' => 'installed']];
337 $ilDB = $this->createStub(ilDBInterface::class);
338 $ilDB->method('query')->willReturn($this->createStub(ilDBStatement::class));
339 $ilDB->method('numRows')->willReturnCallback(static function () use (&$installed): int {
340 return count($installed);
341 });
342 $ilDB->method('fetchAssoc')->willReturnCallback(static function () use (&$installed): ?array {
343 return array_shift($installed);
344 });
345
346 $this->setGlobalVariable('ilDB', $ilDB);
347 }
348}
const IL_CAL_DATE
const IL_CAL_UNIX
const IL_CAL_DATETIME
assertThrows(callable $cb, ?string $expected_class=null, ?string $expected_message=null)
@template T of Throwable
assertDoesNotThrow(callable $cb, string $message='')
setGlobalVariable(string $name, mixed $value)
testExplicitFormatsWorkAsExpected(string $method, $input, int $format, ?string $expected_exception, string $why)
formatDate($raw_date_input, ?ilObjUser $user=null, ?int $date_format=null)
static setUseRelativeDates(bool $a_status)
set use relative dates
language handling
User class.
static _restoreDefaultTimeZone()
static _setDefaultTimeZone(string $a_tz)
return['3gp', '7z', 'ai', 'aif', 'aifc', 'aiff', 'au', 'arw', 'avi', 'backup', 'bak', 'bas', 'bpmn', 'bpmn2', 'bmp', 'bib', 'bibtex', 'bz', 'bz2', 'c', 'c++', 'cc', 'cct', 'cdf', 'cer', 'class', 'cls', 'conf', 'cpp', 'crt', 'crs', 'crw', 'cr2', 'css', 'cst', 'csv', 'cur', 'db', 'dcr', 'des', 'dng', 'doc', 'docx', 'dot', 'dotx', 'dtd', 'dvi', 'el', 'eps', 'epub', 'f', 'f77', 'f90', 'flv', 'for', 'g3', 'gif', 'gl', 'gan', 'ggb', 'gsd', 'gsm', 'gtar', 'gz', 'gzip', 'h', 'hpp', 'htm', 'html', 'htmls', 'ibooks', 'ico', 'ics', 'ini', 'ipynb', 'java', 'jbf', 'jpeg', 'jpg', 'js', 'jsf', 'jso', 'json', 'latex', 'lang', 'less', 'log', 'lsp', 'ltx', 'm1v', 'm2a', 'm2v', 'm3u', 'm4a', 'm4v', 'markdown', 'm', 'mat', 'md', 'mdl', 'mdown', 'mid', 'min', 'midi', 'mobi', 'mod', 'mov', 'movie', 'mp2', 'mp3', 'mp4', 'mpa', 'mpeg', 'mpg', 'mph', 'mpga', 'mpp', 'mpt', 'mpv', 'mpx', 'mv', 'mw', 'mv4', 'nb', 'nbp', 'nef', 'nif', 'niff', 'obj', 'obm', 'odt', 'ods', 'odp', 'odg', 'odf', 'oga', 'ogg', 'ogv', 'old', 'p', 'pas', 'pbm', 'pcl', 'pct', 'pcx', 'pdf', 'pgm', 'pic', 'pict', 'png', 'por', 'pov', 'project', 'properties', 'ppa', 'ppm', 'pps', 'ppsx', 'ppt', 'pptx', 'ppz', 'ps', 'psd', 'pwz', 'qt', 'qtc', 'qti', 'qtif', 'r', 'ra', 'ram', 'rar', 'rast', 'rda', 'rev', 'rexx', 'ris', 'rf', 'rgb', 'rm', 'rmd', 'rmi', 'rmm', 'rmp', 'rt', 'rtf', 'rtx', 'rv', 's', 's3m', 'sav', 'sbs', 'sec', 'sdml', 'sgm', 'sgml', 'smi', 'smil', 'srt', 'sps', 'spv', 'stl', 'svg', 'swa', 'swf', 'swz', 'tar', 'tex', 'texi', 'texinfo', 'text', 'tgz', 'tif', 'tiff', 'ttf', 'txt', 'tmp', 'uvproj', 'vdf', 'vimeo', 'viv', 'vivo', 'vrml', 'vsdx', 'vtt', 'wav', 'webm', 'wmv', 'wmx', 'wmz', 'woff', 'wwd', 'xhtml', 'xif', 'xls', 'xlsx', 'xmind', 'xml', 'xsl', 'xsd', 'zip']
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setGlobalVariable(string $name, mixed $value)
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
global $lng
Definition: privfeed.php:26