alephant-broker 3.11.0 → 3.12.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: 58251bb948e3620c95b0c67e8643e60426c25818
4
- data.tar.gz: c355b17fe2d366043fbd84f5e284377f9d353a44
3
+ metadata.gz: 60b6af683863285e27316bde5b7392d93439b20e
4
+ data.tar.gz: 7052275d91783c7b02ab1996cdced8e606b58e51
5
5
  SHA512:
6
- metadata.gz: dbdaf0f97e7c873b030be8418d6b7b7a076826fcd576d7f60b9c5f734f4ac8a13db6af1cb4744b222b48ee01abd267c6df051f22fac85dd8285b53b36128ce2c
7
- data.tar.gz: a143fb0fbca1a39ab62a1a7facd718f9f38221a53daae7514ca82d1f9b7a42b3992ba06f8b427da717a919a50801f9877bb56d7c4b34e7adeae69702c5d63fde
6
+ metadata.gz: b8307c2cbe4304ebf233878d20026529e21302cec83e78132b43a6bb7da377da977f85d2f48b447c76d4e3647d2f7915659ec56cdbb9b4ecda8b4e5e26b26777
7
+ data.tar.gz: 0c2ba375708bfb96376954db24ab557b8bc615db013d9e85bd4ad3833d5f03861c6efc1074cd72e4a890d25ca42181f57caaf5da74ea29c458bd16ad71a7dafe
@@ -25,7 +25,7 @@ module Alephant
25
25
  @content = STATUS_CODE_MAPPING[status]
26
26
  @headers = {
27
27
  "Content-Type" => content_type,
28
- "Access-Control-Allow-Headers" => "If-None-Match",
28
+ "Access-Control-Allow-Headers" => "If-None-Match, If-Modified-Since",
29
29
  "Access-Control-Allow-Origin" => "*"
30
30
  }
31
31
  headers.merge!(Broker.config[:headers]) if Broker.config.has_key?(:headers)
@@ -62,6 +62,7 @@ module Alephant
62
62
  end
63
63
 
64
64
  def self.component_not_modified(headers, request_env)
65
+ return false unless allow_not_modified_response_status
65
66
  return false if request_env.post?
66
67
  return false if request_env.if_modified_since.nil? && request_env.if_none_match.nil?
67
68
 
@@ -76,6 +77,10 @@ module Alephant
76
77
  etag.to_s.gsub(/\A"|"\Z/, '')
77
78
  end
78
79
 
80
+ def self.allow_not_modified_response_status
81
+ Broker.config[:allow_not_modified_response_status] || false
82
+ end
83
+
79
84
  def log
80
85
  logger.metric "BrokerNon200Response#{status}"
81
86
  end
@@ -1,5 +1,5 @@
1
1
  module Alephant
2
2
  module Broker
3
- VERSION = "3.11.0"
3
+ VERSION = "3.12.0"
4
4
  end
5
5
  end
@@ -0,0 +1,230 @@
1
+ require_relative "spec_helper"
2
+ require "alephant/broker"
3
+
4
+ describe Alephant::Broker::Application do
5
+ include Rack::Test::Methods
6
+
7
+ let(:options) do
8
+ {
9
+ :lookup_table_name => "test_table",
10
+ :bucket_id => "test_bucket",
11
+ :path => "bucket_path",
12
+ :allow_not_modified_response_status => true
13
+ }
14
+ end
15
+
16
+ let(:app) do
17
+ described_class.new(
18
+ Alephant::Broker::LoadStrategy::S3::Sequenced.new,
19
+ options
20
+ )
21
+ end
22
+
23
+ let(:content) do
24
+ AWS::Core::Data.new(
25
+ :content_type => "test/content",
26
+ :content => "Test",
27
+ :meta => {
28
+ "head_ETag" => "123",
29
+ "head_Last-Modified" => "Mon, 11 Apr 2016 10:39:57 GMT"
30
+ }
31
+ )
32
+ end
33
+
34
+ let(:sequencer_double) do
35
+ instance_double(
36
+ "Alephant::Sequencer::Sequencer",
37
+ :get_last_seen => "111"
38
+ )
39
+ end
40
+
41
+ let(:lookup_location_double) do
42
+ instance_double("Alephant::Lookup::Location", :location => "test/location")
43
+ end
44
+ let(:lookup_helper_double) do
45
+ instance_double(
46
+ "Alephant::Lookup::LookupHelper",
47
+ :read => lookup_location_double
48
+ )
49
+ end
50
+
51
+ let(:s3_double) { instance_double("Alephant::Storage", :get => content) }
52
+
53
+ let(:not_modified_status_code) { Alephant::Broker::Response::Base::NOT_MODIFIED_STATUS_CODE }
54
+
55
+ before do
56
+ allow_any_instance_of(Logger).to receive(:info)
57
+ allow_any_instance_of(Logger).to receive(:debug)
58
+ allow(Alephant::Lookup).to receive(:create) { lookup_helper_double }
59
+ allow(Alephant::Sequencer).to receive(:create) { sequencer_double }
60
+ end
61
+
62
+ describe "single component not modified response" do
63
+ before do
64
+ allow(Alephant::Storage).to receive(:new) { s3_double }
65
+ get(
66
+ "/component/test_component",
67
+ {},
68
+ {
69
+ "HTTP_IF_MODIFIED_SINCE" => "Mon, 11 Apr 2016 10:39:57 GMT"
70
+ }
71
+ )
72
+ end
73
+
74
+ specify { expect(last_response.status).to eql not_modified_status_code }
75
+ specify { expect(last_response.body).to eql "" }
76
+ specify { expect(last_response.headers).to_not include("Cache-Control") }
77
+ specify { expect(last_response.headers).to_not include("Pragma") }
78
+ specify { expect(last_response.headers).to_not include("Expires") }
79
+ specify { expect(last_response.headers["ETag"]).to eq("123") }
80
+ specify { expect(last_response.headers["Last-Modified"]).to eq("Mon, 11 Apr 2016 10:39:57 GMT") }
81
+ end
82
+
83
+ describe "Components POST unmodified '/components' response" do
84
+ let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
85
+ let(:batch_json) { IO.read("#{fixture_path}/batch.json").strip }
86
+ let(:batch_compiled_json) { IO.read("#{fixture_path}/batch_compiled.json").strip }
87
+ let(:s3_double_with_etag) { instance_double("Alephant::Storage") }
88
+ let(:lookup_location_double_for_options_request) do
89
+ instance_double("Alephant::Lookup::Location", :location => "test/location/with/options")
90
+ end
91
+
92
+ before do
93
+ allow(lookup_helper_double).to receive(:read)
94
+ .with("ni_council_results_table", { :foo => "bar" }, "111")
95
+ .and_return(lookup_location_double_for_options_request)
96
+
97
+ allow(s3_double_with_etag).to receive(:get)
98
+ .with("test/location")
99
+ .and_return(
100
+ content
101
+ )
102
+
103
+ allow(s3_double_with_etag).to receive(:get)
104
+ .with("test/location/with/options")
105
+ .and_return(
106
+ AWS::Core::Data.new(
107
+ :content_type => "test/content",
108
+ :content => "Test",
109
+ :meta => {
110
+ "head_ETag" => "abc",
111
+ "head_Last-Modified" => "Mon, 11 Apr 2016 09:39:57 GMT"
112
+ }
113
+ )
114
+ )
115
+
116
+ allow(Alephant::Storage).to receive(:new) { s3_double_with_etag }
117
+ end
118
+
119
+ context "when requesting an unmodified response" do
120
+ let(:path) { "/components/batch" }
121
+ let(:content_type) { "application/json" }
122
+ let(:etag) { '"34774567db979628363e6e865127623f"' }
123
+
124
+ before do
125
+ post(path, batch_json,
126
+ "CONTENT_TYPE" => content_type,
127
+ "HTTP_IF_NONE_MATCH" => etag)
128
+ end
129
+
130
+ specify { expect(last_response.status).to eql 200 }
131
+ specify { expect(last_response.body).to eq batch_compiled_json }
132
+
133
+ describe "response should have headers" do
134
+ it "should have a Content-Type header" do
135
+ expect(last_response.headers).to include("Content-Type")
136
+ end
137
+
138
+ it "should have ETag cache header" do
139
+ expect(last_response.headers["ETag"]).to eq(etag)
140
+ end
141
+
142
+ it "should have most recent Last-Modified header" do
143
+ expect(last_response.headers["Last-Modified"]).to eq("Mon, 11 Apr 2016 10:39:57 GMT")
144
+ end
145
+
146
+ it "shoud not have no cache headers" do
147
+ expect(last_response.headers).to_not include("Cache-Control")
148
+ expect(last_response.headers).to_not include("Pragma")
149
+ expect(last_response.headers).to_not include("Expires")
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ describe "Components GET unmodified '/components' response" do
156
+ let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
157
+ let(:batch_compiled_json) { IO.read("#{fixture_path}/batch_compiled.json").strip }
158
+ let(:s3_double_with_etag) { instance_double("Alephant::Storage") }
159
+ let(:lookup_location_double_for_options_request) do
160
+ instance_double("Alephant::Lookup::Location", :location => "test/location/with/options")
161
+ end
162
+
163
+ before do
164
+ allow(lookup_helper_double).to receive(:read)
165
+ .with("ni_council_results_table", { :foo => "bar" }, "111")
166
+ .and_return(lookup_location_double_for_options_request)
167
+
168
+ allow(s3_double_with_etag).to receive(:get)
169
+ .with("test/location")
170
+ .and_return(
171
+ content
172
+ )
173
+
174
+ allow(s3_double_with_etag).to receive(:get)
175
+ .with("test/location/with/options")
176
+ .and_return(
177
+ AWS::Core::Data.new(
178
+ :content_type => "test/content",
179
+ :content => "Test",
180
+ :meta => {
181
+ "head_ETag" => "abc",
182
+ "head_Last-Modified" => "Mon, 11 Apr 2016 09:39:57 GMT"
183
+ }
184
+ )
185
+ )
186
+
187
+ allow(Alephant::Storage).to receive(:new) { s3_double_with_etag }
188
+ end
189
+
190
+ context "when requesting an unmodified response with GET" do
191
+ let(:path) { "/components/batch?batch_id=baz&components[ni_council_results_table][component]=ni_council_results_table&components[ni_council_results_table][options][foo]=bar&components[ni_council_results_table_no_options][component]=ni_council_results_table" }
192
+ let(:content_type) { "application/json" }
193
+ let(:etag) { '"34774567db979628363e6e865127623f"' }
194
+
195
+ before do
196
+ get(
197
+ path,
198
+ {},
199
+ {
200
+ "CONTENT_TYPE" => content_type,
201
+ "HTTP_IF_NONE_MATCH" => etag
202
+ }
203
+ )
204
+ end
205
+
206
+ specify { expect(last_response.status).to eql not_modified_status_code }
207
+ specify { expect(last_response.body).to eq "" }
208
+
209
+ describe "response should have headers" do
210
+ it "should not have a Content-Type header" do
211
+ expect(last_response.headers).to_not include("Content-Type")
212
+ end
213
+
214
+ it "should have ETag cache header" do
215
+ expect(last_response.headers["ETag"]).to eq(etag)
216
+ end
217
+
218
+ it "should have most recent Last-Modified header" do
219
+ expect(last_response.headers["Last-Modified"]).to eq("Mon, 11 Apr 2016 10:39:57 GMT")
220
+ end
221
+
222
+ it "shoud not have no cache headers" do
223
+ expect(last_response.headers).to_not include("Cache-Control")
224
+ expect(last_response.headers).to_not include("Pragma")
225
+ expect(last_response.headers).to_not include("Expires")
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
@@ -96,27 +96,6 @@ describe Alephant::Broker::Application do
96
96
  end
97
97
  end
98
98
 
99
- describe "single component not modified response" do
100
- before do
101
- allow(Alephant::Storage).to receive(:new) { s3_double }
102
- get(
103
- "/component/test_component",
104
- {},
105
- {
106
- "HTTP_IF_MODIFIED_SINCE" => "Mon, 11 Apr 2016 10:39:57 GMT"
107
- }
108
- )
109
- end
110
-
111
- specify { expect(last_response.status).to eql not_modified_status_code }
112
- specify { expect(last_response.body).to eql "" }
113
- specify { expect(last_response.headers).to_not include("Cache-Control") }
114
- specify { expect(last_response.headers).to_not include("Pragma") }
115
- specify { expect(last_response.headers).to_not include("Expires") }
116
- specify { expect(last_response.headers["ETag"]).to eq("123") }
117
- specify { expect(last_response.headers["Last-Modified"]).to eq("Mon, 11 Apr 2016 10:39:57 GMT") }
118
- end
119
-
120
99
  describe "Components endpoint '/components' POST" do
121
100
  let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
122
101
  let(:batch_json) do
@@ -169,78 +148,6 @@ describe Alephant::Broker::Application do
169
148
  end
170
149
  end
171
150
 
172
- describe "Components POST unmodified '/components' response" do
173
- let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
174
- let(:batch_json) { IO.read("#{fixture_path}/batch.json").strip }
175
- let(:batch_compiled_json) { IO.read("#{fixture_path}/batch_compiled.json").strip }
176
- let(:s3_double_with_etag) { instance_double("Alephant::Storage") }
177
- let(:lookup_location_double_for_options_request) do
178
- instance_double("Alephant::Lookup::Location", :location => "test/location/with/options")
179
- end
180
-
181
- before do
182
- allow(lookup_helper_double).to receive(:read)
183
- .with("ni_council_results_table", { :foo => "bar" }, "111")
184
- .and_return(lookup_location_double_for_options_request)
185
-
186
- allow(s3_double_with_etag).to receive(:get)
187
- .with("test/location")
188
- .and_return(
189
- content
190
- )
191
-
192
- allow(s3_double_with_etag).to receive(:get)
193
- .with("test/location/with/options")
194
- .and_return(
195
- AWS::Core::Data.new(
196
- :content_type => "test/content",
197
- :content => "Test",
198
- :meta => {
199
- "head_ETag" => "abc",
200
- "head_Last-Modified" => "Mon, 11 Apr 2016 09:39:57 GMT"
201
- }
202
- )
203
- )
204
-
205
- allow(Alephant::Storage).to receive(:new) { s3_double_with_etag }
206
- end
207
-
208
- context "when requesting an unmodified response" do
209
- let(:path) { "/components/batch" }
210
- let(:content_type) { "application/json" }
211
- let(:etag) { '"34774567db979628363e6e865127623f"' }
212
-
213
- before do
214
- post(path, batch_json,
215
- "CONTENT_TYPE" => content_type,
216
- "HTTP_IF_NONE_MATCH" => etag)
217
- end
218
-
219
- specify { expect(last_response.status).to eql 200 }
220
- specify { expect(last_response.body).to eq batch_compiled_json }
221
-
222
- describe "response should have headers" do
223
- it "should have a Content-Type header" do
224
- expect(last_response.headers).to include("Content-Type")
225
- end
226
-
227
- it "should have ETag cache header" do
228
- expect(last_response.headers["ETag"]).to eq(etag)
229
- end
230
-
231
- it "should have most recent Last-Modified header" do
232
- expect(last_response.headers["Last-Modified"]).to eq("Mon, 11 Apr 2016 10:39:57 GMT")
233
- end
234
-
235
- it "shoud not have no cache headers" do
236
- expect(last_response.headers).to_not include("Cache-Control")
237
- expect(last_response.headers).to_not include("Pragma")
238
- expect(last_response.headers).to_not include("Expires")
239
- end
240
- end
241
- end
242
- end
243
-
244
151
  describe "Components endpoint '/components' GET" do
245
152
  let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
246
153
  let(:batch_compiled_json) do
@@ -290,82 +197,6 @@ describe Alephant::Broker::Application do
290
197
  end
291
198
  end
292
199
 
293
- describe "Components GET unmodified '/components' response" do
294
- let(:fixture_path) { "#{File.dirname(__FILE__)}/../fixtures/json" }
295
- let(:batch_compiled_json) { IO.read("#{fixture_path}/batch_compiled.json").strip }
296
- let(:s3_double_with_etag) { instance_double("Alephant::Storage") }
297
- let(:lookup_location_double_for_options_request) do
298
- instance_double("Alephant::Lookup::Location", :location => "test/location/with/options")
299
- end
300
-
301
- before do
302
- allow(lookup_helper_double).to receive(:read)
303
- .with("ni_council_results_table", { :foo => "bar" }, "111")
304
- .and_return(lookup_location_double_for_options_request)
305
-
306
- allow(s3_double_with_etag).to receive(:get)
307
- .with("test/location")
308
- .and_return(
309
- content
310
- )
311
-
312
- allow(s3_double_with_etag).to receive(:get)
313
- .with("test/location/with/options")
314
- .and_return(
315
- AWS::Core::Data.new(
316
- :content_type => "test/content",
317
- :content => "Test",
318
- :meta => {
319
- "head_ETag" => "abc",
320
- "head_Last-Modified" => "Mon, 11 Apr 2016 09:39:57 GMT"
321
- }
322
- )
323
- )
324
-
325
- allow(Alephant::Storage).to receive(:new) { s3_double_with_etag }
326
- end
327
-
328
- context "when requesting an unmodified response with GET" do
329
- let(:path) { "/components/batch?batch_id=baz&components[ni_council_results_table][component]=ni_council_results_table&components[ni_council_results_table][options][foo]=bar&components[ni_council_results_table_no_options][component]=ni_council_results_table" }
330
- let(:content_type) { "application/json" }
331
- let(:etag) { '"34774567db979628363e6e865127623f"' }
332
-
333
- before do
334
- get(
335
- path,
336
- {},
337
- {
338
- "CONTENT_TYPE" => content_type,
339
- "HTTP_IF_NONE_MATCH" => etag
340
- }
341
- )
342
- end
343
-
344
- specify { expect(last_response.status).to eql not_modified_status_code }
345
- specify { expect(last_response.body).to eq "" }
346
-
347
- describe "response should have headers" do
348
- it "should not have a Content-Type header" do
349
- expect(last_response.headers).to_not include("Content-Type")
350
- end
351
-
352
- it "should have ETag cache header" do
353
- expect(last_response.headers["ETag"]).to eq(etag)
354
- end
355
-
356
- it "should have most recent Last-Modified header" do
357
- expect(last_response.headers["Last-Modified"]).to eq("Mon, 11 Apr 2016 10:39:57 GMT")
358
- end
359
-
360
- it "shoud not have no cache headers" do
361
- expect(last_response.headers).to_not include("Cache-Control")
362
- expect(last_response.headers).to_not include("Pragma")
363
- expect(last_response.headers).to_not include("Expires")
364
- end
365
- end
366
- end
367
- end
368
-
369
200
  describe "S3 headers" do
370
201
  let(:content) do
371
202
  AWS::Core::Data.new(
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alephant-broker
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.11.0
4
+ version: 3.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - BBC News
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-27 00:00:00.000000000 Z
11
+ date: 2016-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -322,6 +322,7 @@ files:
322
322
  - spec/fixtures/json/batch.json
323
323
  - spec/fixtures/json/batch_compiled.json
324
324
  - spec/http_spec.rb
325
+ - spec/integration/not_modified_response_spec.rb
325
326
  - spec/integration/rack_spec.rb
326
327
  - spec/integration/spec_helper.rb
327
328
  - spec/spec_helper.rb
@@ -355,6 +356,7 @@ test_files:
355
356
  - spec/fixtures/json/batch.json
356
357
  - spec/fixtures/json/batch_compiled.json
357
358
  - spec/http_spec.rb
359
+ - spec/integration/not_modified_response_spec.rb
358
360
  - spec/integration/rack_spec.rb
359
361
  - spec/integration/spec_helper.rb
360
362
  - spec/spec_helper.rb