gds-api-adapters 25.0.0 → 25.1.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: e7e6dd6ee7232cd76f967088448461c8b572f56d
4
- data.tar.gz: 12338e6a3ca65715876c502dfc81d4ca519f2c5f
3
+ metadata.gz: 8afbe2d34bba51917e28dd3f85e89d6e734c35af
4
+ data.tar.gz: da4fdfd37ae75f002f6dc163a039856672bd40eb
5
5
  SHA512:
6
- metadata.gz: 760651cf21cbdaa624527b5f2b9442ac7cf522ac3345aa551235ef28579826ab9e7b39cebffdf514f23658f8099f27b20428622cc951da31fd3d2e7761e63180
7
- data.tar.gz: 8fbdf293064d55223de66030d1b47525501f5a48a8f93226fffd6a844ebe873b80736d8ceefd3174e466b95b1c282629016aabfcf631ddefd75378b8d0b2c7a4
6
+ metadata.gz: 2b31b1493c90363a24080b9d8bb0864ecf400dd52ae23d44b15bc5f59ba539f55bcdfcaf97b7923307dd27510299dd880e79af29b2cfbad6d8820c34219edd10
7
+ data.tar.gz: 61cace3dd9782add1a8814776db7643054734766f72f3545954cd87a1356a12836860f489e2589b4cfa744caaa76c6486dd3249bcbc8f1dd6ce416ec7c42673c
@@ -14,8 +14,16 @@ class GdsApi::PublishingApiV2 < GdsApi::Base
14
14
  end
15
15
 
16
16
  def publish(content_id, update_type, options = {})
17
- params = { update_type: update_type }
18
- params = params.merge(locale: options[:locale]) if options[:locale]
17
+ params = {
18
+ update_type: update_type
19
+ }
20
+
21
+ optional_keys = [
22
+ :locale,
23
+ :previous_version,
24
+ ]
25
+
26
+ params = merge_optional_keys(params, options, optional_keys)
19
27
 
20
28
  post_json!(publish_url(content_id), params)
21
29
  end
@@ -25,8 +33,13 @@ class GdsApi::PublishingApiV2 < GdsApi::Base
25
33
  end
26
34
 
27
35
  def put_links(content_id, payload)
28
- links = payload.fetch(:links)
29
- put_json!(links_url(content_id), links: links)
36
+ params = {
37
+ links: payload.fetch(:links)
38
+ }
39
+
40
+ params = merge_optional_keys(params, payload, [:previous_version])
41
+
42
+ put_json!(links_url(content_id), params)
30
43
  end
31
44
 
32
45
  private
@@ -43,4 +56,10 @@ private
43
56
  def publish_url(content_id)
44
57
  "#{endpoint}/v2/content/#{content_id}/publish"
45
58
  end
59
+
60
+ def merge_optional_keys(params, options, optional_keys)
61
+ optional_keys.each_with_object(params) do |optional_key, hash|
62
+ hash.merge!(optional_key => options[optional_key]) if options[optional_key]
63
+ end
64
+ end
46
65
  end
@@ -1,3 +1,3 @@
1
1
  module GdsApi
2
- VERSION = '25.0.0'
2
+ VERSION = '25.1.0'
3
3
  end
@@ -17,7 +17,7 @@ describe GdsApi::PublishingApi do
17
17
  content_item = content_item_for_publishing_api(base_path).merge("update_type" => "major")
18
18
 
19
19
  publishing_api
20
- .given("both content stores and the url-arbiter are empty")
20
+ .given("no content exists")
21
21
  .upon_receiving("a request to create a content item")
22
22
  .with(
23
23
  method: :put,
@@ -46,7 +46,7 @@ describe GdsApi::PublishingApi do
46
46
  content_item = content_item_for_publishing_api(base_path).merge("update_type" => "major")
47
47
 
48
48
  publishing_api
49
- .given("both content stores and the url-arbiter are empty")
49
+ .given("no content exists")
50
50
  .upon_receiving("a request to create a draft content item")
51
51
  .with(
52
52
  method: :put,
@@ -75,7 +75,7 @@ describe GdsApi::PublishingApi do
75
75
  publish_intent = intent_for_publishing_api(base_path)
76
76
 
77
77
  publishing_api
78
- .given("both content stores and the url-arbiter are empty")
78
+ .given("no content exists")
79
79
  .upon_receiving("a request to create a publish intent")
80
80
  .with(
81
81
  method: :put,
@@ -105,7 +105,7 @@ describe GdsApi::PublishingApi do
105
105
  publish_intent = intent_for_publishing_api(base_path)
106
106
 
107
107
  publishing_api
108
- .given("a publish intent exists at /test-intent in the live content store")
108
+ .given("a publish intent exists at /test-intent")
109
109
  .upon_receiving("a request to delete a publish intent")
110
110
  .with(
111
111
  method: :delete,
@@ -129,7 +129,7 @@ describe GdsApi::PublishingApi do
129
129
  publish_intent = intent_for_publishing_api(base_path)
130
130
 
131
131
  publishing_api
132
- .given("both content stores and the url-arbiter are empty")
132
+ .given("no content exists")
133
133
  .upon_receiving("a request to delete a publish intent")
134
134
  .with(
135
135
  method: :delete,
@@ -156,7 +156,7 @@ describe GdsApi::PublishingApi do
156
156
  }
157
157
 
158
158
  publishing_api
159
- .given("both content stores and the url-arbiter are empty")
159
+ .given("no content exists")
160
160
  .upon_receiving("a request to put a path")
161
161
  .with(
162
162
  method: :put,
@@ -185,7 +185,7 @@ describe GdsApi::PublishingApi do
185
185
  }
186
186
 
187
187
  publishing_api
188
- .given("/test-item has been reserved in url-arbiter by the Publisher application")
188
+ .given("/test-item has been reserved by the Publisher application")
189
189
  .upon_receiving("a request to change publishing app")
190
190
  .with(
191
191
  method: :put,
@@ -38,7 +38,7 @@ describe GdsApi::PublishingApiV2 do
38
38
  @content_item = content_item_for_content_id(@content_id)
39
39
 
40
40
  publishing_api
41
- .given("both content stores and the url-arbiter are empty")
41
+ .given("no content exists")
42
42
  .upon_receiving("a request to create a content item without links")
43
43
  .with(
44
44
  method: :put,
@@ -64,7 +64,7 @@ describe GdsApi::PublishingApiV2 do
64
64
  @content_item = content_item_for_content_id(@content_id, "base_path" => "/test-item", "publishing_app" => "whitehall")
65
65
 
66
66
  publishing_api
67
- .given("/test-item has been reserved in url-arbiter by the Publisher application")
67
+ .given("/test-item has been reserved by the Publisher application")
68
68
  .upon_receiving("a request from the Whitehall application to create a content item at /test-item")
69
69
  .with(
70
70
  method: :put,
@@ -104,7 +104,7 @@ describe GdsApi::PublishingApiV2 do
104
104
  @content_item = content_item_for_content_id(@content_id, "base_path" => "not a url path")
105
105
 
106
106
  publishing_api
107
- .given("both content stores and the url-arbiter are empty")
107
+ .given("no content exists")
108
108
  .upon_receiving("a request to create an invalid content-item")
109
109
  .with(
110
110
  method: :put,
@@ -139,6 +139,75 @@ describe GdsApi::PublishingApiV2 do
139
139
  assert_equal "Unprocessable entity", error.error_details["error"]["message"]
140
140
  end
141
141
  end
142
+
143
+ describe "optimistic locking" do
144
+ describe "if the content item has not change since it was requested" do
145
+ before do
146
+ @content_item = content_item_for_content_id(@content_id, "previous_version" => 3)
147
+
148
+ publishing_api
149
+ .given("the content item #{@content_id} is at version 3")
150
+ .upon_receiving("a request to update the content item at version 3")
151
+ .with(
152
+ method: :put,
153
+ path: "/v2/content/#{@content_id}",
154
+ body: @content_item,
155
+ headers: {
156
+ "Content-Type" => "application/json",
157
+ },
158
+ )
159
+ .will_respond_with(
160
+ status: 200,
161
+ )
162
+ end
163
+
164
+ it "responds with 200 OK" do
165
+ response = @api_client.put_content(@content_id, @content_item)
166
+ assert_equal 200, response.code
167
+ end
168
+ end
169
+
170
+ describe "if the content item has changed in the meantime" do
171
+ before do
172
+ @content_item = content_item_for_content_id(@content_id, "previous_version" => 2)
173
+
174
+ publishing_api
175
+ .given("the content item #{@content_id} is at version 3")
176
+ .upon_receiving("a request to update the content item at version 2")
177
+ .with(
178
+ method: :put,
179
+ path: "/v2/content/#{@content_id}",
180
+ body: @content_item,
181
+ headers: {
182
+ "Content-Type" => "application/json",
183
+ },
184
+ )
185
+ .will_respond_with(
186
+ status: 409,
187
+ body: {
188
+ "error" => {
189
+ "code" => 409,
190
+ "message" => Pact.term(generate: "Conflict", matcher:/\S+/),
191
+ "fields" => {
192
+ "previous_version" => Pact.each_like("does not match", :min => 1),
193
+ },
194
+ },
195
+ },
196
+ headers: {
197
+ "Content-Type" => "application/json; charset=utf-8"
198
+ }
199
+ )
200
+ end
201
+
202
+ it "responds with 409 Conflict" do
203
+ error = assert_raises GdsApi::HTTPClientError do
204
+ @api_client.put_content(@content_id, @content_item)
205
+ end
206
+ assert_equal 409, error.code
207
+ assert_equal "Conflict", error.error_details["error"]["message"]
208
+ end
209
+ end
210
+ end
142
211
  end
143
212
 
144
213
  describe "#get_content" do
@@ -218,7 +287,7 @@ describe GdsApi::PublishingApiV2 do
218
287
  describe "a non-existent item" do
219
288
  before do
220
289
  publishing_api
221
- .given("both content stores and the url-arbiter are empty")
290
+ .given("no content exists")
222
291
  .upon_receiving("a request for a non-existent content item")
223
292
  .with(
224
293
  method: :get,
@@ -274,7 +343,7 @@ describe GdsApi::PublishingApiV2 do
274
343
  describe "if the content item does not exist" do
275
344
  before do
276
345
  publishing_api
277
- .given("both content stores and the url-arbiter are empty")
346
+ .given("no content exists")
278
347
  .upon_receiving("a publish request")
279
348
  .with(
280
349
  method: :post,
@@ -438,6 +507,77 @@ describe GdsApi::PublishingApiV2 do
438
507
  assert_equal 200, response.code
439
508
  end
440
509
  end
510
+
511
+ describe "optimistic locking" do
512
+ describe "if the content item has not change since it was requested" do
513
+ before do
514
+ publishing_api
515
+ .given("the content item #{@content_id} is at version 3")
516
+ .upon_receiving("a publish request for version 3")
517
+ .with(
518
+ method: :post,
519
+ path: "/v2/content/#{@content_id}/publish",
520
+ body: {
521
+ update_type: "minor",
522
+ previous_version: 3,
523
+ },
524
+ headers: {
525
+ "Content-Type" => "application/json",
526
+ },
527
+ )
528
+ .will_respond_with(
529
+ status: 200,
530
+ )
531
+ end
532
+
533
+ it "responds with 200 OK" do
534
+ response = @api_client.publish(@content_id, "minor", previous_version: 3)
535
+ assert_equal 200, response.code
536
+ end
537
+ end
538
+
539
+ describe "if the content item has changed in the meantime" do
540
+ before do
541
+ publishing_api
542
+ .given("the content item #{@content_id} is at version 3")
543
+ .upon_receiving("a publish request for version 2")
544
+ .with(
545
+ method: :post,
546
+ path: "/v2/content/#{@content_id}/publish",
547
+ body: {
548
+ update_type: "minor",
549
+ previous_version: 2,
550
+ },
551
+ headers: {
552
+ "Content-Type" => "application/json",
553
+ },
554
+ )
555
+ .will_respond_with(
556
+ status: 409,
557
+ body: {
558
+ "error" => {
559
+ "code" => 409,
560
+ "message" => Pact.term(generate: "Conflict", matcher:/\S+/),
561
+ "fields" => {
562
+ "previous_version" => Pact.each_like("does not match", :min => 1),
563
+ },
564
+ },
565
+ },
566
+ headers: {
567
+ "Content-Type" => "application/json; charset=utf-8"
568
+ }
569
+ )
570
+ end
571
+
572
+ it "responds with 409 Conflict" do
573
+ error = assert_raises GdsApi::HTTPClientError do
574
+ @api_client.publish(@content_id, "minor", previous_version: 2)
575
+ end
576
+ assert_equal 409, error.code
577
+ assert_equal "Conflict", error.error_details["error"]["message"]
578
+ end
579
+ end
580
+ end
441
581
  end
442
582
 
443
583
  describe "#get_links" do
@@ -664,5 +804,92 @@ describe GdsApi::PublishingApiV2 do
664
804
  ), response.links)
665
805
  end
666
806
  end
807
+
808
+ describe "optimistic locking" do
809
+ describe "if the linkset has not change since it was requested" do
810
+ before do
811
+ publishing_api
812
+ .given("the linkset for #{@content_id} is at version 3")
813
+ .upon_receiving("a request to update the linkset at version 3")
814
+ .with(
815
+ method: :put,
816
+ path: "/v2/links/#{@content_id}",
817
+ body: {
818
+ links: {
819
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
820
+ },
821
+ previous_version: 3,
822
+ },
823
+ headers: {
824
+ "Content-Type" => "application/json",
825
+ },
826
+ )
827
+ .will_respond_with(
828
+ status: 200,
829
+ )
830
+ end
831
+
832
+ it "responds with 200 OK" do
833
+ response = @api_client.put_links(@content_id,
834
+ links: {
835
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
836
+ },
837
+ previous_version: 3,
838
+ )
839
+
840
+ assert_equal 200, response.code
841
+ end
842
+ end
843
+
844
+ describe "if the content item has changed in the meantime" do
845
+ before do
846
+ publishing_api
847
+ .given("the linkset for #{@content_id} is at version 3")
848
+ .upon_receiving("a request to update the linkset at version 2")
849
+ .with(
850
+ method: :put,
851
+ path: "/v2/links/#{@content_id}",
852
+ body: {
853
+ links: {
854
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
855
+ },
856
+ previous_version: 2,
857
+ },
858
+ headers: {
859
+ "Content-Type" => "application/json",
860
+ },
861
+ )
862
+ .will_respond_with(
863
+ status: 409,
864
+ body: {
865
+ "error" => {
866
+ "code" => 409,
867
+ "message" => Pact.term(generate: "Conflict", matcher:/\S+/),
868
+ "fields" => {
869
+ "previous_version" => Pact.each_like("does not match", :min => 1),
870
+ },
871
+ },
872
+ },
873
+ headers: {
874
+ "Content-Type" => "application/json; charset=utf-8"
875
+ }
876
+ )
877
+ end
878
+
879
+ it "responds with 409 Conflict" do
880
+ error = assert_raises GdsApi::HTTPClientError do
881
+ @api_client.put_links(@content_id,
882
+ links: {
883
+ organisations: ["591436ab-c2ae-416f-a3c5-1901d633fbfb"],
884
+ },
885
+ previous_version: 2,
886
+ )
887
+ end
888
+
889
+ assert_equal 409, error.code
890
+ assert_equal "Conflict", error.error_details["error"]["message"]
891
+ end
892
+ end
893
+ end
667
894
  end
668
895
  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: 25.0.0
4
+ version: 25.1.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-11-02 00:00:00.000000000 Z
11
+ date: 2015-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: plek