roust 1.7.2 → 1.8.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 +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +20 -3
- data/lib/roust/ticket.rb +130 -3
- data/lib/roust/version.rb +1 -1
- data/roust.gemspec +1 -1
- data/spec/mocks/ticket-150-links-update.txt +3 -0
- data/spec/mocks/ticket-150-links.txt +12 -0
- data/spec/mocks/ticket-151-links-update.txt +3 -0
- data/spec/mocks/ticket-151-links.txt +4 -0
- data/spec/roust/ticket_spec.rb +62 -2
- data/spec/spec_helper.rb +1 -0
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adb62caf4380e165a89d2f82f76d73d547714e53
|
4
|
+
data.tar.gz: 9e4df8a5696550388821a139258f317f31866469
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a66ae81eb10c83712f7bf3adfe96d4e6d01ca764eb15bbfc5164c2e9cec56e3c30d78e9c645a73cdd85d23e690f2921e55cd983d2d28261a08415f997021b314
|
7
|
+
data.tar.gz: d72f69e97951c026451cef70e2c5c2cd1a11963ed2a2c2bbe954e2e2c3b9263a2b0594c97bf6ab38ecbe1034630a792f1fb87539515c32a445be7d18f984ee30
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -55,11 +55,28 @@ rt.history("1", :format => "short") # => [["1", "Ticket created by alice"], ["2"
|
|
55
55
|
rt.history("1", :format => "long") # => [{"id"=>"1", "ticket"=>"1", "timetaken"=>"0", "type"=>"Create", "field"=>"", "oldvalue"=>"", "newvalue"=>"", "data"=>"", "description"=>"Ticket created by alice" }, … ]
|
56
56
|
|
57
57
|
# Create ticket
|
58
|
+
body = """This is a multiline
|
59
|
+
text body"""
|
60
|
+
|
61
|
+
attrs = {
|
62
|
+
'Subject' => 'A test ticket',
|
63
|
+
'Queue' => 'sales',
|
64
|
+
'Owner' => 'Nobody',
|
65
|
+
'Requestors' => 'a@test.com, b@test.com',
|
66
|
+
'Cc' => 'c@test.com, d@test.com',
|
67
|
+
'AdminCc' => 'e@test.com, f@test.com',
|
68
|
+
'Text' => body
|
69
|
+
}
|
70
|
+
rt.ticket_create(attrs) # => { 'Subject' => 'a test ticket', 'Queue' => 'sales', … }
|
71
|
+
|
72
|
+
# Update ticket
|
58
73
|
attrs = {
|
59
|
-
'Subject' => '
|
60
|
-
'
|
74
|
+
'Subject' => 'A new subject'
|
75
|
+
'Owner' => 'alice'
|
61
76
|
}
|
62
|
-
|
77
|
+
|
78
|
+
rt.ticket_update(ticket_id, attrs) # => { 'Subject' => 'a test ticket', 'Queue' => 'sales', … }
|
79
|
+
|
63
80
|
|
64
81
|
# Fetch user details
|
65
82
|
rt.user("dan@us.example") # => {"id"=>"user/160000", "name"=>"dan", "password"=>"********", "emailaddress"=>"dan@us.example", "realname"=>"Dan Smith", "nickname"=>"dan", … }
|
data/lib/roust/ticket.rb
CHANGED
@@ -136,21 +136,148 @@ class Roust
|
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
|
-
def
|
139
|
+
def ticket_links_show(id)
|
140
140
|
response = self.class.get("/ticket/#{id}/links")
|
141
141
|
body, _ = explode_response(response)
|
142
142
|
|
143
143
|
hash = body_to_hash(body)
|
144
144
|
id = hash.delete('id').split('/')[1]
|
145
145
|
cleaned_hash = hash.map do |k, v|
|
146
|
-
ids = v.split(/\s*,\s*/).map
|
146
|
+
ids = v.split(/\s*,\s*/).map do |url|
|
147
|
+
url =~ /^fsck\.com\-/ ? url.split('/').last : url
|
148
|
+
end
|
147
149
|
[ k, ids ]
|
148
150
|
end
|
149
151
|
|
150
152
|
Hash[cleaned_hash].merge('id' => id)
|
151
153
|
end
|
152
154
|
|
153
|
-
#
|
155
|
+
# Add links on a ticket.
|
156
|
+
#
|
157
|
+
# @param id [Fixnum] the id of the ticket to add links on.
|
158
|
+
# @param attrs [Hash] the links to add.
|
159
|
+
# @return [Hash] all the links on the ticket after the add action.
|
160
|
+
#
|
161
|
+
# Example attrs:
|
162
|
+
#
|
163
|
+
# {
|
164
|
+
# "RefersTo" => [
|
165
|
+
# "http://us.example",
|
166
|
+
# "http://them.example",
|
167
|
+
# ]
|
168
|
+
# }
|
169
|
+
#
|
170
|
+
def ticket_links_add(id, attrs)
|
171
|
+
# Get the current links state
|
172
|
+
current_links = ticket_links_show(id)
|
173
|
+
current_links.delete('id')
|
174
|
+
desired_links = Marshal.load(Marshal.dump(current_links))
|
175
|
+
|
176
|
+
# Build up the desired link state
|
177
|
+
attrs.each do |k,v|
|
178
|
+
desired_links[k] ||= []
|
179
|
+
v.each do |link|
|
180
|
+
desired_links[k] << link
|
181
|
+
end
|
182
|
+
desired_links[k].uniq!
|
183
|
+
end
|
184
|
+
|
185
|
+
# Remove all links before we add any new ones. Fucking RT API.
|
186
|
+
ticket_links_remove(id, current_links)
|
187
|
+
|
188
|
+
# Work out how many times we'll need to make the same request until we
|
189
|
+
# get the desired state.
|
190
|
+
tries = desired_links.max_by {|k,v| v.size }.last.size
|
191
|
+
|
192
|
+
tries.times do
|
193
|
+
content = compose_content('ticket', id, desired_links)
|
194
|
+
|
195
|
+
response = self.class.post(
|
196
|
+
"/ticket/#{id}/links",
|
197
|
+
:body => {
|
198
|
+
:content => content
|
199
|
+
}
|
200
|
+
)
|
201
|
+
|
202
|
+
body, _ = explode_response(response)
|
203
|
+
|
204
|
+
case body
|
205
|
+
when /^# Links for ticket (\d+) updated/
|
206
|
+
id = $1
|
207
|
+
#ticket_links_show(id)
|
208
|
+
when /^# You are not allowed to modify ticket \d+/
|
209
|
+
raise Unauthorized, body
|
210
|
+
when /^# Syntax error/
|
211
|
+
raise SyntaxError, body
|
212
|
+
else
|
213
|
+
raise UnhandledResponse, body
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
ticket_links_show(id)
|
218
|
+
end
|
219
|
+
|
220
|
+
# Remove links on a ticket.
|
221
|
+
#
|
222
|
+
# @param id [Fixnum] the id of the ticket to remove links on.
|
223
|
+
# @param attrs [Hash] the links to remove.
|
224
|
+
# @return [Hash] all the links on the ticket after the remove action.
|
225
|
+
#
|
226
|
+
# Example attrs:
|
227
|
+
#
|
228
|
+
# {
|
229
|
+
# "DependsOn" => [
|
230
|
+
# "http://us.example",
|
231
|
+
# "http://them.example",
|
232
|
+
# ],
|
233
|
+
# "RefersTo" => [
|
234
|
+
# "http://others.example",
|
235
|
+
# ],
|
236
|
+
# }
|
237
|
+
#
|
238
|
+
def ticket_links_remove(id, attrs)
|
239
|
+
# Get the current links state
|
240
|
+
current_links = ticket_links_show(id)
|
241
|
+
desired_links = Marshal.load(Marshal.dump(current_links))
|
242
|
+
|
243
|
+
# Build up the desired link state
|
244
|
+
attrs.each do |k,v|
|
245
|
+
v.each do |link|
|
246
|
+
desired_links[k].delete(link) if desired_links[k]
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# Work out how many times we'll need to make the same request until we
|
251
|
+
# get the desired state.
|
252
|
+
tries = attrs.empty? ? 0 : attrs.max_by {|k,v| v.size }.last.size
|
253
|
+
|
254
|
+
tries.times do
|
255
|
+
content = compose_content('ticket', id, desired_links)
|
256
|
+
|
257
|
+
response = self.class.post(
|
258
|
+
"/ticket/#{id}/links",
|
259
|
+
:body => {
|
260
|
+
:content => content
|
261
|
+
}
|
262
|
+
)
|
263
|
+
|
264
|
+
body, _ = explode_response(response)
|
265
|
+
|
266
|
+
case body
|
267
|
+
when /^# Links for ticket (\d+) updated/
|
268
|
+
id = $1
|
269
|
+
when /^# You are not allowed to modify ticket \d+/
|
270
|
+
raise Unauthorized, body
|
271
|
+
when /^# Syntax error/
|
272
|
+
raise SyntaxError, body
|
273
|
+
else
|
274
|
+
raise UnhandledResponse, body
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
ticket_links_show(id)
|
279
|
+
end
|
280
|
+
|
154
281
|
# TODO(auxesis): add method for listing ticket attachments
|
155
282
|
# TODO(auxesis): add method for getting a ticket attachment
|
156
283
|
# TODO(auxesis): add method for commenting on a ticket
|
data/lib/roust/version.rb
CHANGED
data/roust.gemspec
CHANGED
data/spec/roust/ticket_spec.rb
CHANGED
@@ -65,6 +65,26 @@ describe Roust do
|
|
65
65
|
:body => mocks_path.join('ticket-100-show.txt').read,
|
66
66
|
:headers => {})
|
67
67
|
|
68
|
+
stub_request(:get, "http://rt.example.org/REST/1.0/ticket/150/links")
|
69
|
+
.to_return(:status => 200,
|
70
|
+
:body => mocks_path.join('ticket-150-links.txt').read,
|
71
|
+
:headers => {})
|
72
|
+
|
73
|
+
stub_request(:post, "http://rt.example.org/REST/1.0/ticket/150/links")
|
74
|
+
.to_return(:status => 200,
|
75
|
+
:body => mocks_path.join('ticket-150-links-update.txt').read,
|
76
|
+
:headers => {})
|
77
|
+
|
78
|
+
stub_request(:get, "http://rt.example.org/REST/1.0/ticket/151/links")
|
79
|
+
.to_return(:status => 200,
|
80
|
+
:body => mocks_path.join('ticket-151-links.txt').read,
|
81
|
+
:headers => {})
|
82
|
+
|
83
|
+
stub_request(:post, "http://rt.example.org/REST/1.0/ticket/151/links")
|
84
|
+
.to_return(:status => 200,
|
85
|
+
:body => mocks_path.join('ticket-151-links-update.txt').read,
|
86
|
+
:headers => {})
|
87
|
+
|
68
88
|
@rt = Roust.new(credentials)
|
69
89
|
expect(@rt.authenticated?).to eq(true)
|
70
90
|
end
|
@@ -147,7 +167,7 @@ describe Roust do
|
|
147
167
|
end
|
148
168
|
|
149
169
|
it 'can list linked tickets on individual tickets' do
|
150
|
-
links = @rt.
|
170
|
+
links = @rt.ticket_links_show('3')
|
151
171
|
|
152
172
|
expect(links['id']).to eq('3')
|
153
173
|
|
@@ -169,7 +189,7 @@ describe Roust do
|
|
169
189
|
end
|
170
190
|
end
|
171
191
|
|
172
|
-
it 'transforms attribute case when
|
192
|
+
it 'transforms attribute case when manipulating principals' do
|
173
193
|
attrs = {
|
174
194
|
'requestors' => 'alice@them.example,bob@them.example',
|
175
195
|
'cc' => 'charlie@them.example',
|
@@ -185,5 +205,45 @@ describe Roust do
|
|
185
205
|
query['content'] =~ /AdminCc:/
|
186
206
|
}
|
187
207
|
end
|
208
|
+
|
209
|
+
it 'adds links' do
|
210
|
+
attrs = {
|
211
|
+
'RefersTo' => [
|
212
|
+
'http://google.com/',
|
213
|
+
'http://google.com.au/',
|
214
|
+
'http://google.co.uk/',
|
215
|
+
'http://google.ca/',
|
216
|
+
],
|
217
|
+
'DependsOn' => [
|
218
|
+
'http://amazon.com/',
|
219
|
+
'http://amazon.co.uk/',
|
220
|
+
]
|
221
|
+
}
|
222
|
+
ticket = @rt.ticket_links_add(150, attrs)
|
223
|
+
|
224
|
+
expect(ticket['RefersTo'].size).to eq(attrs['RefersTo'].size)
|
225
|
+
expect(ticket['DependsOn'].size).to eq(attrs['DependsOn'].size)
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'removes links' do
|
229
|
+
attrs = {
|
230
|
+
'RefersTo' => [
|
231
|
+
'http://google.com/',
|
232
|
+
'http://google.com.au/',
|
233
|
+
'http://google.co.uk/',
|
234
|
+
'http://google.ca/',
|
235
|
+
],
|
236
|
+
'DependsOn' => [
|
237
|
+
'http://amazon.com/',
|
238
|
+
'http://amazon.co.uk/',
|
239
|
+
]
|
240
|
+
}
|
241
|
+
ticket = @rt.ticket_links_remove(151, attrs)
|
242
|
+
|
243
|
+
expect(ticket['RefersTo']).to eq(nil)
|
244
|
+
expect(ticket['DependsOn']).to eq(nil)
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'transforms attribute case when manipulating links'
|
188
248
|
end
|
189
249
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roust
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lindsay Holmwood
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mail
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 4.
|
47
|
+
version: 4.0.10
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 4.
|
54
|
+
version: 4.0.10
|
55
55
|
description: Roust is a Ruby API client to access Request Tracker's REST interface.
|
56
56
|
email:
|
57
57
|
- lindsay@holmwood.id.au
|
@@ -86,6 +86,10 @@ files:
|
|
86
86
|
- spec/mocks/ticket-1-show.txt
|
87
87
|
- spec/mocks/ticket-100-show.txt
|
88
88
|
- spec/mocks/ticket-100-update.txt
|
89
|
+
- spec/mocks/ticket-150-links-update.txt
|
90
|
+
- spec/mocks/ticket-150-links.txt
|
91
|
+
- spec/mocks/ticket-151-links-update.txt
|
92
|
+
- spec/mocks/ticket-151-links.txt
|
89
93
|
- spec/mocks/ticket-3-links.txt
|
90
94
|
- spec/mocks/ticket-99-show.txt
|
91
95
|
- spec/mocks/ticket-create.txt
|
@@ -136,6 +140,10 @@ test_files:
|
|
136
140
|
- spec/mocks/ticket-1-show.txt
|
137
141
|
- spec/mocks/ticket-100-show.txt
|
138
142
|
- spec/mocks/ticket-100-update.txt
|
143
|
+
- spec/mocks/ticket-150-links-update.txt
|
144
|
+
- spec/mocks/ticket-150-links.txt
|
145
|
+
- spec/mocks/ticket-151-links-update.txt
|
146
|
+
- spec/mocks/ticket-151-links.txt
|
139
147
|
- spec/mocks/ticket-3-links.txt
|
140
148
|
- spec/mocks/ticket-99-show.txt
|
141
149
|
- spec/mocks/ticket-create.txt
|