rainforest-cli 1.4.0 → 1.5.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 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