gds-api-adapters 24.4.0 → 24.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 917b62c21c23af44bb7bd701631407f93ad3e528
4
- data.tar.gz: 5cfcbf49f3381b24011fbaddc4809c173267436e
3
+ metadata.gz: 1cdf38f1b222c05d8d81625b25b222de03f6f273
4
+ data.tar.gz: 41fb59bce925ffd63f782566ccb50beda983bf8f
5
5
  SHA512:
6
- metadata.gz: d6febf466943aca5a5ccec8a099d88956d8bbbbfede4f527986ddfe4e8484799200bc99d06861c39fef999ffb367b450889ace42be7e0cc84788f4cac9f08a30
7
- data.tar.gz: 59a64bbbe9fee9466c90b61760d09ef560159e398e7380e4902c17b56b4838ea06f78763ecde700ae2f28cdd12a0cdcc8e9c5ec213406a3cea561ac2a11e20c5
6
+ metadata.gz: 2a57d45ce36edc708d49082e6fc47a66094e1d6717cfb71b24acd142cd7c996188cf1c2d3b7c109284720fd14fe459e405b54e48f5d0ccf8b4a61264642ef1ff
7
+ data.tar.gz: 82494aeda400c32f9bdf66541d52c9e9a78a552dcd3ac606621e02f957ef92b5cdc08e55932dc97622cc8b15030d52e542165fd8985c82238183b7bfe4019032
@@ -16,7 +16,9 @@ class GdsApi::PublishingApi < GdsApi::Base
16
16
  end
17
17
 
18
18
  def destroy_intent(base_path)
19
- delete_json(intent_url(base_path))
19
+ delete_json!(intent_url(base_path))
20
+ rescue GdsApi::HTTPNotFound => e
21
+ e
20
22
  end
21
23
 
22
24
 
@@ -0,0 +1,37 @@
1
+ require_relative 'base'
2
+
3
+ class GdsApi::PublishingApiV2 < GdsApi::Base
4
+
5
+ def put_content(content_id, payload)
6
+ put_json!(content_url(content_id), payload)
7
+ end
8
+
9
+ def get_content(content_id)
10
+ get_json(content_url(content_id))
11
+ end
12
+
13
+ def publish(content_id, update_type)
14
+ post_json!(content_url(content_id) + "/publish", {
15
+ update_type: update_type,
16
+ })
17
+ end
18
+
19
+ def get_links(content_id)
20
+ get_json(links_url(content_id))
21
+ end
22
+
23
+ def put_links(content_id, payload)
24
+ links = payload.fetch(:links)
25
+ put_json!(links_url(content_id), links: links)
26
+ end
27
+
28
+ private
29
+
30
+ def content_url(content_id)
31
+ "#{endpoint}/v2/content/#{content_id}"
32
+ end
33
+
34
+ def links_url(content_id)
35
+ "#{endpoint}/v2/links/#{content_id}"
36
+ end
37
+ end
@@ -17,18 +17,18 @@ module GdsApi
17
17
 
18
18
  def stub_publishing_api_put_item(base_path, body = content_item_for_base_path(base_path), resource_path = '/content')
19
19
  url = PUBLISHING_API_ENDPOINT + resource_path + base_path
20
- stub_request(:put, url).with(body: body).to_return(status: 201, body: '{}', headers: {})
20
+ stub_request(:put, url).with(body: body).to_return(status: 200, body: '{}', headers: {"Content-Type" => "application/json; charset=utf-8"})
21
21
  end
22
22
 
23
23
  def stub_publishing_api_put_intent(base_path, body = intent_for_base_path(base_path))
24
24
  url = PUBLISHING_API_ENDPOINT + "/publish-intent" + base_path
25
25
  body = body.to_json unless body.is_a?(String)
26
- stub_request(:put, url).with(body: body).to_return(status: 201, body: '{}', headers: {})
26
+ stub_request(:put, url).with(body: body).to_return(status: 200, body: '{}', headers: {"Content-Type" => "application/json; charset=utf-8"})
27
27
  end
28
28
 
29
29
  def stub_publishing_api_destroy_intent(base_path)
30
30
  url = PUBLISHING_API_ENDPOINT + "/publish-intent" + base_path
31
- stub_request(:delete, url).to_return(status: 201, body: '{}')
31
+ stub_request(:delete, url).to_return(status: 200, body: '{}', headers: {"Content-Type" => "application/json; charset=utf-8"})
32
32
  end
33
33
 
34
34
  def stub_default_publishing_api_put()
@@ -31,10 +31,9 @@ module GdsApi
31
31
  if id =~ %r{^/}
32
32
  raise ArgumentError, 'Rummager id must not start with a slash'
33
33
  end
34
- stub_request(:delete, %r{#{Plek.new.find('search')}/documents/#{id}})
34
+ assert_requested(:delete, %r{#{Plek.new.find('search')}/documents/#{id}})
35
35
  end
36
36
 
37
-
38
37
  def rummager_has_services_and_info_data_for_organisation
39
38
  stub_request_for(search_results_found)
40
39
  run_example_query
@@ -1,3 +1,3 @@
1
1
  module GdsApi
2
- VERSION = '24.4.0'
2
+ VERSION = '24.5.0'
3
3
  end
@@ -4,44 +4,147 @@ require 'gds_api/test_helpers/publishing_api'
4
4
 
5
5
  describe GdsApi::PublishingApi do
6
6
  include GdsApi::TestHelpers::PublishingApi
7
+ include PactTest
7
8
 
8
9
  before do
9
10
  @base_api_url = Plek.current.find("publishing-api")
10
- @api = GdsApi::PublishingApi.new(@base_api_url)
11
+ @api_client = GdsApi::PublishingApi.new('http://localhost:3093')
11
12
  end
12
13
 
13
- describe "item" do
14
- it "should create the item" do
14
+ describe "#put_content_item" do
15
+ it "responds with 200 OK if the entry is valid" do
15
16
  base_path = "/test-content-item"
16
- stub_publishing_api_put_item(base_path)
17
- response = @api.put_content_item(base_path, content_item_for_base_path(base_path))
18
- assert_equal 201, response.code
17
+ content_item = content_item_for_base_path(base_path).merge("update_type" => "major")
18
+
19
+ publishing_api
20
+ .given("both content stores and the url-arbiter are empty")
21
+ .upon_receiving("a request to create a content item")
22
+ .with(
23
+ method: :put,
24
+ path: "/content#{base_path}",
25
+ body: content_item,
26
+ headers: {
27
+ "Content-Type" => "application/json"
28
+ },
29
+ )
30
+ .will_respond_with(
31
+ status: 200,
32
+ body: content_item,
33
+ headers: {
34
+ "Content-Type" => "application/json; charset=utf-8"
35
+ },
36
+ )
37
+
38
+ response = @api_client.put_content_item(base_path, content_item)
39
+ assert_equal 200, response.code
19
40
  end
20
41
  end
21
42
 
22
- describe "draft item" do
23
- it "should create the draft item" do
43
+ describe "#put_draft_content_item" do
44
+ it "responds with 200 OK if the entry is valid" do
24
45
  base_path = "/test-draft-content-item"
25
- stub_publishing_api_put_draft_item(base_path)
46
+ content_item = content_item_for_base_path(base_path).merge("update_type" => "major")
26
47
 
27
- response = @api.put_draft_content_item(base_path, content_item_for_base_path(base_path))
28
- assert_equal 201, response.code
48
+ publishing_api
49
+ .given("both content stores and the url-arbiter are empty")
50
+ .upon_receiving("a request to create a draft content item")
51
+ .with(
52
+ method: :put,
53
+ path: "/draft-content#{base_path}",
54
+ body: content_item,
55
+ headers: {
56
+ "Content-Type" => "application/json"
57
+ },
58
+ )
59
+ .will_respond_with(
60
+ status: 200,
61
+ body: content_item,
62
+ headers: {
63
+ "Content-Type" => "application/json; charset=utf-8"
64
+ },
65
+ )
66
+
67
+ response = @api_client.put_draft_content_item(base_path, content_item)
68
+ assert_equal 200, response.code
29
69
  end
30
70
  end
31
71
 
32
- describe "intent" do
33
- it "should create the intent" do
72
+ describe "#put_intent" do
73
+ it "responds with 200 OK if publish intent is valid" do
34
74
  base_path = "/test-intent"
35
- stub_publishing_api_put_intent(base_path)
36
- response = @api.put_intent(base_path, intent_for_base_path(base_path))
37
- assert_equal 201, response.code
75
+ publish_intent = intent_for_base_path(base_path)
76
+
77
+ publishing_api
78
+ .given("both content stores and the url-arbiter are empty")
79
+ .upon_receiving("a request to create a publish intent")
80
+ .with(
81
+ method: :put,
82
+ path: "/publish-intent#{base_path}",
83
+ body: publish_intent,
84
+ headers: {
85
+ "Content-Type" => "application/json"
86
+ },
87
+ )
88
+ .will_respond_with(
89
+ status: 200,
90
+ body: {},
91
+ headers: {
92
+ "Content-Type" => "application/json; charset=utf-8"
93
+ },
94
+ )
95
+
96
+ response = @api_client.put_intent(base_path, publish_intent)
97
+ assert_equal 200, response.code
38
98
  end
99
+ end
39
100
 
40
- it "should delete an intent" do
101
+ describe "#delete_intent" do
102
+ it "returns 200 OK if intent existed and was deleted" do
41
103
  base_path = "/test-intent"
42
- stub_publishing_api_destroy_intent(base_path)
43
- response = @api.destroy_intent(base_path)
44
- assert_equal 201, response.code
104
+
105
+ publish_intent = intent_for_base_path(base_path)
106
+
107
+ publishing_api
108
+ .given("a publish intent exists at /test-intent in the live content store")
109
+ .upon_receiving("a request to delete a publish intent")
110
+ .with(
111
+ method: :delete,
112
+ path: "/publish-intent#{base_path}",
113
+ )
114
+ .will_respond_with(
115
+ status: 200,
116
+ body: {},
117
+ headers: {
118
+ "Content-Type" => "application/json; charset=utf-8"
119
+ }
120
+ )
121
+
122
+ response = @api_client.destroy_intent(base_path)
123
+ assert_equal 200, response.code
124
+ end
125
+
126
+ it "returns 404 Not found if the intent does not exist" do
127
+ base_path = "/test-intent"
128
+
129
+ publish_intent = intent_for_base_path(base_path)
130
+
131
+ publishing_api
132
+ .given("both content stores and the url-arbiter are empty")
133
+ .upon_receiving("a request to delete a publish intent")
134
+ .with(
135
+ method: :delete,
136
+ path: "/publish-intent#{base_path}",
137
+ )
138
+ .will_respond_with(
139
+ status: 404,
140
+ body: {},
141
+ headers: {
142
+ "Content-Type" => "application/json; charset=utf-8"
143
+ }
144
+ )
145
+
146
+ response = @api_client.destroy_intent(base_path)
147
+ assert_equal 404, response.code
45
148
  end
46
149
  end
47
150
  end
@@ -0,0 +1,604 @@
1
+ require 'test_helper'
2
+ require 'gds_api/publishing_api_v2'
3
+ require 'json'
4
+
5
+ describe GdsApi::PublishingApiV2 do
6
+ include PactTest
7
+
8
+ def content_item_for_content_id(content_id, attrs = {})
9
+ {
10
+ "base_path" => "/robots.txt",
11
+ "content_id" => content_id,
12
+ "title" => "Instructions for crawler robots",
13
+ "description" => "robots.txt provides rules for which parts of GOV.UK are permitted to be crawled by different bots.",
14
+ "format" => "special_route",
15
+ "public_updated_at" => "2015-07-30T13:58:11.000Z",
16
+ "publishing_app" => "static",
17
+ "rendering_app" => "static",
18
+ "routes" => [
19
+ {
20
+ "path" => attrs["base_path"] || "/robots.txt",
21
+ "type" => "exact"
22
+ }
23
+ ],
24
+ "update_type" => "major"
25
+ }.merge(attrs)
26
+ end
27
+
28
+ before do
29
+ @base_api_url = Plek.current.find("publishing-api")
30
+ @api_client = GdsApi::PublishingApiV2.new('http://localhost:3093')
31
+
32
+ @content_id = "bed722e6-db68-43e5-9079-063f623335a7"
33
+ end
34
+
35
+ describe "#put_content" do
36
+ describe "if the entry is valid" do
37
+ before do
38
+ @content_item = content_item_for_content_id(@content_id)
39
+
40
+ publishing_api
41
+ .given("both content stores and the url-arbiter are empty")
42
+ .upon_receiving("a request to create a content item without links")
43
+ .with(
44
+ method: :put,
45
+ path: "/v2/content/#{@content_id}",
46
+ body: @content_item,
47
+ headers: {
48
+ "Content-Type" => "application/json",
49
+ },
50
+ )
51
+ .will_respond_with(
52
+ status: 200,
53
+ )
54
+ end
55
+
56
+ it "responds with 200 OK" do
57
+ response = @api_client.put_content(@content_id, @content_item)
58
+ assert_equal 200, response.code
59
+ end
60
+ end
61
+
62
+ describe "if the path is reserved by a different app" do
63
+ before do
64
+ @content_item = content_item_for_content_id(@content_id, "base_path" => "/test-item", "publishing_app" => "whitehall")
65
+
66
+ publishing_api
67
+ .given("/test-item has been reserved in url-arbiter by the Publisher application")
68
+ .upon_receiving("a request from the Whitehall application to create a content item at /test-item")
69
+ .with(
70
+ method: :put,
71
+ path: "/v2/content/#{@content_id}",
72
+ body: @content_item,
73
+ headers: {
74
+ "Content-Type" => "application/json",
75
+ }
76
+ )
77
+ .will_respond_with(
78
+ status: 409,
79
+ body: {
80
+ "error" => {
81
+ "code" => 409,
82
+ "message" => Pact.term(generate: "Conflict", matcher:/\S+/),
83
+ "fields" => {
84
+ "base_path" => Pact.each_like("is already in use by the 'publisher' app", :min => 1),
85
+ },
86
+ },
87
+ },
88
+ headers: {
89
+ "Content-Type" => "application/json; charset=utf-8"
90
+ }
91
+ )
92
+ end
93
+
94
+ it "responds with 409 Conflict" do
95
+ error = assert_raises GdsApi::HTTPConflict do
96
+ @api_client.put_content(@content_id, @content_item)
97
+ end
98
+ assert_equal "Conflict", error.error_details["error"]["message"]
99
+ end
100
+ end
101
+
102
+ describe "with an invalid item" do
103
+ before do
104
+ @content_item = content_item_for_content_id(@content_id, "base_path" => "not a url path")
105
+
106
+ publishing_api
107
+ .given("both content stores and the url-arbiter are empty")
108
+ .upon_receiving("a request to create an invalid content-item")
109
+ .with(
110
+ method: :put,
111
+ path: "/v2/content/#{@content_id}",
112
+ body: @content_item,
113
+ headers: {
114
+ "Content-Type" => "application/json",
115
+ },
116
+ )
117
+ .will_respond_with(
118
+ status: 422,
119
+ body: {
120
+ "error" => {
121
+ "code" => 422,
122
+ "message" => Pact.term(generate: "Unprocessable entity", matcher:/\S+/),
123
+ "fields" => {
124
+ "base_path" => Pact.each_like("is invalid", :min => 1),
125
+ },
126
+ },
127
+ },
128
+ headers: {
129
+ "Content-Type" => "application/json; charset=utf-8"
130
+ }
131
+ )
132
+ end
133
+
134
+ it "responds with 422 Unprocessable Entity" do
135
+ error = assert_raises GdsApi::HTTPClientError do
136
+ @api_client.put_content(@content_id, @content_item)
137
+ end
138
+ assert_equal 422, error.code
139
+ assert_equal "Unprocessable entity", error.error_details["error"]["message"]
140
+ end
141
+ end
142
+ end
143
+
144
+ describe "#get_content" do
145
+ describe "when the content item exists" do
146
+ before do
147
+ @content_item = content_item_for_content_id(@content_id)
148
+
149
+ publishing_api
150
+ .given("a content item exists with content_id: #{@content_id}")
151
+ .upon_receiving("a request to return the content item")
152
+ .with(
153
+ method: :get,
154
+ path: "/v2/content/#{@content_id}",
155
+ )
156
+ .will_respond_with(
157
+ status: 200,
158
+ body: {
159
+ "content_id" => @content_id,
160
+ "format" => Pact.like("special_route"),
161
+ "publishing_app" => Pact.like("publisher"),
162
+ "rendering_app" => Pact.like("frontend"),
163
+ "locale" => Pact.like("en"),
164
+ "routes" => Pact.like([{}]),
165
+ "public_updated_at" => Pact.like("2015-07-30T13:58:11.000Z"),
166
+ "details" => Pact.like({})
167
+ },
168
+ headers: {
169
+ "Content-Type" => "application/json; charset=utf-8",
170
+ },
171
+ )
172
+ end
173
+
174
+ it "responds with 200 and the content item" do
175
+ response = @api_client.get_content(@content_id)
176
+ assert_equal 200, response.code
177
+ assert_equal @content_item["format"], response["format"]
178
+ end
179
+ end
180
+
181
+ describe "a non-existent item" do
182
+ before do
183
+ publishing_api
184
+ .given("both content stores and the url-arbiter are empty")
185
+ .upon_receiving("a request for a non-existent content item")
186
+ .with(
187
+ method: :get,
188
+ path: "/v2/content/#{@content_id}",
189
+ )
190
+ .will_respond_with(
191
+ status: 404,
192
+ body: {
193
+ "error" => {
194
+ "code" => 404,
195
+ "message" => Pact.term(generate: "not found", matcher:/\S+/)
196
+ },
197
+ },
198
+ headers: {
199
+ "Content-Type" => "application/json; charset=utf-8",
200
+ },
201
+ )
202
+ end
203
+
204
+ it "responds with 404" do
205
+ assert_nil @api_client.get_content(@content_id)
206
+ end
207
+ end
208
+ end
209
+
210
+ describe "#publish" do
211
+ describe "if the publish command succeeds" do
212
+ before do
213
+ publishing_api
214
+ .given("a draft content item exists with content_id: #{@content_id}")
215
+ .upon_receiving("a publish request")
216
+ .with(
217
+ method: :post,
218
+ path: "/v2/content/#{@content_id}/publish",
219
+ body: {
220
+ update_type: "major",
221
+ },
222
+ headers: {
223
+ "Content-Type" => "application/json",
224
+ },
225
+ )
226
+ .will_respond_with(
227
+ status: 200
228
+ )
229
+ end
230
+
231
+ it "responds with 200 if the publish command succeeds" do
232
+ response = @api_client.publish(@content_id, "major")
233
+ assert_equal 200, response.code
234
+ end
235
+ end
236
+
237
+ describe "if the content item does not exist" do
238
+ before do
239
+ publishing_api
240
+ .given("both content stores and url-arbiter empty")
241
+ .upon_receiving("a publish request")
242
+ .with(
243
+ method: :post,
244
+ path: "/v2/content/#{@content_id}/publish",
245
+ body: {
246
+ update_type: "major",
247
+ },
248
+ headers: {
249
+ "Content-Type" => "application/json",
250
+ },
251
+ )
252
+ .will_respond_with(
253
+ status: 404
254
+ )
255
+ end
256
+
257
+ it "responds with 404" do
258
+ error = assert_raises GdsApi::HTTPClientError do
259
+ @api_client.publish(@content_id, "major")
260
+ end
261
+
262
+ assert_equal 404, error.code
263
+ end
264
+ end
265
+
266
+ describe "if the content item is not publishable" do
267
+ before do
268
+ publishing_api
269
+ .given("a draft content item exists with content_id: #{@content_id} which does not have a publishing_app")
270
+ .upon_receiving("a publish request")
271
+ .with(
272
+ method: :post,
273
+ path: "/v2/content/#{@content_id}/publish",
274
+ body: {
275
+ update_type: "major",
276
+ },
277
+ headers: {
278
+ "Content-Type" => "application/json",
279
+ },
280
+ )
281
+ .will_respond_with(
282
+ status: 422,
283
+ body: {
284
+ "error" => {
285
+ "code" => 422,
286
+ "fields" => {
287
+ "publishing_app"=>["can't be blank"],
288
+ },
289
+ },
290
+ }
291
+ )
292
+ end
293
+
294
+ it "responds with 422" do
295
+ error = assert_raises GdsApi::HTTPClientError do
296
+ @api_client.publish(@content_id, "major")
297
+ end
298
+
299
+ assert_equal 422, error.code
300
+ assert_equal ["can't be blank"], error.error_details["error"]["fields"]["publishing_app"]
301
+ end
302
+ end
303
+
304
+ describe "if the update information is invalid" do
305
+ before do
306
+ publishing_api
307
+ .given("a draft content item exists with content_id: #{@content_id}")
308
+ .upon_receiving("an invalid publish request")
309
+ .with(
310
+ method: :post,
311
+ path: "/v2/content/#{@content_id}/publish",
312
+ body: {
313
+ "update_type" => ""
314
+ },
315
+ headers: {
316
+ "Content-Type" => "application/json",
317
+ },
318
+ )
319
+ .will_respond_with(
320
+ status: 422,
321
+ body: {
322
+ "error" => {
323
+ "code" => 422,
324
+ "message" => Pact.term(generate: "Unprocessable entity", matcher:/\S+/),
325
+ "fields" => {
326
+ "update_type" => Pact.each_like("is required", :min => 1),
327
+ },
328
+ },
329
+ }
330
+ )
331
+ end
332
+
333
+ it "responds with 422" do
334
+ error = assert_raises GdsApi::HTTPClientError do
335
+ @api_client.publish(@content_id, "")
336
+ end
337
+
338
+ assert_equal 422, error.code
339
+ assert_equal "Unprocessable entity", error.error_details["error"]["message"]
340
+ end
341
+ end
342
+
343
+ describe "if the content item is already published" do
344
+ before do
345
+ publishing_api
346
+ .given("a published content item exists with content_id: #{@content_id}")
347
+ .upon_receiving("a publish request")
348
+ .with(
349
+ method: :post,
350
+ path: "/v2/content/#{@content_id}/publish",
351
+ body: {
352
+ update_type: "major",
353
+ },
354
+ headers: {
355
+ "Content-Type" => "application/json",
356
+ },
357
+ )
358
+ .will_respond_with(
359
+ status: 400,
360
+ body: {
361
+ "error" => {
362
+ "code" => 400, "message" => Pact.term(generate: "Cannot publish an already published content item", matcher:/\S+/),
363
+ },
364
+ }
365
+ )
366
+ end
367
+
368
+ it "responds with 400" do
369
+ error = assert_raises GdsApi::HTTPClientError do
370
+ @api_client.publish(@content_id, "major")
371
+ end
372
+
373
+ assert_equal 400, error.code
374
+ assert_equal "Cannot publish an already published content item", error.error_details["error"]["message"]
375
+ end
376
+ end
377
+ end
378
+
379
+ describe "#get_links" do
380
+ describe "when there's a links entry with links" do
381
+ before do
382
+ publishing_api
383
+ .given("organisation links exist for content_id #{@content_id}")
384
+ .upon_receiving("a get-links request")
385
+ .with(
386
+ method: :get,
387
+ path: "/v2/links/#{@content_id}",
388
+ )
389
+ .will_respond_with(
390
+ status: 200,
391
+ body: {
392
+ links: {
393
+ organisations: ["20583132-1619-4c68-af24-77583172c070"]
394
+ }
395
+ }
396
+ )
397
+ end
398
+
399
+ it "responds with the links" do
400
+ response = @api_client.get_links(@content_id)
401
+ assert_equal 200, response.code
402
+ assert_equal ["20583132-1619-4c68-af24-77583172c070"], response.links.organisations
403
+ end
404
+ end
405
+
406
+ describe "when there's an empty links entry" do
407
+ before do
408
+ publishing_api
409
+ .given("empty links exist for content_id #{@content_id}")
410
+ .upon_receiving("a get-links request")
411
+ .with(
412
+ method: :get,
413
+ path: "/v2/links/#{@content_id}",
414
+ )
415
+ .will_respond_with(
416
+ status: 200,
417
+ body: {
418
+ links: {
419
+ }
420
+ }
421
+ )
422
+ end
423
+
424
+ it "responds with the empty link set" do
425
+ response = @api_client.get_links(@content_id)
426
+ assert_equal 200, response.code
427
+ assert_equal OpenStruct.new({}), response.links
428
+ end
429
+ end
430
+
431
+ describe "when there's no links entry" do
432
+ before do
433
+ publishing_api
434
+ .given("no links exist for content_id #{@content_id}")
435
+ .upon_receiving("a get-links request")
436
+ .with(
437
+ method: :get,
438
+ path: "/v2/links/#{@content_id}",
439
+ )
440
+ .will_respond_with(
441
+ status: 404
442
+ )
443
+ end
444
+
445
+ it "responds with 404" do
446
+ response = @api_client.get_links(@content_id)
447
+ assert_nil response
448
+ end
449
+ end
450
+ end
451
+
452
+ describe "#put_links" do
453
+ describe "when setting links of the same type" do
454
+ before do
455
+ publishing_api
456
+ .given("organisation links exist for content_id #{@content_id}")
457
+ .upon_receiving("a put organisation links request")
458
+ .with(
459
+ method: :put,
460
+ path: "/v2/links/#{@content_id}",
461
+ body: {
462
+ links: {
463
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
464
+ }
465
+ },
466
+ headers: {
467
+ "Content-Type" => "application/json",
468
+ },
469
+ )
470
+ .will_respond_with(
471
+ status: 200,
472
+ body: {
473
+ links: {
474
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
475
+ }
476
+ }
477
+ )
478
+ end
479
+
480
+ it "replaces the links and responds with the new links" do
481
+ response = @api_client.put_links(@content_id, links: {
482
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
483
+ })
484
+ assert_equal 200, response.code
485
+ assert_equal ["591436ab-c2ae-416f-a3c5-1901d633fbfb"], response.links.organisations
486
+ end
487
+ end
488
+
489
+ describe "when setting links of a different type" do
490
+ before do
491
+ publishing_api
492
+ .given("organisation links exist for content_id #{@content_id}")
493
+ .upon_receiving("a put topic links request")
494
+ .with(
495
+ method: :put,
496
+ path: "/v2/links/#{@content_id}",
497
+ body: {
498
+ links: {
499
+ topics: ["225df4a8-2945-4e9b-8799-df7424a90b69"],
500
+ }
501
+ },
502
+ headers: {
503
+ "Content-Type" => "application/json",
504
+ },
505
+ )
506
+ .will_respond_with(
507
+ status: 200,
508
+ body: {
509
+ links: {
510
+ topics: ["225df4a8-2945-4e9b-8799-df7424a90b69"],
511
+ organisations: ["20583132-1619-4c68-af24-77583172c070"]
512
+ }
513
+ }
514
+ )
515
+ end
516
+
517
+ it "adds the new type of links and responds with the whole link set" do
518
+ response = @api_client.put_links(@content_id, links: {
519
+ topics: ["225df4a8-2945-4e9b-8799-df7424a90b69"],
520
+ })
521
+
522
+ assert_equal 200, response.code
523
+ assert_equal(OpenStruct.new(
524
+ topics: ["225df4a8-2945-4e9b-8799-df7424a90b69"],
525
+ organisations: ["20583132-1619-4c68-af24-77583172c070"],
526
+ ), response.links)
527
+ end
528
+ end
529
+
530
+ describe "when deleting links of a specific type" do
531
+ before do
532
+ publishing_api
533
+ .given("organisation links exist for content_id #{@content_id}")
534
+ .upon_receiving("a put blank organisation links request")
535
+ .with(
536
+ method: :put,
537
+ path: "/v2/links/#{@content_id}",
538
+ body: {
539
+ links: {
540
+ organisations: [],
541
+ }
542
+ },
543
+ headers: {
544
+ "Content-Type" => "application/json",
545
+ },
546
+ )
547
+ .will_respond_with(
548
+ status: 200,
549
+ body: {
550
+ links: {}
551
+ }
552
+ )
553
+ end
554
+
555
+ it "responds with the links" do
556
+ response = @api_client.put_links(@content_id, links: {
557
+ organisations: [],
558
+ })
559
+
560
+ assert_equal 200, response.code
561
+ assert_equal OpenStruct.new({}), response.links
562
+ end
563
+ end
564
+
565
+ describe "when there's no links entry" do
566
+ before do
567
+ publishing_api
568
+ .given("no links exist for content_id #{@content_id}")
569
+ .upon_receiving("a put organisation links request")
570
+ .with(
571
+ method: :put,
572
+ path: "/v2/links/#{@content_id}",
573
+ body: {
574
+ links: {
575
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
576
+ }
577
+ },
578
+ headers: {
579
+ "Content-Type" => "application/json",
580
+ },
581
+ )
582
+ .will_respond_with(
583
+ status: 200,
584
+ body: {
585
+ links: {
586
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
587
+ }
588
+ },
589
+ )
590
+ end
591
+
592
+ it "responds with the links" do
593
+ response = @api_client.put_links(@content_id, links: {
594
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
595
+ })
596
+
597
+ assert_equal 200, response.code
598
+ assert_equal(OpenStruct.new(
599
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
600
+ ), response.links)
601
+ end
602
+ end
603
+ end
604
+ end
data/test/test_helper.rb CHANGED
@@ -11,7 +11,7 @@ require 'rack/utils'
11
11
  require 'rack/test'
12
12
  require 'simplecov'
13
13
  require 'simplecov-rcov'
14
- require 'mocha'
14
+ require 'mocha/mini_test'
15
15
  require 'timecop'
16
16
 
17
17
  SimpleCov.start do
@@ -26,6 +26,23 @@ class MiniTest::Unit::TestCase
26
26
  end
27
27
  end
28
28
 
29
+ require 'pact/consumer/minitest'
30
+ module PactTest
31
+ include Pact::Consumer::Minitest
32
+
33
+ def before_suite
34
+ # Pact does its own stubbing of network connections, so we want to
35
+ # prevent WebMock interfering when pact is being used.
36
+ ::WebMock.allow_net_connect!
37
+ super
38
+ end
39
+
40
+ def after_suite
41
+ super
42
+ ::WebMock.disable_net_connect!
43
+ end
44
+ end
45
+
29
46
  def load_fixture_file(filename)
30
47
  File.open( File.join( File.dirname(__FILE__), "fixtures", filename ), :encoding => 'utf-8' )
31
48
  end
@@ -34,3 +51,4 @@ require 'webmock/minitest'
34
51
  WebMock.disable_net_connect!
35
52
 
36
53
  require 'gds_api/test_helpers/json_client_helper'
54
+ require 'test_helpers/pact_helper'
@@ -0,0 +1,7 @@
1
+ Pact.service_consumer "GDS API Adapters" do
2
+ has_pact_with "Publishing API" do
3
+ mock_service :publishing_api do
4
+ port 3093
5
+ end
6
+ end
7
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gds-api-adapters
3
3
  version: !ruby/object:Gem::Version
4
- version: 24.4.0
4
+ version: 24.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Stewart
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-17 00:00:00.000000000 Z
11
+ date: 2015-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: plek
@@ -95,75 +95,89 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rdoc
98
+ name: gem_publisher
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '='
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '3.12'
103
+ version: 1.5.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '='
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '3.12'
110
+ version: 1.5.0
111
111
  - !ruby/object:Gem::Dependency
112
- name: rake
112
+ name: mocha
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ">"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.9.2.2
117
+ version: 1.0.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ">"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.9.2.2
124
+ version: 1.0.0
125
125
  - !ruby/object:Gem::Dependency
126
- name: webmock
126
+ name: minitest
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
129
+ - - ">"
130
130
  - !ruby/object:Gem::Version
131
- version: '1.19'
131
+ version: 5.0.0
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - "~>"
136
+ - - ">"
137
137
  - !ruby/object:Gem::Version
138
- version: '1.19'
138
+ version: 5.0.0
139
139
  - !ruby/object:Gem::Dependency
140
- name: mocha
140
+ name: pact
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - "~>"
143
+ - - ">="
144
144
  - !ruby/object:Gem::Version
145
- version: 0.12.4
145
+ version: '0'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - "~>"
150
+ - - ">="
151
151
  - !ruby/object:Gem::Version
152
- version: 0.12.4
152
+ version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: minitest
154
+ name: pact-consumer-minitest
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - "~>"
157
+ - - ">="
158
158
  - !ruby/object:Gem::Version
159
- version: 3.4.0
159
+ version: '0'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - "~>"
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: pry
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
165
179
  - !ruby/object:Gem::Version
166
- version: 3.4.0
180
+ version: '0'
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: rack
169
183
  requirement: !ruby/object:Gem::Requirement
@@ -193,47 +207,61 @@ dependencies:
193
207
  - !ruby/object:Gem::Version
194
208
  version: '0'
195
209
  - !ruby/object:Gem::Dependency
196
- name: simplecov
210
+ name: rake
197
211
  requirement: !ruby/object:Gem::Requirement
198
212
  requirements:
199
213
  - - "~>"
200
214
  - !ruby/object:Gem::Version
201
- version: 0.5.4
215
+ version: 0.9.2.2
202
216
  type: :development
203
217
  prerelease: false
204
218
  version_requirements: !ruby/object:Gem::Requirement
205
219
  requirements:
206
220
  - - "~>"
207
221
  - !ruby/object:Gem::Version
208
- version: 0.5.4
222
+ version: 0.9.2.2
209
223
  - !ruby/object:Gem::Dependency
210
- name: simplecov-rcov
224
+ name: rdoc
211
225
  requirement: !ruby/object:Gem::Requirement
212
226
  requirements:
213
- - - ">="
227
+ - - '='
214
228
  - !ruby/object:Gem::Version
215
- version: '0'
229
+ version: '3.12'
216
230
  type: :development
217
231
  prerelease: false
218
232
  version_requirements: !ruby/object:Gem::Requirement
219
233
  requirements:
220
- - - ">="
234
+ - - '='
221
235
  - !ruby/object:Gem::Version
222
- version: '0'
236
+ version: '3.12'
223
237
  - !ruby/object:Gem::Dependency
224
- name: gem_publisher
238
+ name: simplecov
225
239
  requirement: !ruby/object:Gem::Requirement
226
240
  requirements:
227
241
  - - "~>"
228
242
  - !ruby/object:Gem::Version
229
- version: 1.5.0
243
+ version: 0.5.4
230
244
  type: :development
231
245
  prerelease: false
232
246
  version_requirements: !ruby/object:Gem::Requirement
233
247
  requirements:
234
248
  - - "~>"
235
249
  - !ruby/object:Gem::Version
236
- version: 1.5.0
250
+ version: 0.5.4
251
+ - !ruby/object:Gem::Dependency
252
+ name: simplecov-rcov
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
237
265
  - !ruby/object:Gem::Dependency
238
266
  name: timecop
239
267
  requirement: !ruby/object:Gem::Requirement
@@ -249,19 +277,19 @@ dependencies:
249
277
  - !ruby/object:Gem::Version
250
278
  version: 0.5.1
251
279
  - !ruby/object:Gem::Dependency
252
- name: pry
280
+ name: webmock
253
281
  requirement: !ruby/object:Gem::Requirement
254
282
  requirements:
255
- - - ">="
283
+ - - "~>"
256
284
  - !ruby/object:Gem::Version
257
- version: '0'
285
+ version: '1.19'
258
286
  type: :development
259
287
  prerelease: false
260
288
  version_requirements: !ruby/object:Gem::Requirement
261
289
  requirements:
262
- - - ">="
290
+ - - "~>"
263
291
  - !ruby/object:Gem::Version
264
- version: '0'
292
+ version: '1.19'
265
293
  description: A set of adapters providing easy access to the GDS GOV.UK APIs
266
294
  email:
267
295
  - jystewart@gmail.com
@@ -304,6 +332,7 @@ files:
304
332
  - lib/gds_api/publisher.rb
305
333
  - lib/gds_api/publishing_api.rb
306
334
  - lib/gds_api/publishing_api/special_route_publisher.rb
335
+ - lib/gds_api/publishing_api_v2.rb
307
336
  - lib/gds_api/railtie.rb
308
337
  - lib/gds_api/response.rb
309
338
  - lib/gds_api/router.rb
@@ -376,6 +405,7 @@ files:
376
405
  - test/publisher_api_test.rb
377
406
  - test/publishing_api/special_route_publisher_test.rb
378
407
  - test/publishing_api_test.rb
408
+ - test/publishing_api_v2_test.rb
379
409
  - test/response_test.rb
380
410
  - test/router_test.rb
381
411
  - test/rummager_helpers_test.rb
@@ -383,6 +413,7 @@ files:
383
413
  - test/support_api_test.rb
384
414
  - test/support_test.rb
385
415
  - test/test_helper.rb
416
+ - test/test_helpers/pact_helper.rb
386
417
  - test/test_helpers/panopticon_test.rb
387
418
  - test/test_helpers/publishing_api_test.rb
388
419
  - test/whitehall_admin_api_test.rb
@@ -424,6 +455,7 @@ test_files:
424
455
  - test/content_register_test.rb
425
456
  - test/fact_cave_test.rb
426
457
  - test/test_helpers/publishing_api_test.rb
458
+ - test/test_helpers/pact_helper.rb
427
459
  - test/test_helpers/panopticon_test.rb
428
460
  - test/licence_application_api_test.rb
429
461
  - test/gov_uk_delivery_test.rb
@@ -455,4 +487,5 @@ test_files:
455
487
  - test/gds_api_base_test.rb
456
488
  - test/worldwide_api_test.rb
457
489
  - test/test_helper.rb
490
+ - test/publishing_api_v2_test.rb
458
491
  - test/business_support_api_test.rb