Skip to content

Commit 8ad435a

Browse files
committed
test: Test de la couche controleur
1 parent fa42307 commit 8ad435a

8 files changed

Lines changed: 1045 additions & 5 deletions

File tree

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Blitz PHP framework.
5+
*
6+
* (c) 2022 Dimitri Sitchet Tomkeu <devcode.dst@gmail.com>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace Spec\BlitzPHP\App\Controllers;
13+
14+
use BlitzPHP\Controllers\RestController as BaseController;
15+
use Psr\Http\Message\ResponseInterface;
16+
17+
class RestController extends BaseController
18+
{
19+
public $before = null;
20+
public $after = null;
21+
22+
23+
// Méthodes accessibles pour les tests
24+
public function testRemap($method, $params = []) {
25+
return $this->_remap($method, $params);
26+
}
27+
28+
public function testHandleException($ex) {
29+
return $this->handleException($ex);
30+
}
31+
32+
public function testValidateRequest() {
33+
return $this->validateRequest();
34+
}
35+
36+
public function testValidateAjaxOnly() {
37+
return $this->validateAjaxOnly();
38+
}
39+
40+
public function testValidateHttps() {
41+
return $this->validateHttps();
42+
}
43+
44+
public function testValidateIpBlacklist() {
45+
return $this->validateIpBlacklist();
46+
}
47+
48+
public function testValidateIpWhitelist() {
49+
return $this->validateIpWhitelist();
50+
}
51+
52+
public function testAjaxOnly() {
53+
return $this->ajaxOnly();
54+
}
55+
56+
public function testReturnFormat($format) {
57+
return $this->returnFormat($format);
58+
}
59+
60+
public function testRequireHttps() {
61+
return $this->requireHttps();
62+
}
63+
64+
public function testIpBlacklist(...$ips) {
65+
return $this->ipBlacklist(...$ips);
66+
}
67+
68+
public function testIpWhitelist(...$ips) {
69+
return $this->ipWhitelist(...$ips);
70+
}
71+
72+
public function testRespond($data, $status = null) {
73+
return $this->respond($data, $status);
74+
}
75+
76+
public function testRespondFail($message = null, $status = null, $code = null, $errors = []) {
77+
return $this->respondFail($message, $status, $code, $errors);
78+
}
79+
80+
public function testRespondSuccess($message = null, $result = null, $status = null) {
81+
return $this->respondSuccess($message, $result, $status);
82+
}
83+
84+
public function testFormatResult($result) {
85+
return $this->formatResult($result);
86+
}
87+
88+
public function testFormatEntity($element) {
89+
return $this->formatEntity($element);
90+
}
91+
92+
public function testFormatResponse($data) {
93+
return $this->formatResponse($data);
94+
}
95+
96+
public function testLang($line, $args = []) {
97+
return $this->lang($line, $args);
98+
}
99+
100+
public function testTranslate($line, $args = []) {
101+
return $this->_translate($line, $args);
102+
}
103+
104+
public function testBefore($method, $params) {
105+
return $this->before($method, $params);
106+
}
107+
108+
public function testAfter($method, $params, $response) {
109+
return $this->after($method, $params, $response);
110+
}
111+
112+
// Méthode de test pour _remap
113+
public function testMethod() {
114+
return 'test response';
115+
}
116+
117+
public function before($method, $params): ?ResponseInterface {
118+
return $this->before;
119+
}
120+
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Blitz PHP framework.
5+
*
6+
* (c) 2022 Dimitri Sitchet Tomkeu <devcode.dst@gmail.com>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
use BlitzPHP\Controllers\ApplicationController;
13+
use BlitzPHP\Exceptions\ViewException;
14+
use BlitzPHP\Utilities\Reflection\ReflectionClass;
15+
use BlitzPHP\View\View;
16+
use Psr\Http\Message\ResponseInterface;
17+
18+
use function Kahlan\expect;
19+
20+
describe('Controllers / ApplicationController', function (): void {
21+
beforeEach(function (): void {
22+
// Création de la classe de test
23+
$this->controller = new class extends ApplicationController {
24+
// Méthodes d'accès pour tester les méthodes protected
25+
public function testView(string $view, array $data = [], array $options = []): View {
26+
return $this->view($view, $data, $options);
27+
}
28+
29+
public function testRender(array|string $view = '', ?array $data = [], ?array $options = []): ResponseInterface {
30+
return $this->render($view, $data, $options);
31+
}
32+
33+
public function testAddData(array|string $key, $value = null): self {
34+
return $this->addData($key, $value);
35+
}
36+
};
37+
$this->controller->initialize(service('request'), service('response'), service('logger'));
38+
});
39+
40+
describe('Méthode view()', function (): void {
41+
it('Doit charger une vue avec chemin relatif', function (): void {
42+
$result = $this->controller->testView('test_view', ['key' => 'value']);
43+
44+
expect($result)->toBeAnInstanceOf(View::class);
45+
});
46+
47+
it('Doit ajouter les données partagées', function (): void {
48+
$this->controller->testAddData('shared', 'shared_value');
49+
$this->controller->testView('test_view', ['specific' => 'specific_value']);
50+
51+
$viewer = service('viewer');
52+
$data = $viewer->getData();
53+
54+
// Vérifie que le viewer a reçu les données combinées
55+
expect($data)->toContainKey('shared');
56+
expect($data['shared'])->toBe('shared_value');
57+
});
58+
59+
it('Doit définir un titre par défaut si non fourni', function (): void {
60+
$this->controller->testView('test_view');
61+
62+
$viewer = service('viewer');
63+
$data = $viewer->getData();
64+
65+
// Vérifie que le viewer a reçu les données combinées
66+
expect($data)->toContainKey('title');
67+
expect($data['title'])->toMatch('/ - index$/');
68+
});
69+
70+
it('Doit utiliser le titre fourni dans les données', function (): void {
71+
$this->controller->testView('test_view', ['title' => 'Custom Title']);
72+
73+
$viewer = service('viewer');
74+
$data = $viewer->getData();
75+
76+
expect($data['title'])->toBe('Custom Title');
77+
});
78+
79+
it('Doit appliquer un layout si défini', function (): void {
80+
$controller = new class extends ApplicationController {
81+
protected string $layout = 'default';
82+
83+
public function testView(string $view, array $data = [], array $options = []): View {
84+
return $this->view($view, $data, $options);
85+
}
86+
};
87+
88+
$result = $controller->testView('test_view');
89+
90+
$viewer = service('viewer');
91+
$reflection = new ReflectionClass($viewer->getAdapter());
92+
$layout = $reflection->getValue('layout');
93+
94+
expect($layout)->toBe('default');
95+
$reflection->setValue('layout', null);
96+
});
97+
});
98+
99+
describe('Méthode render()', function (): void {
100+
it('Doit rendre une vue avec nom spécifié', function (): void {
101+
try {
102+
$this->controller->testRender('test_view', ['key' => 'value']);
103+
} catch (ViewException $e) {
104+
// en temps normal, on va chercher à charger le fichier "spec\\system\\framework\\Views\\test_view"
105+
// or ce fichier existe pas bien evidement.
106+
// l'important pour nous à ce niveau est que le dossier et le nom du fichier soient bien déterminés
107+
expect($e->getMessage())
108+
->toMatch(fn($actual) => str_ends_with($actual, 'Views\test_view'));
109+
}
110+
});
111+
112+
it('Doit déduire le nom de la vue depuis la méthode appelante', function (): void {
113+
try {
114+
$this->controller->testRender();
115+
} catch (ViewException $e) {
116+
// en temps normal, on va chercher à charger le fichier "spec\\system\\framework\\Views\\test_view"
117+
// or ce fichier existe pas bien evidement.
118+
// l'important pour nous à ce niveau est que le dossier et le nom du fichier soient bien déterminés
119+
expect($e->getMessage())
120+
->toMatch(fn($actual) => str_ends_with($actual, 'Views\\testRender'));
121+
}
122+
});
123+
124+
it('Doit gérer le tableau en premier paramètre', function (): void {
125+
try {
126+
$this->controller->testRender(['key' => 'value']);
127+
} catch (ViewException $e) {
128+
// en temps normal, on va chercher à charger le fichier "spec\\system\\framework\\Views\\test_view"
129+
// or ce fichier existe pas bien evidement.
130+
// l'important pour nous à ce niveau est que le dossier et le nom du fichier soient bien déterminés
131+
expect($e->getMessage())
132+
->toMatch(fn($actual) => str_ends_with($actual, 'Views\\testRender'));
133+
}
134+
});
135+
});
136+
137+
describe('Méthode addData()', function (): void {
138+
it('Doit ajouter une seule paire clé-valeur', function (): void {
139+
$result = $this->controller->testAddData('key', 'value');
140+
141+
expect($result)->toBe($this->controller);
142+
143+
// Tester que les données sont bien ajoutées aux données partagées
144+
$reflection = new ReflectionClass($this->controller);
145+
146+
expect($reflection->getValue('viewDatas'))->toContainKey('key');
147+
expect($reflection->getValue('viewDatas')['key'])->toBe('value');
148+
});
149+
150+
it('Doit ajouter un tableau de données', function (): void {
151+
$this->controller->testAddData(['key1' => 'value1', 'key2' => 'value2']);
152+
153+
$reflection = new ReflectionClass($this->controller);
154+
$data = $reflection->getValue('viewDatas');
155+
156+
expect($data)->toContainKey('key1');
157+
expect($data)->toContainKey('key2');
158+
expect($data['key1'])->toBe('value1');
159+
expect($data['key2'])->toBe('value2');
160+
});
161+
162+
it('Doit fusionner les données existantes', function (): void {
163+
$this->controller->testAddData(['key1' => 'value1']);
164+
$this->controller->testAddData(['key2' => 'value2']);
165+
166+
$reflection = new ReflectionClass($this->controller);
167+
$data = $reflection->getValue('viewDatas');
168+
169+
expect($data)->toContainKey('key1');
170+
expect($data)->toContainKey('key2');
171+
});
172+
});
173+
});

0 commit comments

Comments
 (0)