rainforest-cli 1.4.0 → 1.5.0

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
  SHA1:
3
- metadata.gz: 70b8d8fad3a7886f4cdff271fc383dca7614061a
4
- data.tar.gz: b9bc2a5e63a3b95ad661a6d74212f9b01a8cefee
3
+ metadata.gz: 854465637763f313d813365ea7996c8aa2d43808
4
+ data.tar.gz: 44115420d528b8ee03e501eba5fca683439aecca
5
5
  SHA512:
6
- metadata.gz: c0888185bfefe12bf782dbf73c380b5c75dc3d36bdc8971031b467ff716b152989ebfcafe24ded4c67fe2a190f20a5e87a2ef0fcc8c7ddf880af2cf98ec4be9a
7
- data.tar.gz: f0080514d2ae49f2bec4662e746343ab8336e721f97e32f3f00250d340b24444cd4290aaa88bb90b59d7d3bab65676b026c26051ba3247294d62b409e8d574f1
6
+ metadata.gz: 6c8ed4a11a1bca3e2b58672f1ebaae2c3e12265d458107bd19082a193f44cc47bb22113c4d9714190e19bff7fa383ebab4d8cc4d5b260ffc28a3462c72dff957
7
+ data.tar.gz: 3a335dbc44d8a00c7910d5b1eabb66d6f25e0d7f4d4e9f982b2b246d8450ec78706c189afbbf817559d091eb613a81dc19f80a319b857289ae02848add661f32
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Rainforest CLI Changelog
2
2
 
3
+ ## 1.5.0
4
+ - Retry on API exceptions when creating a run. (85830adcef426e64bd72c9d6208881e955a5bb0c, @bbeck)
5
+ - Add `browsers` command. (2a810ec27edfc66ef7bf27d8cb7da1129b05e32b, @epaulet)
6
+ - Add support for files using `app-source-url`. (562e4772e71e8028209d128091ff644f4ae0a9f6, @marianafranco)
7
+ - Remove newlines from test actions and questions when exporting. (e28583b553b5f30b33b232b2e377c109123b11ff, @epaulet)
8
+
3
9
  ## 1.4.0
4
10
  - Support for new `--version` command. (4362c85fe599a02eaa1b772d184be31e692e934e, @epaulet)
5
11
  - Validate duplicate RFML IDs before uploading. (67f71d053c755eaf92c1bd205931e89e903b88c9, @curtis-rainforestqa)
data/README.md CHANGED
@@ -72,6 +72,11 @@ See a list of all of your smart folders and their IDs
72
72
  rainforest folders
73
73
  ```
74
74
 
75
+ See a list of all of your browsers and their IDs
76
+ ```bash
77
+ rainforest browsers
78
+ ```
79
+
75
80
  ## Options
76
81
 
77
82
  ### General
@@ -87,6 +92,7 @@ Rainforest Tests written using RFML have the following format
87
92
  # start_uri: [START_URI]
88
93
  # tags: [TAGS]
89
94
  # site_id: [SITE ID]
95
+ # browsers: [BROWSER IDS]
90
96
  # [OTHER COMMENTS]
91
97
 
92
98
  [ACTION 1]
@@ -116,6 +122,8 @@ Optional Fields:
116
122
  - `SITE ID` - Site ID for the site this test is for. You can find your available
117
123
  site IDs with the `sites` command. Sites can be configured at
118
124
  https://app.rainforestqa.com/settings/sites.
125
+ - `BROWSER IDS` - Comma separated list of browsers for this test. You can reference
126
+ your available browsers with the `browsers` command.
119
127
  - `TAGS` - Comma separated list of your desired tags for this test.
120
128
  - `OTHER COMMENTS` - Any comments you'd like to save to this test. All lines beginning with
121
129
  `#` will be ignored by Rainforest unless they begin with a supported data field,
@@ -35,7 +35,8 @@ module RainforestCli
35
35
  when 'validate' then Validator.new(options).validate
36
36
  when 'upload' then Uploader.new(options).upload
37
37
  when 'export' then Exporter.new(options).export
38
- when 'sites', 'folders' then Resources.new(options).public_send(options.command)
38
+ when 'sites', 'folders', 'browsers'
39
+ Resources.new(options).public_send(options.command)
39
40
  else
40
41
  logger.fatal 'Unknown command'
41
42
  exit 2
@@ -64,8 +64,8 @@ class RainforestCli::Exporter
64
64
  when 'step'
65
65
  file.puts '' unless index == 0
66
66
  file.puts "# step #{index + 1}" if @options.debug
67
- file.puts element[:element][:action]
68
- file.puts element[:element][:response]
67
+ file.puts element[:element][:action].gsub("\n", ' ')
68
+ file.puts element[:element][:response].gsub("\n", ' ')
69
69
  else
70
70
  raise "Unknown element type: #{element[:type]}"
71
71
  end
@@ -23,14 +23,16 @@ module RainforestCli
23
23
  JSON.parse(response.body)
24
24
  end
25
25
 
26
- def post(url, body = {})
27
- response = HTTParty.post make_url(url), {
28
- body: body,
29
- headers: headers,
30
- verify: false
31
- }
26
+ def post(url, body = {}, options = {})
27
+ wrap_exceptions(options[:retries_on_failures]) do
28
+ response = HTTParty.post make_url(url), {
29
+ body: body,
30
+ headers: headers,
31
+ verify: false
32
+ }
32
33
 
33
- JSON.parse(response.body)
34
+ return JSON.parse(response.body)
35
+ end
34
36
  end
35
37
 
36
38
  def get(url, body = {}, options = {})
@@ -1,43 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
  class RainforestCli::Resources
3
+ Resource = Struct.new(:identifier, :name)
4
+
3
5
  def initialize(options)
4
6
  @client = RainforestCli::HttpClient.new(token: options.token)
5
7
  end
6
8
 
7
9
  def sites
8
- sites = @client.get('/sites')
10
+ sites = @client.get('/sites').map { |s| Resource.new(s['id'], s['name']) }
9
11
 
10
12
  if sites.empty?
11
13
  logger.info('No sites found on your account.')
12
14
  logger.info('Please visit https://app.rainforestqa.com/settings/sites to create and edit your sites.')
13
15
  else
14
- print_table('Site', sites) do |site|
15
- { id: site['id'], name: site['name'] }
16
- end
16
+ print_table('Site', sites)
17
17
  end
18
18
  end
19
19
 
20
20
  def folders
21
- folders = @client.get('/folders')
21
+ folders = @client.get('/folders').map { |f| Resource.new(f['id'], f['title']) }
22
22
 
23
23
  if folders.empty?
24
24
  logger.info('No folders found on your account.')
25
25
  logger.info('Please visit https://app.rainforestqa.com/folders to create and edit your sites.')
26
26
  else
27
- print_table('Folder', folders) do |folder|
28
- { id: folder['id'], name: folder['title'] }
29
- end
27
+ print_table('Folder', folders)
30
28
  end
31
29
  end
32
30
 
31
+ def browsers
32
+ account = @client.get('/clients')
33
+ browsers = account['available_browsers'].map { |b| Resource.new(b['name'], b['description']) }
34
+ print_table('Browser', browsers)
35
+ end
36
+
33
37
  def print_table(resource_name, resources)
34
38
  id_col = "#{resource_name} ID"
35
- table_heading = "#{id_col} | #{resource_name} Name"
39
+ longest_id = resources.map { |r| r.identifier.to_s }.max_by(&:length)
40
+ col_length = [id_col.length, longest_id.length].max
41
+
42
+ table_heading = "#{id_col.rjust(col_length)} | #{resource_name} Name"
36
43
  puts table_heading
37
44
  puts '-' * table_heading.length
38
45
  resources.each do |resource|
39
- resource_data = yield(resource)
40
- puts "#{resource_data[:id].to_s.rjust(id_col.length)} | #{resource_data[:name]}"
46
+ puts "#{resource.identifier.to_s.rjust(col_length)} | #{resource.name}"
41
47
  end
42
48
  end
43
49
 
@@ -19,7 +19,7 @@ module RainforestCli
19
19
  logger.debug "POST options: #{post_opts.inspect}"
20
20
  logger.info 'Issuing run'
21
21
 
22
- response = client.post('/runs', post_opts)
22
+ response = client.post('/runs', post_opts, retries_on_failures: true)
23
23
 
24
24
  if response['error']
25
25
  logger.fatal "Error starting your run: #{response['error']}"
@@ -99,7 +99,9 @@ module RainforestCli
99
99
  end
100
100
  end
101
101
 
102
- post_opts[:app_source_url] = options.app_source_url if options.app_source_url
102
+ app_source_url = options.app_source_url ? upload_app(options.app_source_url) : options.app_source_url
103
+
104
+ post_opts[:app_source_url] = app_source_url if app_source_url
103
105
  post_opts[:crowd] = options.crowd if options.crowd
104
106
  post_opts[:conflict] = options.conflict if options.conflict
105
107
  post_opts[:browsers] = options.browsers if options.browsers
@@ -153,5 +155,55 @@ module RainforestCli
153
155
 
154
156
  return environment['id']
155
157
  end
158
+
159
+ def upload_app(app_source_url)
160
+ return app_source_url if url_valid?(app_source_url)
161
+
162
+ unless File.exist?(app_source_url)
163
+ logger.fatal "App source file: #{app_source_url} not found"
164
+ exit 1
165
+ end
166
+
167
+ unless File.extname(app_source_url) == '.ipa'
168
+ logger.fatal "Invalid app source file: #{app_source_url}"
169
+ exit 1
170
+ end
171
+
172
+ url = client.get('/uploads', {}, retries_on_failures: true)
173
+ unless url
174
+ logger.fatal "Failed to upload file #{app_source_url}. Please, check your API token."
175
+ exit 1
176
+ end
177
+ data = File.read(app_source_url)
178
+ logger.info 'Uploading app source file, this operation may take few minutes...'
179
+ response_code = upload_file(url, data)
180
+
181
+ if response_code != '200'
182
+ logger.fatal "Failed to upload file #{app_source_url}"
183
+ exit 1
184
+ else
185
+ logger.info 'Upload completed.'
186
+ return url['path']
187
+ end
188
+ end
189
+
190
+ def upload_file(url, body)
191
+ begin
192
+ # using Net::HTTP because HTTParty do not support large files
193
+ http = Net::HTTP.new(url['host'], url['port'])
194
+ http.use_ssl = true
195
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
196
+
197
+ request = Net::HTTP::Put.new(url['uri'])
198
+ request['Content-Type'] = 'application/zip'
199
+ request.body = body
200
+
201
+ response = http.request(request)
202
+ return response.code
203
+ rescue Http::Exceptions::HttpException => e
204
+ logger.fatal "Error uploading the app source file: #{e.message}"
205
+ exit 1
206
+ end
207
+ end
156
208
  end
157
209
  end
@@ -87,7 +87,7 @@ module RainforestCli::TestParser
87
87
  @test.browsers = []
88
88
  end
89
89
 
90
- TEST_DATA_FIELDS = [:start_uri, :title, :tags, :site_id].freeze
90
+ TEST_DATA_FIELDS = [:start_uri, :title, :site_id, :browsers].freeze
91
91
  STEP_DATA_FIELDS = [:redirect].freeze
92
92
  CSV_FIELDS = [:tags, :browsers].freeze
93
93
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module RainforestCli
3
- VERSION = '1.4.0'
3
+ VERSION = '1.5.0'
4
4
  end
data/spec/cli_spec.rb CHANGED
@@ -102,7 +102,7 @@ describe RainforestCli do
102
102
 
103
103
  it 'starts the run with the specified tags' do
104
104
  expect_any_instance_of(http_client).to receive(:post)
105
- .with('/runs', tags: ['run-me']).and_return({})
105
+ .with('/runs', { tags: ['run-me'] }, { retries_on_failures: true }).and_return({})
106
106
 
107
107
  start_with_params(params, 0)
108
108
  end
@@ -116,7 +116,7 @@ describe RainforestCli do
116
116
  .with('/environments', name: 'temporary-env-for-custom-url-via-CLI', url: 'http://ad-hoc.example.com')
117
117
  .and_return({ 'id' => 333 })
118
118
 
119
- expect_any_instance_of(http_client).to receive(:post).with('/runs', anything)
119
+ expect_any_instance_of(http_client).to receive(:post).with('/runs', anything, { retries_on_failures: true })
120
120
  .and_return({ 'id' => 1 })
121
121
 
122
122
  # This is a hack because when expecting a function to be called with
@@ -140,7 +140,8 @@ describe RainforestCli do
140
140
 
141
141
  expect_any_instance_of(http_client).to receive(:post).with(
142
142
  '/runs',
143
- { tests: [], site_id: 3, environment_id: 333 }
143
+ { tests: [], site_id: 3, environment_id: 333 },
144
+ { retries_on_failures: true }
144
145
  ).and_return({})
145
146
  described_class.start(params)
146
147
  end
@@ -155,7 +156,8 @@ describe RainforestCli do
155
156
 
156
157
  expect_any_instance_of(http_client).to receive(:post).with(
157
158
  '/runs',
158
- { tests: [], environment_id: 123 }
159
+ { tests: [], environment_id: 123 },
160
+ { retries_on_failures: true }
159
161
  ).and_return({})
160
162
  described_class.start(params)
161
163
  end
@@ -167,7 +169,8 @@ describe RainforestCli do
167
169
  it 'starts the run with smart folder' do
168
170
  expect_any_instance_of(http_client).to receive(:post).with(
169
171
  '/runs',
170
- { smart_folder_id: 123 }
172
+ { smart_folder_id: 123 },
173
+ { retries_on_failures: true }
171
174
  ).and_return({})
172
175
  described_class.start(params)
173
176
  end
@@ -179,7 +182,8 @@ describe RainforestCli do
179
182
  it 'starts the run without error' do
180
183
  expect_any_instance_of(http_client).to receive(:post).with(
181
184
  '/runs',
182
- { tests: [] }
185
+ { tests: [] },
186
+ { retries_on_failures: true }
183
187
  ).and_return({})
184
188
  allow(ENV).to receive(:[]).with('RAINFOREST_API_TOKEN').and_return('x')
185
189
  described_class.start(params)
@@ -9,6 +9,11 @@ describe RainforestCli::Exporter do
9
9
  # Collect everything printed to file in an array-like file double object
10
10
  class FileDouble < Array
11
11
  alias_method :puts, :push
12
+
13
+ # join into a string like a file
14
+ def include?(str)
15
+ join("\n").include?(str)
16
+ end
12
17
  end
13
18
 
14
19
  let(:file) { FileDouble.new }
@@ -28,6 +33,21 @@ describe RainforestCli::Exporter do
28
33
  ]
29
34
  }
30
35
  end
36
+ let(:test_elements) do
37
+ [
38
+ {
39
+ type: 'step',
40
+ element: {
41
+ action: 'Step Action',
42
+ response: 'Step Response'
43
+ }
44
+ },
45
+ {
46
+ type: 'test',
47
+ element: embedded_test
48
+ }
49
+ ]
50
+ end
31
51
  let(:single_test) do
32
52
  Rainforest::Test.new(
33
53
  {
@@ -36,32 +56,11 @@ describe RainforestCli::Exporter do
36
56
  start_uri: '/uri',
37
57
  tags: ['foo', 'bar'],
38
58
  browsers: [
39
- {
40
- name: 'chrome',
41
- state: 'enabled'
42
- },
43
- {
44
- name: 'safari',
45
- state: 'enabled'
46
- },
47
- {
48
- name: 'firefox',
49
- state: 'disabled'
50
- }
59
+ { name: 'chrome', state: 'enabled' },
60
+ { name: 'safari', state: 'enabled' },
61
+ { name: 'firefox', state: 'disabled' }
51
62
  ],
52
- elements: [
53
- {
54
- type: 'step',
55
- element: {
56
- action: 'Step Action',
57
- response: 'Step Response'
58
- }
59
- },
60
- {
61
- type: 'test',
62
- element: embedded_test
63
- }
64
- ]
63
+ elements: test_elements
65
64
  }
66
65
  )
67
66
  end
@@ -98,6 +97,29 @@ describe RainforestCli::Exporter do
98
97
  expect(comments).to_not include('firefox')
99
98
  end
100
99
 
100
+ context 'action and/or question contain newlines' do
101
+ let(:action) { "Step Action\nwith newlines\n" }
102
+ let(:expected_action) { 'Step Action with newlines' }
103
+ let(:response) { "Step Response\nwith\nnewlines\n" }
104
+ let(:expected_response) { 'Step Response with newlines' }
105
+ let(:test_elements) do
106
+ [
107
+ {
108
+ type: 'step',
109
+ element: {
110
+ action: action,
111
+ response: response
112
+ }
113
+ }
114
+ ]
115
+ end
116
+
117
+ it 'removes the newlines' do
118
+ expect(file).to include(expected_action)
119
+ expect(file).to include(expected_response)
120
+ end
121
+ end
122
+
101
123
  context 'with embed-tests flag' do
102
124
  let(:options) do
103
125
  instance_double(
@@ -3,6 +3,22 @@ describe RainforestCli::Resources do
3
3
  let(:options) { instance_double('RainforestCli::Options', token: 'fake_token') }
4
4
  subject { described_class.new(options) }
5
5
 
6
+ shared_examples 'a properly formatted resource' do |tested_method|
7
+ before do
8
+ allow_any_instance_of(RainforestCli::HttpClient).to receive(:get).and_return(api_response)
9
+ end
10
+
11
+ it 'calls the print method with the correct information' do
12
+ expect(subject).to receive(:print_table) do |_name, resources|
13
+ resource = resources.first
14
+ expect(resource.identifier).to eq(expected_id)
15
+ expect(resource.name).to eq(expected_name)
16
+ end
17
+
18
+ subject.send(tested_method)
19
+ end
20
+ end
21
+
6
22
  describe '#sites' do
7
23
  context 'no sites configured' do
8
24
  before do
@@ -22,39 +38,17 @@ describe RainforestCli::Resources do
22
38
  end
23
39
 
24
40
  context 'with sites in account' do
25
- let(:sites) do
41
+ let(:api_response) do
26
42
  [
27
- {
28
- 'id' => 123,
29
- 'name' => 'The Foo Site'
30
- },
31
- {
32
- 'id' => 456,
33
- 'name'=> 'The Bar Site'
34
- },
35
- {
36
- 'id' => 789,
37
- 'name' => 'The Baz Site'
38
- }
43
+ { 'id' => 123, 'name' => 'The Foo Site' },
44
+ { 'id' => 456, 'name'=> 'The Bar Site' },
45
+ { 'id' => 789, 'name' => 'The Baz Site' }
39
46
  ]
40
47
  end
48
+ let(:expected_id) { api_response.first['id'] }
49
+ let(:expected_name) { api_response.first['name'] }
41
50
 
42
- before do
43
- allow_any_instance_of(RainforestCli::HttpClient).to receive(:get).and_return(sites)
44
- end
45
-
46
- it 'calls the print method' do
47
- expect(subject).to receive(:print_table).with('Site', sites).and_yield(sites.first)
48
- subject.sites
49
- end
50
-
51
- it 'correctly formats the site information in the given block' do
52
- expect(subject).to receive(:print_table) do |_resource_name, _resource, &blk|
53
- site = sites.first
54
- expect(blk.call(site)).to include(id: site['id'], name: site['name'])
55
- end
56
- subject.sites
57
- end
51
+ it_should_behave_like 'a properly formatted resource', :sites
58
52
  end
59
53
  end
60
54
 
@@ -77,46 +71,39 @@ describe RainforestCli::Resources do
77
71
  end
78
72
 
79
73
  context 'with folders in account' do
80
- let(:folders) do
74
+ let(:api_response) do
81
75
  [
82
- {
83
- 'id' => 123,
84
- 'title' => 'The Foo Folder'
85
- },
86
- {
87
- 'id' => 456,
88
- 'title'=> 'The Bar Folder'
89
- },
90
- {
91
- 'id' => 789,
92
- 'title' => 'The Baz Folder'
93
- }
76
+ { 'id' => 123, 'title' => 'The Foo Folder' },
77
+ { 'id' => 456, 'title'=> 'The Bar Folder' },
78
+ { 'id' => 789, 'title' => 'The Baz Folder' }
94
79
  ]
95
80
  end
81
+ let(:expected_id) { api_response.first['id'] }
82
+ let(:expected_name) { api_response.first['title'] }
96
83
 
97
- before do
98
- allow_any_instance_of(RainforestCli::HttpClient).to receive(:get).and_return(folders)
99
- end
100
-
101
- it 'calls the print method' do
102
- expect(subject).to receive(:print_table).with('Folder', folders).and_yield(folders.first)
103
- subject.folders
104
- end
84
+ it_should_behave_like 'a properly formatted resource', :folders
85
+ end
86
+ end
105
87
 
106
- it 'correctly formats the site information in the given block' do
107
- expect(subject).to receive(:print_table) do |_resource_name, _resource, &blk|
108
- folder = folders.first
109
- expect(blk.call(folder)).to include(id: folder['id'], name: folder['title'])
110
- end
111
- subject.folders
112
- end
88
+ describe '#browsers' do
89
+ let(:api_resources) do
90
+ [
91
+ { 'name' => 'chrome', 'description' => 'Chrome' },
92
+ { 'name' => 'safari', 'description' => 'Safari' },
93
+ { 'name' => 'firefox', 'description' => 'Firefox' }
94
+ ]
113
95
  end
96
+ let(:api_response) { { 'available_browsers' => api_resources } }
97
+ let(:expected_id) { api_resources.first['name'] }
98
+ let(:expected_name) { api_resources.first['description'] }
99
+
100
+ it_should_behave_like 'a properly formatted resource', :browsers
114
101
  end
115
102
 
116
103
  describe '#print_table' do
117
104
  let(:resource_id) { 123456 }
118
105
  let(:resource_name) { 'resource name' }
119
- let(:resources) { [ { id: resource_id, name: resource_name } ] }
106
+ let(:resources) { [ RainforestCli::Resources::Resource.new(resource_id, resource_name) ] }
120
107
 
121
108
  it 'prints out the resources' do
122
109
  expect(subject).to receive(:puts) do |message|
@@ -132,9 +119,7 @@ describe RainforestCli::Resources do
132
119
  expect(message).to include(resource_name)
133
120
  end
134
121
 
135
- subject.print_table('Resource', resources) do
136
- { id: resource_id, name: resource_name }
137
- end
122
+ subject.print_table('Resource', resources)
138
123
  end
139
124
  end
140
125
  end
data/spec/runner_spec.rb CHANGED
@@ -57,4 +57,72 @@ describe RainforestCli::Runner do
57
57
  end
58
58
  end
59
59
 
60
+ describe '#upload_app' do
61
+
62
+ context 'with valid URL' do
63
+ it 'returns the given app_source_url' do
64
+ expect(subject.upload_app('http://my.app.url')).to eq 'http://my.app.url'
65
+ end
66
+ end
67
+
68
+ context 'with invalid URL' do
69
+
70
+ it 'errors out and exits if the file does not exists' do
71
+ expect_any_instance_of(Logger).to receive(:fatal).with('App source file: fobar not found')
72
+ expect do
73
+ subject.upload_app('fobar')
74
+ end.to raise_error(SystemExit) { |error|
75
+ expect(error.status).to eq 1
76
+ }
77
+ end
78
+
79
+ it 'errors out and exits if not an .ipa file' do
80
+ File.should_receive(:exist?).with('fobar.txt') { true }
81
+ expect_any_instance_of(Logger).to receive(:fatal).with('Invalid app source file: fobar.txt')
82
+ expect do
83
+ subject.upload_app('fobar.txt')
84
+ end.to raise_error(SystemExit) { |error|
85
+ expect(error.status).to eq 1
86
+ }
87
+ end
88
+
89
+ it 'errors out and exits if valid file but invalid token' do
90
+ File.should_receive(:exist?).with('fobar.ipa') { true }
91
+ subject.client.should_receive(:get).with('/uploads', {}, retries_on_failures: true) { nil }
92
+ expect_any_instance_of(Logger).to receive(:fatal).with(
93
+ 'Failed to upload file fobar.ipa. Please, check your API token.')
94
+ expect do
95
+ subject.upload_app('fobar.ipa')
96
+ end.to raise_error(SystemExit) { |error|
97
+ expect(error.status).to eq 1
98
+ }
99
+ end
100
+
101
+ it 'errors out and exits if was not possible to upload the file' do
102
+ File.should_receive(:exist?).with('fobar.ipa') { true }
103
+ File.should_receive(:read).with('fobar.ipa') { 'File data' }
104
+ url = {'host' => 'host', 'port' => 'port', 'uri' => 'uri', 'path' => 'path'}
105
+ subject.client.should_receive(:get).with('/uploads', {}, retries_on_failures: true) { url }
106
+ subject.should_receive(:upload_file).with(url, 'File data') { '500' }
107
+ expect_any_instance_of(Logger).to receive(:fatal).with('Failed to upload file fobar.ipa')
108
+ expect do
109
+ subject.upload_app('fobar.ipa')
110
+ end.to raise_error(SystemExit) { |error|
111
+ expect(error.status).to eq 1
112
+ }
113
+ end
114
+
115
+ it 'returns the new app_source_url in case of success' do
116
+ File.should_receive(:exist?).with('fobar.ipa') { true }
117
+ File.should_receive(:read).with('fobar.ipa') { 'File data' }
118
+ url = {'host' => 'host', 'port' => 'port', 'uri' => 'uri', 'path' => 'path'}
119
+ subject.client.should_receive(:get).with('/uploads', {}, retries_on_failures: true) { url }
120
+ subject.should_receive(:upload_file).with(url, 'File data') { '200' }
121
+
122
+ expect(subject.upload_app('fobar.ipa')).to eq 'path'
123
+ end
124
+
125
+ end
126
+ end
127
+
60
128
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rainforest-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Russell Smith
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-04-22 00:00:00.000000000 Z
12
+ date: 2016-05-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty