Update copyright
[friendica.git/.git] / tests / src / App / RouterTest.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\App;
23
24 use Friendica\App\Router;
25 use Friendica\Core\Cache\ICache;
26 use Friendica\Core\L10n;
27 use Friendica\Module;
28 use Friendica\Network\HTTPException\MethodNotAllowedException;
29 use Friendica\Network\HTTPException\NotFoundException;
30 use Mockery;
31 use Mockery\MockInterface;
32 use PHPUnit\Framework\TestCase;
33
34 class RouterTest extends TestCase
35 {
36         /** @var L10n|MockInterface */
37         private $l10n;
38         /**
39          * @var ICache
40          */
41         private $cache;
42
43         protected function setUp()
44         {
45                 parent::setUp();
46
47                 $this->l10n = Mockery::mock(L10n::class);
48                 $this->l10n->shouldReceive('t')->andReturnUsing(function ($args) { return $args; });
49
50                 $this->cache = Mockery::mock(ICache::class);
51                 $this->cache->shouldReceive('get')->andReturn(null);
52                 $this->cache->shouldReceive('set')->andReturn(false);
53         }
54
55         public function testGetModuleClass()
56         {
57                 $router = new Router(['REQUEST_METHOD' => Router::GET], '', $this->l10n, $this->cache);
58
59                 $routeCollector = $router->getRouteCollector();
60                 $routeCollector->addRoute([Router::GET], '/', 'IndexModuleClassName');
61                 $routeCollector->addRoute([Router::GET], '/test', 'TestModuleClassName');
62                 $routeCollector->addRoute([Router::GET, Router::POST], '/testgetpost', 'TestGetPostModuleClassName');
63                 $routeCollector->addRoute([Router::GET], '/test/sub', 'TestSubModuleClassName');
64                 $routeCollector->addRoute([Router::GET], '/optional[/option]', 'OptionalModuleClassName');
65                 $routeCollector->addRoute([Router::GET], '/variable/{var}', 'VariableModuleClassName');
66                 $routeCollector->addRoute([Router::GET], '/optionalvariable[/{option}]', 'OptionalVariableModuleClassName');
67
68                 self::assertEquals('IndexModuleClassName', $router->getModuleClass('/'));
69                 self::assertEquals('TestModuleClassName', $router->getModuleClass('/test'));
70                 self::assertEquals('TestGetPostModuleClassName', $router->getModuleClass('/testgetpost'));
71                 self::assertEquals('TestSubModuleClassName', $router->getModuleClass('/test/sub'));
72                 self::assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional'));
73                 self::assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional/option'));
74                 self::assertEquals('VariableModuleClassName', $router->getModuleClass('/variable/123abc'));
75                 self::assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable'));
76                 self::assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable/123abc'));
77         }
78
79         public function testPostModuleClass()
80         {
81                 $router = new Router(['REQUEST_METHOD' => Router::POST], '', $this->l10n, $this->cache);
82
83                 $routeCollector = $router->getRouteCollector();
84                 $routeCollector->addRoute([Router::POST], '/', 'IndexModuleClassName');
85                 $routeCollector->addRoute([Router::POST], '/test', 'TestModuleClassName');
86                 $routeCollector->addRoute([Router::GET, Router::POST], '/testgetpost', 'TestGetPostModuleClassName');
87                 $routeCollector->addRoute([Router::POST], '/test/sub', 'TestSubModuleClassName');
88                 $routeCollector->addRoute([Router::POST], '/optional[/option]', 'OptionalModuleClassName');
89                 $routeCollector->addRoute([Router::POST], '/variable/{var}', 'VariableModuleClassName');
90                 $routeCollector->addRoute([Router::POST], '/optionalvariable[/{option}]', 'OptionalVariableModuleClassName');
91
92                 self::assertEquals('IndexModuleClassName', $router->getModuleClass('/'));
93                 self::assertEquals('TestModuleClassName', $router->getModuleClass('/test'));
94                 self::assertEquals('TestGetPostModuleClassName', $router->getModuleClass('/testgetpost'));
95                 self::assertEquals('TestSubModuleClassName', $router->getModuleClass('/test/sub'));
96                 self::assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional'));
97                 self::assertEquals('OptionalModuleClassName', $router->getModuleClass('/optional/option'));
98                 self::assertEquals('VariableModuleClassName', $router->getModuleClass('/variable/123abc'));
99                 self::assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable'));
100                 self::assertEquals('OptionalVariableModuleClassName', $router->getModuleClass('/optionalvariable/123abc'));
101         }
102
103         public function testGetModuleClassNotFound()
104         {
105                 $this->expectException(NotFoundException::class);
106
107                 $router = new Router(['REQUEST_METHOD' => Router::GET], '', $this->l10n, $this->cache);
108
109                 $router->getModuleClass('/unsupported');
110         }
111
112         public function testGetModuleClassNotFoundTypo()
113         {
114                 $this->expectException(NotFoundException::class);
115
116                 $router = new Router(['REQUEST_METHOD' => Router::GET], '', $this->l10n, $this->cache);
117
118                 $routeCollector = $router->getRouteCollector();
119                 $routeCollector->addRoute([Router::GET], '/test', 'TestModuleClassName');
120
121                 $router->getModuleClass('/tes');
122         }
123
124         public function testGetModuleClassNotFoundOptional()
125         {
126                 $this->expectException(NotFoundException::class);
127
128                 $router = new Router(['REQUEST_METHOD' => Router::GET], '', $this->l10n, $this->cache);
129
130                 $routeCollector = $router->getRouteCollector();
131                 $routeCollector->addRoute([Router::GET], '/optional[/option]', 'OptionalModuleClassName');
132
133                 $router->getModuleClass('/optional/opt');
134         }
135
136         public function testGetModuleClassNotFoundVariable()
137         {
138                 $this->expectException(NotFoundException::class);
139
140                 $router = new Router(['REQUEST_METHOD' => Router::GET], '', $this->l10n, $this->cache);
141
142                 $routeCollector = $router->getRouteCollector();
143                 $routeCollector->addRoute([Router::GET], '/variable/{var}', 'VariableModuleClassName');
144
145                 $router->getModuleClass('/variable');
146         }
147
148         public function testGetModuleClassMethodNotAllowed()
149         {
150                 $this->expectException(MethodNotAllowedException::class);
151
152                 $router = new Router(['REQUEST_METHOD' => Router::POST], '', $this->l10n, $this->cache);
153
154                 $routeCollector = $router->getRouteCollector();
155                 $routeCollector->addRoute([Router::GET], '/test', 'TestModuleClassName');
156
157                 $router->getModuleClass('/test');
158         }
159         
160         public function testPostModuleClassMethodNotAllowed()
161         {
162                 $this->expectException(MethodNotAllowedException::class);
163
164                 $router = new Router(['REQUEST_METHOD' => Router::GET], '', $this->l10n, $this->cache);
165
166                 $routeCollector = $router->getRouteCollector();
167                 $routeCollector->addRoute([Router::POST], '/test', 'TestModuleClassName');
168
169                 $router->getModuleClass('/test');
170         }
171
172         public function dataRoutes()
173         {
174                 return [
175                         'default' => [
176                                 'routes' => [
177                                         '/'       => [Module\Home::class, [Router::GET]],
178                                         '/group'  => [
179                                                 '/route' => [Module\Friendica::class, [Router::GET]],
180                                         ],
181
182
183                                         '/group2' => [
184                                                 '/group3' => [
185                                                         '/route' => [Module\Xrd::class, [Router::GET]],
186                                                 ],
187                                         ],
188                                         '/post' => [
189                                                 '/it' => [Module\WellKnown\NodeInfo::class, [Router::POST]],
190                                         ],
191                                         '/double' => [Module\Profile\Index::class, [Router::GET, Router::POST]]
192                                 ],
193                         ],
194                 ];
195         }
196
197         /**
198          * @dataProvider dataRoutes
199          */
200         public function testGetRoutes(array $routes)
201         {
202                 $router = (new Router(
203                         ['REQUEST_METHOD' => Router::GET],
204                         '',
205                         $this->l10n,
206                         $this->cache
207                 ))->loadRoutes($routes);
208
209                 self::assertEquals(Module\Home::class, $router->getModuleClass('/'));
210                 self::assertEquals(Module\Friendica::class, $router->getModuleClass('/group/route'));
211                 self::assertEquals(Module\Xrd::class, $router->getModuleClass('/group2/group3/route'));
212                 self::assertEquals(Module\Profile\Index::class, $router->getModuleClass('/double'));
213         }
214
215         /**
216          * @dataProvider dataRoutes
217          */
218         public function testPostRouter(array $routes)
219         {
220                 $router = (new Router([
221                         'REQUEST_METHOD' => Router::POST
222                 ], '', $this->l10n, $this->cache))->loadRoutes($routes);
223
224                 // Don't find GET
225                 self::assertEquals(Module\WellKnown\NodeInfo::class, $router->getModuleClass('/post/it'));
226                 self::assertEquals(Module\Profile\Index::class, $router->getModuleClass('/double'));
227         }
228 }