4me-sdk 1.1.4 → 1.2.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 +5 -5
- data/4me-sdk.gemspec +1 -1
- data/Gemfile.lock +15 -17
- data/LICENSE +1 -1
- data/README.md +45 -27
- data/lib/sdk4me.rb +4 -3
- data/lib/sdk4me/client.rb +52 -20
- data/lib/sdk4me/client/attachments.rb +52 -9
- data/lib/sdk4me/client/response.rb +9 -0
- data/lib/sdk4me/client/version.rb +1 -1
- data/spec/lib/sdk4me/attachments_spec.rb +230 -145
- data/spec/lib/sdk4me/certificate_spec.rb +15 -1
- data/spec/lib/sdk4me/client_spec.rb +480 -441
- data/spec/lib/sdk4me/response_spec.rb +251 -231
- data/spec/lib/sdk4me_spec.rb +4 -4
- metadata +8 -9
@@ -59,6 +59,11 @@ module Sdk4me
|
|
59
59
|
end
|
60
60
|
alias_method :success?, :valid?
|
61
61
|
|
62
|
+
# +true+ in case of a HTTP 5xx error
|
63
|
+
def failure?
|
64
|
+
!success? && (@response.code.to_s.blank? || @response.code.to_s =~ /5\d\d/)
|
65
|
+
end
|
66
|
+
|
62
67
|
# retrieve a value from the resource
|
63
68
|
# if the JSON value is an Array a array with the value for each resource will be given
|
64
69
|
# @param keys: a single key or a key-path separated by comma
|
@@ -111,6 +116,10 @@ module Sdk4me
|
|
111
116
|
!!(@response.code.to_s == '429' || (message && message =~ /Too Many Requests/))
|
112
117
|
end
|
113
118
|
|
119
|
+
def retry_after
|
120
|
+
@current_page ||= @response.header['Retry-After'].to_i
|
121
|
+
end
|
122
|
+
|
114
123
|
def to_s
|
115
124
|
valid? ? json.to_s : message
|
116
125
|
end
|
@@ -2,177 +2,262 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Sdk4me::Attachments do
|
4
4
|
|
5
|
-
|
6
|
-
@
|
7
|
-
|
5
|
+
def attachments(authentication)
|
6
|
+
(@attachments ||= {})[authentication] ||= begin
|
7
|
+
client = if authentication == :api_token
|
8
|
+
Sdk4me::Client.new(api_token: 'secret', max_retry_time: -1)
|
9
|
+
else
|
10
|
+
Sdk4me::Client.new(access_token: 'secret', max_retry_time: -1)
|
11
|
+
end
|
12
|
+
Sdk4me::Attachments.new(client)
|
13
|
+
end
|
8
14
|
end
|
9
15
|
|
10
|
-
|
11
|
-
|
12
|
-
|
16
|
+
def credentials(authentication)
|
17
|
+
if authentication == :api_token
|
18
|
+
{ basic_auth: ['secret', 'x'] }
|
19
|
+
else
|
20
|
+
{ headers: {'Authorization' => 'Bearer secret'} }
|
13
21
|
end
|
22
|
+
end
|
14
23
|
|
15
|
-
|
16
|
-
expect(@attachments.upload_attachments!('/requests', {attachments: nil})).to be_nil
|
17
|
-
end
|
24
|
+
[:api_token, :access_token].each do |authentication|
|
18
25
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
26
|
+
context "#{authentication} - " do
|
27
|
+
context 'upload_attachments!' do
|
28
|
+
context 'normal' do
|
29
|
+
it 'should not do anything when no :attachments are present' do
|
30
|
+
expect(attachments(authentication).upload_attachments!('/requests', {status: :in_progress})).to be_nil
|
31
|
+
end
|
23
32
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
expect(@attachments.upload_attachments!('/sites/1', {attachments: ['file1.png']})).to be_nil
|
28
|
-
end
|
33
|
+
it 'should not do anything when :attachments is nil' do
|
34
|
+
expect(attachments(authentication).upload_attachments!('/requests', {attachments: nil})).to be_nil
|
35
|
+
end
|
29
36
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
37
|
+
it 'should not do anything when :attachments is empty' do
|
38
|
+
expect(attachments(authentication).upload_attachments!('/requests', {attachments: []})).to be_nil
|
39
|
+
expect(attachments(authentication).upload_attachments!('/requests', {attachments: [nil]})).to be_nil
|
40
|
+
end
|
35
41
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
42
|
+
it 'should show a error if no attachment may be uploaded' do
|
43
|
+
stub_request(:get, 'https://api.4me.com/v1/sites/1?attachment_upload_token=true').with(credentials(authentication)).to_return(body: {name: 'site 1'}.to_json)
|
44
|
+
expect_log('Attachments not allowed for /sites/1', :error)
|
45
|
+
expect(attachments(authentication).upload_attachments!('/sites/1', {attachments: ['file1.png']})).to be_nil
|
46
|
+
end
|
41
47
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
[:slas, :remarks],
|
48
|
-
[:service_instances, :remarks],
|
49
|
-
[:service_offerings, :summary],
|
50
|
-
[:any_other_model, :note]].each do |model, attribute|
|
51
|
-
|
52
|
-
it "should replace :attachments with :#{attribute}_attachments after upload at /#{model}" do
|
53
|
-
stub_request(:get, "https://api.4me.com/v1/#{model}/new?attachment_upload_token=true").with(basic_auth: ['secret', 'x']).to_return(body: {storage_upload: 'conf'}.to_json)
|
54
|
-
expect(@attachments).to receive(:upload_attachment).with('conf', 'file1.png', false).ordered{ 'uploaded file1.png' }
|
55
|
-
expect(@attachments).to receive(:upload_attachment).with('conf', 'file2.zip', false).ordered{ 'uploaded file2.zip' }
|
56
|
-
data = {leave: 'me alone', attachments: %w(file1.png file2.zip)}
|
57
|
-
@attachments.upload_attachments!("/#{model}", data)
|
58
|
-
expect(data[:attachments]).to be_nil
|
59
|
-
expect(data[:leave]).to eq('me alone')
|
60
|
-
expect(data[:"#{attribute}_attachments"]).to eq(['uploaded file1.png', 'uploaded file2.zip'].to_json)
|
61
|
-
end
|
62
|
-
end
|
48
|
+
it 'should raise an exception if no attachment may be uploaded' do
|
49
|
+
stub_request(:get, 'https://api.4me.com/v1/sites/1?attachment_upload_token=true').with(credentials(authentication)).to_return(body: {name: 'site 1'}.to_json)
|
50
|
+
message = 'Attachments not allowed for /sites/1'
|
51
|
+
expect{ attachments(authentication).upload_attachments!('/sites/1', {attachments: ['file1.png'], attachments_exception: true}) }.to raise_error(::Sdk4me::UploadFailed, message)
|
52
|
+
end
|
63
53
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
expect(data[:attachments]).to be_nil
|
70
|
-
expect(data[:attachments_exception]).to be_nil
|
71
|
-
expect(data[:leave]).to eq('me alone')
|
72
|
-
expect(data[:note_attachments]).to eq(['uploaded file1.png'].to_json)
|
73
|
-
end
|
74
|
-
end
|
54
|
+
it 'should add /new to the path for new records' do
|
55
|
+
stub_request(:get, 'https://api.4me.com/v1/sites/new?attachment_upload_token=true').with(credentials(authentication)).to_return(body: {missing: 'storage'}.to_json)
|
56
|
+
expect_log('Attachments not allowed for /sites', :error)
|
57
|
+
expect(attachments(authentication).upload_attachments!('/sites', {attachments: ['file1.png']})).to be_nil
|
58
|
+
end
|
75
59
|
|
76
|
-
|
60
|
+
[ [:requests, :note],
|
61
|
+
[:problems, :note],
|
62
|
+
[:contracts, :remarks],
|
63
|
+
[:cis, :remarks],
|
64
|
+
[:flsas, :remarks],
|
65
|
+
[:slas, :remarks],
|
66
|
+
[:service_instances, :remarks],
|
67
|
+
[:service_offerings, :summary],
|
68
|
+
[:any_other_model, :note]].each do |model, attribute|
|
77
69
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
70
|
+
it "should replace :attachments with :#{attribute}_attachments after upload at /#{model}" do
|
71
|
+
stub_request(:get, "https://api.4me.com/v1/#{model}/new?attachment_upload_token=true").with(credentials(authentication)).to_return(body: {storage_upload: 'conf'}.to_json)
|
72
|
+
expect(attachments(authentication)).to receive(:upload_attachment).with('conf', 'file1.png', false).ordered{ 'uploaded file1.png' }
|
73
|
+
expect(attachments(authentication)).to receive(:upload_attachment).with('conf', 'file2.zip', false).ordered{ 'uploaded file2.zip' }
|
74
|
+
data = {leave: 'me alone', attachments: %w(file1.png file2.zip)}
|
75
|
+
attachments(authentication).upload_attachments!("/#{model}", data)
|
76
|
+
expect(data[:attachments]).to be_nil
|
77
|
+
expect(data[:leave]).to eq('me alone')
|
78
|
+
expect(data[:"#{attribute}_attachments"]).to eq(['uploaded file1.png', 'uploaded file2.zip'].to_json)
|
79
|
+
end
|
80
|
+
end
|
82
81
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
82
|
+
it 'should set raise_exception flag to true when :attachments_exception is set' do
|
83
|
+
stub_request(:get, 'https://api.4me.com/v1/requests/new?attachment_upload_token=true').with(credentials(authentication)).to_return(body: {storage_upload: 'conf'}.to_json)
|
84
|
+
expect(attachments(authentication)).to receive(:upload_attachment).with('conf', 'file1.png', true).ordered{ 'uploaded file1.png' }
|
85
|
+
data = {leave: 'me alone', attachments: 'file1.png', attachments_exception: true}
|
86
|
+
attachments(authentication).upload_attachments!('/requests', data)
|
87
|
+
expect(data[:attachments]).to be_nil
|
88
|
+
expect(data[:attachments_exception]).to be_nil
|
89
|
+
expect(data[:leave]).to eq('me alone')
|
90
|
+
expect(data[:note_attachments]).to eq(['uploaded file1.png'].to_json)
|
91
|
+
end
|
92
|
+
end
|
87
93
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
upload_uri: 'https://itrp.s3.amazonaws.com/',
|
93
|
-
access_key: 'AKIA6RYQ',
|
94
|
-
success_url: 'https://mycompany.4me.com/s3_success?sig=99e82e8a046',
|
95
|
-
policy: 'eydlgIH0=',
|
96
|
-
signature: 'nbhdec4k=',
|
97
|
-
upload_path: 'attachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/'
|
98
|
-
}
|
99
|
-
@key_template = 'attachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/${filename}'
|
100
|
-
@key = 'attachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/upload.txt'
|
101
|
-
|
102
|
-
@multi_part_body = "--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"Content-Type\"\r\n\r\napplication/octet-stream\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"x-amz-server-side-encryption\"\r\n\r\nAES256\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"key\"\r\n\r\nattachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/${filename}\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\nAKIA6RYQ\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"acl\"\r\n\r\nprivate\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"signature\"\r\n\r\nnbhdec4k=\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"success_action_status\"\r\n\r\n201\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"policy\"\r\n\r\neydlgIH0=\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"file\"; filename=\"#{@fixture_dir}/upload.txt\"\r\nContent-Type: text/plain\r\n\r\ncontent\r\n--0123456789ABLEWASIEREISAWELBA9876543210--"
|
103
|
-
@multi_part_headers = {'Accept'=>'*/*', 'Content-Type'=>'multipart/form-data; boundary=0123456789ABLEWASIEREISAWELBA9876543210', 'User-Agent'=>'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/523.10.6 (KHTML, like Gecko) Version/3.0.4 Safari/523.10.6'}
|
104
|
-
end
|
94
|
+
context 'inline' do
|
95
|
+
it 'should not do anything when no [attachment:...] is present in the note' do
|
96
|
+
expect(attachments(authentication).upload_attachments!('/requests', {note: '[attachmen:/type]'})).to be_nil
|
97
|
+
end
|
105
98
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
end
|
99
|
+
it 'should not do anything when attachment is empty' do
|
100
|
+
expect(attachments(authentication).upload_attachments!('/requests', {note: '[attachment:]'})).to be_nil
|
101
|
+
end
|
110
102
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
103
|
+
it 'should show a error if no attachment may be uploaded' do
|
104
|
+
stub_request(:get, 'https://api.4me.com/v1/sites/1?attachment_upload_token=true').with(credentials(authentication)).to_return(body: {name: 'site 1'}.to_json)
|
105
|
+
expect_log('Attachments not allowed for /sites/1', :error)
|
106
|
+
expect(attachments(authentication).upload_attachments!('/sites/1', {note: '[attachment:file1.png]'})).to be_nil
|
107
|
+
end
|
116
108
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
109
|
+
it 'should raise an exception if no attachment may be uploaded' do
|
110
|
+
stub_request(:get, 'https://api.4me.com/v1/sites/1?attachment_upload_token=true').with(credentials(authentication)).to_return(body: {name: 'site 1'}.to_json)
|
111
|
+
message = 'Attachments not allowed for /sites/1'
|
112
|
+
expect{ attachments(authentication).upload_attachments!('/sites/1', {note: '[attachment:file1.png]', attachments_exception: true}) }.to raise_error(::Sdk4me::UploadFailed, message)
|
113
|
+
end
|
122
114
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
expect(@attachments.send(:upload_attachment, @aws_conf, "#{@fixture_dir}/upload.txt", false)).to be_nil
|
129
|
-
end
|
115
|
+
it 'should add /new to the path for new records' do
|
116
|
+
stub_request(:get, 'https://api.4me.com/v1/sites/new?attachment_upload_token=true').with(credentials(authentication)).to_return(body: {missing: 'storage'}.to_json)
|
117
|
+
expect_log('Attachments not allowed for /sites', :error)
|
118
|
+
expect(attachments(authentication).upload_attachments!('/sites', {note: '[attachment:file1.png]'})).to be_nil
|
119
|
+
end
|
130
120
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
121
|
+
[ [:requests, :note],
|
122
|
+
[:problems, :note],
|
123
|
+
[:contracts, :remarks],
|
124
|
+
[:cis, :remarks],
|
125
|
+
[:flsas, :remarks],
|
126
|
+
[:slas, :remarks],
|
127
|
+
[:service_instances, :remarks],
|
128
|
+
[:service_offerings, :summary],
|
129
|
+
[:any_other_model, :note]].each do |model, attribute|
|
137
130
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
end
|
131
|
+
it "should replace :attachments with :#{attribute}_attachments after upload at /#{model}" do
|
132
|
+
stub_request(:get, "https://api.4me.com/v1/#{model}/new?attachment_upload_token=true").with(credentials(authentication)).to_return(body: {storage_upload: 'conf'}.to_json)
|
133
|
+
expect(attachments(authentication)).to receive(:upload_attachment).with('conf', 'file1.png', false).ordered{ {key: 'uploaded file1.png'} }
|
134
|
+
expect(attachments(authentication)).to receive(:upload_attachment).with('conf', 'file2.zip', false).ordered{ {key: 'uploaded file2.zip'} }
|
135
|
+
data = {leave: 'me alone', attribute => '[attachment:file1.png] and [attachment:file2.zip]'}
|
136
|
+
attachments(authentication).upload_attachments!("/#{model}", data)
|
137
|
+
expect(data[:attachments]).to be_nil
|
138
|
+
expect(data[:leave]).to eq('me alone')
|
139
|
+
expect(data[:"#{attribute}_attachments"]).to eq([{key: 'uploaded file1.png', inline: true}, {key: 'uploaded file2.zip', inline: true}].to_json)
|
140
|
+
expect(data[:"#{attribute}"]).to eq(' and ')
|
141
|
+
end
|
142
|
+
end
|
151
143
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
144
|
+
it 'should set raise_exception flag to true when :attachments_exception is set' do
|
145
|
+
stub_request(:get, 'https://api.4me.com/v1/requests/new?attachment_upload_token=true').with(credentials(authentication)).to_return(body: {storage_upload: 'conf'}.to_json)
|
146
|
+
expect(attachments(authentication)).to receive(:upload_attachment).with('conf', 'file1.png', true).ordered{ {key: 'uploaded file1.png'} }
|
147
|
+
data = {leave: 'me alone', note: '[attachment:file1.png]', attachments_exception: true}
|
148
|
+
attachments(authentication).upload_attachments!('/requests', data)
|
149
|
+
expect(data[:attachments]).to be_nil
|
150
|
+
expect(data[:attachments_exception]).to be_nil
|
151
|
+
expect(data[:leave]).to eq('me alone')
|
152
|
+
expect(data[:note_attachments]).to eq([{key: 'uploaded file1.png', inline: true}].to_json)
|
153
|
+
expect(data[:note]).to eq('')
|
154
|
+
end
|
155
|
+
end
|
156
156
|
|
157
|
-
it 'should sent the upload to 4me' do
|
158
|
-
stub_request(:post, 'https://api.4me.com/v1/attachments').with(basic_auth: ['secret', 'x']).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {}.to_json)
|
159
|
-
expect(@attachments.send(:upload_attachment, @sdk4me_conf, "#{@fixture_dir}/upload.txt", false)).to eq({key: @key, filesize: 7})
|
160
157
|
end
|
161
158
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
159
|
+
context 'upload_attachment' do
|
160
|
+
|
161
|
+
it 'should log an exception when the file could not be found' do
|
162
|
+
expect_log('Attachment upload failed: file does not exist: unknown_file', :error)
|
163
|
+
expect(attachments(authentication).send(:upload_attachment, nil, 'unknown_file', false)).to be_nil
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should raise an exception when the file could not be found' do
|
167
|
+
message = 'Attachment upload failed: file does not exist: unknown_file'
|
168
|
+
expect{ attachments(authentication).send(:upload_attachment, nil, 'unknown_file', true) }.to raise_error(::Sdk4me::UploadFailed, message)
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'aws' do
|
172
|
+
before(:each) do
|
173
|
+
@aws_conf = {
|
174
|
+
provider: 'aws',
|
175
|
+
upload_uri: 'https://itrp.s3.amazonaws.com/',
|
176
|
+
access_key: 'AKIA6RYQ',
|
177
|
+
success_url: 'https://mycompany.4me.com/s3_success?sig=99e82e8a046',
|
178
|
+
policy: 'eydlgIH0=',
|
179
|
+
signature: 'nbhdec4k=',
|
180
|
+
upload_path: 'attachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/'
|
181
|
+
}
|
182
|
+
@key_template = 'attachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/${filename}'
|
183
|
+
@key = 'attachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/upload.txt'
|
184
|
+
|
185
|
+
@multi_part_body = "--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"Content-Type\"\r\n\r\napplication/octet-stream\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"x-amz-server-side-encryption\"\r\n\r\nAES256\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"key\"\r\n\r\nattachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/${filename}\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\nAKIA6RYQ\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"acl\"\r\n\r\nprivate\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"signature\"\r\n\r\nnbhdec4k=\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"success_action_status\"\r\n\r\n201\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"policy\"\r\n\r\neydlgIH0=\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"file\"; filename=\"#{@fixture_dir}/upload.txt\"\r\nContent-Type: text/plain\r\n\r\ncontent\r\n--0123456789ABLEWASIEREISAWELBA9876543210--"
|
186
|
+
@multi_part_headers = {'Accept'=>'*/*', 'Content-Type'=>'multipart/form-data; boundary=0123456789ABLEWASIEREISAWELBA9876543210', 'User-Agent'=>'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/523.10.6 (KHTML, like Gecko) Version/3.0.4 Safari/523.10.6'}
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'should open a file from disk' do
|
190
|
+
expect(attachments(authentication)).to receive(:aws_upload).with(@aws_conf, @key_template, @key, kind_of(File))
|
191
|
+
expect(attachments(authentication).send(:upload_attachment, @aws_conf, "#{@fixture_dir}/upload.txt", false)).to eq({key: @key, filesize: 7})
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'should sent the upload to AWS' do
|
195
|
+
stub_request(:post, 'https://itrp.s3.amazonaws.com/').with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: 'OK', status: 303, headers: {'Location' => 'https://mycompany.4me.com/s3_success?sig=99e82e8a046'})
|
196
|
+
stub_request(:get, "https://api.4me.com/v1/s3_success?sig=99e82e8a046&key=#{@key}").with(credentials(authentication)).to_return(body: {}.to_json)
|
197
|
+
expect(attachments(authentication).send(:upload_attachment, @aws_conf, "#{@fixture_dir}/upload.txt", false)).to eq({key: @key, filesize: 7})
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'should report an error when AWS upload fails' do
|
201
|
+
stub_request(:post, 'https://itrp.s3.amazonaws.com/').with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: %(<?xml version="1.0" encoding="UTF-8"?>\n<Error><Code>AccessDenied</Code><Message>Invalid according to Policy</Message><RequestId>1FECC4B719E426B1</RequestId><HostId>15+14lXt+HlF</HostId></Error>), status: 303, headers: {'Location' => 'https://mycompany.4me.com/s3_success?sig=99e82e8a046'})
|
202
|
+
expect_log("Attachment upload failed: AWS upload to https://itrp.s3.amazonaws.com/ for #{@key} failed: Invalid according to Policy", :error)
|
203
|
+
expect(attachments(authentication).send(:upload_attachment, @aws_conf, "#{@fixture_dir}/upload.txt", false)).to be_nil
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should report an error when 4me confirmation fails' do
|
207
|
+
stub_request(:post, 'https://itrp.s3.amazonaws.com/').with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: 'OK', status: 303, headers: {'Location' => 'https://mycompany.4me.com/s3_success?sig=99e82e8a046'})
|
208
|
+
stub_request(:get, "https://api.4me.com/v1/s3_success?sig=99e82e8a046&key=#{@key}").with(credentials(authentication)).to_return(body: {message: 'oops!'}.to_json)
|
209
|
+
expect_log('GET request to api.4me.com:443/v1/s3_success?sig=99e82e8a046&key=attachments%2F5%2Freqs%2F000%2F070%2F451%2Fzxxb4ot60xfd6sjg%2Fupload%2Etxt failed: oops!', :error)
|
210
|
+
expect_log("Attachment upload failed: 4me confirmation s3_success?sig=99e82e8a046 for #{@key} failed: oops!", :error)
|
211
|
+
expect(attachments(authentication).send(:upload_attachment, @aws_conf, "#{@fixture_dir}/upload.txt", false)).to be_nil
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'should raise an exception when AWS upload fails' do
|
215
|
+
stub_request(:post, 'https://itrp.s3.amazonaws.com/').with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: %(<?xml version="1.0" encoding="UTF-8"?>\n<Error><Code>AccessDenied</Code><Message>Invalid according to Policy</Message><RequestId>1FECC4B719E426B1</RequestId><HostId>15+14lXt+HlF</HostId></Error>), status: 303, headers: {'Location' => 'https://mycompany.4me.com/s3_success?sig=99e82e8a046'})
|
216
|
+
message = "Attachment upload failed: AWS upload to https://itrp.s3.amazonaws.com/ for #{@key} failed: Invalid according to Policy"
|
217
|
+
expect{ attachments(authentication).send(:upload_attachment, @aws_conf, "#{@fixture_dir}/upload.txt", true) }.to raise_error(::Sdk4me::UploadFailed, message)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context '4me' do
|
222
|
+
before(:each) do
|
223
|
+
@sdk4me_conf = {
|
224
|
+
provider: 'local',
|
225
|
+
upload_uri: 'https://api.4me.com/attachments',
|
226
|
+
upload_path: 'attachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/'
|
227
|
+
}
|
228
|
+
@key_template = 'attachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/${filename}'
|
229
|
+
@key = 'attachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/upload.txt'
|
230
|
+
|
231
|
+
@multi_part_body = "--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"Content-Type\"\r\n\r\napplication/octet-stream\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"file\"; filename=\"#{@spec_dir}/support/fixtures/upload.txt\"\r\nContent-Type: text/plain\r\n\r\ncontent\r\n--0123456789ABLEWASIEREISAWELBA9876543210\r\nContent-Disposition: form-data; name=\"key\"\r\n\r\nattachments/5/reqs/000/070/451/zxxb4ot60xfd6sjg/${filename}\r\n--0123456789ABLEWASIEREISAWELBA9876543210--"
|
232
|
+
@multi_part_headers = {'Accept'=>'*/*', 'Content-Type'=>'multipart/form-data; boundary=0123456789ABLEWASIEREISAWELBA9876543210', 'User-Agent'=>'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/523.10.6 (KHTML, like Gecko) Version/3.0.4 Safari/523.10.6'}
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'should open a file from disk' do
|
236
|
+
expect(attachments(authentication)).to receive(:upload_to_4me).with(@sdk4me_conf, @key_template, @key, kind_of(File))
|
237
|
+
expect(attachments(authentication).send(:upload_attachment, @sdk4me_conf, "#{@fixture_dir}/upload.txt", false)).to eq({key: @key, filesize: 7})
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'should sent the upload to 4me' do
|
241
|
+
stub_request(:post, 'https://api.4me.com/v1/attachments').with(credentials(authentication)).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {}.to_json)
|
242
|
+
expect(attachments(authentication).send(:upload_attachment, @sdk4me_conf, "#{@fixture_dir}/upload.txt", false)).to eq({key: @key, filesize: 7})
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'should report an error when 4me upload fails' do
|
246
|
+
stub_request(:post, 'https://api.4me.com/v1/attachments').with(credentials(authentication)).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {message: 'oops!'}.to_json)
|
247
|
+
expect_log('POST request to api.4me.com:443/v1/attachments failed: oops!', :error)
|
248
|
+
expect_log("Attachment upload failed: 4me upload to https://api.4me.com/attachments for #{@key} failed: oops!", :error)
|
249
|
+
expect(attachments(authentication).send(:upload_attachment, @sdk4me_conf, "#{@fixture_dir}/upload.txt", false)).to be_nil
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should raise an exception when 4me upload fails' do
|
253
|
+
stub_request(:post, 'https://api.4me.com/v1/attachments').with(credentials(authentication)).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {message: 'oops!'}.to_json)
|
254
|
+
expect_log('POST request to api.4me.com:443/v1/attachments failed: oops!', :error)
|
255
|
+
message = "Attachment upload failed: 4me upload to https://api.4me.com/attachments for #{@key} failed: oops!"
|
256
|
+
expect{ attachments(authentication).send(:upload_attachment, @sdk4me_conf, "#{@fixture_dir}/upload.txt", true) }.to raise_error(::Sdk4me::UploadFailed, message)
|
257
|
+
end
|
258
|
+
end
|
168
259
|
|
169
|
-
it 'should raise an exception when 4me upload fails' do
|
170
|
-
stub_request(:post, 'https://api.4me.com/v1/attachments').with(basic_auth: ['secret', 'x']).with(body: @multi_part_body, headers: @multi_part_headers).to_return(body: {message: 'oops!'}.to_json)
|
171
|
-
expect_log('Request failed: oops!', :error)
|
172
|
-
message = "Attachment upload failed: 4me upload to https://api.4me.com/attachments for #{@key} failed: oops!"
|
173
|
-
expect{ @attachments.send(:upload_attachment, @sdk4me_conf, "#{@fixture_dir}/upload.txt", true) }.to raise_error(::Sdk4me::UploadFailed, message)
|
174
260
|
end
|
175
261
|
end
|
176
|
-
|
177
262
|
end
|
178
263
|
end
|
@@ -13,7 +13,21 @@ describe 'ca-bundle.crt' do
|
|
13
13
|
expect(response.valid?).to be_falsey
|
14
14
|
|
15
15
|
# expecting 401 error
|
16
|
-
expect(response.message).to eq('401:
|
16
|
+
expect(response.message).to eq('401: Bad credentials')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should be able to connect to the 4me API (access token)' do
|
20
|
+
WebMock.allow_net_connect!
|
21
|
+
client = Sdk4me::Client.new(access_token: 'invalid', max_retry_time: -1)
|
22
|
+
result = {}
|
23
|
+
|
24
|
+
# no exception concerning the certificate
|
25
|
+
expect { result[:response] = client.get('me') }.not_to raise_error
|
26
|
+
response = result[:response]
|
27
|
+
expect(response.valid?).to be_falsey
|
28
|
+
|
29
|
+
# expecting 401 error
|
30
|
+
expect(response.message).to eq('401: Bad credentials')
|
17
31
|
end
|
18
32
|
|
19
33
|
it 'should be able to connect to S3' do
|