]> git.agnieray.net Git - galette.git/blob - tests/Galette/Entity/tests/units/Adherent.php
Social networks/contact externalization
[galette.git] / tests / Galette / Entity / tests / units / Adherent.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Adherent tests
7 *
8 * PHP version 5
9 *
10 * Copyright © 2017-2021 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category Entity
28 * @package GaletteTests
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2017-2021 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @version SVN: $Id$
34 * @link http://galette.tuxfamily.org
35 * @since 2017-04-17
36 */
37
38 namespace Galette\Entity\test\units;
39
40 use Galette\GaletteTestCase;
41
42 /**
43 * Adherent tests class
44 *
45 * @category Entity
46 * @name Adherent
47 * @package GaletteTests
48 * @author Johan Cwiklinski <johan@x-tnd.be>
49 * @copyright 2017-2021 The Galette Team
50 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
51 * @link http://galette.tuxfamily.org
52 * @since 2017-04-17
53 */
54 class Adherent extends GaletteTestCase
55 {
56 protected $seed = 95842354;
57 private $default_deps;
58
59 /**
60 * Cleanup after tests
61 *
62 * @return void
63 */
64 public function tearDown()
65 {
66 $this->zdb = new \Galette\Core\Db();
67
68 $delete = $this->zdb->delete(\Galette\Entity\Adherent::TABLE);
69 $delete->where(['fingerprint' => 'FAKER' . $this->seed]);
70 $delete->where('parent_id IS NOT NULL');
71 $this->zdb->execute($delete);
72
73 $delete = $this->zdb->delete(\Galette\Entity\Adherent::TABLE);
74 $delete->where(['fingerprint' => 'FAKER' . $this->seed]);
75 $this->zdb->execute($delete);
76
77 $this->cleanHistory();
78 }
79
80 /**
81 * Set up tests
82 *
83 * @param string $method Calling method
84 *
85 * @return void
86 */
87 public function beforeTestMethod($method)
88 {
89 parent::beforeTestMethod($method);
90 $this->initStatus();
91 $this->initTitles();
92
93 $this->default_deps = [
94 'picture' => true,
95 'groups' => true,
96 'dues' => true,
97 'parent' => false,
98 'children' => false,
99 'dynamics' => false,
100 'socials' => false
101 ];
102
103 $this->adh = new \Galette\Entity\Adherent($this->zdb);
104 $this->adh->setDependencies(
105 $this->preferences,
106 $this->members_fields,
107 $this->history
108 );
109 }
110
111 /**
112 * Test empty member
113 *
114 * @return void
115 */
116 public function testEmpty()
117 {
118 $adh = $this->adh;
119 $this->boolean($adh->isAdmin())->isFalse();
120 $this->boolean($adh->admin)->isFalse();
121 $this->boolean($adh->isStaff())->isFalse();
122 $this->boolean($adh->staff)->isFalse();
123 $this->boolean($adh->isDueFree())->isFalse();
124 $this->boolean($adh->due_free)->isFalse();
125 $this->boolean($adh->isGroupMember('any'))->isFalse();
126 $this->boolean($adh->isGroupManager('any'))->isFalse();
127 $this->boolean($adh->isCompany())->isFalse();
128 $this->boolean($adh->isMan())->isFalse();
129 $this->boolean($adh->isWoman())->isFalse();
130 $this->boolean($adh->isActive())->isTrue();
131 $this->boolean($adh->active)->isTrue();
132 $this->boolean($adh->isUp2Date())->isFalse();
133 $this->boolean($adh->appearsInMembersList())->isFalse();
134 $this->boolean($adh->appears_in_list)->isFalse();
135
136 $this->variable($adh->fake_prop)->isNull();
137
138 $this->array($adh->deps)->isIdenticalTo($this->default_deps);
139 }
140
141 /**
142 * Test member load dependencies
143 *
144 * @return void
145 */
146 public function testDependencies()
147 {
148 $adh = $this->adh;
149 $this->array($adh->deps)->isIdenticalTo($this->default_deps);
150
151 $adh = clone $this->adh;
152 $adh->disableAllDeps();
153 $expected = [
154 'picture' => false,
155 'groups' => false,
156 'dues' => false,
157 'parent' => false,
158 'children' => false,
159 'dynamics' => false,
160 'socials' => false
161 ];
162 $this->array($adh->deps)->isIdenticalTo($expected);
163
164 $expected = [
165 'picture' => false,
166 'groups' => false,
167 'dues' => true,
168 'parent' => false,
169 'children' => true,
170 'dynamics' => true,
171 'socials' => false
172 ];
173 $adh
174 ->enableDep('dues')
175 ->enableDep('dynamics')
176 ->enableDep('children');
177 $this->array($adh->deps)->isIdenticalTo($expected);
178
179 $expected = [
180 'picture' => false,
181 'groups' => false,
182 'dues' => true,
183 'parent' => false,
184 'children' => false,
185 'dynamics' => true,
186 'socials' => false
187 ];
188 $adh->disableDep('children');
189 $this->array($adh->deps)->isIdenticalTo($expected);
190
191 $adh->disableDep('none')->enableDep('anothernone');
192 $this->array($adh->deps)->isIdenticalTo($expected);
193
194 $expected = [
195 'picture' => true,
196 'groups' => true,
197 'dues' => true,
198 'parent' => true,
199 'children' => true,
200 'dynamics' => true,
201 'socials' => true
202 ];
203 $adh->enableAllDeps('children');
204 $this->array($adh->deps)->isIdenticalTo($expected);
205 }
206
207 /**
208 * Tests getter
209 *
210 * @return void
211 */
212 public function testGetterWException()
213 {
214 $adh = $this->adh;
215
216 $this->exception(
217 function () use ($adh) {
218 $adh->row_classes;
219 }
220 )->isInstanceOf('RuntimeException');
221 }
222
223 /**
224 * Set dependencies from constructor
225 *
226 * @return void
227 */
228 public function testDepsAtConstuct()
229 {
230 $deps = [
231 'picture' => false,
232 'groups' => false,
233 'dues' => false,
234 'parent' => false,
235 'children' => false,
236 'dynamics' => false,
237 'socials' => false
238 ];
239 $adh = new \Galette\Entity\Adherent(
240 $this->zdb,
241 null,
242 $deps
243 );
244
245 $this->array($adh->deps)->isIdenticalTo($deps);
246
247 $adh = new \Galette\Entity\Adherent(
248 $this->zdb,
249 null,
250 'not an array'
251 );
252 $this->array($adh->deps)->isIdenticalTo($this->default_deps);
253 }
254
255 /**
256 * Test simple member creation
257 *
258 * @return void
259 */
260 public function testSimpleMember()
261 {
262 $this->getMemberOne();
263 $this->checkMemberOneExpected();
264
265 //load member from db
266 $adh = new \Galette\Entity\Adherent($this->zdb, $this->adh->id);
267 $this->checkMemberOneExpected($adh);
268 }
269
270 /**
271 * Test load form login and email
272 *
273 * @return void
274 */
275 public function testLoadForLogin()
276 {
277 $this->getMemberOne();
278
279 $login = $this->adh->login;
280 $email = $this->adh->email;
281
282 $this->variable($this->adh->email)->isIdenticalTo($this->adh->getEmail());
283
284 $adh = new \Galette\Entity\Adherent($this->zdb, $login);
285 $this->checkMemberOneExpected($adh);
286
287 $adh = new \Galette\Entity\Adherent($this->zdb, $email);
288 $this->checkMemberOneExpected($adh);
289 }
290
291 /**
292 * Test password updating
293 *
294 * @return void
295 */
296 public function testUpdatePassword()
297 {
298 $this->getMemberOne();
299
300 $this->checkMemberOneExpected();
301
302 $newpass = 'aezrty';
303 \Galette\Entity\Adherent::updatePassword($this->zdb, $this->adh->id, $newpass);
304 $adh = new \Galette\Entity\Adherent($this->zdb, $this->adh->id);
305 $pw_checked = password_verify($newpass, $adh->password);
306 $this->boolean($pw_checked)->isTrue();
307
308 //reset original password
309 \Galette\Entity\Adherent::updatePassword($this->zdb, $this->adh->id, 'J^B-()f');
310 }
311
312 /**
313 * Tests check errors
314 *
315 * @return void
316 */
317 public function testCheckErrors()
318 {
319 $adh = $this->adh;
320
321 $data = ['ddn_adh' => 'not a date'];
322 $expected = ['- Wrong date format (Y-m-d) for Birth date!'];
323 $check = $adh->check($data, [], []);
324 $this->array($check)->isIdenticalTo($expected);
325
326 $data = [
327 'ddn_adh' => '',
328 'date_crea_adh' => 'not a date'
329 ];
330 $expected = ['- Wrong date format (Y-m-d) for Creation date!'];
331 $check = $adh->check($data, [], []);
332 $this->array($check)->isIdenticalTo($expected);
333
334 //reste creation date to its default value
335 $data = ['date_crea_adh' => date('Y-m-d')];
336 $check = $adh->check($data, [], []);
337 $this->boolean($check)->isTrue();
338
339 $data = ['email_adh' => 'not an email'];
340 $expected = ['- Non-valid E-Mail address! (E-Mail)'];
341 $check = $adh->check($data, [], []);
342 $this->array($check)->isIdenticalTo($expected);
343
344 $data = ['login_adh' => 'a'];
345 $expected = ['- The username must be composed of at least 2 characters!'];
346 $check = $adh->check($data, [], []);
347 $this->array($check)->isIdenticalTo($expected);
348
349 $data = ['login_adh' => 'login@galette'];
350 $expected = ['- The username cannot contain the @ character'];
351 $check = $adh->check($data, [], []);
352 $this->array($check)->isIdenticalTo($expected);
353
354 $data = [
355 'login_adh' => '',
356 'mdp_adh' => 'short',
357 'mdp_adh2' => 'short'
358 ];
359 $expected = ['Too short (6 characters minimum, 5 found)'];
360 $check = $adh->check($data, [], []);
361 $this->array($check)->isIdenticalTo($expected);
362
363 $data = ['mdp_adh' => 'mypassword'];
364 $expected = ['- The passwords don\'t match!'];
365 $check = $adh->check($data, [], []);
366 $this->array($check)->isIdenticalTo($expected);
367
368 $data = [
369 'mdp_adh' => 'mypassword',
370 'mdp_adh2' => 'mypasswor'
371 ];
372 $expected = ['- The passwords don\'t match!'];
373 $check = $adh->check($data, [], []);
374 $this->array($check)->isIdenticalTo($expected);
375
376 $data = ['id_statut' => 256];
377 $expected = ['Status #256 does not exists in database.'];
378 $check = $adh->check($data, [], []);
379 $this->array($check)->isIdenticalTo($expected);
380 }
381
382 /**
383 * Test picture
384 *
385 * @return void
386 */
387 public function testPhoto()
388 {
389 $this->getMemberOne();
390
391 $fakedata = new \Galette\Util\FakeData($this->zdb, $this->i18n);
392 $this->boolean($fakedata->addPhoto($this->adh))->isTrue();
393
394 $this->boolean($this->adh->hasPicture())->isTrue();
395
396 //remove photo
397 $this->boolean($this->adh->picture->delete())->isTrue();
398 }
399
400 /**
401 * Test canEdit
402 *
403 * @return void
404 */
405 public function testCanEdit()
406 {
407 $adh = new \Galette\Entity\Adherent($this->zdb);
408
409 //non authorized
410 $login = new \mock\Galette\Core\Login($this->zdb, $this->i18n);
411 $this->boolean($adh->canEdit($login))->isFalse();
412
413 //admin => authorized
414 $login = new \mock\Galette\Core\Login($this->zdb, $this->i18n);
415 $this->calling($login)->isAdmin = true;
416 $this->boolean($adh->canEdit($login))->isTrue();
417
418 //staff => authorized
419 $login = new \mock\Galette\Core\Login($this->zdb, $this->i18n);
420 $this->calling($login)->isStaff = true;
421 $this->boolean($adh->canEdit($login))->isTrue();
422
423 //group managers
424 $adh = new \mock\Galette\Entity\Adherent($this->zdb);
425
426 $g1 = new \mock\Galette\Entity\Group();
427 $this->calling($g1)->getId = 1;
428 $g2 = new \mock\Galette\Entity\Group();
429 $this->calling($g1)->getId = 2;
430
431 $this->calling($adh)->getGroups = [$g1, $g2];
432 $login = new \mock\Galette\Core\Login($this->zdb, $this->i18n);
433 $this->boolean($adh->canEdit($login))->isFalse();
434
435 $this->calling($login)->isGroupManager = true;
436 $this->boolean($adh->canEdit($login))->isTrue();
437 }
438
439 /**
440 * Test member duplication
441 *
442 * @return void
443 */
444 public function testDuplicate()
445 {
446 $this->getMemberOne();
447
448 $this->checkMemberOneExpected();
449
450 //load member from db
451 $adh = new \Galette\Entity\Adherent($this->zdb, $this->adh->id);
452 $this->checkMemberOneExpected($adh);
453
454 $adh->setDuplicate();
455
456 $this->string($adh->others_infos_admin)->contains('Duplicated from');
457 $this->variable($adh->email)->isNull();
458 $this->variable($adh->id)->isNull();
459 $this->variable($adh->login)->isNull();
460 $this->variable($adh->birthdate)->isNull();
461 $this->variable($adh->surname)->isNull();
462 }
463
464 /**
465 * Test parents
466 *
467 * @return void
468 */
469 public function testParents()
470 {
471 $this->getMemberOne();
472
473 $this->checkMemberOneExpected();
474
475 //load member from db
476 $parent = new \Galette\Entity\Adherent($this->zdb, $this->adh->id);
477 $this->checkMemberOneExpected($parent);
478
479 $this->logSuperAdmin();
480
481 $child_data = [
482 'nom_adh' => 'Doe',
483 'prenom_adh' => 'Johny',
484 'parent_id' => $parent->id,
485 'attach' => true
486 ];
487 $child = $this->createMember($child_data);
488
489 $this->string($child->name)->isIdenticalTo($child_data['nom_adh']);
490 $this->object($child->parent)->isInstanceOf('\Galette\Entity\Adherent');
491 $this->integer($child->parent->id)->isIdenticalTo($parent->id);
492
493 $check = $child->check(['detach_parent' => true], [], []);
494 if (is_array($check)) {
495 var_dump($check);
496 }
497 $this->boolean($check)->isTrue();
498 $this->boolean($child->store())->isTrue();
499 $this->variable($child->parent)->isNull();
500 }
501
502 /**
503 * Test XSS/SQL injection
504 *
505 * @return void
506 */
507 public function testInjection()
508 {
509 $data = [
510 'nom_adh' => 'Doe',
511 'prenom_adh' => 'Johny <script>console.log("anything");</script>',
512 'email_adh' => 'jdoe@doe.com',
513 'login_adh' => 'jdoe',
514 'info_public_adh' => 'Any <script>console.log("useful");</script> information'
515 ] + $this->dataAdherentOne();
516 $member = $this->createMember($data);
517
518 $this->string($member->sfullname)->isIdenticalTo('DOE Johny Console.log("anything");');
519 $this->string($member->others_infos)->isIdenticalTo('Any console.log("useful"); information');
520 }
521
522 /**
523 * Test can* methods
524 *
525 * @return void
526 */
527 public function testCan()
528 {
529 $this->getMemberOne();
530 //load member from db
531 $member = new \Galette\Entity\Adherent($this->zdb, $this->adh->id);
532
533 $this->boolean($member->canShow($this->login))->isFalse();
534 $this->boolean($member->canCreate($this->login))->isFalse();
535 $this->boolean($member->canEdit($this->login))->isFalse();
536
537 //Superadmin can fully change members
538 $this->logSuperAdmin();
539
540 $this->boolean($member->canShow($this->login))->isTrue();
541 $this->boolean($member->canCreate($this->login))->isTrue();
542 $this->boolean($member->canEdit($this->login))->isTrue();
543
544 //logout
545 $this->login->logOut();
546 $this->boolean($this->login->isLogged())->isFalse();
547
548 //Member can fully change its own information
549 $mdata = $this->dataAdherentOne();
550 $this->boolean($this->login->login($mdata['login_adh'], $mdata['mdp_adh']))->isTrue();
551 $this->boolean($this->login->isLogged())->isTrue();
552 $this->boolean($this->login->isAdmin())->isFalse();
553 $this->boolean($this->login->isStaff())->isFalse();
554
555 $this->boolean($member->canShow($this->login))->isTrue();
556 $this->boolean($member->canCreate($this->login))->isTrue();
557 $this->boolean($member->canEdit($this->login))->isTrue();
558
559 //logout
560 $this->login->logOut();
561 $this->boolean($this->login->isLogged())->isFalse();
562
563 //Another member has no access
564 $this->getMemberTwo();
565 $mdata = $this->dataAdherentTwo();
566 $this->boolean($this->login->login($mdata['login_adh'], $mdata['mdp_adh']))->isTrue();
567 $this->boolean($this->login->isLogged())->isTrue();
568 $this->boolean($this->login->isAdmin())->isFalse();
569 $this->boolean($this->login->isStaff())->isFalse();
570
571 $this->boolean($member->canShow($this->login))->isFalse();
572 $this->boolean($member->canCreate($this->login))->isFalse();
573 $this->boolean($member->canEdit($this->login))->isFalse();
574
575 //parents can fully change children information
576 $this->getMemberOne();
577 $mdata = $this->dataAdherentOne();
578 global $login;
579 $login = $this->login;
580 $this->logSuperAdmin();
581
582 $child_data = [
583 'nom_adh' => 'Doe',
584 'prenom_adh' => 'Johny',
585 'parent_id' => $member->id,
586 'attach' => true,
587 'login_adh' => 'child.johny.doe',
588 'fingerprint' => 'FAKER' . $this->seed
589 ];
590 $child = $this->createMember($child_data);
591 $cid = $child->id;
592 $this->login->logOut();
593
594 //load child from db
595 $child = new \Galette\Entity\Adherent($this->zdb);
596 $child->enableDep('parent');
597 $this->boolean($child->load($cid))->isTrue();
598
599 $this->string($child->name)->isIdenticalTo($child_data['nom_adh']);
600 $this->object($child->parent)->isInstanceOf('\Galette\Entity\Adherent');
601 $this->integer($child->parent->id)->isIdenticalTo($member->id);
602 $this->boolean($this->login->login($mdata['login_adh'], $mdata['mdp_adh']))->isTrue();
603
604 $mdata = $this->dataAdherentOne();
605 $this->boolean($this->login->login($mdata['login_adh'], $mdata['mdp_adh']))->isTrue();
606 $this->boolean($this->login->isLogged())->isTrue();
607 $this->boolean($this->login->isAdmin())->isFalse();
608 $this->boolean($this->login->isStaff())->isFalse();
609
610 $this->boolean($child->canShow($this->login))->isTrue();
611 $this->boolean($child->canCreate($this->login))->isFalse();
612 $this->boolean($child->canEdit($this->login))->isTrue();
613
614 //logout
615 $this->login->logOut();
616 $this->boolean($this->login->isLogged())->isFalse();
617 }
618
619 /**
620 * Names provider
621 *
622 * @return array[]
623 */
624 protected function nameCaseProvider(): array
625 {
626 return [
627 [
628 'name' => 'Doe',
629 'surname' => 'John',
630 'title' => false,
631 'id' => false,
632 'nick' => false,
633 'expected' => 'DOE John'
634 ],
635 [
636 'name' => 'Doéè',
637 'surname' => 'John',
638 'title' => false,
639 'id' => false,
640 'nick' => false,
641 'expected' => 'DOÉÈ John'
642 ],
643 [
644 'name' => 'Doe',
645 'surname' => 'John',
646 'title' => new \Galette\Entity\Title(\Galette\Entity\Title::MR),
647 'id' => false,
648 'nick' => false,
649 'expected' => 'Mr. DOE John'
650 ],
651 [
652 'name' => 'Doe',
653 'surname' => 'John',
654 'title' => false,
655 'id' => false,
656 'nick' => 'foo',
657 'expected' => 'DOE John (foo)'
658 ],
659 [
660 'name' => 'Doe',
661 'surname' => 'John',
662 'title' => false,
663 'id' => 42,
664 'nick' => false,
665 'expected' => 'DOE John (42)'
666 ],
667 [
668 'name' => 'Doe',
669 'surname' => 'John',
670 'title' => new \Galette\Entity\Title(\Galette\Entity\Title::MR),
671 'id' => 42,
672 'nick' => 'foo',
673 'expected' => 'Mr. DOE John (foo, 42)'
674 ],
675 ];
676 }
677
678 /**
679 * Test getNameWithCase
680 *
681 * @dataProvider nameCaseProvider
682 *
683 * @param string $name Name
684 * @param string $surname Surname
685 * @param \Galette\Entity\Title|false $title Title
686 * @param string|false $id ID
687 * @param string|false $nick Nick
688 * @param string $expected Expected result
689 *
690 * @return void
691 */
692 public function testsGetNameWithCase(string $name, string $surname, $title, $id, $nick, string $expected)
693 {
694 $this->string(
695 \Galette\Entity\Adherent::getNameWithCase(
696 $name,
697 $surname,
698 $title,
699 $id,
700 $nick,
701 )
702 )->isIdenticalTo($expected);
703 }
704 }