4me-sdk 1.1.7 → 1.1.8

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 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