Skip to content
This repository has been archived by the owner on Dec 26, 2022. It is now read-only.

Add Behat tests for Mandate #97

Merged
merged 1 commit into from
Oct 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions features/api/job.feature
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ Feature: Jobs management
And the JSON should be equal to:
"""
"""

When I send a DELETE request to "/api/jobs/1"
Then the response status code should be 404

When I send a GET request to "/api/mandates/1"
Then the JSON node "jobs" should have 0 element
Expand Down
127 changes: 52 additions & 75 deletions features/api/mandate.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@mandate @ignore
@mandate
Feature: Mandates management
There is a mandate for every year.
A mandate is composed of a group of users, although may not have any user.
Expand All @@ -10,81 +10,95 @@ Feature: Mandates management
A user may have one or several mandate, with or without a job.

Background:
Given the database is empty
Given the fixtures file "authentication.yml" is loaded
Given I authenticate myself as admin


Scenario: Get a collection
@crud
Scenario: It should be possible to get all mandates
Given the fixtures file "mandate/collection.yml" is loaded
When I send a GET request to "/api/mandates"
Then the response status code should be 200
And the response should be in JSON-LD
And I should get a paged collection with the context "/api/contexts/Mandate"
And the JSON node "hydra:totalItems" should be equal to 2

Scenario: Get a resource
@crud
Scenario: It should be possible to get a specific mandate
Given the fixtures file "mandate/collection.yml" is loaded
When I send a GET request to "/api/mandates/1"
Then the response status code should be 200
And the JSON node "jobs" should have 2 element
And the response should be in JSON-LD
And the JSON node "jobs" should have 3 element
Then the JSON response should have the following nodes:
| node | value | type  |
| @context | /api/contexts/Mandate | |
| @id | /api/mandates/1 | |
| @type | Mandate | |
| endAt | 2007-03-18T10:25:58+00:00 |   |
| endAt | 2006-04-17T09:38:34+00:00 |   |
| jobs | | array |
| jobs[0] | /api/jobs/4 | |
| jobs[1] | /api/jobs/51 | |
| name | Mandate 2005/2007 | |
| startAt | 2005-11-27T17:41:35+00:00 | |

| jobs[0] | /api/jobs/1 | |
| jobs[1] | /api/jobs/2 | |
| jobs[2] | /api/jobs/3 | |
| name | Mandate 2005/2006 | |
| startAt | 2005-06-25T16:43:30+00:00 | |

Scenario: Create a new resource
# With valid data
@crud
Scenario: It should be possible to create a new mandate
Given the fixtures file "mandate/job-president.yml" is loaded
When I send a POST request to "/api/mandates" with body:
"""
{
"name": "Dummy date",
"endAt": "2010-01-21T23:00:00+00:00",
"startAt": "2009-01-26T23:00:00+00:00"
"name": "My Mandate",
"startAt": "2005-08-15T15:52:01+00:00",
"endAt": "2005-12-15T15:52:01+00:00",
"jobs": [ "/api/jobs/1" ]
}
"""
Then the response status code should be 201
And the JSON node "jobs" should have 0 element
Then the JSON response should have the following nodes:
And the response status code should be 201
And the response should be in JSON-LD
And the JSON node "jobs" should have 1 element
And the JSON response should have the following nodes:
| node | value | type  |
| @context | /api/contexts/Mandate | |
| @id | /api/mandates/13 | |
| @id | /api/mandates/1 | |
| @type | Mandate | |
| endAt | 2010-01-21T23:00:00+00:00 | string  |
| name | My Mandate | |
| startAt | 2005-08-15T15:52:01+00:00 | string |
| endAt | 2005-12-15T15:52:01+00:00 | string  |
| jobs | | array |
| name | Dummy date | |
| startAt | 2009-01-26T23:00:00+00:00 | string |
| jobs[0] | /api/jobs/1 | array |

# Check if the resource has been properly persisted
When I send a GET request to "/api/mandates/13"
When I send a GET request to "/api/mandates/1"
Then the response status code should be 200
And the JSON node "jobs" should have 0 element
And the response should be in JSON-LD
And the JSON node "jobs" should have 1 element
Then the JSON response should have the following nodes:
| node | value | type  |
| @context | /api/contexts/Mandate | |
| @id | /api/mandates/1 | |
| @type | Mandate | |
| endAt | 2007-03-18T10:25:58+00:00 |   |
| jobs | | array |
| name | Mandate 2005/2007 | |
| startAt | 2005-11-27T17:41:35+00:00 | |
| node | value | type  |
| @context | /api/contexts/Mandate | |
| @id | /api/mandates/1 | |
| @type | Mandate | |
| name | My Mandate | |
| startAt | 2005-08-15T15:52:01+00:00 | string |
| endAt | 2005-12-15T15:52:01+00:00 | string  |
| jobs | | array |
| jobs[0] | /api/jobs/1 | array |

# Post again with some other valid values but no name
# Expect to have a name generated
@crud
Scenario: A mandate name is automatically picked up if none is given when creating a new mandate
When I send a POST request to "/api/mandates" with body:
"""
{
"endAt": "2051-01-21",
"startAt": "2050-01-26"
}
"""
Then the response status code should be 200
Then the response status code should be 201
And I should get a resource page with the context "/api/contexts/Mandate"
And the JSON node "name" should be equal to "Mandate 2050/2051"

# Test validation rules
@crud
Scenario: Data send for creating a mandate should be validated
When I send a POST request to "/api/mandates" with body:
"""
{
Expand All @@ -105,40 +119,3 @@ Feature: Mandates management
| violations[1] | | object |
| violations[1]->propertyPath | startAt | |
| violations[1]->message | Cette valeur ne doit pas être nulle. | |



# Scenario: If one list all the mandates, there it at least one mandate: the current one.
# #TODO
#
# Scenario: A mandate may have users.
# #TODO
#
# Scenario: It should be possible to list all the mandates.
# #TODO
#
# Scenario: It should be possible to list all the members of a given mandate.
# #TODO
#
# Scenario: It should not be possible to create a mandate unless it starts at the current year. The ending date
# should then be during the next year and may be omitted.
# #TODO
#
# Scenario: If not ending date is given for a mandate, it ends at the end of the next year.
# #TODO
#
# Scenario: If no new mandate has be created, a new one is automatically created and keep all the admin users as if
# they have a new mandate.
# #TODO
#
# Scenario: It should not be possible to delete a mandate.
# #TODO
#
# Scenario: A new member can be added to a mandate even if the mandate already ended.
# #TODO
#
# Scenario: A member may be deleted from a mandate even if the mandate already ended.
# #TODO
#
# Scenario: Once a mandate created, the dates may change but must be of the same year.
# #TODO
39 changes: 39 additions & 0 deletions features/fixtures/ORM/mandate/collection.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
ApiBundle\Entity\Mandate:
mandate_2005:
startAt: <dateTimeFromFormat(DateTime::ATOM, '2005-06-25T16:43:30+00:00')>
endAt: <dateTimeFromFormat(DateTime::ATOM, '2006-04-17T09:38:34+00:00')>
jobs: [ @job_president, @job_pr, @job__1 ]

mandate_2006:
startAt: <startMandateDateTime(2006)>
endAt: <endMandateDateTime($startAt)>

ApiBundle\Entity\Job:
job (template):
title: <jobTitle()>
abbreviation: <jobAbbreviation()>
enabled: <boolean()>
#user: Should be kept unset since because is set in the user entity
#mandate: Should be kept unset since because is set in the mandate entity

job_president (extends job):
title: President
abbreviation: PR
enabled: true

job_pr (extends job):
abbreviation: PR

job__{1..9} (extends job): {}

ApiBundle\Entity\User:
user_president:
username: president.tendiserp
fullname: Président TENDISERP
email: [email protected]
roles: [ ROLE_ADMIN ]
plainPassword: guest
enabled: true
jobs: [ @job_president ]
studentConvention: ~
types: <userTypes('member')>
5 changes: 5 additions & 0 deletions features/fixtures/ORM/mandate/job-president.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ApiBundle\Entity\Job:
job_president:
title: President
abbreviation: PR
enabled: true
36 changes: 36 additions & 0 deletions src/ApiBundle/DataFixtures/Faker/Provider/DateTimeProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/*
* This file is part of the Incipio package.
*
* (c) Théo FIDRY <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace ApiBundle\DataFixtures\Faker\Provider;

/**
* Extends {@see \Faker\Provider\DateTime}. As all method are static does not literally extend the class to avoid
* useless overhead.
*
* @author Théo FIDRY <[email protected]>
*/
class DateTimeProvider
{
/**
* Parses a string into a new DateTime object according to the specified format.
*
* @param string $format Format accepted by date().
* @param string $time String representing the time.
*
* @return \DateTime
*
* @link http://php.net/manual/en/datetime.createfromformat.php
*/
public static function dateTimeFromFormat($format, $time)
{
return \DateTime::createFromFormat($format, $time);
}
}
4 changes: 2 additions & 2 deletions src/ApiBundle/DataFixtures/Faker/Provider/MandateProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace ApiBundle\DataFixtures\Faker\Provider;

use Faker\Provider\DateTime as DateTimeProvider;
use Faker\Provider\DateTime as FakerDateTimeProvider;

/**
* Faker provider for mandates.
Expand All @@ -20,7 +20,7 @@
*
* @author Théo FIDRY <[email protected]>
*/
class MandateProvider extends DateTimeProvider
class MandateProvider extends FakerDateTimeProvider
{
/**
* Generate a datetime starting from the date given and on a period going from 3 month to 2 years.
Expand Down
25 changes: 22 additions & 3 deletions src/ApiBundle/Doctrine/DBAL/Type/UTCDateTimeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace ApiBundle\Doctrine\DBAL\Type;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\ConversionException;
use Doctrine\DBAL\Types\DateTimeType;

/**
Expand Down Expand Up @@ -40,10 +41,28 @@ public function convertToDatabaseValue($phpValue, AbstractPlatform $platform)
*/
public function convertToPHPValue($databaseValue, AbstractPlatform $platform)
{
$phpValue = parent::convertToPHPValue($databaseValue, $platform);
if (null === $databaseValue || $databaseValue instanceof \DateTime) {
return $databaseValue;
}

if ($phpValue instanceof \DateTime) {
$phpValue->setTimeZone(new \DateTimeZone('UTC'));
// The changed part is the following bloc where we put the DateTimeZone as the third argument rather than
// relying on the local timezone
$phpValue = \DateTime::createFromFormat(
$platform->getDateTimeFormatString(),
$databaseValue,
new \DateTimeZone('UTC')
);

if (false === $phpValue) {
$phpValue = date_create($databaseValue);
}

if (false === $phpValue) {
throw ConversionException::conversionFailedFormat(
$databaseValue,
$this->getName(),
$platform->getDateTimeFormatString()
);
}

return $phpValue;
Expand Down
26 changes: 25 additions & 1 deletion src/ApiBundle/Entity/Mandate.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,42 @@ public function getEndAt()
return $this->endAt;
}

/**
* @param Job[] $jobs
*
* @return $this
*
* @throws \InvalidArgumentException If jobs type is incorrect
*/
public function setJobs($jobs)
{
$this->jobs = new ArrayCollection();
foreach ($jobs as $job) {
$this->addJob($job);
}

return $this;
}

/**
* Adds Job. Will automatically update job's mandate too.
*
* @param Job $job
*
* @return $this
*
* @throws \InvalidArgumentException If job type is incorrect
*/
public function addJob(Job $job)
public function addJob($job)
{
if (false === $job instanceof Job) {
throw new \InvalidArgumentException('Unexpected type.');
}

// Check for duplication
if (false === $this->jobs->contains($job)) {
$this->jobs->add($job);
$this->jobs = new ArrayCollection(array_values($this->jobs->toArray()));
}

// Ensure the relation is bidirectional
Expand Down
4 changes: 4 additions & 0 deletions src/ApiBundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ services:
#
# Faker's providers
#
faker.provider.datetime:
class: ApiBundle\DataFixtures\Faker\Provider\DateTimeProvider
tags: [ { name: hautelook_alice.faker.provider } ]

faker.provider.job:
class: ApiBundle\DataFixtures\Faker\Provider\JobProvider
tags: [ { name: hautelook_alice.faker.provider } ]
Expand Down
Loading