Skip to content

Commit 4d69498

Browse files
vid-3
1 parent 0a89540 commit 4d69498

File tree

12 files changed

+264
-84
lines changed

12 files changed

+264
-84
lines changed

app/config/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ imports:
33
- { resource: security.yml }
44
- { resource: services.yml }
55
- { resource: services/doctrine_entity_repository.yml }
6-
- { resource: services/listener.yml }
6+
- { resource: services/factory.yml}
77
- { resource: services/repository.yml }
88

99
# Put parameters here that don't need to change on each machine where the app is deployed

app/config/services/factory.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
services:
2+
3+
crv.factory.widget:
4+
class: AppBundle\Factory\WidgetFactory
5+
arguments:
6+
- "@crv.clock"

app/config/services/listener.yml

Lines changed: 0 additions & 9 deletions
This file was deleted.

behat.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ default:
1616
- AppBundle\Features\Context\WidgetSetupContext:
1717
em: "@doctrine.orm.entity_manager"
1818
clock: "@crv.clock"
19+
widgetFactory: "@crv.factory.widget"
1920
- AppBundle\Features\Context\TimeContext:
2021
clock: "@crv.clock"
2122

composer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@
3838
"twig/twig": "^1.0||^2.0"
3939
},
4040
"require-dev": {
41-
"sensio/generator-bundle": "^3.0",
42-
"symfony/phpunit-bridge": "^3.0",
43-
4441
"behat/behat": "^3.1",
4542
"behat/symfony2-extension": "^2.1",
4643
"behat/web-api-extension": "~1.0@dev",
4744
"behatch/contexts": "dev-master",
48-
"eightpoints/guzzle-bundle": "^6.0"
45+
"eightpoints/guzzle-bundle": "^6.0",
46+
"phpspec/phpspec": "^4.0",
47+
"sensio/generator-bundle": "^3.0",
48+
"symfony/phpunit-bridge": "^3.0"
4949
},
5050
"scripts": {
5151
"symfony-scripts": [

composer.lock

Lines changed: 120 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/AppBundle/Controller/WidgetController.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace AppBundle\Controller;
44

55
use AppBundle\Entity\Widget;
6+
use AppBundle\Form\Type\WidgetType;
67
use AppBundle\Repository\WidgetRepository;
78
use FOS\RestBundle\View\View;
89
use FOS\RestBundle\Controller\Annotations;
@@ -68,4 +69,77 @@ public function cgetAction(
6869
{
6970
return $widgetRepository->findAll();
7071
}
72+
73+
74+
/**
75+
* Create new Widget from the submitted data
76+
*
77+
* @Annotations\Post(path="/widget")
78+
*/
79+
public function postAction(Request $request)
80+
{
81+
// creates a Widget with the `createdAt` property already set
82+
$widget = $this->get('crv.factory.widget')->create();
83+
84+
$form = $this->createForm(WidgetType::class, $widget, [
85+
'csrf_protection' => false,
86+
]);
87+
88+
$form->submit($request->request->all(), false);
89+
90+
if (!$form->isValid()) {
91+
return $form;
92+
}
93+
94+
$widget = $form->getData();
95+
96+
$em = $this->getDoctrine()->getManager();
97+
$em->persist($widget);
98+
$em->flush();
99+
100+
$routeOptions = [
101+
'id' => $widget->getId(),
102+
'_format' => $request->get('_format'),
103+
];
104+
105+
return $this->routeRedirectView('get_widget', $routeOptions, Response::HTTP_CREATED);
106+
}
107+
108+
/**
109+
* Update existing Widget from the submitted data
110+
*
111+
* @Annotations\Put(path="/widget/{id}")
112+
*/
113+
public function putAction(Request $request, int $id)
114+
{
115+
// getRepo() being a private method to return
116+
// whatever repo we have configured
117+
$widget = $this->getRepo()->find($id);
118+
119+
$form = $this->createForm(WidgetType::class, $widget, [
120+
'csrf_protection' => false,
121+
]);
122+
123+
$form->submit($request->request->all(), false);
124+
125+
if (!$form->isValid()) {
126+
return $form;
127+
}
128+
129+
$widget = $form->getData();
130+
131+
// a manual process
132+
$widget->setUpdatedAt();
133+
134+
$em = $this->getDoctrine()->getManager();
135+
$em->flush();
136+
137+
$routeOptions = [
138+
'id' => $widget->getId(),
139+
'_format' => $request->get('_format'),
140+
];
141+
142+
return $this->routeRedirectView('get_widget', $routeOptions, Response::HTTP_NO_CONTENT);
143+
}
144+
71145
}

src/AppBundle/Entity/Widget.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
/**
1010
* @ORM\Entity()
1111
* @ORM\Table(name="widget")
12-
* @ORM\HasLifecycleCallbacks()
1312
* @JMSSerializer\ExclusionPolicy("all")
1413
*/
1514
class Widget

src/AppBundle/Features/Context/WidgetSetupContext.php

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace AppBundle\Features\Context;
44

55
use AppBundle\Entity\Widget;
6+
use AppBundle\Factory\WidgetFactory;
67
use AppBundle\Model\Clock;
78
use Behat\Behat\Context\Context;
89
use Behat\Gherkin\Node\TableNode;
@@ -19,6 +20,10 @@ class WidgetSetupContext implements Context
1920
* @var Clock
2021
*/
2122
private $clock;
23+
/**
24+
* @var WidgetFactory
25+
*/
26+
private $widgetFactory;
2227

2328
/**
2429
* WidgetSetupContext constructor.
@@ -28,11 +33,13 @@ class WidgetSetupContext implements Context
2833
*/
2934
public function __construct(
3035
EntityManagerInterface $em,
31-
Clock $clock
36+
Clock $clock,
37+
WidgetFactory $widgetFactory
3238
)
3339
{
3440
$this->em = $em;
3541
$this->clock = $clock;
42+
$this->widgetFactory = $widgetFactory;
3643
}
3744

3845
/**
@@ -42,35 +49,18 @@ public function thereAreWidgetsWithTheFollowingDetails(TableNode $widgets)
4249
{
4350
foreach ($widgets->getColumnsHash() as $key => $val) {
4451

45-
$widget = (new Widget())
52+
$widget = $this->widgetFactory->create()
4653
->setName($val['name'])
47-
;
48-
49-
$this->em->persist($widget);
50-
$this->em->flush();
51-
52-
53-
$qb = $this->em->createQueryBuilder();
54-
55-
$query = $qb->update('AppBundle:Widget', 'w')
56-
->set(
57-
'w.createdAt',
58-
$qb->expr()->literal(
59-
$this->clock->now()->modify($val['created_at'])->format('c')
60-
)
54+
->setCreatedAt(
55+
$this->clock->now()->modify($val['created_at'])
6156
)
62-
->set(
63-
'w.updatedAt',
64-
$qb->expr()->literal(
65-
$this->clock->now()->modify($val['updated_at'])->format('c')
66-
)
57+
->setUpdatedAt(
58+
$this->clock->now()->modify($val['updated_at'])
6759
)
68-
->where('w.id = :id')
69-
->setParameter('id', $widget->getId())
70-
->getQuery()
7160
;
7261

73-
$query->execute();
62+
$this->em->persist($widget);
63+
$this->em->flush();
7464
}
7565
}
7666
}

src/AppBundle/Features/widget.feature

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,21 @@ Feature: Manage Widget data via a JSON API
2626
"created_at": "2019-12-25T00:00:00+0000",
2727
"updated_at": "2019-12-31T23:55:00+0000"
2828
}
29-
"""
29+
"""
30+
31+
32+
Scenario: Can add a new Widget
33+
When I send a "POST" request to "/widget" with body:
34+
"""
35+
{
36+
"name": "new widget"
37+
}
38+
"""
39+
Then the response code should be 201
40+
And I follow the link in the Location response header
41+
Then the response should contain json:
42+
"""
43+
{
44+
"name": "new widget"
45+
}
46+
"""

0 commit comments

Comments
 (0)