flying-sphinx 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ class FlyingSphinx::Request::HMAC < Faraday::Middleware
2
+ def initialize(app, identifier, api_key, service)
3
+ super app
4
+
5
+ @identifier = identifier
6
+ @api_key = api_key
7
+ @service = service
8
+ end
9
+
10
+ def call(environment)
11
+ Ey::Hmac.sign! environment, identifier, api_key,
12
+ :adapter => Ey::Hmac::Adapter::Faraday, :service => service
13
+
14
+ app.call environment
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :app, :identifier, :api_key, :service
20
+ end
@@ -1,5 +1,7 @@
1
1
  class FlyingSphinx::Response::JSON < Faraday::Response::Middleware
2
2
  def on_complete(environment)
3
+ return if environment[:request_headers]['Authorization'].nil?
4
+
3
5
  environment[:body] = MultiJson.load environment[:body]
4
6
  end
5
7
  end
@@ -10,7 +10,7 @@ class FlyingSphinx::SettingFiles
10
10
  hash = {}
11
11
 
12
12
  each_file_for_setting do |setting, file|
13
- hash["#{setting}:#{File.basename(file)}"] = File.read(file)
13
+ hash["#{setting}/#{File.basename(file)}"] = File.read(file)
14
14
  end
15
15
 
16
16
  hash['extra'] = hash.keys.join(';')
@@ -1,3 +1,3 @@
1
1
  module FlyingSphinx
2
- Version = '1.2.1'
2
+ Version = '1.3.0'
3
3
  end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'cgi'
3
+
4
+ describe 'Configuring Sphinx' do
5
+ let(:cli) { FlyingSphinx::CLI.new 'configure' }
6
+ let(:translator) { double 'Translator', :sphinx_indices => [index],
7
+ :sphinx_configuration => 'searchd { }' }
8
+ let(:index) { double 'Index' }
9
+
10
+ before :each do
11
+ allow(FlyingSphinx).to receive(:translator).and_return(translator)
12
+
13
+ stub_hmac_request(:post, 'https://flying-sphinx.com/api/my/v5/perform').
14
+ to_return(:body => '{"id":953, "status":"OK"}')
15
+ stub_hmac_request(:get, "https://flying-sphinx.com/api/my/v5/presignature").
16
+ to_return(
17
+ :body => '{"url":"https://foo","path":"bar","fields":{},"status":"OK"}'
18
+ )
19
+ stub_request(:post, "https://foo/").to_return(:status => 200)
20
+ end
21
+
22
+ it 'sends the configuration to the server' do
23
+ SuccessfulAction.new(953).matches? lambda { cli.run }
24
+
25
+ expect(
26
+ a_hmac_request(:post, 'https://flying-sphinx.com/api/my/v5/perform').
27
+ with { |request| CGI::parse(request.body)["action"] == ["configure"] }
28
+ ).to have_been_made
29
+ end
30
+
31
+ it 'handles the full request successfully' do
32
+ expect { cli.run }.to be_successful_with 953
33
+ end
34
+ end
@@ -4,10 +4,11 @@ describe 'Requesting customer information' do
4
4
  let(:configuration) { FlyingSphinx::Configuration.new 'foo', 'bar' }
5
5
 
6
6
  before :each do
7
- stub_request(:get, 'https://flying-sphinx.com/api/my/app').to_return(
8
- :status => 200,
9
- :body => '{"server":"my.sphinx.server","port":9307}'
10
- )
7
+ stub_hmac_request(:get, 'https://flying-sphinx.com/api/my/v5/app').
8
+ to_return(
9
+ :status => 200,
10
+ :body => '{"server":"my.sphinx.server","port":9307}'
11
+ )
11
12
  end
12
13
 
13
14
  it { expect(configuration.host).to eq('my.sphinx.server') }
@@ -4,12 +4,17 @@ describe 'Starting Sphinx' do
4
4
  let(:cli) { FlyingSphinx::CLI.new 'start' }
5
5
 
6
6
  before :each do
7
- stub_request(:post, 'https://flying-sphinx.com/api/my/app/start').
7
+ stub_hmac_request(:post, 'https://flying-sphinx.com/api/my/v5/perform').
8
8
  to_return(:status => 200, :body => '{"id":429, "status":"OK"}')
9
9
  end
10
10
 
11
11
  it 'makes the request to the server', :retry => 3 do
12
12
  expect { cli.run }.to be_successful_with 429
13
+
14
+ expect(
15
+ a_hmac_request(:post, 'https://flying-sphinx.com/api/my/v5/perform').
16
+ with(:body => {:action => 'start'})
17
+ ).to have_been_made
13
18
  end
14
19
  end
15
20
 
@@ -17,11 +22,16 @@ describe 'Stopping Sphinx', :retry => 3 do
17
22
  let(:cli) { FlyingSphinx::CLI.new 'stop' }
18
23
 
19
24
  before :each do
20
- stub_request(:post, 'https://flying-sphinx.com/api/my/app/stop').
25
+ stub_request(:post, 'https://flying-sphinx.com/api/my/v5/perform').
21
26
  to_return(:status => 200, :body => '{"id":537, "status":"OK"}')
22
27
  end
23
28
 
24
29
  it 'makes the request to the server', :retry => 3 do
25
30
  expect { cli.run }.to be_successful_with 537
31
+
32
+ expect(
33
+ a_hmac_request(:post, 'https://flying-sphinx.com/api/my/v5/perform').
34
+ with(:body => {:action => 'stop'})
35
+ ).to have_been_made
26
36
  end
27
37
  end
@@ -6,7 +6,7 @@ describe FlyingSphinx::Action do
6
6
  let(:socket) { double 'socket', :connect => true, :disconnect => true,
7
7
  :subscribe => true, :[] => channel, :connected => true }
8
8
  let(:channel) { double 'channel', :bind => true }
9
- let(:response) { double :body => {'status' => 'OK', 'id' => 748} }
9
+ let(:response) { {'status' => 'OK', 'id' => 748} }
10
10
  let(:logger) { double 'logger', :debug => true }
11
11
 
12
12
  before :each do
@@ -18,8 +18,6 @@ describe FlyingSphinx::API do
18
18
  it "sets up a connection with the appropriate headers" do
19
19
  faraday.should_receive(:new) do |options|
20
20
  options[:headers].should == {
21
- 'Accept' => 'application/vnd.flying-sphinx-v4+json',
22
- 'X-Flying-Sphinx-Token' => 'foo:bar',
23
21
  'X-Flying-Sphinx-Version' => FlyingSphinx::Version
24
22
  }
25
23
 
@@ -52,7 +50,7 @@ describe FlyingSphinx::API do
52
50
 
53
51
  it "sends the GET request with the given path and data" do
54
52
  request.should_receive(:url).
55
- with('/api/my/app/resource', 'param' => 'value')
53
+ with('/api/my/v5/resource', 'param' => 'value')
56
54
 
57
55
  send_request
58
56
  end
@@ -69,25 +67,7 @@ describe FlyingSphinx::API do
69
67
 
70
68
  it "sends the POST request with the given path and data" do
71
69
  connection.should_receive(:post).
72
- with('/api/my/app/resource', 'param' => 'value').
73
- and_return(response)
74
-
75
- send_request
76
- end
77
- end
78
-
79
- describe '#put' do
80
- let(:send_request) { api.put '/resource', 'param' => 'value' }
81
-
82
- before :each do
83
- connection.stub(:put => response)
84
- end
85
-
86
- it_should_behave_like 'an API call'
87
-
88
- it "sends the PUT request with the given path and data" do
89
- connection.should_receive(:put).
90
- with('/api/my/app/resource', 'param' => 'value').
70
+ with('/api/my/v5/resource', 'param' => 'value').
91
71
  and_return(response)
92
72
 
93
73
  send_request
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FlyingSphinx::Configuration do
4
- let(:api) { double 'FlyingSphinx::API', :get => double(:body => body) }
4
+ let(:api) { double 'FlyingSphinx::API', :get => body }
5
5
  let(:body) { {'server' => 'foo.bar.com', 'port' => 9319} }
6
6
  let(:api_key) { 'foo-bar-baz' }
7
7
  let(:identifier) { 'my-identifier' }
@@ -2,11 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  describe FlyingSphinx::Controller do
4
4
  let(:controller) { FlyingSphinx::Controller.new api }
5
- let(:api) { double 'API', :identifier => 'foo', :put => true }
5
+ let(:api) { double 'API', :identifier => 'foo', :put => true,
6
+ :get => {"path" => "/foo", "url" => "https://confserver", "status" => "OK"} }
6
7
  let(:action_class) { double }
7
8
  let(:configuration) { double 'TS Configuration' }
8
- let(:setting_files) { double :to_hash => {'extra' => 'wordforms:txt.txt',
9
- 'wordforms:txt.txt' => 'something'} }
9
+ let(:setting_files) { double :to_hash => {'extra' => 'wordforms/txt.txt',
10
+ 'wordforms/txt.txt' => 'something'} }
10
11
  let(:translator) { double :sphinx_configuration => 'indexer ...' }
11
12
 
12
13
  before :each do
@@ -20,38 +21,51 @@ describe FlyingSphinx::Controller do
20
21
 
21
22
  stub_const 'FlyingSphinx::SettingFiles', double(:new => setting_files)
22
23
  FlyingSphinx.stub :translator => translator
23
- end
24
24
 
25
- def ungzip(contents)
26
- io = StringIO.new contents, 'rb'
27
- reader = Zlib::GzipReader.new io
28
- reader.read
25
+ stub_request(:post, "https://confserver").to_return(:status => 200)
29
26
  end
30
27
 
31
28
  describe 'configure' do
32
29
  it 'sends data to the server' do
33
- api.should_receive(:put)
30
+ api.should_receive(:post)
34
31
 
35
32
  controller.configure
36
33
  end
37
34
 
38
- it 'sends through gzipped configuration files' do
39
- api.should_receive(:put) do |path, options|
40
- path.should == 'configure'
41
- options[:configuration]['gzip'].should == 'true'
42
- ungzip(options[:configuration]['sphinx'].read).should == 'indexer ...'
43
- ungzip(options[:configuration]['wordforms:txt.txt'].read).should == 'something'
44
- end
35
+ it 'sends through gzipped configuration archive' do
36
+ expect(api).to receive(:post).with '/perform',
37
+ :action => 'configure',
38
+ :path => '/foo'
45
39
 
46
40
  controller.configure
41
+
42
+ expect(
43
+ a_multipart_request(:post, 'https://confserver').
44
+ with_file { |contents|
45
+ reader = GZippedTar::Reader.new contents
46
+
47
+ reader.read("sphinx/raw.conf") == "indexer ..." &&
48
+ reader.read("sphinx/version.txt") == "2.2.3" &&
49
+ reader.read("wordforms/txt.txt") == "something"
50
+ }
51
+ ).to have_been_made
47
52
  end
48
53
 
49
54
  it 'sends through file if provided' do
50
- api.should_receive(:put).with 'configure',
51
- :configuration => {'sphinx' => 'searchd ...'},
52
- :sphinx_version => '2.0.6'
55
+ expect(api).to receive(:post).with '/perform',
56
+ :action => 'configure',
57
+ :path => '/foo'
53
58
 
54
59
  controller.configure 'searchd ...'
60
+
61
+ expect(
62
+ a_multipart_request(:post, 'https://confserver').
63
+ with_file { |contents|
64
+ reader = GZippedTar::Reader.new contents
65
+
66
+ reader.read("sphinx/raw.conf") == "searchd ..."
67
+ }
68
+ ).to have_been_made
55
69
  end
56
70
  end
57
71
  end
@@ -18,12 +18,12 @@ describe FlyingSphinx::SettingFiles do
18
18
  end
19
19
 
20
20
  [:stopwords, :wordforms, :exceptions].each do |setting|
21
- it "uploads #{setting} files from indices" do
21
+ it "collects #{setting} files from indices" do
22
22
  indices << index_double(setting => '/my/file/foo.txt')
23
23
 
24
24
  files.to_hash.should == {
25
- "#{setting}:foo.txt" => 'blah',
26
- 'extra' => "#{setting}:foo.txt"
25
+ "#{setting}/foo.txt" => 'blah',
26
+ 'extra' => "#{setting}/foo.txt"
27
27
  }
28
28
  end
29
29
 
@@ -32,8 +32,8 @@ describe FlyingSphinx::SettingFiles do
32
32
  indices << index_double(setting => '/my/file/foo.txt')
33
33
 
34
34
  files.to_hash.should == {
35
- "#{setting}:foo.txt" => 'blah',
36
- 'extra' => "#{setting}:foo.txt"
35
+ "#{setting}/foo.txt" => 'blah',
36
+ 'extra' => "#{setting}/foo.txt"
37
37
  }
38
38
  end
39
39
 
@@ -41,22 +41,22 @@ describe FlyingSphinx::SettingFiles do
41
41
  indices << index_double(
42
42
  setting => '/my/file/foo.txt /my/file/bar.txt')
43
43
 
44
- files.to_hash["#{setting}:foo.txt"].should == 'blah'
45
- files.to_hash["#{setting}:bar.txt"].should == 'blah'
44
+ files.to_hash["#{setting}/foo.txt"].should == 'blah'
45
+ files.to_hash["#{setting}/bar.txt"].should == 'blah'
46
46
  files.to_hash['extra'].split(';').should =~ [
47
- "#{setting}:foo.txt", "#{setting}:bar.txt"
47
+ "#{setting}/foo.txt", "#{setting}/bar.txt"
48
48
  ]
49
49
  end
50
50
  end
51
51
 
52
52
  [:mysql_ssl_cert, :mysql_ssl_key, :mysql_ssl_ca].each do |setting|
53
- it "uploads #{setting} files from indices" do
53
+ it "collects #{setting} files from sources" do
54
54
  indices << index_double(:sources => [
55
55
  source_double(setting => '/my/file/foo.txt')])
56
56
 
57
57
  files.to_hash.should == {
58
- "#{setting}:foo.txt" => 'blah',
59
- 'extra' => "#{setting}:foo.txt"
58
+ "#{setting}/foo.txt" => 'blah',
59
+ 'extra' => "#{setting}/foo.txt"
60
60
  }
61
61
  end
62
62
 
@@ -67,8 +67,8 @@ describe FlyingSphinx::SettingFiles do
67
67
  source_double(setting => '/my/file/foo.txt')])
68
68
 
69
69
  files.to_hash.should == {
70
- "#{setting}:foo.txt" => 'blah',
71
- 'extra' => "#{setting}:foo.txt"
70
+ "#{setting}/foo.txt" => 'blah',
71
+ 'extra' => "#{setting}/foo.txt"
72
72
  }
73
73
  end
74
74
 
@@ -76,10 +76,10 @@ describe FlyingSphinx::SettingFiles do
76
76
  indices << index_double(:sources => [
77
77
  source_double(setting => '/my/file/foo.txt /my/file/bar.txt')])
78
78
 
79
- files.to_hash["#{setting}:foo.txt"].should == 'blah'
80
- files.to_hash["#{setting}:bar.txt"].should == 'blah'
79
+ files.to_hash["#{setting}/foo.txt"].should == 'blah'
80
+ files.to_hash["#{setting}/bar.txt"].should == 'blah'
81
81
  files.to_hash['extra'].split(';').should =~ [
82
- "#{setting}:foo.txt", "#{setting}:bar.txt"
82
+ "#{setting}/foo.txt", "#{setting}/bar.txt"
83
83
  ]
84
84
  end
85
85
  end
@@ -4,6 +4,7 @@ require 'bundler'
4
4
  require 'dotenv'
5
5
  require 'webmock/rspec'
6
6
  require 'em-websocket'
7
+ require 'rack'
7
8
 
8
9
  Dotenv.load '.env.test'
9
10
  WebMock.disable_net_connect!
@@ -0,0 +1,23 @@
1
+ class HMACRequestPattern < WebMock::RequestPattern
2
+ def matches?(request_signature)
3
+ request_signature.headers['Authorization'].present? && super
4
+ end
5
+ end
6
+
7
+ module HMACHelpers
8
+ def stub_hmac_request(method, uri)
9
+ stub_request(method, uri).with { |request|
10
+ request.headers['Authorization'].present?
11
+ }
12
+ end
13
+
14
+ def a_hmac_request(method, uri)
15
+ HMACRequestPattern.new method, uri
16
+ end
17
+
18
+ private
19
+ end
20
+
21
+ RSpec.configure do |config|
22
+ config.include HMACHelpers
23
+ end
@@ -0,0 +1,56 @@
1
+ module MultipartHelpers
2
+ def a_multipart_request(method, uri)
3
+ MultipartRequestPattern.new method, uri
4
+ end
5
+ end
6
+
7
+ class MultipartRequestPattern < WebMock::RequestPattern
8
+ def with_file(&block)
9
+ with { |request| block.call MultipartRequestToFile.call(request) }
10
+ end
11
+ end
12
+
13
+ class MultipartRequestToFile
14
+ def self.call(request)
15
+ new(request).call
16
+ end
17
+
18
+ def initialize(request)
19
+ @request = request
20
+ end
21
+
22
+ def call
23
+ parsed["file"][:tempfile].read
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :request
29
+
30
+ def parsed
31
+ if Rack::Multipart.respond_to? :extract_multipart
32
+ Rack::Multipart.extract_multipart rack_request
33
+ else
34
+ Rack::Multipart.parse_multipart rack_env
35
+ end
36
+ end
37
+
38
+ def rack_env
39
+ transformed_headers.merge 'rack.input' => StringIO.new(request.body)
40
+ end
41
+
42
+ def rack_request
43
+ Rack::Request.new rack_env
44
+ end
45
+
46
+ def transformed_headers
47
+ request.headers.keys.inject({}) do |hash, key|
48
+ hash[key.underscore.upcase] = request.headers[key]
49
+ hash
50
+ end
51
+ end
52
+ end
53
+
54
+ RSpec.configure do |config|
55
+ config.include MultipartHelpers
56
+ end