Fix Object parsing for Logging
[friendica.git/.git] / tests / src / Util / Logger / AbstractLoggerTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2021, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Test\src\Util\Logger;
23
24 use Friendica\Test\MockedTest;
25 use Friendica\Util\Introspection;
26 use Mockery\MockInterface;
27 use Psr\Log\LoggerInterface;
28 use Psr\Log\LogLevel;
29
30 abstract class AbstractLoggerTest extends MockedTest
31 {
32         use LoggerDataTrait;
33
34         const LOGLINE = '/.* \[.*\]: .* \{.*\"file\":\".*\".*,.*\"line\":\d*,.*\"function\":\".*\".*,.*\"uid\":\".*\".*}/';
35
36         const FILE = 'test';
37         const LINE = 666;
38         const FUNC = 'myfunction';
39
40         /**
41          * @var Introspection|MockInterface
42          */
43         protected $introspection;
44
45         /**
46          * Returns the content of the current logger instance
47          *
48          * @return string
49          */
50         abstract protected function getContent();
51
52         /**
53          * Returns the current logger instance
54          *
55          * @param string $level the default loglevel
56          *
57          * @return LoggerInterface
58          */
59         abstract protected function getInstance($level = LogLevel::DEBUG);
60
61         protected function setUp()
62         {
63                 parent::setUp();
64
65                 $this->introspection = \Mockery::mock(Introspection::class);
66                 $this->introspection->shouldReceive('getRecord')->andReturn([
67                         'file'     => self::FILE,
68                         'line'     => self::LINE,
69                         'function' => self::FUNC
70                 ]);
71         }
72
73         public function assertLogline($string)
74         {
75                 self::assertRegExp(self::LOGLINE, $string);
76         }
77
78         public function assertLoglineNums($assertNum, $string)
79         {
80                 self::assertEquals($assertNum, preg_match_all(self::LOGLINE, $string));
81         }
82
83         /**
84          * Test if the logger works correctly
85          */
86         public function testNormal()
87         {
88                 $logger = $this->getInstance();
89                 $logger->emergency('working!');
90                 $logger->alert('working too!');
91                 $logger->debug('and now?');
92                 $logger->notice('message', ['an' => 'context']);
93
94                 $text = $this->getContent();
95                 self::assertLogline($text);
96                 self::assertLoglineNums(4, $text);
97         }
98
99         /**
100          * Test if a log entry is correctly interpolated
101          */
102         public function testPsrInterpolate()
103         {
104                 $logger = $this->getInstance();
105
106                 $logger->emergency('A {psr} test', ['psr' => 'working']);
107                 $logger->alert('An {array} test', ['array' => ['it', 'is', 'working']]);
108                 $text = $this->getContent();
109                 self::assertContains('A working test', $text);
110                 self::assertContains('An ["it","is","working"] test', $text);
111         }
112
113         /**
114          * Test if a log entry contains all necessary information
115          */
116         public function testContainsInformation()
117         {
118                 $logger = $this->getInstance();
119                 $logger->emergency('A test');
120
121                 $text = $this->getContent();
122                 self::assertContains('"file":"' . self::FILE . '"', $text);
123                 self::assertContains('"line":' . self::LINE, $text);
124                 self::assertContains('"function":"' . self::FUNC . '"', $text);
125         }
126
127         /**
128          * Test if the minimum level is working
129          */
130         public function testMinimumLevel()
131         {
132                 $logger = $this->getInstance(LogLevel::NOTICE);
133
134                 $logger->emergency('working');
135                 $logger->alert('working');
136                 $logger->error('working');
137                 $logger->warning('working');
138                 $logger->notice('working');
139                 $logger->info('not working');
140                 $logger->debug('not working');
141
142                 $text = $this->getContent();
143
144                 self::assertLoglineNums(5, $text);
145         }
146
147         /**
148          * Test with different logging data
149          * @dataProvider dataTests
150          */
151         public function testDifferentTypes($function, $message, array $context)
152         {
153                 $logger = $this->getInstance();
154                 $logger->$function($message, $context);
155
156                 $text = $this->getContent();
157
158                 self::assertLogline($text);
159
160                 self::assertContains(@json_encode($context), $text);
161         }
162
163         /**
164          * Test a message with an exception
165          */
166         public function testExceptionHandling()
167         {
168                 $e = new \Exception("Test String", 123);
169                 $eFollowUp = new \Exception("FollowUp", 456, $e);
170
171                 $assertion = $eFollowUp->__toString();
172
173                 $logger = $this->getInstance();
174                 $logger->alert('test', ['e' => $eFollowUp]);
175                 $text = $this->getContent();
176
177                 self::assertLogline($text);
178
179                 self::assertContains(@json_encode($assertion), $this->getContent());
180         }
181
182         public function testNoObjectHandling()
183         {
184                 $logger = $this->getInstance();
185                 $logger->alert('test', ['e' => ['test' => 'test']]);
186                 $text = $this->getContent();
187
188                 self::assertLogline($text);
189
190                 self::assertContains('test', $this->getContent());
191         }
192 }