stockboy 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +5 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile +12 -0
- data/Guardfile +10 -0
- data/LICENSE +21 -0
- data/README.md +293 -0
- data/Rakefile +30 -0
- data/lib/stockboy.rb +80 -0
- data/lib/stockboy/attribute.rb +11 -0
- data/lib/stockboy/attribute_map.rb +74 -0
- data/lib/stockboy/candidate_record.rb +130 -0
- data/lib/stockboy/configuration.rb +62 -0
- data/lib/stockboy/configurator.rb +176 -0
- data/lib/stockboy/dsl.rb +68 -0
- data/lib/stockboy/exceptions.rb +3 -0
- data/lib/stockboy/filter.rb +58 -0
- data/lib/stockboy/filter_chain.rb +41 -0
- data/lib/stockboy/filters.rb +11 -0
- data/lib/stockboy/filters/missing_email.rb +37 -0
- data/lib/stockboy/job.rb +241 -0
- data/lib/stockboy/mapped_record.rb +59 -0
- data/lib/stockboy/provider.rb +238 -0
- data/lib/stockboy/providers.rb +11 -0
- data/lib/stockboy/providers/file.rb +135 -0
- data/lib/stockboy/providers/ftp.rb +205 -0
- data/lib/stockboy/providers/http.rb +123 -0
- data/lib/stockboy/providers/imap.rb +290 -0
- data/lib/stockboy/providers/soap.rb +120 -0
- data/lib/stockboy/railtie.rb +28 -0
- data/lib/stockboy/reader.rb +59 -0
- data/lib/stockboy/readers.rb +11 -0
- data/lib/stockboy/readers/csv.rb +115 -0
- data/lib/stockboy/readers/fixed_width.rb +121 -0
- data/lib/stockboy/readers/spreadsheet.rb +144 -0
- data/lib/stockboy/readers/xml.rb +155 -0
- data/lib/stockboy/registry.rb +42 -0
- data/lib/stockboy/source_record.rb +43 -0
- data/lib/stockboy/string_pool.rb +35 -0
- data/lib/stockboy/template_file.rb +44 -0
- data/lib/stockboy/translations.rb +70 -0
- data/lib/stockboy/translations/boolean.rb +58 -0
- data/lib/stockboy/translations/date.rb +41 -0
- data/lib/stockboy/translations/decimal.rb +33 -0
- data/lib/stockboy/translations/default_empty_string.rb +38 -0
- data/lib/stockboy/translations/default_false.rb +41 -0
- data/lib/stockboy/translations/default_nil.rb +38 -0
- data/lib/stockboy/translations/default_true.rb +41 -0
- data/lib/stockboy/translations/default_zero.rb +41 -0
- data/lib/stockboy/translations/integer.rb +33 -0
- data/lib/stockboy/translations/string.rb +33 -0
- data/lib/stockboy/translations/time.rb +41 -0
- data/lib/stockboy/translations/uk_date.rb +51 -0
- data/lib/stockboy/translations/us_date.rb +51 -0
- data/lib/stockboy/translator.rb +66 -0
- data/lib/stockboy/version.rb +3 -0
- data/spec/fixtures/.gitkeep +0 -0
- data/spec/fixtures/files/a_garbage.csv +1 -0
- data/spec/fixtures/files/test_data-20120101.csv +1 -0
- data/spec/fixtures/files/test_data-20120202.csv +1 -0
- data/spec/fixtures/files/z_garbage.csv +1 -0
- data/spec/fixtures/jobs/test_job.rb +1 -0
- data/spec/fixtures/soap/get_list/fault.xml +8 -0
- data/spec/fixtures/soap/get_list/success.xml +18 -0
- data/spec/fixtures/spreadsheets/test_data.xls +0 -0
- data/spec/fixtures/spreadsheets/test_row_options.xls +0 -0
- data/spec/fixtures/xml/body.xml +14 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/stockboy/attribute_map_spec.rb +59 -0
- data/spec/stockboy/attribute_spec.rb +11 -0
- data/spec/stockboy/candidate_record_spec.rb +150 -0
- data/spec/stockboy/configuration_spec.rb +28 -0
- data/spec/stockboy/configurator_spec.rb +127 -0
- data/spec/stockboy/filter_chain_spec.rb +40 -0
- data/spec/stockboy/filter_spec.rb +41 -0
- data/spec/stockboy/filters/missing_email_spec.rb +26 -0
- data/spec/stockboy/filters_spec.rb +38 -0
- data/spec/stockboy/job_spec.rb +238 -0
- data/spec/stockboy/mapped_record_spec.rb +30 -0
- data/spec/stockboy/provider_spec.rb +34 -0
- data/spec/stockboy/providers/file_spec.rb +116 -0
- data/spec/stockboy/providers/ftp_spec.rb +143 -0
- data/spec/stockboy/providers/http_spec.rb +94 -0
- data/spec/stockboy/providers/imap_spec.rb +76 -0
- data/spec/stockboy/providers/soap_spec.rb +107 -0
- data/spec/stockboy/providers_spec.rb +38 -0
- data/spec/stockboy/readers/csv_spec.rb +68 -0
- data/spec/stockboy/readers/fixed_width_spec.rb +52 -0
- data/spec/stockboy/readers/spreadsheet_spec.rb +121 -0
- data/spec/stockboy/readers/xml_spec.rb +94 -0
- data/spec/stockboy/readers_spec.rb +30 -0
- data/spec/stockboy/source_record_spec.rb +19 -0
- data/spec/stockboy/template_file_spec.rb +30 -0
- data/spec/stockboy/translations/boolean_spec.rb +48 -0
- data/spec/stockboy/translations/date_spec.rb +38 -0
- data/spec/stockboy/translations/decimal_spec.rb +23 -0
- data/spec/stockboy/translations/default_empty_string_spec.rb +32 -0
- data/spec/stockboy/translations/default_false_spec.rb +25 -0
- data/spec/stockboy/translations/default_nil_spec.rb +32 -0
- data/spec/stockboy/translations/default_true_spec.rb +25 -0
- data/spec/stockboy/translations/default_zero_spec.rb +32 -0
- data/spec/stockboy/translations/integer_spec.rb +22 -0
- data/spec/stockboy/translations/string_spec.rb +22 -0
- data/spec/stockboy/translations/time_spec.rb +27 -0
- data/spec/stockboy/translations/uk_date_spec.rb +37 -0
- data/spec/stockboy/translations/us_date_spec.rb +37 -0
- data/spec/stockboy/translations_spec.rb +55 -0
- data/spec/stockboy/translator_spec.rb +27 -0
- data/stockboy.gemspec +32 -0
- metadata +305 -0
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stockboy/providers/file'
|
3
|
+
|
4
|
+
module Stockboy
|
5
|
+
describe Providers::File do
|
6
|
+
subject(:provider) { Stockboy::Providers::File.new }
|
7
|
+
|
8
|
+
it "should assign parameters" do
|
9
|
+
provider.file_dir = "fixtures/files"
|
10
|
+
provider.file_name = %r{import_20[1-9][0-9]-(0[1-9]|1[0-2])-([0-2][1-9]|3[0-1]).csv}
|
11
|
+
provider.file_newer = Date.today
|
12
|
+
provider.file_smaller = 1024**2
|
13
|
+
provider.file_larger = 1024
|
14
|
+
provider.pick = :first
|
15
|
+
|
16
|
+
provider.file_dir.should == "fixtures/files"
|
17
|
+
provider.file_name.should == %r{import_20[1-9][0-9]-(0[1-9]|1[0-2])-([0-2][1-9]|3[0-1]).csv}
|
18
|
+
provider.file_newer.should == Date.today
|
19
|
+
provider.file_smaller.should == 1024**2
|
20
|
+
provider.file_larger.should == 1024
|
21
|
+
provider.pick.should == :first
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".new" do
|
25
|
+
it "has no errors" do
|
26
|
+
provider.errors.messages.should be_empty
|
27
|
+
end
|
28
|
+
|
29
|
+
it "accepts block initialization" do
|
30
|
+
provider = Providers::File.new{ |f| f.file_dir 'fixtures/files' }
|
31
|
+
provider.file_dir.should == 'fixtures/files'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#matching_file" do
|
36
|
+
subject(:provider) do
|
37
|
+
Providers::File.new do |f|
|
38
|
+
f.file_dir = RSpec.configuration.fixture_path.join("files")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns the full path to the matching file name" do
|
43
|
+
provider.file_name = "test_data-*"
|
44
|
+
provider.matching_file.should end_with "fixtures/files/test_data-20120202.csv"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#data" do
|
49
|
+
subject(:provider) do
|
50
|
+
Providers::File.new do |f|
|
51
|
+
f.file_dir = RSpec.configuration.fixture_path.join("files")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "fails with an error if the file doesn't exist" do
|
56
|
+
provider.file_name = "missing-file.csv"
|
57
|
+
provider.data.should be_nil
|
58
|
+
provider.valid?.should == false
|
59
|
+
provider.errors[:base].should_not be_empty
|
60
|
+
end
|
61
|
+
|
62
|
+
it "finds last matching file from string glob" do
|
63
|
+
provider.file_name = "test_data-*.csv"
|
64
|
+
provider.data.should == "2012-02-02\n"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "finds first matching file from string glob" do
|
68
|
+
provider.file_name = "test_data-*.csv"
|
69
|
+
provider.pick = :first
|
70
|
+
provider.data.should == "2012-01-01\n"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "finds last matching file from regex" do
|
74
|
+
provider.file_name = /test_data/
|
75
|
+
provider.data.should == "2012-02-02\n"
|
76
|
+
end
|
77
|
+
|
78
|
+
context "with :since validation" do
|
79
|
+
let(:recently) { Time.now - 60 }
|
80
|
+
|
81
|
+
it "skips old files" do
|
82
|
+
expect_any_instance_of(::File).to receive(:mtime).and_return Time.now - 86400
|
83
|
+
provider.file_dir = RSpec.configuration.fixture_path.join("files")
|
84
|
+
provider.file_name = '*.csv'
|
85
|
+
provider.since = recently
|
86
|
+
|
87
|
+
provider.data.should be_nil
|
88
|
+
provider.errors[:response].should include "No new files since #{recently}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe ".delete_data" do
|
94
|
+
let(:target) { ::Tempfile.new(['delete', '.csv']) }
|
95
|
+
let(:target_dir) { File.dirname(target) }
|
96
|
+
subject(:provider) { Providers::File.new(file_name: 'delete*.csv', file_dir: target_dir) }
|
97
|
+
|
98
|
+
after do
|
99
|
+
target.unlink
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should raise an error when called blindly" do
|
103
|
+
expect_any_instance_of(::File).to_not receive(:delete)
|
104
|
+
expect { provider.delete_data }.to raise_error Stockboy::OutOfSequence
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should call delete on the matched file" do
|
108
|
+
provider.matching_file
|
109
|
+
|
110
|
+
expect(::File).to receive(:delete).with(target.path)
|
111
|
+
provider.delete_data
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stockboy/providers/ftp'
|
3
|
+
|
4
|
+
module Stockboy
|
5
|
+
describe Providers::FTP do
|
6
|
+
|
7
|
+
subject(:provider) do
|
8
|
+
Stockboy::Providers::FTP.new do |ftp|
|
9
|
+
ftp.host = "localhost.test"
|
10
|
+
ftp.username = "a"
|
11
|
+
ftp.password = "b"
|
12
|
+
ftp.binary = true
|
13
|
+
ftp.passive = true
|
14
|
+
ftp.file_name = '*.csv'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should assign parameters" do
|
19
|
+
ftp = Stockboy::Providers::FTP.new
|
20
|
+
ftp.host = "localhost.test"
|
21
|
+
ftp.username = "uuu"
|
22
|
+
ftp.password = "ppp"
|
23
|
+
ftp.file_dir = "files/here"
|
24
|
+
ftp.file_name = %r{import_20[1-9][0-9]-(0[1-9]|1[0-2])-([0-2][1-9]|3[0-1]).csv}
|
25
|
+
|
26
|
+
ftp.host.should == "localhost.test"
|
27
|
+
ftp.username.should == "uuu"
|
28
|
+
ftp.password.should == "ppp"
|
29
|
+
ftp.file_dir.should == "files/here"
|
30
|
+
ftp.file_name.should == %r{import_20[1-9][0-9]-(0[1-9]|1[0-2])-([0-2][1-9]|3[0-1]).csv}
|
31
|
+
end
|
32
|
+
|
33
|
+
describe ".new" do
|
34
|
+
it "has no errors" do
|
35
|
+
subject.errors.messages.should be_empty
|
36
|
+
end
|
37
|
+
|
38
|
+
it "accepts block initialization" do
|
39
|
+
ftp = Providers::FTP.new{ |f| f.host 'test2.local' }
|
40
|
+
ftp.host.should == 'test2.local'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#client" do
|
45
|
+
it "should open connection to host with username and password" do
|
46
|
+
expect_connection
|
47
|
+
|
48
|
+
connection = false
|
49
|
+
provider.client { |f| connection = f }
|
50
|
+
|
51
|
+
connection.should be_a Net::FTP
|
52
|
+
connection.binary.should be_true
|
53
|
+
connection.passive.should be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should return yielded result" do
|
57
|
+
expect_connection
|
58
|
+
|
59
|
+
result = provider.client { |_| "a_file_name.csv" }
|
60
|
+
|
61
|
+
result.should == "a_file_name.csv"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#data" do
|
66
|
+
it "adds an error on missing host" do
|
67
|
+
provider.host = nil
|
68
|
+
provider.data
|
69
|
+
|
70
|
+
provider.errors.include?(:host).should be_true
|
71
|
+
end
|
72
|
+
|
73
|
+
it "adds an error on missing file_name" do
|
74
|
+
provider.file_name = nil
|
75
|
+
provider.data
|
76
|
+
|
77
|
+
provider.errors.include?(:file_name).should be_true
|
78
|
+
end
|
79
|
+
|
80
|
+
it "downloads the last matching file" do
|
81
|
+
net_ftp = expect_connection
|
82
|
+
expect(net_ftp).to receive(:nlst).and_return ['20120101.csv', '20120102.csv']
|
83
|
+
expect(net_ftp).to receive(:get).with('20120102.csv', nil).and_return "DATA"
|
84
|
+
expect(provider).to receive(:validate_file).and_return true
|
85
|
+
|
86
|
+
provider.data.should == "DATA"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "skips old files" do
|
90
|
+
net_ftp = expect_connection
|
91
|
+
expect(net_ftp).to receive(:nlst).and_return ['20120101.csv', '20120102.csv']
|
92
|
+
expect(net_ftp).to receive(:mtime).with('20120102.csv').and_return(Time.new(2009,01,01))
|
93
|
+
expect(net_ftp).to_not receive(:get)
|
94
|
+
|
95
|
+
provider.file_newer = Time.new(2010,1,1)
|
96
|
+
|
97
|
+
provider.data.should be_nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#matching_file" do
|
102
|
+
it "does not change until cleared" do
|
103
|
+
net_ftp = expect_connection
|
104
|
+
expect(net_ftp).to receive(:nlst).and_return ["1.csv", "2.csv"]
|
105
|
+
|
106
|
+
provider.matching_file.should == "2.csv"
|
107
|
+
|
108
|
+
net_ftp = expect_connection
|
109
|
+
expect(net_ftp).to receive(:nlst).and_return ["1.csv", "2.csv", "3.csv"]
|
110
|
+
|
111
|
+
provider.matching_file.should == "2.csv"
|
112
|
+
provider.clear
|
113
|
+
provider.matching_file.should == "3.csv"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#delete_data" do
|
118
|
+
it "should raise an error when called blindly" do
|
119
|
+
expect_any_instance_of(Net::FTP).to_not receive(:delete)
|
120
|
+
expect { provider.delete_data }.to raise_error Stockboy::OutOfSequence
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should delete the matching file" do
|
124
|
+
net_ftp = expect_connection
|
125
|
+
expect(net_ftp).to receive(:nlst).and_return ["1.csv", "2.csv"]
|
126
|
+
|
127
|
+
provider.matching_file.should == "2.csv"
|
128
|
+
|
129
|
+
net_ftp = expect_connection
|
130
|
+
expect(net_ftp).to receive(:delete).with("2.csv")
|
131
|
+
|
132
|
+
provider.delete_data.should == "2.csv"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def expect_connection(host="localhost.test", user="a", pass="b")
|
137
|
+
net_ftp = Net::FTP.new
|
138
|
+
expect(Net::FTP).to receive(:open).with(host, user, pass).and_yield(net_ftp)
|
139
|
+
net_ftp
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stockboy/providers/http'
|
3
|
+
|
4
|
+
module Stockboy
|
5
|
+
describe Providers::HTTP do
|
6
|
+
subject(:provider) { Stockboy::Providers::HTTP.new }
|
7
|
+
|
8
|
+
it "should assign parameters from :uri option" do
|
9
|
+
provider.uri = "http://www.example.com/"
|
10
|
+
provider.query = {user: 'u'}
|
11
|
+
provider.method = :get
|
12
|
+
|
13
|
+
provider.uri.should == URI("http://www.example.com/?user=u")
|
14
|
+
provider.query.should == {user: 'u'}
|
15
|
+
provider.method.should == :get
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should assign parameters from :get" do
|
19
|
+
provider.get = "http://www.example.com/"
|
20
|
+
provider.query = {user: 'u'}
|
21
|
+
|
22
|
+
provider.uri.should == URI("http://www.example.com/?user=u")
|
23
|
+
provider.query.should == {user: 'u'}
|
24
|
+
provider.method.should == :get
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should assign parameters from :post" do
|
28
|
+
provider.post = "http://www.example.com/"
|
29
|
+
provider.query = {user: 'u'}
|
30
|
+
|
31
|
+
provider.uri.should == URI("http://www.example.com/?user=u")
|
32
|
+
provider.query.should == {user: 'u'}
|
33
|
+
provider.method.should == :post
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ".new" do
|
37
|
+
its(:errors) { should be_empty }
|
38
|
+
|
39
|
+
it "accepts block DSL initialization" do
|
40
|
+
provider = Providers::HTTP.new do
|
41
|
+
get "http://www.example.com/"
|
42
|
+
query user: 'u'
|
43
|
+
end
|
44
|
+
|
45
|
+
provider.uri.should == URI("http://www.example.com/?user=u")
|
46
|
+
provider.query.should == { user: 'u' }
|
47
|
+
provider.method.should == :get
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "validation" do
|
52
|
+
it "should not be valid without a method" do
|
53
|
+
provider.method = nil
|
54
|
+
provider.should_not be_valid
|
55
|
+
provider.errors.keys.should include(:method)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should not be valid without a uri" do
|
59
|
+
provider.uri = ""
|
60
|
+
provider.should_not be_valid
|
61
|
+
provider.errors.keys.should include(:uri)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#data" do
|
66
|
+
let(:response) { HTTPI::Response.new(200, {}, '{"success":true}') }
|
67
|
+
|
68
|
+
subject(:provider) do
|
69
|
+
Providers::HTTP.new do |s|
|
70
|
+
s.uri = "http://www.example.com/"
|
71
|
+
s.query = {username: "user"}
|
72
|
+
s.method = :get
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns string body on success" do
|
77
|
+
expect(HTTPI).to receive(:request) { response }
|
78
|
+
|
79
|
+
provider.data.should == '{"success":true}'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#client" do
|
84
|
+
it "yields a generic HTTP interface" do
|
85
|
+
provider.client do |http|
|
86
|
+
http.should respond_to :get
|
87
|
+
http.should respond_to :post
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stockboy/providers/imap'
|
3
|
+
|
4
|
+
module Stockboy
|
5
|
+
describe Providers::IMAP do
|
6
|
+
subject(:provider) { Stockboy::Providers::IMAP.new }
|
7
|
+
|
8
|
+
it "should assign parameters" do
|
9
|
+
provider.host = "mail.localhost.test"
|
10
|
+
provider.username = "uuu"
|
11
|
+
provider.password = "ppp"
|
12
|
+
provider.mailbox = "INBOX/Data"
|
13
|
+
provider.subject = %r{New Records 20[1-9][0-9]-(0[1-9]|1[0-2])-([0-2][1-9]|3[0-1])}
|
14
|
+
provider.since = Date.new(2012,12,1)
|
15
|
+
provider.attachment = %r{data-[0-9]+\.csv}
|
16
|
+
|
17
|
+
provider.host.should == "mail.localhost.test"
|
18
|
+
provider.username.should == "uuu"
|
19
|
+
provider.password.should == "ppp"
|
20
|
+
provider.mailbox.should == "INBOX/Data"
|
21
|
+
provider.subject.should == %r{New Records 20[1-9][0-9]-(0[1-9]|1[0-2])-([0-2][1-9]|3[0-1])}
|
22
|
+
provider.attachment.should == %r{data-[0-9]+\.csv}
|
23
|
+
provider.since.should == Date.new(2012,12,1)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "deprecated options", pending: "implement deprecated_alias" do
|
27
|
+
it "promotes since instead of newer_than" do
|
28
|
+
provider = Providers::IMAP.new{ |f| f.newer_than Date.new(2012,12,1) }
|
29
|
+
provider.since.should == Date.new(2012,12,1)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe ".new" do
|
34
|
+
it "has no errors" do
|
35
|
+
provider.errors.messages.should be_empty
|
36
|
+
end
|
37
|
+
|
38
|
+
it "accepts block initialization" do
|
39
|
+
provider = Providers::IMAP.new{ |f| f.host 'mail.test2.local' }
|
40
|
+
provider.host.should == 'mail.test2.local'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#data" do
|
45
|
+
|
46
|
+
context "with no messages found" do
|
47
|
+
it "should be nil" do
|
48
|
+
allow(provider).to receive(:fetch_imap_message_keys).and_return []
|
49
|
+
provider.data.should be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#delete_data" do
|
56
|
+
let(:imap) { double(:imap) }
|
57
|
+
|
58
|
+
it "should raise an error when called blindly" do
|
59
|
+
expect { provider.delete_data }.to raise_error Stockboy::OutOfSequence
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should call delete on the matching message" do
|
63
|
+
allow(provider).to receive(:client).and_yield(imap)
|
64
|
+
allow(provider).to receive(:fetch_imap_message_keys) { [5] }
|
65
|
+
|
66
|
+
provider.matching_message
|
67
|
+
|
68
|
+
expect(imap).to receive(:uid_store).with(5, "+FLAGS", [:Deleted])
|
69
|
+
expect(imap).to receive(:expunge)
|
70
|
+
|
71
|
+
provider.delete_data
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stockboy/providers/soap'
|
3
|
+
|
4
|
+
module Stockboy
|
5
|
+
describe Providers::SOAP do
|
6
|
+
before(:all) { savon.mock! }
|
7
|
+
after(:all) { savon.unmock! }
|
8
|
+
subject(:provider) { Stockboy::Providers::SOAP.new }
|
9
|
+
|
10
|
+
it "should assign parameters" do
|
11
|
+
provider.wsdl = "http://api.example.com/?wsdl"
|
12
|
+
provider.request = :get_user
|
13
|
+
provider.namespace = "http://api.example.com/"
|
14
|
+
provider.message = {user: 'u', pass: 'p'}
|
15
|
+
provider.headers = {key: 'k'}
|
16
|
+
|
17
|
+
provider.wsdl.should == "http://api.example.com/?wsdl"
|
18
|
+
provider.request.should == :get_user
|
19
|
+
provider.namespace.should == "http://api.example.com/"
|
20
|
+
provider.message.should == {user: 'u', pass: 'p'}
|
21
|
+
provider.headers.should == {key: 'k'}
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".new" do
|
25
|
+
its(:errors) { should be_empty }
|
26
|
+
|
27
|
+
it "accepts block initialization" do
|
28
|
+
provider = Providers::SOAP.new do |p|
|
29
|
+
p.request = :get_user
|
30
|
+
p.endpoint = "http://api.example.com/v1"
|
31
|
+
p.namespace = "http://api.example.com/namespace"
|
32
|
+
p.wsdl = "http://api.example.com/?wsdl"
|
33
|
+
p.message = {user: 'u', pass: 'p'}
|
34
|
+
p.headers = {key: 'k'}
|
35
|
+
end
|
36
|
+
|
37
|
+
provider.request.should == :get_user
|
38
|
+
provider.endpoint.should == "http://api.example.com/v1"
|
39
|
+
provider.wsdl.should == "http://api.example.com/?wsdl"
|
40
|
+
provider.namespace.should == "http://api.example.com/namespace"
|
41
|
+
provider.message.should == {user: 'u', pass: 'p'}
|
42
|
+
provider.headers.should == {key: 'k'}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "validation" do
|
47
|
+
context "with a WSDL document" do
|
48
|
+
before { provider.wsdl = "http://api.example.com/?wsdl" }
|
49
|
+
it { should be_valid }
|
50
|
+
end
|
51
|
+
|
52
|
+
context "without a WSDL document" do
|
53
|
+
it "has error for blank endpoint & WSDL namespace" do
|
54
|
+
provider.valid?
|
55
|
+
provider.errors.keys.should include(:endpoint)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#client" do
|
61
|
+
it "yields a Savon client" do
|
62
|
+
provider.endpoint = "http://api.example.com/v1"
|
63
|
+
provider.namespace = ''
|
64
|
+
provider.client do |soap|
|
65
|
+
soap.should be_a Savon::Client
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#data" do
|
71
|
+
let(:xml_success_fixture) do
|
72
|
+
File.read(RSpec.configuration.fixture_path.join "soap/get_list/success.xml")
|
73
|
+
end
|
74
|
+
|
75
|
+
let(:provider) do
|
76
|
+
Providers::SOAP.new do |s|
|
77
|
+
s.endpoint = "http://api.example.com/v1"
|
78
|
+
s.namespace = ''
|
79
|
+
s.request = :get_list
|
80
|
+
s.message = {username: "user", password: "pass"}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
subject(:response) do
|
85
|
+
savon.expects(:get_list)
|
86
|
+
.with(message: {username: 'user', password: 'pass'})
|
87
|
+
.returns(xml_success_fixture)
|
88
|
+
provider.data
|
89
|
+
end
|
90
|
+
|
91
|
+
it "returns hash data on success" do
|
92
|
+
should be_a Hash
|
93
|
+
end
|
94
|
+
|
95
|
+
it "uses string keys" do
|
96
|
+
response.keys.each { |k| k.should be_a String }
|
97
|
+
end
|
98
|
+
|
99
|
+
it "shares key string objects from a common pool" do
|
100
|
+
cases = response["MultiNamespacedEntryResponse"]["history"]["case"]
|
101
|
+
text_keys = cases.map { |c| c.keys[c.keys.index("logText")] }
|
102
|
+
text_keys[0].should be text_keys[1]
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|