Commit 6bddffe9 authored by Christian BUFFIN's avatar Christian BUFFIN

Ajout de tests d'accès pour la classe ResponsablesController, corrections et...

Ajout de tests d'accès pour la classe ResponsablesController, corrections et améliorations de celle-ci et des fichiers y étant liés, mise à jour des fixtures suite aux tests fonctionnels automatisés.
parent ca880fc5
......@@ -29,6 +29,16 @@ class ResponsablesController extends AppController {
'ResponsableOrganisation',
'Organisation'
];
/**
* Vérification de l'accès aux actions en fonction du profil de l'utilisateur connecté.
* Les vérifications de l'accès aux enregistrements se font dans les méthodes d'actions.
*/
public function beforeFilter() {
parent::beforeFilter();
$this->Droits->assertAuthorized([ListeDroit::GESTION_CORESPONSABLE]);
}
/**
* @throws ForbiddenException
......@@ -39,10 +49,6 @@ class ResponsablesController extends AppController {
* @version v1.0.0
*/
public function index() {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$this->set('title', __d('responsable', 'responsable.titreGestionResponsableApplication'));
$condition = [];
......@@ -142,14 +148,7 @@ class ResponsablesController extends AppController {
$responsables = $this->paginate($this->Responsable);
$this->set(compact('responsables'));
$mesOrganisations = $this->WebcilUsers->organisations(
'list',
[
'droits' => 'add' === $this->request->params['action']
? ListeDroit::CREER_UTILISATEUR
: ListeDroit::MODIFIER_UTILISATEUR
]
);
$mesOrganisations = $this->_mesOrganisations();
$this->set(compact('mesOrganisations'));
$options = $this->_optionsFiltre();
......@@ -228,10 +227,6 @@ class ResponsablesController extends AppController {
* @version v1.0.0
*/
public function entite() {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$this->set('title', __d('responsable', 'responsable.titreGestionResponsableEntitee'));
$organisation_id = $this->Session->read('Organisation.id');
......@@ -272,6 +267,19 @@ class ResponsablesController extends AppController {
$this->set(compact('options'));
}
protected function _mesOrganisations() {
$mesOrganisations = $this->WebcilUsers->organisations(
'list',
[
'droits' => 'add' === $this->request->params['action']
? ListeDroit::CREER_UTILISATEUR
: ListeDroit::MODIFIER_UTILISATEUR
]
);
return $mesOrganisations;
}
/**
* Fonction qui permet l'ajout d'une nouvelle norme
*
......@@ -283,57 +291,7 @@ class ResponsablesController extends AppController {
* @version V1.0.0
*/
public function add() {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$this->set('title', __d('responsable', 'responsable.titreAjouterResponsable'));
if ($this->request->is('post')) {
if ('Cancel' === Hash::get($this->request->data, 'submit')) {
$this->redirect($this->Referers->get());
}
$success = true;
$this->Responsable->begin();
$this->Responsable->create($this->request->data['Responsable']);
$success = $success && false !== $this->Responsable->save(null, ['atomic' => false]);
if (!empty($this->request->data['ResponsableOrganisation']['organisation_id']) && $success == true) {
$responsableId = $this->Responsable->id;
foreach ($this->request->data['ResponsableOrganisation']['organisation_id'] as $organisationId) {
if ($success == true) {
$this->ResponsableOrganisation->create([
'responsable_id' => $responsableId,
'organisation_id' => $organisationId
]);
$success = $success && false !== $this->ResponsableOrganisation->save(null, ['atomic' => false]);
}
}
}
if ($success == true) {
$this->Responsable->commit();
$this->Session->setFlash(__d('role', 'role.flashsuccessProfilEnregistrer'), 'flashsuccess');
$this->redirect($this->Referers->get());
} else {
$this->Responsable->rollback();
$this->Session->setFlash(__d('role', 'role.flasherrorErreurEnregistrementProfil'), 'flasherror');
}
}
$mesOrganisations = $this->WebcilUsers->organisations(
'list',
[
'droits' => 'add' === $this->request->params['action']
? ListeDroit::CREER_UTILISATEUR
: ListeDroit::MODIFIER_UTILISATEUR
]
);
$this->set(compact('mesOrganisations'));
$this->edit(null);
}
/**
......@@ -347,88 +305,46 @@ class ResponsablesController extends AppController {
* @created 20/12/2017
* @version V1.0.0
*/
public function edit($id = null) {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
public function edit($id) {
if ($this->request->params['action'] === 'add') {
$this->set('title', __d('responsable', 'responsable.titreAjouterResponsable'));
} else {
$responsable = $this->Droits->getAndCheckLinkedOrganisationsRecord('Responsable', $id, false);
$this->set('title', __d('responsable', 'responsable.titreModifierResponsable'));
}
$this->set('title', __d('responsable', 'responsable.titreModifierResponsable'));
if ($this->request->is('post') || $this->request->is('put')) {
if ('Cancel' === Hash::get($this->request->data, 'submit')) {
$this->redirect($this->Referers->get());
}
$success = true;
$this->Responsable->begin();
$this->request->data['Responsable']['id'] = $id;
$this->Responsable->create($this->request->data['Responsable']);
$success = $success && false !== $this->Responsable->save(null, ['atomic' => false]);
if ($success == true) {
$responsableId = $this->Responsable->id;
$success = $this->ResponsableOrganisation->deleteAll([
'ResponsableOrganisation.responsable_id' => $responsableId
]) && $success;
if ($success == true && !empty($this->request->data['ResponsableOrganisation']['organisation_id'])) {
foreach ($this->request->data['ResponsableOrganisation']['organisation_id'] as $organisationId) {
if ($success == true) {
$this->ResponsableOrganisation->create([
'responsable_id' => $responsableId,
'organisation_id' => $organisationId
]);
$success = $success && false !== $this->ResponsableOrganisation->save(null, ['atomic' => false]);
}
}
if ($this->request->params['action'] === 'add') {
$data = $this->request->data;
$data['Responsable']['createdbyorganisation'] = $this->Droits->isSu() ? null : $this->Session->read('Organisation.id');
} else {
$data = $this->request->data;
foreach (['id', 'createdbyorganisation'] as $fieldName) {
$data['Responsable'][$fieldName] = $responsable['Responsable'][$fieldName];
}
}
if ($success == true) {
$this->Responsable->commit();
$this->Session->setFlash(__d('role', 'role.flashsuccessProfilEnregistrer'), 'flashsuccess');
$this->Responsable->create($data);
if (false !== $this->Responsable->save(null, ['atomic' => true])) {
$this->Session->setFlash(__d('responsable', 'responsable.flashsuccessSaveResponsable'), 'flashsuccess');
$this->redirect($this->Referers->get());
} else {
$this->Responsable->rollback();
$this->Session->setFlash(__d('role', 'role.flasherrorErreurEnregistrementProfil'), 'flasherror');
$this->Session->setFlash(__d('responsable', 'responsable.flasherrorSaveResponsable'), 'flasherror');
}
} elseif ($this->request->params['action'] === 'add') {
$this->request->data['Organisation']['Organisation'] = $this->Droits->isSu() ? null : $this->Session->read('Organisation.id');
} else {
$this->request->data = $responsable;
}
$responsable = $this->Responsable->find('first', [
'conditions' => [
'id' => $id
]
]);
$this->request->data = $responsable;
$responsableOrganisation = $this->ResponsableOrganisation->find('all', [
'conditions' => [
'responsable_id' => $id
]
]);
$organisationResponsableSelect = Hash::extract($responsableOrganisation, '{n}.ResponsableOrganisation.organisation_id');
$optionsAffecter = [
'ResponsableOrganisation' => [
'organisation_id' => $organisationResponsableSelect
]
];
$this->request->data += $optionsAffecter;
$mesOrganisations = $this->WebcilUsers->organisations(
'list',
[
'droits' => 'add' === $this->request->params['action']
? ListeDroit::CREER_UTILISATEUR
: ListeDroit::MODIFIER_UTILISATEUR
]
);
$mesOrganisations = $this->_mesOrganisations();
$this->set(compact('mesOrganisations'));
$this->view = 'edit';
}
/**
......@@ -442,10 +358,6 @@ class ResponsablesController extends AppController {
* @version v1.0.0
*/
public function show($id) {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$this->set('title', __d('responsable', 'responsable.titreVisualiserResponsable'));
$responsable = $this->Responsable->find('first', [
......@@ -453,6 +365,11 @@ class ResponsablesController extends AppController {
'id' => $id
]
]);
if (empty($responsable) == true) {
throw new NotFoundException();
}
$this->request->data = $responsable;
$responsableOrganisation = $this->ResponsableOrganisation->find('all', [
......@@ -491,33 +408,16 @@ class ResponsablesController extends AppController {
* @version v1.0.0
*/
public function delete($id) {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$associationResponsable = $this->ResponsableOrganisation->find('all', [
'conditions' => [
'responsable_id' => $id
]
]);
if (empty($associationResponsable)) {
$success = true;
$this->Responsable->begin();
$this->Droits->getAndCheckLinkedOrganisationsRecord('Responsable', $id, true);
$success = $success && false !== $this->Responsable->deleteAll([
'id' => $id
]);
$this->Responsable->begin();
if ($success == true) {
$this->Responsable->commit();
$this->Session->setFlash(__d('responsable', 'responsable.flashsuccessSuppressionResponsableEntite'), 'flashsuccess');
} else {
$this->Responsable->rollback();
$this->Session->setFlash(__d('responsable', 'responsable.flasherrorErreurSuppressionResponsableEntite'), 'flasherror');
}
if (false !== $this->Responsable->delete($id)) {
$this->Responsable->commit();
$this->Session->setFlash(__d('responsable', 'responsable.flashsuccessSuppressionResponsableEntite'), 'flashsuccess');
} else {
$this->Session->setFlash(__d('responsable', 'responsable.flasherrorErreurAssociationExistanteResponsableEntite'), 'flasherror');
$this->Responsable->rollback();
$this->Session->setFlash(__d('responsable', 'responsable.flasherrorErreurSuppressionResponsableEntite'), 'flasherror');
}
$this->redirect($this->Referers->get());
......@@ -526,7 +426,7 @@ class ResponsablesController extends AppController {
/**
* Fonction qui permet de supprimer un responsable liée à l'entité
*
* @param int $responsableId
* @param int $id
* @throws ForbiddenException
*
* @author Théo GUILLON <theo.guillon@libriciel.coop>
......@@ -534,17 +434,14 @@ class ResponsablesController extends AppController {
* @created 12/04/2018
* @version v1.0.0
*/
public function dissocierResponsable($responsableId) {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$success = true;
public function dissocierResponsable($id) {
$this->Droits->assertRecordAuthorized('Responsable', $id, ['superadmin' => true]);
$this->ResponsableOrganisation->begin();
$success = $success && false !== $this->ResponsableOrganisation->deleteAll([
$success = false !== $this->ResponsableOrganisation->deleteAll([
'ResponsableOrganisation.organisation_id' => $this->Session->read('Organisation.id'),
'ResponsableOrganisation.responsable_id' => $responsableId
'ResponsableOrganisation.responsable_id' => $id
]);
if ($success == true) {
......
......@@ -144,7 +144,7 @@ class SoustraitantsController extends AppController {
$this->set(compact('options'));
}
private function _mesOrganisations() {
protected function _mesOrganisations() {
$mesOrganisations = $this->WebcilUsers->organisations(
'list',
[
......
......@@ -36,11 +36,14 @@ msgstr "Visualiser un responsable"
#### SUCCESS ####
msgid "responsable.flashsuccessSaveResponsable"
msgstr "Le responsable a bien été enregistré"
msgid "responsable.flashsuccessDissocierResponsableEntite"
msgstr "La dissociation du responsable de l'entité a été enregistrée"
msgid "responsable.flashsuccessSuppressionResponsableEntite"
msgstr "La suppression du responsable pour l'entité a été enregistrée"
msgstr "La suppression du responsable a été enregistrée"
msgid "responsable.flashsuccessSousTraitantAffecterEnregistrer"
msgstr "Le responsable a été associé dans l'entité"
......@@ -49,6 +52,9 @@ msgstr "Le responsable a été associé dans l'entité"
#### ERREUR ####
msgid "responsable.flasherrorSaveResponsable"
msgstr "Une erreur est survenue lors de l'enregistrement du responsable"
msgid "responsable.flasherrorErreurDissocierResponsableEntite"
msgstr "Une erreur est survenue lors de la dissociation du responsable de l'entité"
......
......@@ -21,8 +21,9 @@
*/
App::uses('AppModel', 'Model');
App::uses('LinkedOrganisationInterface', 'Model/Interface');
class Responsable extends AppModel {
class Responsable extends AppModel implements LinkedOrganisationInterface {
public $name = 'Responsable';
......@@ -119,4 +120,43 @@ class Responsable extends AppModel {
'with' => 'ResponsableOrganisation'
]
];
/**
* Retourne les id des organisations liées au responsable.
*
* @param int $id
* @return array
*/
public function getLinkedOrganisationsIds($id) {
$query = [
'fields' => ['organisation_id'],
'conditions' => ['responsable_id' => $id],
];
return Hash::extract(
$this->ResponsableOrganisation->find('all', $query),
'{n}.ResponsableOrganisation.organisation_id'
);
}
/**
* Retourne un champ virtuel contenant le nombre d'entités liées au responsable.
*
* @deprecated
*
* @param string $primaryKeyField | 'Responsable.id' --> Champ représentant le Responsable.id
* @param string $fieldName | 'organisations_count' --> Nom du champ virtuel
* @return string
*/
public function vfLinkedOrganisationsCount($primaryKeyField = 'Responsable.id', $fieldName = 'organisations_count') {
$subQuery = [
'alias' => 'responsables_organisations',
'fields' => ['COUNT(DISTINCT(responsables_organisations.organisation_id))'],
'conditions' => [
"responsables_organisations.responsable_id = {$primaryKeyField}"
],
'contain' => false
];
$sql = $this->ResponsableOrganisation->sql($subQuery);
return "( {$sql} ) AS \"{$this->alias}__{$fieldName}\"";
}
}
......@@ -203,7 +203,7 @@ class WebcilUsersComponentTest extends ControllerTestCase
'prefixenumero' => 'DPO-',
'numeroregistre' => 1,
'civiliteresponsable' => 'Mme.',
'rgpd' => true,
'rgpd' => false,
'usemodelepresentation' => false,
]
];
......
<?php
App::uses('AppController', 'Controller');
App::uses( 'ControllerTestCaseAccessTrait', 'Test/Trait/Controller' );
/**
* Tests d'intégration de la classe ResponsablesController.
*
* ./cake_utils.sh tests app Controller/ResponsablesController
*
* @package app.Test.Case.Controller
*/
class ResponsablesControllerTest extends ControllerTestCase
{
use ControllerTestCaseAccessTrait;
public $fixtures = [
'app.Fiche',
'app.ListeDroit',
'app.Notification',
'app.Organisation',
'app.OrganisationUser',
'app.OrganisationUserRole',
'app.Responsable',
'app.ResponsableOrganisation',
'app.Role',
'app.RoleDroit',
'app.User',
'app.Valeur',
];
public function setUp() {
parent::setUp();
$this->controller = $this->generate('Responsables');
}
public function dataAccessAdd() {
return [
// 1. Utilisateurs pouvant accéder à la fonctionnalité
[200, 'Superadministrateur.superadmin', '/responsables/add'],
[200, 'Administrateur.ibleu', '/responsables/add'],
[200, 'DPO.nroux', '/responsables/add'],
// 2. Utilisateurs ne pouvant pas accéder à la fonctionnalité
[403, 'Rédacteur.rjaune', '/responsables/add'],
[403, 'Valideur.cnoir', '/responsables/add'],
[403, 'Consultant.mrose', '/responsables/add'],
];
}
/**
* @dataProvider dataAccessAdd
*/
public function testAccessAdd($expectedStatus, $user, $url, $options = []) {
$this->assertActionAccess($expectedStatus, $user, $url, $options);
}
public function dataAccessDelete() {
return [
// 1. Utilisateurs pouvant accéder à la fonctionnalité
// 1.1. Enregistrement existant
[302, 'Superadministrateur.superadmin', '/responsables/delete/1'],
[302, 'Administrateur.ibleu', '/responsables/delete/1'],
[302, 'DPO.nroux', '/responsables/delete/1'],
// Un utilisateur mono-collectivité ne peut pas accéder à l'enregistrement d'une autre collectivité
[403, 'Administrateur.findigo', '/responsables/delete/1'],
[403, 'DPO.hvermeil', '/responsables/delete/1'],
// 1.2. Enregistrement inexistant
[404, 'Superadministrateur.superadmin', '/responsables/delete/666'],
[404, 'Administrateur.ibleu', '/responsables/delete/666'],
[404, 'DPO.nroux', '/responsables/delete/666'],
// 2. Utilisateurs ne pouvant pas accéder à la fonctionnalité
// 1.1. Enregistrement existant
[403, 'Rédacteur.rjaune', '/responsables/delete/1'],
[403, 'Valideur.cnoir', '/responsables/delete/1'],
[403, 'Consultant.mrose', '/responsables/delete/1'],
// 2.2. Enregistrement inexistant
[403, 'Rédacteur.rjaune', '/responsables/delete/666'],
[403, 'Valideur.cnoir', '/responsables/delete/666'],
[403, 'Consultant.mrose', '/responsables/delete/666'],
];
}
/**
* @dataProvider dataAccessDelete
*/
public function testAccessDelete($expectedStatus, $user, $url, $options = []) {
$this->assertActionAccess($expectedStatus, $user, $url, $options);
}
public function dataAccessDissocierResponsable() {
return [
// 1. Utilisateurs pouvant accéder à la fonctionnalité
// 1.1. Enregistrement existant et associé
[302, 'Superadministrateur.superadmin', '/responsables/dissocierResponsable/8'],
[302, 'Administrateur.ibleu', '/responsables/dissocierResponsable/8'],
[302, 'DPO.nroux', '/responsables/dissocierResponsable/8'],
// Un utilisateur mono-collectivité ne peut pas accéder à l'enregistrement d'une autre collectivité
[403, 'Administrateur.findigo', '/responsables/dissocierResponsable/8'],
[403, 'DPO.hvermeil', '/responsables/dissocierResponsable/8'],
// 1.2. Enregistrement inexistant
[404, 'Superadministrateur.superadmin', '/responsables/dissocierResponsable/666'],
[404, 'Administrateur.ibleu', '/responsables/dissocierResponsable/666'],
[404, 'DPO.nroux', '/responsables/dissocierResponsable/666'],
// 2. Utilisateurs ne pouvant pas accéder à la fonctionnalité
// 1.1. Enregistrement existant
[403, 'Rédacteur.rjaune', '/responsables/dissocierResponsable/8'],
[403, 'Valideur.cnoir', '/responsables/dissocierResponsable/8'],
[403, 'Consultant.mrose', '/responsables/dissocierResponsable/8'],
// 2.2. Enregistrement inexistant
[403, 'Rédacteur.rjaune', '/responsables/dissocierResponsable/666'],
[403, 'Valideur.cnoir', '/responsables/dissocierResponsable/666'],
[403, 'Consultant.mrose', '/responsables/dissocierResponsable/666'],
];
}
/**
* @dataProvider dataAccessDissocierResponsable
*/
public function testAccessDissocierResponsable($expectedStatus, $user, $url, $options = []) {
$this->assertActionAccess($expectedStatus, $user, $url, $options);
}
public function dataAccessEdit() {
return [
// 1. Utilisateurs pouvant accéder à la fonctionnalité
// 1.1. Enregistrement existant
[200, 'Superadministrateur.superadmin', '/responsables/edit/1'],
[200, 'Administrateur.ibleu', '/responsables/edit/1'],
[200, 'DPO.nroux', '/responsables/edit/1'],
// Un utilisateur mono-collectivité ne peut pas accéder à l'enregistrement d'une autre collectivité
[403, 'Administrateur.findigo', '/responsables/edit/1'],
[403, 'DPO.hvermeil', '/responsables/edit/1'],
// 1.2. Enregistrement inexistant
[404, 'Superadministrateur.superadmin', '/responsables/edit/666'],
[404, 'Administrateur.ibleu', '/responsables/edit/666'],
[404, 'DPO.nroux', '/responsables/edit/666'],
// 2. Utilisateurs ne pouvant pas accéder à la fonctionnalité
// 1.1. Enregistrement existant
[403, 'Rédacteur.rjaune', '/responsables/edit/1'],
[403, 'Valideur.cnoir', '/responsables/edit/1'],
[403, 'Consultant.mrose', '/responsables/edit/1'],
// 2.2. Enregistrement inexistant
[403, 'Rédacteur.rjaune', '/responsables/edit/666'],
[403, 'Valideur.cnoir', '/responsables/edit/666'],
[403, 'Consultant.mrose', '/responsables/edit/666'],
];
}
/**
* @dataProvider dataAccessEdit
*/
public function testAccessEdit($expectedStatus, $user, $url, $options = []) {
$this->assertActionAccess($expectedStatus, $user, $url, $options);
}
public function dataAccessEntite() {
return [
// 1. Utilisateurs pouvant accéder à la fonctionnalité
[200, 'Superadministrateur.superadmin', '/responsables/entite'],
[200, 'Administrateur.ibleu', '/responsables/entite'],
[200, 'DPO.nroux', '/responsables/entite'],
// 2. Utilisateurs ne pouvant pas accéder à la fonctionnalité
[403, 'Rédacteur.rjaune', '/responsables/entite'],
[403, 'Valideur.cnoir', '/responsables/entite'],
[403, 'Consultant.mrose', '/responsables/entite'],
];
}