alephant-broker 0.0.3 → 0.1.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: 62ea8a88fdcc92e2e8d8cacf3b7b35e4dc3077d0
4
- data.tar.gz: e58c67bdb11c2b4028bb897337f795ca13e9a48f
3
+ metadata.gz: 88c15819c22cfcde769e9b1b1406d9563ddd11f8
4
+ data.tar.gz: f1ed322acae0dc5740f6a965e3d790e1fca99dfd
5
5
  SHA512:
6
- metadata.gz: f4a00e454e3dd9ea1b6ca4bfd8c62e99df6791891c30873153a1546254e29c679e4145751cb7371f46da59f317c583f5a35231650d954fb863b97d7a6dcbef99
7
- data.tar.gz: 2dbbb0dbdd399039794d5e72f120d1901087506e544384ada28c627422e7e2639dc1eee9b507e68925e06e82d0ffa8fba5b6db05eaa5f3f32f44cd49492bb8e0
6
+ metadata.gz: c3360481c1f7707c893d55635660cf3a5c56894c71aba9d87d80e73c549338ed47b9cede9a36233dbe5f0459b8405d7dbd39824819b4f2d42fcfc06aba0448c8
7
+ data.tar.gz: 2192c4157e16662cf51d26645d9cb0e9c1f859d487669926a87ab68bba3a78046de9eb49cc1cf8fa2dba60db5e579baf7c5e265b8cf2a3a5944119baa5913600
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "bundler", "~> 1.5"
30
30
  spec.add_development_dependency "rake"
31
31
  spec.add_development_dependency "rack-test"
32
+ spec.add_development_dependency "request_store"
32
33
 
33
34
  spec.add_runtime_dependency "alephant-lookup"
34
35
  spec.add_runtime_dependency "alephant-cache"
@@ -4,9 +4,8 @@ require "alephant/broker/models/request_handler"
4
4
  module Alephant
5
5
  module Broker
6
6
 
7
- def self.handle(request, config = {})
8
- @@request_handler ||= RequestHandler.new(config)
9
- @@request_handler.process(request)
7
+ def self.handle(config = {})
8
+ RequestHandler.new(config).process
10
9
  end
11
10
  end
12
11
 
@@ -1,7 +1,6 @@
1
1
  $: << File.dirname(__FILE__)
2
2
 
3
3
  require 'alephant/broker'
4
- require 'alephant/broker/models/request'
5
4
  require 'alephant/logger'
6
5
 
7
6
  module Alephant
@@ -13,14 +12,9 @@ module Alephant
13
12
  @config = config
14
13
  end
15
14
 
16
- def handle(request)
17
- Alephant::Broker.handle(request, @config)
15
+ def handle
16
+ Alephant::Broker.handle(@config)
18
17
  end
19
-
20
- def request_from(path, querystring)
21
- Request.new(path, querystring)
22
- end
23
-
24
18
  end
25
19
  end
26
20
  end
@@ -1,23 +1,23 @@
1
1
  $: << File.dirname(__FILE__)
2
2
 
3
3
  require 'alephant/broker/app'
4
+ require 'alephant/broker/call_environment'
4
5
 
5
6
  module Alephant
6
7
  module Broker
7
8
  class RackApplication < Application
8
9
 
9
10
  def call(env)
10
- response = handle(
11
- request_from(env['PATH_INFO'], env['QUERY_STRING'])
12
- )
11
+ RequestStore.store[:env] ||= CallEnvironment.new(env)
12
+ response = handle
13
13
  send response
14
14
  end
15
15
 
16
16
  def send(response)
17
17
  [
18
18
  response.status,
19
- {"Content-Type" => response.content_type},
20
- [response.content.to_s]
19
+ { "Content-Type" => response.content_type },
20
+ [ response.content.to_s ]
21
21
  ]
22
22
  end
23
23
  end
@@ -0,0 +1,51 @@
1
+ module Alephant
2
+ module Broker
3
+ class CallEnvironment
4
+ include Logger
5
+ attr_reader :settings
6
+
7
+ def initialize(env)
8
+ @settings = env
9
+ end
10
+
11
+ def method
12
+ @settings['REQUEST_METHOD']
13
+ end
14
+
15
+ def post?
16
+ @settings['REQUEST_METHOD'] == 'POST'
17
+ end
18
+
19
+ def get?
20
+ @settings['REQUEST_METHOD'] == 'GET'
21
+ end
22
+
23
+ def query
24
+ @settings['QUERY_STRING']
25
+ end
26
+
27
+ def path
28
+ @settings['PATH_INFO']
29
+ end
30
+
31
+ def data
32
+ parse(rack_input) if post?
33
+ end
34
+
35
+ private
36
+
37
+ def rack_input
38
+ (@settings['rack.input'].read).tap { @settings['rack.input'].rewind } # http://rack.rubyforge.org/doc/SPEC.html
39
+ end
40
+
41
+ def parse(json)
42
+ begin
43
+ JSON.parse(json)
44
+ rescue JSON::ParserError => e
45
+ logger.info("Broker.environment#data: ParserError")
46
+ nil
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,11 @@
1
+ module Alephant
2
+ module Broker
3
+ class InvalidAssetId < Exception
4
+
5
+ def initialize(msg)
6
+ super
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -4,8 +4,7 @@ module Alephant
4
4
  module Broker
5
5
  class Request
6
6
  include Logger
7
-
8
- attr_reader :type, :component_id, :options, :extension, :content_type
7
+ attr_reader :type
9
8
 
10
9
  DEFAULT_EXTENSION = :html
11
10
 
@@ -14,39 +13,9 @@ module Alephant
14
13
  :json => 'application/json'
15
14
  }
16
15
 
17
- def initialize(path, querystring)
18
- request = request_components(path, querystring)
19
- case request[:type]
20
- when "component"
21
- logger.info("Broker.request: Type: component, Asset ID: #{request[:component_id]}, Options: #{request[:options].inspect}")
22
- @type = :asset
23
-
24
- @component_id = request[:component_id]
25
- raise Errors::InvalidAssetId.new("No Asset ID specified") if @component_id.nil?
26
-
27
- @options = request[:options]
28
- @extension = request[:extension]
29
- @content_type = @@extension_mapping[@extension.to_sym] || @@extension_mapping[DEFAULT_EXTENSION]
30
- when "status"
31
- logger.info("Broker.request: Type: status")
32
- @type = :status
33
- else
34
- logger.info("Broker.request: Type: notfound")
35
- @type = :notfound
36
- end
37
- end
38
-
39
- private
40
-
41
- def request_components(path, query_string)
42
- request_parts = path.split('/')
43
- extension = path.split('.')[1] ? path.split('.')[1].to_sym : DEFAULT_EXTENSION
44
- {
45
- :type => request_parts[1],
46
- :component_id => (request_parts[2] || '').split('.')[0],
47
- :extension => extension,
48
- :options => options_from(query_string)
49
- }
16
+ def initialize(request_type)
17
+ logger.info("Broker.request: Type: #{request_type}")
18
+ @type = request_type
50
19
  end
51
20
 
52
21
  def options_from(query_string)
@@ -55,6 +24,18 @@ module Alephant
55
24
  object.tap { |o| o.store(key.to_sym, value) }
56
25
  end
57
26
  end
27
+
28
+ def get_type_from(request_parts)
29
+ request_parts[1]
30
+ end
31
+
32
+ def get_extension_for(path)
33
+ path.split('.')[1] ? path.split('.')[1].to_sym : DEFAULT_EXTENSION
34
+ end
35
+
36
+ def get_component_id_from(request_parts)
37
+ (request_parts[2] || '').split('.')[0]
38
+ end
58
39
  end
59
40
  end
60
41
  end
@@ -0,0 +1,11 @@
1
+ require 'alephant/broker/models/request'
2
+
3
+ module Alephant
4
+ module Broker
5
+ class ErrorRequest < Request
6
+ def initialize
7
+ super(:error)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,38 @@
1
+ require 'alephant/broker/errors/invalid_asset_id'
2
+ require 'alephant/broker/models/request'
3
+
4
+ module Alephant
5
+ module Broker
6
+ class GetRequest < Request
7
+ attr_reader :type, :component_id, :extension, :options, :content_type
8
+
9
+ def initialize
10
+ env = RequestStore.store[:env]
11
+ parse requested_components(env.path, env.query)
12
+ super(:asset)
13
+ end
14
+
15
+ def requested_components(path, query_string)
16
+ request_parts = path.split('/')
17
+
18
+ {
19
+ :type => get_type_from(request_parts),
20
+ :component_id => get_component_id_from(request_parts),
21
+ :extension => get_extension_for(path),
22
+ :options => options_from(query_string)
23
+ }
24
+ end
25
+
26
+ def parse(request)
27
+ @component_id = request[:component_id]
28
+ @extension = request[:extension]
29
+ @options = request[:options]
30
+ @content_type = @@extension_mapping[@extension.to_sym] || @@extension_mapping[DEFAULT_EXTENSION]
31
+
32
+ logger.info("Broker.request: Type: #{@type}, Asset ID: #{@component_id}, Options: #{@options.inspect}")
33
+
34
+ raise InvalidAssetId.new("No Asset ID specified") if @component_id.nil?
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ require 'alephant/broker/models/request'
2
+
3
+ module Alephant
4
+ module Broker
5
+ class NotFoundRequest < Request
6
+ def initialize
7
+ super(:notfound)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ require 'alephant/broker/models/request'
2
+
3
+ module Alephant
4
+ module Broker
5
+ class PostRequest < Request
6
+ attr_reader :type, :component_id, :options, :content_type
7
+
8
+ def initialize
9
+ @env = RequestStore.store[:env]
10
+ @content_type = 'application/json'
11
+ super(:batch)
12
+ end
13
+
14
+ def components
15
+ @requested_components ||= components_for @env.path
16
+ end
17
+
18
+ def set_component(id, options)
19
+ @component_id = id
20
+ @options = options
21
+ end
22
+
23
+ private
24
+
25
+ def components_for(path)
26
+ request_parts = path.split('/')
27
+
28
+ {
29
+ :batch_id => batch_id,
30
+ :type => get_type_from(request_parts),
31
+ :component_id => get_component_id_from(request_parts)
32
+ }.merge! batched
33
+ end
34
+
35
+ def batch_id
36
+ @env.data['batch_id']
37
+ end
38
+
39
+ def batched
40
+ @env.data['components'].reduce({ :components => [] }) do |obj, component|
41
+ obj.tap { |o| o[:components].push(component) }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,11 @@
1
+ require 'alephant/broker/models/request'
2
+
3
+ module Alephant
4
+ module Broker
5
+ class StatusRequest < Request
6
+ def initialize
7
+ super(:status)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ require 'alephant/broker/models/request/error_request.rb'
2
+ require 'alephant/broker/models/request/get_request.rb'
3
+ require 'alephant/broker/models/request/notfound_request.rb'
4
+ require 'alephant/broker/models/request/post_request.rb'
5
+ require 'alephant/broker/models/request/status_request.rb'
6
+
7
+ module Alephant
8
+ module Broker
9
+ class RequestFactory
10
+ def self.process(type)
11
+ case type
12
+ when :component
13
+ GetRequest.new
14
+ when :component_batch
15
+ PostRequest.new
16
+ when :status
17
+ StatusRequest.new
18
+ when :notfound
19
+ NotFoundRequest.new
20
+ when :error
21
+ ErrorRequest.new
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,4 +1,4 @@
1
- require 'alephant/broker/models/request'
1
+ require 'alephant/broker/models/request_factory'
2
2
  require 'alephant/broker/models/response_factory'
3
3
 
4
4
  module Alephant
@@ -7,18 +7,41 @@ module Alephant
7
7
  include Logger
8
8
 
9
9
  def initialize(config)
10
+ @env = RequestStore.store[:env]
11
+ @request = RequestFactory.process(request_type)
10
12
  @response_factory = ResponseFactory.new(config)
11
13
  end
12
14
 
13
- def process(request)
15
+ def process
14
16
  begin
15
- @response_factory.response_from(request)
17
+ @response_factory.response_from(@request)
16
18
  rescue Exception => e
17
19
  logger.info("Broker.requestHandler.process: Exception raised (#{e.message})")
18
20
  @response_factory.response(500)
19
21
  end
20
22
  end
21
23
 
24
+ private
25
+
26
+ def request_type
27
+ case @env.path.split('/')[1]
28
+ when 'components'
29
+ component_type
30
+ when 'status'
31
+ :status
32
+ else
33
+ :notfound
34
+ end
35
+ end
36
+
37
+ def component_type
38
+ case @env.method
39
+ when 'POST'
40
+ :component_batch
41
+ when 'GET'
42
+ :component
43
+ end
44
+ end
22
45
  end
23
46
  end
24
47
  end
@@ -25,7 +25,6 @@ module Alephant
25
25
  rescue Exception => e
26
26
  set_error_for(e, 500)
27
27
  end
28
-
29
28
  end
30
29
 
31
30
  private
@@ -39,9 +38,6 @@ module Alephant
39
38
  def cache_id
40
39
  @lookup.read(request.options).tap { |cache_id| raise InvalidCacheKey if cache_id.nil? }
41
40
  end
42
-
43
41
  end
44
42
  end
45
43
  end
46
-
47
-
@@ -0,0 +1,58 @@
1
+ require 'alephant/logger'
2
+
3
+ module Alephant
4
+ module Broker
5
+ class BatchResponse
6
+ include Logger
7
+ attr_reader :status, :content_type, :content
8
+
9
+ def initialize(request, config)
10
+ @request = request
11
+ @config = config
12
+ @status = 200
13
+ @content_type = request.content_type
14
+ end
15
+
16
+ def process
17
+ @content = JSON.generate({ "batch_id" => batch_id, "components" => json })
18
+ self
19
+ end
20
+
21
+ private
22
+
23
+ def json
24
+ get_components.each do |component|
25
+ id = component['component']
26
+ options = set_keys_to_symbols component.fetch('options', {})
27
+
28
+ @request.set_component(id, options)
29
+
30
+ asset = AssetResponse.new(@request, @config)
31
+ component.store('status', asset.status)
32
+ component.store('body', asset.content) if valid_status_for asset
33
+ end
34
+ end
35
+
36
+ def set_keys_to_symbols(hash)
37
+ Hash[hash.map { |k,v| [k.to_sym, v] }]
38
+ end
39
+
40
+ def batch_id
41
+ @request.components.fetch(:batch_id)
42
+ end
43
+
44
+ def get_components
45
+ @request.components.fetch(:components) do |key|
46
+ logger.info("Broker::BatchResponse.process: Received request object but no valid key was found")
47
+ []
48
+ end
49
+ end
50
+
51
+ def valid_status_for(asset)
52
+ asset.status == 200
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+
@@ -1,5 +1,6 @@
1
1
  require 'alephant/broker/models/response'
2
2
  require 'alephant/broker/models/response/asset_response'
3
+ require 'alephant/broker/models/response/batch_response'
3
4
 
4
5
  module Alephant
5
6
  module Broker
@@ -13,6 +14,8 @@ module Alephant
13
14
  case request.type
14
15
  when :asset
15
16
  AssetResponse.new(request, @config)
17
+ when :batch
18
+ BatchResponse.new(request, @config).process
16
19
  when :status
17
20
  response(200)
18
21
  when :notfound
@@ -1,5 +1,5 @@
1
1
  module Alephant
2
2
  module Broker
3
- VERSION = "0.0.3"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -1,21 +1,42 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Alephant::Broker::AssetResponse do
4
-
5
4
  describe "#initialize(request, config)" do
6
- let(:config) { { :lookup_table_name => 'test_table', :bucket_id => 'test_bucket', :path => 'test_path' } }
7
- let(:request) { double("Alephant::Broker::Request", :component_id => 'test', :content_type => 'text/html', :options => {:variant => 'test_variant'} ) }
8
5
  let(:location) { 'test_location' }
6
+ let(:config) {{
7
+ :lookup_table_name => 'test_table',
8
+ :bucket_id => 'test_bucket',
9
+ :path => 'test_path'
10
+ }}
11
+ let(:request) { double(
12
+ "Alephant::Broker::Request",
13
+ :component_id => 'test',
14
+ :content_type => 'text/html',
15
+ :options => { :variant => 'test_variant' }
16
+ )
17
+ }
9
18
 
10
- before {
19
+ before do
11
20
  @lookup_table = double('Alephant::Lookup::LookupTable')
12
21
  Alephant::Lookup.stub(:create).and_return(@lookup_table)
13
- }
22
+ end
14
23
 
15
24
  it "Should return the content from a successful cache lookup" do
16
- allow(@lookup_table).to receive(:read).with(request.options).and_return(location)
17
- Alephant::Cache.any_instance.stub(:initialize)
18
- Alephant::Cache.any_instance.stub(:get).with(location).and_return('Test cache content')
25
+ allow(@lookup_table)
26
+ .to receive(:read)
27
+ .with(request.options)
28
+ .and_return(location)
29
+
30
+ Alephant::Cache
31
+ .any_instance
32
+ .stub(:initialize)
33
+
34
+ Alephant::Cache
35
+ .any_instance
36
+ .stub(:get)
37
+ .with(location)
38
+ .and_return('Test cache content')
39
+
19
40
  instance = Alephant::Broker::AssetResponse.new(request, config)
20
41
 
21
42
  expect(instance.content).to eq('Test cache content')
@@ -23,8 +44,15 @@ describe Alephant::Broker::AssetResponse do
23
44
  end
24
45
 
25
46
  it "should return a 404 if lookup can't find a valid location" do
26
- allow(@lookup_table).to receive(:read).with(request.options).and_return(nil)
27
- Alephant::Cache.any_instance.stub(:initialize)
47
+ allow(@lookup_table)
48
+ .to receive(:read)
49
+ .with(request.options)
50
+ .and_return(nil)
51
+
52
+ Alephant::Cache
53
+ .any_instance
54
+ .stub(:initialize)
55
+
28
56
  instance = Alephant::Broker::AssetResponse.new(request, config)
29
57
 
30
58
  expect(instance.content).to eq('Cache key not found based on component_id and options combination')
@@ -32,15 +60,17 @@ describe Alephant::Broker::AssetResponse do
32
60
  end
33
61
 
34
62
  it "should return a 500 for any other exceptions" do
35
- allow(@lookup_table).to receive(:read).with(request.options).and_raise(Exception)
63
+ allow(@lookup_table)
64
+ .to receive(:read)
65
+ .with(request.options)
66
+ .and_raise(Exception)
67
+
36
68
  instance = Alephant::Broker::AssetResponse.new(request, config)
37
69
 
38
70
  expect(instance.status).to eq(500)
39
-
40
71
  end
41
-
42
72
  end
43
-
44
73
  end
45
74
 
46
75
 
76
+
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe Alephant::Broker::BatchResponse do
4
+ let (:config) {{
5
+ :lookup_table_name => 'test_table',
6
+ :bucket_id => 'test_bucket',
7
+ :path => 'test_path'
8
+ }}
9
+
10
+ let (:post_request) {
11
+ double(
12
+ 'Alephant::Broker::PostRequest',
13
+ :options => {},
14
+ :type => :batch,
15
+ :content_type => 'application/json',
16
+ :set_component => nil,
17
+ :component_id => nil,
18
+ :components => {
19
+ :batch_id => :baz,
20
+ :components => [
21
+ { 'component' => 'foo1', 'options' => { 'variant' => 'bar1' } },
22
+ { 'component' => 'foo2', 'options' => { 'variant' => 'bar2' } }
23
+ ]}
24
+ )
25
+ }
26
+
27
+ before do
28
+ @lookup_table = double('Alephant::Lookup::LookupTable', :read => 'test_location')
29
+
30
+ Alephant::Lookup
31
+ .stub(:create)
32
+ .and_return(@lookup_table)
33
+
34
+ Alephant::Cache
35
+ .any_instance
36
+ .stub(:initialize)
37
+
38
+ Alephant::Cache
39
+ .any_instance
40
+ .stub(:get)
41
+ .and_return('Test response')
42
+ end
43
+
44
+ describe "#process" do
45
+ context "if a component is unrecognised" do
46
+ before(:each) do
47
+ Alephant::Cache
48
+ .any_instance
49
+ .stub(:get)
50
+ .and_raise(Alephant::Broker::InvalidCacheKey)
51
+
52
+ instance = Alephant::Broker::BatchResponse.new(post_request, config)
53
+ json = JSON.parse(instance.process.content)
54
+ @bad_component = json.fetch('components')[1]
55
+ end
56
+
57
+ it "set status to 404" do
58
+ expect(@bad_component['status']).to eq(404)
59
+ end
60
+
61
+ it "remove 'body' key" do
62
+ expect(@bad_component['body']).to eq(nil)
63
+ end
64
+ end
65
+
66
+ context "if a component is recognised" do
67
+ before(:each) do
68
+ @instance = Alephant::Broker::BatchResponse.new(post_request, config)
69
+ @content = @instance.process.content
70
+ @json = JSON.parse(@content)
71
+ end
72
+
73
+ it "set status to 200" do
74
+ @json.fetch('components').each do |component|
75
+ expect(component['status']).to eq(200)
76
+ end
77
+ end
78
+
79
+ it "set @content to be JSON string containing retrieved components" do
80
+ compiled_json = '{"batch_id":"baz","components":[{"component":"foo1","options":{"variant":"bar1"},"status":200,"body":"Test response"},{"component":"foo2","options":{"variant":"bar2"},"status":200,"body":"Test response"}]}'
81
+ expect(@content).to eq(compiled_json)
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe Alephant::Broker::GetRequest do
4
+ subject { Alephant::Broker::GetRequest }
5
+
6
+ before(:each) do
7
+ subject.any_instance.stub(:initialize)
8
+ end
9
+
10
+ describe "#requested_components" do
11
+ it "returns hash of component parts" do
12
+ result = subject.new.requested_components('/foo/bar', 'baz=qux')
13
+ hash = {
14
+ :type => "foo",
15
+ :component_id => "bar",
16
+ :extension => :html,
17
+ :options => { :baz => "qux" }
18
+ }
19
+
20
+ expect(result).to eq(hash)
21
+ end
22
+ end
23
+
24
+ describe "#parse" do
25
+ context "when component_id is nil" do
26
+ it "raise error" do
27
+ expect {
28
+ subject.new.parse :extension => :foobar
29
+ }.to raise_exception
30
+ end
31
+ end
32
+
33
+ context "when component_id is not nil" do
34
+ it "sets values for attr_reader's" do
35
+ request = {
36
+ :component_id => 'foo',
37
+ :extension => 'bar',
38
+ :options => 'baz'
39
+ }
40
+
41
+ instance = subject.new
42
+ instance.parse(request)
43
+
44
+ expect(instance.component_id).to eq('foo')
45
+ expect(instance.extension).to eq('bar')
46
+ expect(instance.options).to eq('baz')
47
+ end
48
+
49
+ context "and extension is recognised" do
50
+ it "sets appropriate value for instance attribute" do
51
+ request = { :extension => 'json', :component_id => 'foo' }
52
+
53
+ instance = subject.new
54
+ instance.parse(request)
55
+
56
+ expect(instance.content_type).to eq('application/json')
57
+ end
58
+ end
59
+
60
+ context "and extension is not recognised" do
61
+ it "sets default value for instance attribute" do
62
+ request = { :extension => 'foobar', :component_id => 'foo' }
63
+
64
+ instance = subject.new
65
+ instance.parse(request)
66
+
67
+ expect(instance.content_type).to eq('text/html')
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Alephant::Broker::PostRequest do
4
+ subject { Alephant::Broker::PostRequest }
5
+
6
+ describe "#components" do
7
+ it "returns hash of component parts + sub components" do
8
+ components = [{
9
+ "component" => "qux",
10
+ "options" => { "variant" => "cor" }
11
+ }]
12
+
13
+ env = (Struct.new(:path, :data)).new("/foo/bar", {
14
+ 'batch_id' => :foobar,
15
+ 'components' => components
16
+ })
17
+
18
+ hash = {
19
+ :batch_id => :foobar,
20
+ :type => "foo",
21
+ :component_id => "bar",
22
+ :components => components
23
+ }
24
+
25
+ RequestStore
26
+ .stub(:store)
27
+ .and_return({
28
+ :env => env
29
+ })
30
+
31
+ instance = subject.new
32
+ expect(instance.components).to eq(hash)
33
+ end
34
+ end
35
+
36
+ describe "#set_component(id, options)" do
37
+ it "sets instance attribute values" do
38
+ subject
39
+ .any_instance
40
+ .stub(:initialize)
41
+
42
+ instance = subject.new
43
+ instance.set_component(:foo, :bar)
44
+
45
+ expect(instance.component_id).to eq(:foo)
46
+ expect(instance.options).to eq(:bar)
47
+ end
48
+ end
49
+ end
@@ -2,20 +2,22 @@ ENV['RACK_ENV'] = 'test'
2
2
 
3
3
  require 'rack/test'
4
4
  require 'alephant/broker/app/rack'
5
+ require 'request_store'
5
6
 
6
7
  RSpec.configure do |conf|
7
8
  conf.include Rack::Test::Methods
8
9
  end
9
10
 
10
- describe 'Broker rack app tests' do
11
+ describe 'Broker Rack Application' do
12
+ before do
13
+ RequestStore.store[:env] = nil
11
14
 
12
- before {
13
15
  @lookup_table = double('Alephant::Lookup::LookupTable')
14
16
  Alephant::Lookup.stub(:create).and_return(@lookup_table)
15
17
 
16
18
  Alephant::Cache.any_instance.stub(:initialize)
17
19
  Alephant::Cache.any_instance.stub(:get).and_return('Test response')
18
- }
20
+ end
19
21
 
20
22
  def app
21
23
  Alephant::Broker::RackApplication.new({
@@ -25,7 +27,7 @@ describe 'Broker rack app tests' do
25
27
  })
26
28
  end
27
29
 
28
- it "Tests status page" do
30
+ it 'Tests status page' do
29
31
  get '/status'
30
32
  expect(last_response).to be_ok
31
33
  expect(last_response.body).to eq('ok')
@@ -40,7 +42,7 @@ describe 'Broker rack app tests' do
40
42
  it "Test asset data is returned" do
41
43
  allow(@lookup_table).to receive(:read).and_return('some_location')
42
44
 
43
- get '/component/test_component'
45
+ get '/components/test_component'
44
46
  expect(last_response).to be_ok
45
47
  expect(last_response.body).to eq('Test response')
46
48
  end
@@ -49,7 +51,7 @@ describe 'Broker rack app tests' do
49
51
  variant = {:variant => 'test_variant'}
50
52
  allow(@lookup_table).to receive(:read).with(variant).and_return('some_location')
51
53
 
52
- get '/component/test_component?variant=test_variant'
54
+ get '/components/test_component?variant=test_variant'
53
55
  expect(last_response).to be_ok
54
56
  expect(last_response.body).to eq('Test response')
55
57
  end
@@ -57,16 +59,26 @@ describe 'Broker rack app tests' do
57
59
  it "Tests 404 when lookup doesn't return a valid location" do
58
60
  allow(@lookup_table).to receive(:read).and_return(nil)
59
61
 
60
- get '/component/test_component'
62
+ get '/components/test_component'
61
63
  expect(last_response.status).to eq(404)
62
-
63
64
  end
64
65
 
65
66
  it "Tests 500 when exception is raised in application" do
66
67
  allow(@lookup_table).to receive(:read).and_raise(Exception)
67
68
 
68
- get '/component/test_component'
69
+ get '/components/test_component'
69
70
  expect(last_response.status).to eq(500)
70
71
  end
71
72
 
73
+ it "Test batch asset data is returned" do
74
+ allow(@lookup_table).to receive(:read).and_return('some_location')
75
+
76
+ json = '{"batch_id":"baz","components":[{"component":"ni_council_results_table"},{"component":"ni_council_results_table"}]}'
77
+ compiled_json = '{"batch_id":"baz","components":[{"component":"ni_council_results_table","status":200,"body":"Test response"},{"component":"ni_council_results_table","status":200,"body":"Test response"}]}'
78
+
79
+ post '/components/batch', json, "CONTENT_TYPE" => "application/json"
80
+
81
+ expect(last_response).to be_ok
82
+ expect(last_response.body).to eq(compiled_json)
83
+ end
72
84
  end
@@ -1,35 +1,61 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Alephant::Broker::ResponseFactory do
4
-
5
4
  describe "#response_from(request)" do
6
5
  let (:request) { double("Alephant::Broker::Request") }
6
+ let (:post_request) { double("Alephant::Broker::PostRequest") }
7
7
 
8
- it "should return as asset response" do
8
+ it "should return asset response" do
9
9
  instance = Alephant::Broker::ResponseFactory.new({})
10
10
  allow(request).to receive(:type).and_return(:asset)
11
11
 
12
- Alephant::Broker::AssetResponse.any_instance.stub(:initialize).with(request, {})
13
- expect(instance.response_from(request)).to be_a Alephant::Broker::AssetResponse
12
+ Alephant::Broker::AssetResponse
13
+ .any_instance
14
+ .stub(:initialize)
15
+ .with(request, {})
16
+
17
+ expect(instance.response_from(request))
18
+ .to be_a Alephant::Broker::AssetResponse
19
+ end
20
+
21
+ it "should return batched response" do
22
+ instance = Alephant::Broker::ResponseFactory.new({})
23
+ allow(post_request).to receive(:type).and_return(:batch)
24
+ allow(post_request).to receive(:content_type).and_return('application/json')
25
+ allow(post_request).to receive(:set_component)
26
+ allow(post_request).to receive(:components).and_return({
27
+ :batch_id => 'baz',
28
+ :components => [
29
+ { 'component' => 'foo1', 'variant' => 'bar1' },
30
+ { 'component' => 'foo2', 'variant' => 'bar2' }
31
+ ]
32
+ })
33
+
34
+ Alephant::Broker::AssetResponse
35
+ .any_instance
36
+ .stub(:initialize)
37
+ .with(post_request, {})
38
+
39
+ expect(instance.response_from(post_request))
40
+ .to be_a Alephant::Broker::BatchResponse
14
41
  end
15
42
 
16
- it "should return a status response" do
43
+ it "should return status response" do
17
44
  allow(request).to receive(:type).and_return(:status)
18
45
  response = subject.response_from(request)
19
46
  expect(response.status).to eq(200)
20
47
  end
21
48
 
22
- it "should return a 404 response" do
49
+ it "should return 404 response" do
23
50
  allow(request).to receive(:type).and_return(:notfound)
24
51
  response = subject.response_from(request)
25
52
  expect(response.status).to eq(404)
26
53
  end
27
54
 
28
- it "should return a 500 response" do
55
+ it "should return 500 response" do
29
56
  allow(request).to receive(:type).and_return(:error)
30
57
  response = subject.response_from(request)
31
58
  expect(response.status).to eq(500)
32
59
  end
33
-
34
60
  end
35
61
  end
@@ -1,5 +1,5 @@
1
- $: << File.join(File.dirname(__FILE__),"..", "lib")
1
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
2
2
 
3
+ require 'pry'
3
4
  require 'alephant/broker'
4
-
5
-
5
+ require 'request_store'
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: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Jack
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-24 00:00:00.000000000 Z
11
+ date: 2014-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -150,6 +150,20 @@ dependencies:
150
150
  version: '0'
151
151
  prerelease: false
152
152
  type: :development
153
+ - !ruby/object:Gem::Dependency
154
+ name: request_store
155
+ version_requirements: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ requirement: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ prerelease: false
166
+ type: :development
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: alephant-lookup
155
169
  version_requirements: !ruby/object:Gem::Requirement
@@ -211,16 +225,27 @@ files:
211
225
  - lib/alephant/broker.rb
212
226
  - lib/alephant/broker/app.rb
213
227
  - lib/alephant/broker/app/rack.rb
228
+ - lib/alephant/broker/call_environment.rb
229
+ - lib/alephant/broker/errors/invalid_asset_id.rb
214
230
  - lib/alephant/broker/errors/invalid_cache_key.rb
215
231
  - lib/alephant/broker/models/request.rb
232
+ - lib/alephant/broker/models/request/error_request.rb
233
+ - lib/alephant/broker/models/request/get_request.rb
234
+ - lib/alephant/broker/models/request/notfound_request.rb
235
+ - lib/alephant/broker/models/request/post_request.rb
236
+ - lib/alephant/broker/models/request/status_request.rb
237
+ - lib/alephant/broker/models/request_factory.rb
216
238
  - lib/alephant/broker/models/request_handler.rb
217
239
  - lib/alephant/broker/models/response.rb
218
240
  - lib/alephant/broker/models/response/asset_response.rb
241
+ - lib/alephant/broker/models/response/batch_response.rb
219
242
  - lib/alephant/broker/models/response_factory.rb
220
243
  - lib/alephant/broker/version.rb
221
244
  - spec/asset_response_spec.rb
245
+ - spec/batch_response_spec.rb
246
+ - spec/get_request_spec.rb
247
+ - spec/post_request_spec.rb
222
248
  - spec/rack_spec.rb
223
- - spec/request_spec.rb
224
249
  - spec/response_factory_spec.rb
225
250
  - spec/spec_helper.rb
226
251
  homepage: https://github.com/BBC-News/alephant-broker
@@ -249,7 +274,10 @@ specification_version: 4
249
274
  summary: Brokers requests for alephant components
250
275
  test_files:
251
276
  - spec/asset_response_spec.rb
277
+ - spec/batch_response_spec.rb
278
+ - spec/get_request_spec.rb
279
+ - spec/post_request_spec.rb
252
280
  - spec/rack_spec.rb
253
- - spec/request_spec.rb
254
281
  - spec/response_factory_spec.rb
255
282
  - spec/spec_helper.rb
283
+ has_rdoc:
@@ -1,51 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Alephant::Broker::Request do
4
-
5
- describe "#initialize(path, querystring)" do
6
- let(:component_id) { 'foo' }
7
- let(:querystring) { 'variant=test' }
8
-
9
-
10
- it "Sets the component id" do
11
-
12
- instance = Alephant::Broker::Request.new("/component/#{component_id}", '')
13
- expect(instance.component_id).to eq(component_id)
14
- end
15
-
16
- it "Sets the request type to asset" do
17
-
18
- instance = Alephant::Broker::Request.new("/component/#{component_id}", '')
19
- expect(instance.type).to eq(:asset)
20
- expect(instance.options).to eq({})
21
- end
22
-
23
- it "Sets the request type to asset with parsed options" do
24
- instance = Alephant::Broker::Request.new("/component/#{component_id}", querystring)
25
- expect(instance.type).to eq(:asset)
26
- expect(instance.options).to eq({ :variant => 'test' })
27
-
28
- end
29
-
30
- it "Sets the request type to status" do
31
- instance = Alephant::Broker::Request.new("/status", '')
32
- expect(instance.type).to eq(:status)
33
- end
34
-
35
- it "Sets the default extension" do
36
- instance = Alephant::Broker::Request.new("/component/blah", '')
37
- expect(instance.extension).to eq(:html)
38
- end
39
-
40
- it "Sets the extension from the path" do
41
- instance = Alephant::Broker::Request.new("/component/blah.json", '')
42
- expect(instance.extension).to eq(:json)
43
- end
44
-
45
- it "Sets the content type to default if the extension does not exist" do
46
- instance = Alephant::Broker::Request.new("/component/blah.test", '')
47
- expect(instance.content_type).to eq('text/html')
48
- end
49
-
50
- end
51
- end