diff --git a/features/api/teams.feature b/features/api/teams.feature index 9018e71d159..32d8ea31902 100644 --- a/features/api/teams.feature +++ b/features/api/teams.feature @@ -496,6 +496,82 @@ Feature: """ Then the response status code should be 401 + Scenario: As a user granted with national scope, I cannot create a national team with the same name + Given I am logged with "deputy@en-marche-dev.fr" via OAuth client "JeMengage Web" + When I add "Content-Type" header equal to "application/json" + And I send a "POST" request to "/api/v3/teams?scope=phoning_national_manager" with body: + """ + { + "name": "Première équipe de phoning" + } + """ + Then the response status code should be 400 + And the response should be in JSON + And the JSON should be equal to: + """ + { + "type": "https://tools.ietf.org/html/rfc2616#section-10", + "title": "An error occurred", + "detail": "name: Une équipe porte déjà le même nom.", + "violations": [ + { + "propertyPath": "name", + "message": "Une équipe porte déjà le même nom." + } + ] + } + """ + + When I add "Content-Type" header equal to "application/json" + And I send a "POST" request to "/api/v3/teams?scope=phoning_national_manager" with body: + """ + { + "name": "Équipe locale du département 92" + } + """ + Then the response status code should be 201 + + Scenario Outline: As a user granted with local scope, I cannot create a team with the same name and zone + When I am logged with "referent@en-marche-dev.fr" via OAuth client "JeMengage Web" + And I add "Content-Type" header equal to "application/json" + And I send a "POST" request to "/api/v3/teams?scope=referent" with body: + """ + { + "name": "Équipe locale du département 92", + "zone": "e3efe6fd-906e-11eb-a875-0242ac150002" + } + """ + Then the response status code should be 400 + And the response should be in JSON + And the JSON should be equal to: + """ + { + "type": "https://tools.ietf.org/html/rfc2616#section-10", + "title": "An error occurred", + "detail": "name: Une équipe porte déjà le même nom.", + "violations": [ + { + "propertyPath": "name", + "message": "Une équipe porte déjà le même nom." + } + ] + } + """ + + When I add "Content-Type" header equal to "application/json" + And I send a "POST" request to "/api/v3/teams?scope=referent" with body: + """ + { + "name": "Première équipe de phoning", + "zone": "e3efe6fd-906e-11eb-a875-0242ac150002" + } + """ + Then the response status code should be 201 + Examples: + | user | scope | + | referent@en-marche-dev.fr | referent | + | senateur@en-marche-dev.fr | delegated_08f40730-d807-4975-8773-69d8fae1da74 | + Scenario: As a user granted with team feature, I can add a member to a team Given I am logged with "referent@en-marche-dev.fr" via OAuth client "JeMengage Web" When I send a "GET" request to "/api/v3/teams/6434f2ac-edd0-412a-9c4b-99ab4b039146?scope=phoning_national_manager" diff --git a/migrations/Version20220616140609.php b/migrations/Version20220616140609.php new file mode 100644 index 00000000000..0bbb1e2f37c --- /dev/null +++ b/migrations/Version20220616140609.php @@ -0,0 +1,21 @@ +<?php + +namespace Migrations; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\Migrations\AbstractMigration; + +final class Version20220616140609 extends AbstractMigration +{ + public function up(Schema $schema): void + { + $this->addSql('DROP INDEX UNIQ_C4E0A61F5E237E06 ON team'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_C4E0A61F5E237E069F2C3FAB ON team (name, zone_id)'); + } + + public function down(Schema $schema): void + { + $this->addSql('DROP INDEX UNIQ_C4E0A61F5E237E069F2C3FAB ON team'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_C4E0A61F5E237E06 ON team (name)'); + } +} diff --git a/src/Entity/Team/Team.php b/src/Entity/Team/Team.php index f62a2733839..4a72cd86ee6 100644 --- a/src/Entity/Team/Team.php +++ b/src/Entity/Team/Team.php @@ -74,9 +74,15 @@ * @ApiFilter(ScopeVisibilityFilter::class) * * @ORM\Entity(repositoryClass="App\Repository\Team\TeamRepository") + * @ORM\Table( + * uniqueConstraints={ + * @ORM\UniqueConstraint(columns={"name", "zone_id"}) + * } + * ) * * @UniqueEntity( - * fields={"name"}, + * fields={"name", "zone"}, + * ignoreNull=false, * message="team.name.already_exists", * errorPath="name" * ) @@ -92,7 +98,7 @@ class Team implements EntityAdherentBlameableInterface, EntityAdministratorBlame use EntityScopeVisibilityTrait; /** - * @ORM\Column(unique=true) + * @ORM\Column * * @Assert\NotBlank(message="team.name.not_blank") * @Assert\Length(