gds-api-adapters 24.4.0 → 24.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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