4me-sdk 1.1.7 → 1.1.8

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
  SHA256:
3
- metadata.gz: e60520cbd73635cb830ffbe38668234a3a626561066fd8b63936e69f80ddbe79
4
- data.tar.gz: 35409fc13cf51fcea5f445347e5fff9e4fdf0bde66f67cb4ee6e42d3b8bda215
3
+ metadata.gz: aba8de45bcc385f1f8ffedfce680f58cb5c73865510798712d7d8c382ecbd9bf
4
+ data.tar.gz: 1ffb444710f94ad590aa4943589465e028ad7cf1957bd5546fd93fe158871c6e
5
5
  SHA512:
6
- metadata.gz: 02ba8ae69285fe81b9915546be3c8ba07298d6cc55620fcd830e2c8ff33429f786d7cf33685c08f90e658dade1d7a30c17031ef89f98c3b1478cbcf976e65f55
7
- data.tar.gz: 16da929f4143f8412faf517e1b8941d932ef8a98508b8cc2a8708db12d481481058118212320089b7a8679c65bb3490089e6f5567bf1329d573206a541d130ff
6
+ metadata.gz: bdd2c6e55c547a2b13ca893a73e3167d77adee143e53e396b48d8712cfb8d7e148f0f3b10090c3b20691e22b20ddad4a1593d6f8e374880a98c9f8b71abfbe85
7
+ data.tar.gz: d63bc178ea462a8b4691ad2d63c25ca48ae5735820d398047dfe98ff450be1a6d3f6c8aa8e27c30829afb9753b5213a6f55c0539d1ba03f134908ea8a59ae4f3
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- 4me-sdk (1.1.6)
4
+ 4me-sdk (1.1.8)
5
5
  activesupport (>= 4.2)
6
6
  gem_config (>= 0.3)
7
7
  mime-types (>= 3.0)
@@ -16,7 +16,7 @@ GEM
16
16
  tzinfo (~> 1.1)
17
17
  addressable (2.5.2)
18
18
  public_suffix (>= 2.0.2, < 4.0)
19
- concurrent-ruby (1.1.4)
19
+ concurrent-ruby (1.1.5)
20
20
  crack (0.4.3)
21
21
  safe_yaml (~> 1.0.0)
22
22
  diff-lcs (1.3)
@@ -28,7 +28,7 @@ GEM
28
28
  json (2.1.0)
29
29
  mime-types (3.2.2)
30
30
  mime-types-data (~> 3.2015)
31
- mime-types-data (3.2018.0812)
31
+ mime-types-data (3.2019.0331)
32
32
  minitest (5.11.3)
33
33
  public_suffix (3.0.3)
34
34
  rake (12.3.1)
@@ -71,4 +71,4 @@ DEPENDENCIES
71
71
  webmock (~> 2)
72
72
 
73
73
  BUNDLED WITH
74
- 1.16.2
74
+ 1.17.3
data/README.md CHANGED
@@ -213,6 +213,14 @@ response = Sdk4me::Client.new.put('requests/416621', {
213
213
  })
214
214
  ```
215
215
 
216
+ It is also possible to add inline attachments as follows:
217
+ ```
218
+ response = Sdk4me::Client.new.put('requests/416621', {
219
+ note: 'Here is some inspiration for you: [attachment:/tmp/images/puppy.png]'
220
+ })
221
+ ```
222
+ Note that only images are accepted as inline attachments.
223
+
216
224
  If an attachment upload fails, the errors are logged but the `post` or `put` request will still be sent to 4me without the
217
225
  failed attachments. To receive exceptions add `attachments_exception: true` to the data.
218
226
 
@@ -211,7 +211,8 @@ module Sdk4me
211
211
  def expand_header(header = {})
212
212
  header = DEFAULT_HEADER.merge(header)
213
213
  header['X-4me-Account'] = option(:account) if option(:account)
214
- header['AUTHORIZATION'] = 'Basic ' + ["#{option(:api_token)}:x"].pack('m*').gsub(/\s/, '')
214
+ token_and_password = option(:api_token).include?(':') ? option(:api_token) : "#{option(:api_token)}:x"
215
+ header['AUTHORIZATION'] = 'Basic ' + [token_and_password].pack('m*').gsub(/\s/, '')
215
216
  if option(:source)
216
217
  header['X-4me-Source'] = option(:source)
217
218
  header['HTTP_USER_AGENT'] = option(:source)
@@ -8,21 +8,64 @@ module Sdk4me
8
8
  @client = client
9
9
  end
10
10
 
11
- # upload the attachments in :attachments to 4me and return the data with the uploaded attachment info
11
+ # upload the attachments and return the data with the uploaded attachment info
12
+ # Two flavours available
13
+ # * data[:attachments]
14
+ # * data[:note] containing text with '[attachment:/tmp/images/green_fuzz.jpg]'
12
15
  def upload_attachments!(path, data)
13
- raise_exceptions = !!data.delete(:attachments_exception)
16
+ upload_options = {
17
+ raise_exceptions: !!data.delete(:attachments_exception),
18
+ attachments_field: attachments_field(path),
19
+ }
20
+ uploaded_attachments = upload_normal_attachments!(path, data, upload_options)
21
+ uploaded_attachments += upload_inline_attachments!(path, data, upload_options)
22
+ # jsonify the attachments, if any were uploaded
23
+ data[upload_options[:attachments_field]] = uploaded_attachments.compact.to_json if uploaded_attachments.compact.any?
24
+ end
25
+
26
+ private
27
+
28
+ # upload the attachments in :attachments to 4me and return the data with the uploaded attachment info
29
+ def upload_normal_attachments!(path, data, upload_options)
14
30
  attachments = [data.delete(:attachments)].flatten.compact
15
- return if attachments.empty?
31
+ return [] if attachments.empty?
16
32
 
17
- # retrieve the upload configuration for this record from 4me
18
- storage = @client.get(path =~ /\d+$/ ? path : "#{path}/new", {attachment_upload_token: true}, @client.send(:expand_header))[:storage_upload]
19
- report_error("Attachments not allowed for #{path}", raise_exceptions) and return unless storage
33
+ upload_options[:storage] ||= storage(path, upload_options[:raise_exceptions])
34
+ return [] unless upload_options[:storage]
20
35
 
21
- # upload each attachment and store the {key, filesize} has in the note_attachments parameter
22
- data[attachments_field(path)] = attachments.map {|attachment| upload_attachment(storage, attachment, raise_exceptions) }.compact.to_json
36
+ attachments.map do |attachment|
37
+ upload_attachment(upload_options[:storage], attachment, upload_options[:raise_exceptions])
38
+ end
23
39
  end
24
40
 
25
- private
41
+ INLINE_ATTACHMENT_REGEXP = /\[attachment:([^\]]+)\]/.freeze
42
+ # upload any '[attachment:/tmp/images/green_fuzz.jpg]' in :note text field to 4me as inline attachment and add the s3 key to the text
43
+ def upload_inline_attachments!(path, data, upload_options)
44
+ text_field = upload_options[:attachments_field].to_s.gsub('_attachments', '').to_sym
45
+ return [] unless (data[text_field] || '') =~ INLINE_ATTACHMENT_REGEXP
46
+
47
+ upload_options[:storage] ||= storage(path, upload_options[:raise_exceptions])
48
+ return [] unless upload_options[:storage]
49
+
50
+ attachments = []
51
+ data[text_field] = data[text_field].gsub(INLINE_ATTACHMENT_REGEXP) do |full_match|
52
+ attachment_details = upload_attachment(upload_options[:storage], $~[1], upload_options[:raise_exceptions])
53
+ if attachment_details
54
+ attachments << attachment_details.merge(inline: true)
55
+ "![](#{attachment_details[:key]})" # magic markdown for inline attachments
56
+ else
57
+ full_match
58
+ end
59
+ end
60
+ attachments
61
+ end
62
+
63
+ def storage(path, raise_exceptions)
64
+ # retrieve the upload configuration for this record from 4me
65
+ storage = @client.get(path =~ /\d+$/ ? path : "#{path}/new", {attachment_upload_token: true}, @client.send(:expand_header))[:storage_upload]
66
+ report_error("Attachments not allowed for #{path}", raise_exceptions) unless storage
67
+ storage
68
+ end
26
69
 
27
70
  def attachments_field(path)
28
71
  case path
@@ -1,5 +1,5 @@
1
1
  module Sdk4me
2
2
  class Client
3
- VERSION = '1.1.7'
3
+ VERSION = '1.1.8'
4
4
  end
5
5
  end
@@ -8,69 +8,135 @@ describe Sdk4me::Attachments do
8
8
  end
9
9
 
10
10
  context 'upload_attachments!' do
11
- it 'should not do anything when no :attachments are present' do
12
- expect(@attachments.upload_attachments!('/requests', {status: :in_progress})).to be_nil
13
- end
11
+ context 'normal' do
12
+ it 'should not do anything when no :attachments are present' do
13
+ expect(@attachments.upload_attachments!('/requests', {status: :in_progress})).to be_nil
14
+ end
14
15
 
15
- it 'should not do anything when :attachments is nil' do
16
- expect(@attachments.upload_attachments!('/requests', {attachments: nil})).to be_nil
17
- end
16
+ it 'should not do anything when :attachments is nil' do
17
+ expect(@attachments.upload_attachments!('/requests', {attachments: nil})).to be_nil
18
+ end
18
19
 
19
- it 'should not do anything when :attachments is empty' do
20
- expect(@attachments.upload_attachments!('/requests', {attachments: []})).to be_nil
21
- expect(@attachments.upload_attachments!('/requests', {attachments: [nil]})).to be_nil
22
- end
20
+ it 'should not do anything when :attachments is empty' do
21
+ expect(@attachments.upload_attachments!('/requests', {attachments: []})).to be_nil
22
+ expect(@attachments.upload_attachments!('/requests', {attachments: [nil]})).to be_nil
23
+ end
23
24
 
24
- it 'should show a error if no attachment may be uploaded' do
25
- stub_request(:get, 'https://api.4me.com/v1/sites/1?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {name: 'site 1'}.to_json)
26
- expect_log('Attachments not allowed for /sites/1', :error)
27
- expect(@attachments.upload_attachments!('/sites/1', {attachments: ['file1.png']})).to be_nil
28
- end
25
+ it 'should show a error if no attachment may be uploaded' do
26
+ stub_request(:get, 'https://api.4me.com/v1/sites/1?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {name: 'site 1'}.to_json)
27
+ expect_log('Attachments not allowed for /sites/1', :error)
28
+ expect(@attachments.upload_attachments!('/sites/1', {attachments: ['file1.png']})).to be_nil
29
+ end
29
30
 
30
- it 'should raise an exception if no attachment may be uploaded' do
31
- stub_request(:get, 'https://api.4me.com/v1/sites/1?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {name: 'site 1'}.to_json)
32
- message = 'Attachments not allowed for /sites/1'
33
- expect{ @attachments.upload_attachments!('/sites/1', {attachments: ['file1.png'], attachments_exception: true}) }.to raise_error(::Sdk4me::UploadFailed, message)
34
- end
31
+ it 'should raise an exception if no attachment may be uploaded' do
32
+ stub_request(:get, 'https://api.4me.com/v1/sites/1?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {name: 'site 1'}.to_json)
33
+ message = 'Attachments not allowed for /sites/1'
34
+ expect{ @attachments.upload_attachments!('/sites/1', {attachments: ['file1.png'], attachments_exception: true}) }.to raise_error(::Sdk4me::UploadFailed, message)
35
+ end
35
36
 
36
- it 'should add /new to the path for new records' do
37
- stub_request(:get, 'https://api.4me.com/v1/sites/new?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {missing: 'storage'}.to_json)
38
- expect_log('Attachments not allowed for /sites', :error)
39
- expect(@attachments.upload_attachments!('/sites', {attachments: ['file1.png']})).to be_nil
40
- end
37
+ it 'should add /new to the path for new records' do
38
+ stub_request(:get, 'https://api.4me.com/v1/sites/new?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {missing: 'storage'}.to_json)
39
+ expect_log('Attachments not allowed for /sites', :error)
40
+ expect(@attachments.upload_attachments!('/sites', {attachments: ['file1.png']})).to be_nil
41
+ end
41
42
 
42
- [ [:requests, :note],
43
- [:problems, :note],
44
- [:contracts, :remarks],
45
- [:cis, :remarks],
46
- [:flsas, :remarks],
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)
43
+ [ [:requests, :note],
44
+ [:problems, :note],
45
+ [:contracts, :remarks],
46
+ [:cis, :remarks],
47
+ [:flsas, :remarks],
48
+ [:slas, :remarks],
49
+ [:service_instances, :remarks],
50
+ [:service_offerings, :summary],
51
+ [:any_other_model, :note]].each do |model, attribute|
52
+
53
+ it "should replace :attachments with :#{attribute}_attachments after upload at /#{model}" do
54
+ 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)
55
+ expect(@attachments).to receive(:upload_attachment).with('conf', 'file1.png', false).ordered{ 'uploaded file1.png' }
56
+ expect(@attachments).to receive(:upload_attachment).with('conf', 'file2.zip', false).ordered{ 'uploaded file2.zip' }
57
+ data = {leave: 'me alone', attachments: %w(file1.png file2.zip)}
58
+ @attachments.upload_attachments!("/#{model}", data)
59
+ expect(data[:attachments]).to be_nil
60
+ expect(data[:leave]).to eq('me alone')
61
+ expect(data[:"#{attribute}_attachments"]).to eq(['uploaded file1.png', 'uploaded file2.zip'].to_json)
62
+ end
63
+ end
64
+
65
+ it 'should set raise_exception flag to true when :attachments_exception is set' do
66
+ stub_request(:get, 'https://api.4me.com/v1/requests/new?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {storage_upload: 'conf'}.to_json)
67
+ expect(@attachments).to receive(:upload_attachment).with('conf', 'file1.png', true).ordered{ 'uploaded file1.png' }
68
+ data = {leave: 'me alone', attachments: 'file1.png', attachments_exception: true}
69
+ @attachments.upload_attachments!('/requests', data)
58
70
  expect(data[:attachments]).to be_nil
71
+ expect(data[:attachments_exception]).to be_nil
59
72
  expect(data[:leave]).to eq('me alone')
60
- expect(data[:"#{attribute}_attachments"]).to eq(['uploaded file1.png', 'uploaded file2.zip'].to_json)
73
+ expect(data[:note_attachments]).to eq(['uploaded file1.png'].to_json)
61
74
  end
62
75
  end
63
76
 
64
- it 'should set raise_exception flag to true when :attachments_exception is set' do
65
- stub_request(:get, 'https://api.4me.com/v1/requests/new?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {storage_upload: 'conf'}.to_json)
66
- expect(@attachments).to receive(:upload_attachment).with('conf', 'file1.png', true).ordered{ 'uploaded file1.png' }
67
- data = {leave: 'me alone', attachments: 'file1.png', attachments_exception: true}
68
- @attachments.upload_attachments!('/requests', data)
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)
77
+ context 'inline' do
78
+ it 'should not do anything when no [attachment:...] is present in the note' do
79
+ expect(@attachments.upload_attachments!('/requests', {note: '[attachmen:/type]'})).to be_nil
80
+ end
81
+
82
+ it 'should not do anything when attachment is empty' do
83
+ expect(@attachments.upload_attachments!('/requests', {note: '[attachment:]'})).to be_nil
84
+ end
85
+
86
+ it 'should show a error if no attachment may be uploaded' do
87
+ stub_request(:get, 'https://api.4me.com/v1/sites/1?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {name: 'site 1'}.to_json)
88
+ expect_log('Attachments not allowed for /sites/1', :error)
89
+ expect(@attachments.upload_attachments!('/sites/1', {note: '[attachment:file1.png]'})).to be_nil
90
+ end
91
+
92
+ it 'should raise an exception if no attachment may be uploaded' do
93
+ stub_request(:get, 'https://api.4me.com/v1/sites/1?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {name: 'site 1'}.to_json)
94
+ message = 'Attachments not allowed for /sites/1'
95
+ expect{ @attachments.upload_attachments!('/sites/1', {note: '[attachment:file1.png]', attachments_exception: true}) }.to raise_error(::Sdk4me::UploadFailed, message)
96
+ end
97
+
98
+ it 'should add /new to the path for new records' do
99
+ stub_request(:get, 'https://api.4me.com/v1/sites/new?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {missing: 'storage'}.to_json)
100
+ expect_log('Attachments not allowed for /sites', :error)
101
+ expect(@attachments.upload_attachments!('/sites', {note: '[attachment:file1.png]'})).to be_nil
102
+ end
103
+
104
+ [ [:requests, :note],
105
+ [:problems, :note],
106
+ [:contracts, :remarks],
107
+ [:cis, :remarks],
108
+ [:flsas, :remarks],
109
+ [:slas, :remarks],
110
+ [:service_instances, :remarks],
111
+ [:service_offerings, :summary],
112
+ [:any_other_model, :note]].each do |model, attribute|
113
+
114
+ it "should replace :attachments with :#{attribute}_attachments after upload at /#{model}" do
115
+ 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)
116
+ expect(@attachments).to receive(:upload_attachment).with('conf', 'file1.png', false).ordered{ {key: 'uploaded file1.png'} }
117
+ expect(@attachments).to receive(:upload_attachment).with('conf', 'file2.zip', false).ordered{ {key: 'uploaded file2.zip'} }
118
+ data = {leave: 'me alone', attribute => '[attachment:file1.png] and [attachment:file2.zip]'}
119
+ @attachments.upload_attachments!("/#{model}", data)
120
+ expect(data[:attachments]).to be_nil
121
+ expect(data[:leave]).to eq('me alone')
122
+ expect(data[:"#{attribute}_attachments"]).to eq([{key: 'uploaded file1.png', inline: true}, {key: 'uploaded file2.zip', inline: true}].to_json)
123
+ expect(data[:"#{attribute}"]).to eq('![](uploaded file1.png) and ![](uploaded file2.zip)')
124
+ end
125
+ end
126
+
127
+ it 'should set raise_exception flag to true when :attachments_exception is set' do
128
+ stub_request(:get, 'https://api.4me.com/v1/requests/new?attachment_upload_token=true').with(basic_auth: ['secret', 'x']).to_return(body: {storage_upload: 'conf'}.to_json)
129
+ expect(@attachments).to receive(:upload_attachment).with('conf', 'file1.png', true).ordered{ {key: 'uploaded file1.png'} }
130
+ data = {leave: 'me alone', note: '[attachment:file1.png]', attachments_exception: true}
131
+ @attachments.upload_attachments!('/requests', data)
132
+ expect(data[:attachments]).to be_nil
133
+ expect(data[:attachments_exception]).to be_nil
134
+ expect(data[:leave]).to eq('me alone')
135
+ expect(data[:note_attachments]).to eq([{key: 'uploaded file1.png', inline: true}].to_json)
136
+ expect(data[:note]).to eq('![](uploaded file1.png)')
137
+ end
73
138
  end
139
+
74
140
  end
75
141
 
76
142
  context 'upload_attachment' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: 4me-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.7
4
+ version: 1.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - 4me
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-01 00:00:00.000000000 Z
11
+ date: 2020-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem_config