Skip to content

Commit 38363aa

Browse files
committed
put post patch
1 parent 1320dc1 commit 38363aa

File tree

5 files changed

+160
-61
lines changed

5 files changed

+160
-61
lines changed

app/config/config.yml

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -73,40 +73,27 @@ sensio_framework_extra:
7373
request: { converters: true }
7474

7575
fos_rest:
76-
serializer:
77-
serialize_null: true
76+
param_fetcher_listener: true
7877
view:
79-
# default_engine: php
80-
view_response_listener: force
81-
force_redirects:
82-
html: true
83-
# xml: true
78+
view_response_listener: 'force'
8479
formats:
80+
xml: true
8581
json: true
86-
xml: true
87-
rss: false
8882
templating_formats:
8983
html: true
90-
mime_types:
91-
json: ['application/json', 'application/x-json', 'application/vnd.example-com.foo+json']
92-
rss: 'application/rss+xml'
93-
jpg: 'image/jpeg'
94-
png: 'image/png'
95-
body_listener: true
96-
param_fetcher_listener: force
97-
allowed_methods_listener: true
98-
access_denied_listener:
99-
json: true
10084
format_listener:
10185
rules:
102-
- { path: '^/', priorities: ['html','json', 'xml'], fallback_format: html, prefer_extension: true }
103-
routing_loader:
104-
default_format: ~
86+
- { path: ^/, priorities: [ html, json, xml ], fallback_format: ~, prefer_extension: true }
10587
exception:
10688
codes:
10789
'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404
90+
'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT
10891
messages:
10992
'Symfony\Component\Routing\Exception\ResourceNotFoundException': true
93+
allowed_methods_listener: true
94+
access_denied_listener:
95+
json: true
96+
body_listener: true
11097

11198
nelmio_api_doc:
11299
name: Page API

src/Acme/BlogBundle/Controller/PageController.php

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
use FOS\RestBundle\Util\Codes;
1010
use FOS\RestBundle\Controller\Annotations;
1111
use FOS\RestBundle\View\View;
12-
use Symfony\Component\Form\FormTypeInterface;
12+
use FOS\RestBundle\Request\ParamFetcherInterface;
1313

14+
use Symfony\Component\Form\FormTypeInterface;
1415
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
1516

1617
use Acme\BlogBundle\Exception\InvalidFormException;
@@ -21,7 +22,41 @@
2122
class PageController extends FOSRestController
2223
{
2324
/**
24-
* Get single Page,
25+
* List all pages.
26+
*
27+
* @ApiDoc(
28+
* resource = true,
29+
* statusCodes = {
30+
* 200 = "Returned when successful"
31+
* }
32+
* )
33+
*
34+
* @Annotations\QueryParam(name="offset", requirements="\d+", nullable=true, description="Offset from which to start listing pages.")
35+
* @Annotations\QueryParam(name="limit", requirements="\d+", default="5", description="How many pages to return.")
36+
*
37+
* @Annotations\View()
38+
*
39+
* @param Request $request the request object
40+
* @param ParamFetcherInterface $paramFetcher param fetcher service
41+
*
42+
* @return array
43+
*/
44+
public function getPagesAction(Request $request, ParamFetcherInterface $paramFetcher)
45+
{
46+
$session = $request->getSession();
47+
48+
$offset = $paramFetcher->get('offset');
49+
$start = null == $offset ? 0 : $offset + 1;
50+
$limit = $paramFetcher->get('limit');
51+
52+
$pages = $session->get(self::SESSION_CONTEXT_PAGE, array());
53+
$pages = array_slice($notes, $start, $limit, true);
54+
55+
return new NoteCollection($notes, $offset, $limit);
56+
}
57+
58+
/**
59+
* Get single Page.
2560
*
2661
* @ApiDoc(
2762
* resource = true,
@@ -58,7 +93,9 @@ public function getPageAction($id)
5893
* }
5994
* )
6095
*
61-
* @Annotations\View()
96+
* @Annotations\View(
97+
* templateVar = "form"
98+
* )
6299
*
63100
* @return FormTypeInterface
64101
*/
@@ -67,7 +104,6 @@ public function newPageAction()
67104
return $this->createForm(new PageType());
68105
}
69106

70-
71107
/**
72108
* Create a Page from the submitted data.
73109
*
@@ -118,6 +154,7 @@ public function postPageAction(Request $request)
118154
* resource = true,
119155
* input = "Acme\DemoBundle\Form\PageType",
120156
* statusCodes = {
157+
* 201 = "Returned when the Page is created",
121158
* 204 = "Returned when successful",
122159
* 400 = "Returned when the form has errors"
123160
* }
@@ -138,18 +175,25 @@ public function postPageAction(Request $request)
138175
public function putPageAction(Request $request, $id)
139176
{
140177
try {
141-
142-
$page = $this->container->get('acme_blog.page.handler')->put(
143-
$this->getOr404($id),
144-
$request->request->all()
145-
);
178+
if (!($page = $this->container->get('acme_blog.page.handler')->get($id))) {
179+
$statusCode = Codes::HTTP_CREATED;
180+
$page = $this->container->get('acme_blog.page.handler')->post(
181+
$request->request->all()
182+
);
183+
} else {
184+
$statusCode = Codes::HTTP_NO_CONTENT;
185+
$page = $this->container->get('acme_blog.page.handler')->put(
186+
$page,
187+
$request->request->all()
188+
);
189+
}
146190

147191
$routeOptions = array(
148192
'id' => $page->getId(),
149193
'_format' => $request->get('_format')
150194
);
151195

152-
return $this->routeRedirectView('api_1_get_page', $routeOptions, Codes::HTTP_NO_CONTENT);
196+
return $this->routeRedirectView('api_1_get_page', $routeOptions, $statusCode);
153197

154198
} catch (InvalidFormException $exception) {
155199

src/Acme/BlogBundle/Handler/PageHandler.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ public function get($id)
3535
return $this->repository->find($id);
3636
}
3737

38+
/**
39+
* Get a Page.
40+
*
41+
* @param mixed $id
42+
*
43+
* @return PageInterface
44+
*/
45+
public function all(int $offset = 0, int $limit = 5)
46+
{
47+
return $this->repository->find($id);
48+
}
49+
3850
/**
3951
* Create a new Page.
4052
*
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11

22
{% block content %}
3-
<h1>Page Form</h1>
3+
<h1>Create Page Form</h1>
4+
{% if (form is defined) %}
45
<form action="{{ url('api_1_post_page') }}" method="POST" {{ form_enctype(form) }}>
56
{{ form_widget(form) }}
67
<input type="submit" value="submit">
78
</form>
9+
{% endif %}
810
{% endblock %}

src/Acme/BlogBundle/Tests/Controller/PageControllerTest.php

Lines changed: 82 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,36 +29,68 @@ public function testJsonGetPageAction()
2929

3030
$decoded = json_decode($content, true);
3131
$this->assertTrue(isset($decoded['id']));
32-
3332
}
3433

35-
public function testJsonPutPageAction()
34+
public function testHeadRoute()
3635
{
3736
$fixtures = array('Acme\BlogBundle\Tests\Fixtures\Entity\LoadPageData');
3837
$this->customSetUp($fixtures);
3938
$pages = LoadPageData::$pages;
4039
$page = array_pop($pages);
4140

41+
$this->client->request('HEAD', sprintf('/api/v1/pages/%d.json', $page->getId()), array('ACCEPT' => 'application/json'));
42+
$response = $this->client->getResponse();
43+
$this->assertJsonResponse($response, 200, false);
44+
}
45+
46+
public function testJsonNewPageAction()
47+
{
4248
$this->client = static::createClient();
4349
$this->client->request(
44-
'PUT',
45-
sprintf('/api/v1/pages/%d.json', $page->getId()),
50+
'GET',
51+
'/api/v1/pages/new.json',
52+
array(),
53+
array()
54+
);
55+
56+
$this->assertJsonResponse($this->client->getResponse(), 200, true);
57+
$this->assertEquals(
58+
'{"children":{"title":[],"body":[]}}',
59+
$this->client->getResponse()->getContent(),
60+
$this->client->getResponse()->getContent());
61+
}
62+
63+
public function testJsonPostPageAction()
64+
{
65+
$this->client = static::createClient();
66+
$this->client->request(
67+
'POST',
68+
'/api/v1/pages.json',
4669
array(),
4770
array(),
4871
array('CONTENT_TYPE' => 'application/json'),
49-
'{"title":"abc","body":"def"}'
72+
'{"title":"title1","body":"body1"}'
5073
);
5174

52-
$page->setTitle('abc');
53-
$page->setBody('def');
75+
$this->assertJsonResponse($this->client->getResponse(), 201, false);
76+
}
5477

55-
$this->assertJsonResponse($this->client->getResponse(), 204, false);
78+
public function testJsonPostPageActionShouldReturn400WithBadParameters()
79+
{
80+
$this->client = static::createClient();
81+
$this->client->request(
82+
'POST',
83+
'/api/v1/pages.json',
84+
array(),
85+
array(),
86+
array('CONTENT_TYPE' => 'application/json'),
87+
'{"titles":"title1","bodys":"body1"}'
88+
);
5689

57-
$updatedPage = $this->getContainer()->get('acme_blog.page.handler')->get($page->getId());
58-
$this->assertEquals($updatedPage, $page);
90+
$this->assertJsonResponse($this->client->getResponse(), 400, false);
5991
}
6092

61-
public function testJsonPatchPageAction()
93+
public function testJsonPutPageActionShouldModify()
6294
{
6395
$fixtures = array('Acme\BlogBundle\Tests\Fixtures\Entity\LoadPageData');
6496
$this->customSetUp($fixtures);
@@ -67,54 +99,76 @@ public function testJsonPatchPageAction()
6799

68100
$this->client = static::createClient();
69101
$this->client->request(
70-
'PATCH',
102+
'PUT',
71103
sprintf('/api/v1/pages/%d.json', $page->getId()),
72104
array(),
73105
array(),
74106
array('CONTENT_TYPE' => 'application/json'),
75-
'{"body":"def"}'
107+
'{"title":"abc","body":"def"}'
76108
);
77109

78-
$page->setBody('def');
79-
80110
$this->assertJsonResponse($this->client->getResponse(), 204, false);
81-
82-
$updatedPage = $this->getContainer()->get('acme_blog.page.handler')->get($page->getId());
83-
$this->assertEquals($updatedPage, $page);
111+
$this->assertTrue(
112+
$this->client->getResponse()->headers->contains(
113+
'Location',
114+
sprintf('http://localhost/api/v1/pages/%d.json', $page->getId())
115+
),
116+
$this->client->getResponse()->headers
117+
);
84118
}
85119

86-
87-
public function testJsonPostPageAction()
120+
public function testJsonPutPageActionShouldCreate()
88121
{
89122
$this->client = static::createClient();
123+
$id = 0;
124+
125+
$this->client->request('GET', sprintf('/api/v1/pages/%d.json', $id), array('ACCEPT' => 'application/json'));
126+
127+
$this->assertEquals(404, $this->client->getResponse()->getStatusCode(), $this->client->getResponse()->getContent());
128+
90129
$this->client->request(
91-
'POST',
92-
'/api/v1/pages.json',
130+
'PUT',
131+
sprintf('/api/v1/pages/%d.json', $id),
93132
array(),
94133
array(),
95134
array('CONTENT_TYPE' => 'application/json'),
96-
'{"title":"title1","body":"body1"}'
135+
'{"title":"abc","body":"def"}'
97136
);
98137

99138
$this->assertJsonResponse($this->client->getResponse(), 201, false);
100139
}
101140

102-
public function testJsonPostPageActionShouldReturn400WithBadParameters()
141+
public function testJsonPatchPageAction()
103142
{
143+
$fixtures = array('Acme\BlogBundle\Tests\Fixtures\Entity\LoadPageData');
144+
$this->customSetUp($fixtures);
145+
$pages = LoadPageData::$pages;
146+
$page = array_pop($pages);
147+
104148
$this->client = static::createClient();
105149
$this->client->request(
106-
'POST',
107-
'/api/v1/pages.json',
150+
'PATCH',
151+
sprintf('/api/v1/pages/%d.json', $page->getId()),
108152
array(),
109153
array(),
110154
array('CONTENT_TYPE' => 'application/json'),
111-
'{"titles":"title1","bodys":"body1"}'
155+
'{"body":"def"}'
112156
);
113157

114-
$this->assertJsonResponse($this->client->getResponse(), 400, false);
158+
$this->assertJsonResponse($this->client->getResponse(), 204, false);
159+
$this->assertTrue(
160+
$this->client->getResponse()->headers->contains(
161+
'Location',
162+
sprintf('http://localhost/api/v1/pages/%d.json', $page->getId())
163+
),
164+
$this->client->getResponse()->headers
165+
);
115166
}
116167

117168

169+
170+
171+
118172
protected function assertJsonResponse($response, $statusCode = 200, $checkValidJson = true, $contentType = 'application/json')
119173
{
120174
$this->assertEquals(

0 commit comments

Comments
 (0)