xfrtuc 0.0.1 → 0.0.2
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/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +40 -0
- data/LICENSE +22 -0
- data/lib/xfrtuc.rb +133 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/xfrtuc_spec.rb +542 -0
- data/xfrtuc.gemspec +22 -0
- metadata +15 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5c7aa88517243fa936da71cd2baf17530348c95
|
4
|
+
data.tar.gz: 4b9e3d6c5a7948cdeeab336a5d1993500f31cc27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a54f5ecd5c7d4b3498641472f56255bc7126002710157a135092ea12ec1e84ce2d74d6e2777086ac426307eef79b8d5fda8175336ba886d6a3826f9a8a4037a2
|
7
|
+
data.tar.gz: 8fbb69a8ab07ac0bc57d689cf232c504fba2c9a99fa6eecf1be2985370b4f02330b9463d07a6ecc534f4cd48a188498933bbc2080197c5b66d93b47debae9d47
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.2
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
xfrtuc (0.0.2)
|
5
|
+
rest-client (~> 1.6)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.2.5)
|
11
|
+
json (1.8.1)
|
12
|
+
mime-types (1.25.1)
|
13
|
+
rack (1.5.2)
|
14
|
+
rdoc (4.1.1)
|
15
|
+
json (~> 1.4)
|
16
|
+
rest-client (1.6.8)
|
17
|
+
mime-types (~> 1.16)
|
18
|
+
rdoc (>= 2.4.2)
|
19
|
+
rspec (3.0.0)
|
20
|
+
rspec-core (~> 3.0.0)
|
21
|
+
rspec-expectations (~> 3.0.0)
|
22
|
+
rspec-mocks (~> 3.0.0)
|
23
|
+
rspec-core (3.0.4)
|
24
|
+
rspec-support (~> 3.0.0)
|
25
|
+
rspec-expectations (3.0.4)
|
26
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
+
rspec-support (~> 3.0.0)
|
28
|
+
rspec-mocks (3.0.4)
|
29
|
+
rspec-support (~> 3.0.0)
|
30
|
+
rspec-support (3.0.4)
|
31
|
+
sham_rack (1.3.6)
|
32
|
+
rack
|
33
|
+
|
34
|
+
PLATFORMS
|
35
|
+
ruby
|
36
|
+
|
37
|
+
DEPENDENCIES
|
38
|
+
rspec (~> 3.0)
|
39
|
+
sham_rack (~> 1.3)
|
40
|
+
xfrtuc!
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Maciek Sakrejda
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/xfrtuc.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'rest_client'
|
3
|
+
|
4
|
+
module Xfrtuc
|
5
|
+
VERSION = "0.0.2"
|
6
|
+
|
7
|
+
class Client
|
8
|
+
attr_reader :base_url
|
9
|
+
|
10
|
+
def initialize(username, password, base_url: 'https://transferatu.heroku.com')
|
11
|
+
@base_url = base_url
|
12
|
+
@username = username
|
13
|
+
@password = password
|
14
|
+
@resource = RestClient::Resource.new(base_url,
|
15
|
+
user: username,
|
16
|
+
password: password,
|
17
|
+
headers: { content_type: 'application/json',
|
18
|
+
accept: 'application/json' })
|
19
|
+
end
|
20
|
+
|
21
|
+
def transfer
|
22
|
+
@xfer_client ||= Xfrtuc::Transfer.new(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def schedule
|
26
|
+
@sched_client ||= Xfrtuc::Schedule.new(self)
|
27
|
+
end
|
28
|
+
|
29
|
+
def group(name=nil)
|
30
|
+
if name.nil?
|
31
|
+
@group_client ||= Xfrtuc::Group.new(self)
|
32
|
+
else
|
33
|
+
self.class.new(@username, @password,
|
34
|
+
base_url: @base_url + "/groups/#{URI.encode(name)}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def get(path, params={})
|
39
|
+
JSON.parse(@resource[path].get(params))
|
40
|
+
end
|
41
|
+
|
42
|
+
def post(path, data)
|
43
|
+
JSON.parse(@resource[path].post(JSON.generate(data)))
|
44
|
+
end
|
45
|
+
|
46
|
+
def delete(path)
|
47
|
+
JSON.parse(@resource[path].delete)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class ApiEndpoint
|
52
|
+
def initialize(client)
|
53
|
+
@client = client
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
|
58
|
+
attr_reader :client
|
59
|
+
end
|
60
|
+
|
61
|
+
class Group < ApiEndpoint
|
62
|
+
def initialize(client); super; end
|
63
|
+
|
64
|
+
def info(name)
|
65
|
+
client.get("/groups/#{URI.encode(name)}")
|
66
|
+
end
|
67
|
+
|
68
|
+
def list
|
69
|
+
client.get("/groups")
|
70
|
+
end
|
71
|
+
|
72
|
+
def create(name, log_input_url=nil)
|
73
|
+
client.post("/groups", { name: name, log_input_url: log_input_url })
|
74
|
+
end
|
75
|
+
|
76
|
+
def delete(name)
|
77
|
+
client.delete("/groups/#{URI.encode(name)}")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Transfer < ApiEndpoint
|
82
|
+
def initialize(client); super; end
|
83
|
+
|
84
|
+
def info(id)
|
85
|
+
client.get("/transfers/#{id}")
|
86
|
+
end
|
87
|
+
|
88
|
+
def list
|
89
|
+
client.get("/transfers")
|
90
|
+
end
|
91
|
+
|
92
|
+
def create(from_type:, from_url:, from_name: nil,
|
93
|
+
to_type:, to_url:, to_name: nil, opts: {})
|
94
|
+
client.post("/transfers",
|
95
|
+
from_type: from_type,
|
96
|
+
from_url: from_url,
|
97
|
+
from_name: from_name,
|
98
|
+
to_type: to_type,
|
99
|
+
to_url: to_url,
|
100
|
+
to_name: to_name)
|
101
|
+
end
|
102
|
+
|
103
|
+
def delete(id)
|
104
|
+
client.delete("/transfers/#{URI.encode(id)}")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class Schedule < ApiEndpoint
|
109
|
+
def initialize(client); super; end
|
110
|
+
|
111
|
+
def info(id)
|
112
|
+
client.get("/schedules/#{id}")
|
113
|
+
end
|
114
|
+
|
115
|
+
def list
|
116
|
+
client.get("/schedules")
|
117
|
+
end
|
118
|
+
|
119
|
+
def create(name:, callback_url:, hour:,
|
120
|
+
days: Date::DAYNAMES, timezone: 'UTC')
|
121
|
+
client.post("/schedules",
|
122
|
+
name: name,
|
123
|
+
callback_url: callback_url,
|
124
|
+
hour: hour,
|
125
|
+
days: days,
|
126
|
+
timezone: timezone)
|
127
|
+
end
|
128
|
+
|
129
|
+
def delete(id)
|
130
|
+
client.delete("/schedules/#{URI.encode(id)}")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.run_all_when_everything_filtered = true
|
9
|
+
config.filter_run :focus
|
10
|
+
|
11
|
+
# Run specs in random order to surface order dependencies. If you find an
|
12
|
+
# order dependency and want to debug it, you can fix the order by providing
|
13
|
+
# the seed, which is printed after each run.
|
14
|
+
# --seed 1234
|
15
|
+
config.order = 'random'
|
16
|
+
|
17
|
+
config.expect_with :rspec do |c|
|
18
|
+
c.syntax = :expect
|
19
|
+
end
|
20
|
+
end
|
data/spec/xfrtuc_spec.rb
ADDED
@@ -0,0 +1,542 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'sham_rack'
|
3
|
+
|
4
|
+
module Xfrtuc
|
5
|
+
User = Struct.new(:name, :password)
|
6
|
+
class FakeTransferatu
|
7
|
+
attr_reader :groups
|
8
|
+
|
9
|
+
def headers
|
10
|
+
{ content_type: 'application/json' }
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(*users)
|
14
|
+
@groups = []
|
15
|
+
@transfers = {}
|
16
|
+
@schedules = {}
|
17
|
+
@users = users
|
18
|
+
end
|
19
|
+
|
20
|
+
def active_groups
|
21
|
+
@groups.reject { |g| g[:deleted] }
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_transfer(group_name, &block)
|
25
|
+
@transfers[group_name].find(&block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def last_transfer(group_name)
|
29
|
+
@transfers[group_name].last
|
30
|
+
end
|
31
|
+
|
32
|
+
def last_schedule(group_name)
|
33
|
+
@schedules[group_name].last
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_group(name, log_url=nil)
|
37
|
+
existing_group = @groups.find { |g| g[:name] == name }
|
38
|
+
if existing_group
|
39
|
+
if existing_group[:deleted]
|
40
|
+
# undelete
|
41
|
+
existing_group.delete(:deleted)
|
42
|
+
[201, headers, [ existing_group.to_json ] ]
|
43
|
+
else
|
44
|
+
[409, headers, [ { id: :conflict, message: "group #{name} already exists" }.to_json ] ]
|
45
|
+
end
|
46
|
+
else
|
47
|
+
group = { name: name, log_input_url: log_url }
|
48
|
+
@groups << group
|
49
|
+
@transfers[name] = []
|
50
|
+
@schedules[name] = []
|
51
|
+
[201, headers, [ group.to_json ] ]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def delete_group(name)
|
56
|
+
target = @groups.find { |g| g[:name] == name }
|
57
|
+
if target && target[:deleted]
|
58
|
+
[410, headers, []]
|
59
|
+
elsif target.nil?
|
60
|
+
[404, headers, []]
|
61
|
+
else
|
62
|
+
target[:deleted] = true
|
63
|
+
[200, headers, [target.to_json]]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def list_groups
|
68
|
+
[200, headers, [@groups.to_json]]
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_group(name)
|
72
|
+
[200, headers, [@groups.find { |g| g[:name] == name }.to_json]]
|
73
|
+
end
|
74
|
+
|
75
|
+
def list_transfers(group_name)
|
76
|
+
group = @groups.find { |g| g[:name] == group_name }
|
77
|
+
if group.nil?
|
78
|
+
[404, headers, []]
|
79
|
+
elsif group[:deleted]
|
80
|
+
[410, headers, []]
|
81
|
+
else
|
82
|
+
transfers = @transfers[group_name]
|
83
|
+
[200, headers, [transfers.to_json]]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_transfer(group_name, xfer_id, verbose: false)
|
88
|
+
group = @groups.find { |g| g[:name] == group_name }
|
89
|
+
if group.nil?
|
90
|
+
[404, headers, []]
|
91
|
+
elsif group[:deleted]
|
92
|
+
[409, headers, []]
|
93
|
+
else
|
94
|
+
transfer = @transfers[group_name].find { |xfer| xfer[:uuid] == xfer_id }
|
95
|
+
if verbose
|
96
|
+
result = transfer.dup
|
97
|
+
result[:logs] = []
|
98
|
+
transfer = result
|
99
|
+
end
|
100
|
+
[200, headers, [transfer.to_json]]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def add_transfer(group_name, transfer)
|
105
|
+
unless @transfers.has_key? group_name
|
106
|
+
return [404, headers, []]
|
107
|
+
end
|
108
|
+
xfer = { uuid: SecureRandom.uuid }
|
109
|
+
%w(from_type from_url from_name to_type to_url to_name).each do |key|
|
110
|
+
xfer[key.to_sym] = transfer[key]
|
111
|
+
end
|
112
|
+
|
113
|
+
@transfers[group_name] << xfer
|
114
|
+
[201, {}, [xfer.to_json]]
|
115
|
+
end
|
116
|
+
|
117
|
+
def delete_transfer(group_name, xfer_id)
|
118
|
+
unless @transfers.has_key? group_name
|
119
|
+
return [404, headers, []]
|
120
|
+
end
|
121
|
+
xfer = @transfers[group_name].find { |item| item[:uuid] == xfer_id }
|
122
|
+
if xfer.nil?
|
123
|
+
return [404, headers, []]
|
124
|
+
else
|
125
|
+
@transfers[group_name].delete xfer
|
126
|
+
return [200, headers, [ xfer.to_json ]]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def add_schedule(group_name, schedule)
|
131
|
+
unless @schedules.has_key? group_name
|
132
|
+
return [404, headers, []]
|
133
|
+
end
|
134
|
+
sched = { uuid: SecureRandom.uuid }
|
135
|
+
%w(name callback_url days hour timezone).each do |key|
|
136
|
+
sched[key.to_sym] = schedule[key]
|
137
|
+
end
|
138
|
+
@schedules[group_name] << sched
|
139
|
+
[201, {}, [sched.to_json]]
|
140
|
+
end
|
141
|
+
|
142
|
+
def delete_schedule(group_name, schedule_id)
|
143
|
+
unless @schedules.has_key? group_name
|
144
|
+
return [404, headers, []]
|
145
|
+
end
|
146
|
+
schedule = @schedules[group_name].find { |item| item[:uuid] == schedule_id }
|
147
|
+
if schedule.nil?
|
148
|
+
return [404, headers, []]
|
149
|
+
else
|
150
|
+
@schedules[group_name].delete schedule
|
151
|
+
return [200, headers, [ schedule.to_json ]]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def list_schedules(group_name)
|
156
|
+
group = @groups.find { |g| g[:name] == group_name }
|
157
|
+
if group.nil?
|
158
|
+
[404, headers, []]
|
159
|
+
elsif group[:deleted]
|
160
|
+
[410, headers, []]
|
161
|
+
else
|
162
|
+
schedules = @schedules[group_name]
|
163
|
+
[200, headers, [schedules.to_json]]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def get_schedule(group_name, sched_id)
|
168
|
+
group = @groups.find { |g| g[:name] == group_name }
|
169
|
+
if group.nil?
|
170
|
+
[404, headers, []]
|
171
|
+
elsif group[:deleted]
|
172
|
+
[410, headers, []]
|
173
|
+
else
|
174
|
+
sched = @schedules[group_name].find { |s| s[:uuid] == sched_id }
|
175
|
+
if sched.nil?
|
176
|
+
[404, headers, []]
|
177
|
+
else
|
178
|
+
[200, headers, [sched.to_json]]
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def call(env)
|
184
|
+
unless verify_auth(env)
|
185
|
+
return [401, headers, ["Not authorized"]]
|
186
|
+
end
|
187
|
+
case path(env)
|
188
|
+
when %r{/groups/[^/]+/transfers} then
|
189
|
+
transfers_endpoint(env)
|
190
|
+
when %r{/groups/[^/]+/schedules} then
|
191
|
+
schedules_endpoint(env)
|
192
|
+
when %r{/groups} then
|
193
|
+
groups_endpoint(env)
|
194
|
+
else
|
195
|
+
[404, headers, []]
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def transfers_endpoint(env)
|
200
|
+
path = path(env)
|
201
|
+
group_name, xfer_id = path.match(%r{\A/groups/(.*)/transfers(?:/(.*))?\z}) && [$1, $2]
|
202
|
+
verb = verb(env)
|
203
|
+
if verb == 'POST'
|
204
|
+
body = body(env)
|
205
|
+
xfer = JSON.parse(body)
|
206
|
+
unless xfer_id.nil?
|
207
|
+
[405, headers, []]
|
208
|
+
end
|
209
|
+
add_transfer(group_name, xfer)
|
210
|
+
elsif verb == 'DELETE'
|
211
|
+
unless group_name && xfer_id
|
212
|
+
return [404, headers, []]
|
213
|
+
end
|
214
|
+
delete_transfer(group_name, xfer_id)
|
215
|
+
elsif verb == 'GET'
|
216
|
+
if xfer_id.nil?
|
217
|
+
list_transfers(group_name)
|
218
|
+
else
|
219
|
+
get_transfer(group_name, xfer_id, verbose: params(env)['verbose'])
|
220
|
+
end
|
221
|
+
else
|
222
|
+
[405, headers, []]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def groups_endpoint(env)
|
227
|
+
path = path(env)
|
228
|
+
verb = verb(env)
|
229
|
+
|
230
|
+
group_name = path.match(%r{\A/groups/(.*)\z}) && $1
|
231
|
+
|
232
|
+
if verb == 'GET'
|
233
|
+
if group_name.nil?
|
234
|
+
list_groups
|
235
|
+
else
|
236
|
+
get_group(group_name)
|
237
|
+
end
|
238
|
+
elsif verb == 'POST'
|
239
|
+
body = body(env)
|
240
|
+
data = JSON.parse(body)
|
241
|
+
add_group(data["name"], data["log_input_url"])
|
242
|
+
elsif verb == 'DELETE'
|
243
|
+
name = path.match(%r{\A/groups/(.*)\z}) && $1
|
244
|
+
unless name
|
245
|
+
return [404, headers, []]
|
246
|
+
end
|
247
|
+
delete_group(name)
|
248
|
+
else
|
249
|
+
[405, headers, []]
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def schedules_endpoint(env)
|
254
|
+
path = path(env)
|
255
|
+
group_name, sched_id = path.match(%r{\A/groups/(.*)/schedules(?:/(.*))?\z}) && [$1, $2]
|
256
|
+
verb = verb(env)
|
257
|
+
if verb == 'POST'
|
258
|
+
body = body(env)
|
259
|
+
sched = JSON.parse(body)
|
260
|
+
unless sched_id.nil?
|
261
|
+
[405, headers, []]
|
262
|
+
end
|
263
|
+
add_schedule(group_name, sched)
|
264
|
+
elsif verb == 'DELETE'
|
265
|
+
unless group_name && sched_id
|
266
|
+
return [404, headers, []]
|
267
|
+
end
|
268
|
+
delete_schedule(group_name, sched_id)
|
269
|
+
elsif verb == 'GET'
|
270
|
+
if sched_id.nil?
|
271
|
+
list_schedules(group_name)
|
272
|
+
else
|
273
|
+
get_schedule(group_name, sched_id)
|
274
|
+
end
|
275
|
+
else
|
276
|
+
[405, headers, []]
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
private
|
281
|
+
def verify_auth(env)
|
282
|
+
auth = Rack::Auth::Basic::Request.new(env)
|
283
|
+
if auth.provided? && auth.basic?
|
284
|
+
user, password = auth.credentials
|
285
|
+
@users.any? { |u| u.name == user && u.password == password }
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def path(rack_env)
|
290
|
+
rack_env['PATH_INFO']
|
291
|
+
end
|
292
|
+
|
293
|
+
def verb(rack_env)
|
294
|
+
rack_env['REQUEST_METHOD']
|
295
|
+
end
|
296
|
+
|
297
|
+
def params(rack_env)
|
298
|
+
Rack::Utils.parse_nested_query rack_env['QUERY_STRING']
|
299
|
+
end
|
300
|
+
|
301
|
+
def body(rack_env)
|
302
|
+
raw_body = rack_env["rack.input"].read
|
303
|
+
rack_env["rack.input"].rewind
|
304
|
+
raw_body
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
describe Client do
|
309
|
+
let(:username) { 'reginald' }
|
310
|
+
let(:password) { 'hunter2' }
|
311
|
+
let(:client) { Client.new(username, password) }
|
312
|
+
|
313
|
+
describe "#group" do
|
314
|
+
context "with an argument" do
|
315
|
+
let(:group_name) { 'foo' }
|
316
|
+
|
317
|
+
it "returns a new client rooted at that group's base URL" do
|
318
|
+
group_client = client.group(group_name)
|
319
|
+
expect(group_client).to be_instance_of(Client)
|
320
|
+
expect(group_client.base_url).to eq(client.base_url +
|
321
|
+
"/groups/#{URI.encode(group_name)}")
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
context "without an argument" do
|
326
|
+
it "returns a group client" do
|
327
|
+
expect(client.group).to be_instance_of(Group)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
describe "#transfer" do
|
333
|
+
it "returns a transfer client" do
|
334
|
+
expect(client.transfer).to be_instance_of(Transfer)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
describe "#schedule" do
|
339
|
+
it "returns a schedule client" do
|
340
|
+
expect(client.schedule).to be_instance_of(Schedule)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
describe "api interactions" do
|
346
|
+
let(:username) { 'vivian' }
|
347
|
+
let(:password) { 'hunter2' }
|
348
|
+
let(:user) { User.new(username, password) }
|
349
|
+
let(:fakesferatu) { FakeTransferatu.new(user) }
|
350
|
+
let(:host) { 'transferatu.example.com' }
|
351
|
+
let(:client) { Client.new(username, password, base_url: "https://#{host}") }
|
352
|
+
|
353
|
+
before do
|
354
|
+
ShamRack.mount(fakesferatu, host, 443)
|
355
|
+
end
|
356
|
+
|
357
|
+
after do
|
358
|
+
ShamRack.unmount_all
|
359
|
+
end
|
360
|
+
|
361
|
+
describe Group do
|
362
|
+
let(:group_name) { "edna" }
|
363
|
+
let(:log_input_url) { "https://token:t.foo@logplex.example.com/logs" }
|
364
|
+
|
365
|
+
describe "#create" do
|
366
|
+
it "creates a new group" do
|
367
|
+
client.group.create("edna", log_input_url)
|
368
|
+
group = fakesferatu.groups.last
|
369
|
+
expect(group[:name]).to eq(group_name)
|
370
|
+
expect(group[:log_input_url]).to eq(log_input_url)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
describe "#list" do
|
375
|
+
before do
|
376
|
+
fakesferatu.add_group('g1')
|
377
|
+
fakesferatu.add_group('g2')
|
378
|
+
end
|
379
|
+
|
380
|
+
it "lists existing groups" do
|
381
|
+
result = client.group.list
|
382
|
+
expect(result.count).to eq(2)
|
383
|
+
expect(result.first["name"]).to eq('g1')
|
384
|
+
expect(result.last["name"]).to eq('g2')
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
describe "#info" do
|
389
|
+
before do
|
390
|
+
fakesferatu.add_group(group_name, log_input_url)
|
391
|
+
end
|
392
|
+
|
393
|
+
it "returns details for the given group" do
|
394
|
+
info = client.group.info(group_name)
|
395
|
+
expect(info["name"]).to eq(group_name)
|
396
|
+
expect(info["log_input_url"]).to eq(log_input_url)
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
describe "#delete" do
|
401
|
+
before do
|
402
|
+
fakesferatu.add_group(group_name, log_input_url)
|
403
|
+
end
|
404
|
+
|
405
|
+
it "deletes the given group" do
|
406
|
+
client.group.delete(group_name)
|
407
|
+
deleted_group = fakesferatu.groups.find { |g| g[:name] == group_name }
|
408
|
+
expect(deleted_group[:deleted]).to be true
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
describe Transfer do
|
414
|
+
let(:g) { "edna" }
|
415
|
+
let(:xfer_data) { { from_url: 'postgres:///test1',
|
416
|
+
from_name: 'earl', from_type: 'pg_dump',
|
417
|
+
to_url: 'postgres:///test2',
|
418
|
+
to_name: 'mildred', to_type: 'pg_restore' } }
|
419
|
+
|
420
|
+
before do
|
421
|
+
fakesferatu.add_group(g)
|
422
|
+
end
|
423
|
+
|
424
|
+
describe "#create" do
|
425
|
+
it "creates a new transfer" do
|
426
|
+
client.group(g).transfer.create(xfer_data)
|
427
|
+
xfer = fakesferatu.last_transfer(g)
|
428
|
+
xfer_data.each do |k,v|
|
429
|
+
expect(xfer[k]).to eq(v)
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
describe "#list" do
|
435
|
+
before do
|
436
|
+
2.times { fakesferatu.add_transfer(g, Hash[xfer_data.map { |k, v| [k.to_s, v] }]) }
|
437
|
+
end
|
438
|
+
|
439
|
+
it "lists existing transfers" do
|
440
|
+
xfers = client.group(g).transfer.list
|
441
|
+
expect(xfers.count).to eq(2)
|
442
|
+
xfers.each do |xfer|
|
443
|
+
xfer_data.each do |k,v|
|
444
|
+
expect(xfer[k.to_s]).to eq(v)
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
describe "#info" do
|
451
|
+
before do
|
452
|
+
fakesferatu.add_transfer(g, Hash[xfer_data.map { |k, v| [k.to_s, v] }])
|
453
|
+
end
|
454
|
+
|
455
|
+
it "gets info for an existing transfer" do
|
456
|
+
id = fakesferatu.last_transfer(g)[:uuid]
|
457
|
+
xfer = client.group(g).transfer.info(id)
|
458
|
+
xfer_data.each do |k,v|
|
459
|
+
expect(xfer[k.to_s]).to eq(v)
|
460
|
+
end
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
describe "#delete" do
|
465
|
+
before do
|
466
|
+
fakesferatu.add_transfer(g, Hash[xfer_data.map { |k, v| [k.to_s, v] }])
|
467
|
+
end
|
468
|
+
|
469
|
+
it "deletes the given transfer" do
|
470
|
+
id = fakesferatu.last_transfer(g)[:uuid]
|
471
|
+
client.group(g).transfer.delete(id)
|
472
|
+
expect(fakesferatu.last_transfer(g)).to be_nil
|
473
|
+
end
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
describe Schedule do
|
478
|
+
let(:g) { "edna" }
|
479
|
+
let(:sched_data) { { name: 'my schedule',
|
480
|
+
callback_url: 'https://example.com/callback/foo',
|
481
|
+
hour: 13,
|
482
|
+
days: Date::DAYNAMES,
|
483
|
+
timezone: 'UTC' } }
|
484
|
+
|
485
|
+
before do
|
486
|
+
fakesferatu.add_group(g)
|
487
|
+
end
|
488
|
+
|
489
|
+
describe "#create" do
|
490
|
+
it "creates a new schedule" do
|
491
|
+
client.group(g).schedule.create(sched_data)
|
492
|
+
sched = fakesferatu.last_schedule(g)
|
493
|
+
sched_data.each do |k,v|
|
494
|
+
expect(sched[k]).to eq(v)
|
495
|
+
end
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
describe "#list" do
|
500
|
+
before do
|
501
|
+
2.times { fakesferatu.add_schedule(g, Hash[sched_data.map { |k, v| [k.to_s, v] }]) }
|
502
|
+
end
|
503
|
+
|
504
|
+
it "lists existing schedules" do
|
505
|
+
scheds = client.group(g).schedule.list
|
506
|
+
expect(scheds.count).to eq(2)
|
507
|
+
scheds.each do |sched|
|
508
|
+
sched_data.each do |k,v|
|
509
|
+
expect(sched[k.to_s]).to eq(v)
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
describe "#info" do
|
516
|
+
before do
|
517
|
+
fakesferatu.add_schedule(g, Hash[sched_data.map { |k, v| [k.to_s, v] }])
|
518
|
+
end
|
519
|
+
|
520
|
+
it "gets info for an existing schedule" do
|
521
|
+
id = fakesferatu.last_schedule(g)[:uuid]
|
522
|
+
sched = client.group(g).schedule.info(id)
|
523
|
+
sched_data.each do |k,v|
|
524
|
+
expect(sched[k.to_s]).to eq(v)
|
525
|
+
end
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
describe "#delete" do
|
530
|
+
before do
|
531
|
+
fakesferatu.add_schedule(g, Hash[sched_data.map { |k, v| [k.to_s, v] }])
|
532
|
+
end
|
533
|
+
|
534
|
+
it "deletes the given schedule" do
|
535
|
+
id = fakesferatu.last_schedule(g)[:uuid]
|
536
|
+
client.group(g).schedule.delete(id)
|
537
|
+
expect(fakesferatu.last_schedule(g)).to be_nil
|
538
|
+
end
|
539
|
+
end
|
540
|
+
end
|
541
|
+
end
|
542
|
+
end
|
data/xfrtuc.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'lib/xfrtuc'
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.authors = ["Maciek Sakrejda"]
|
5
|
+
gem.email = ["m.sakrejda@gmail.com"]
|
6
|
+
gem.description = %q{Transferatu client}
|
7
|
+
gem.summary = %q{Transferatu client: see https://github.com/heroku/transferatu}
|
8
|
+
gem.homepage = "https://github.com/heroku/xfrtuc"
|
9
|
+
|
10
|
+
gem.files = `git ls-files`.split($\)
|
11
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
12
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
13
|
+
gem.name = "xfrtuc"
|
14
|
+
gem.require_paths = ["lib"]
|
15
|
+
gem.version = Xfrtuc::VERSION
|
16
|
+
gem.license = "MIT"
|
17
|
+
|
18
|
+
gem.add_runtime_dependency 'rest-client', '~> 1.6'
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rspec', '~> 3.0'
|
21
|
+
gem.add_development_dependency 'sham_rack', '~> 1.3'
|
22
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xfrtuc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maciek Sakrejda
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.6'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,15 @@ email:
|
|
58
58
|
executables: []
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
|
-
files:
|
61
|
+
files:
|
62
|
+
- ".ruby-version"
|
63
|
+
- Gemfile
|
64
|
+
- Gemfile.lock
|
65
|
+
- LICENSE
|
66
|
+
- lib/xfrtuc.rb
|
67
|
+
- spec/spec_helper.rb
|
68
|
+
- spec/xfrtuc_spec.rb
|
69
|
+
- xfrtuc.gemspec
|
62
70
|
homepage: https://github.com/heroku/xfrtuc
|
63
71
|
licenses:
|
64
72
|
- MIT
|
@@ -83,5 +91,7 @@ rubygems_version: 2.2.2
|
|
83
91
|
signing_key:
|
84
92
|
specification_version: 4
|
85
93
|
summary: 'Transferatu client: see https://github.com/heroku/transferatu'
|
86
|
-
test_files:
|
94
|
+
test_files:
|
95
|
+
- spec/spec_helper.rb
|
96
|
+
- spec/xfrtuc_spec.rb
|
87
97
|
has_rdoc:
|