lib/spaceship/tunes/tunes_client.rb in spaceship-0.1.2 vs lib/spaceship/tunes/tunes_client.rb in spaceship-0.2.0
- old
+ new
@@ -1,8 +1,12 @@
module Spaceship
class TunesClient < Spaceship::Client
+ # ITunesConnectError is only thrown when iTunes Connect raises an exception
+ class ITunesConnectError < StandardError
+ end
+
#####################################################
# @!group Init and Login
#####################################################
def self.hostname
@@ -63,13 +67,15 @@
# User Credentials are wrong
raise InvalidUserCredentialsError.new(response)
end
end
- def handle_itc_response(data)
- return unless data
- return unless data.kind_of?Hash
+ def handle_itc_response(raw)
+ return unless raw
+ return unless raw.kind_of?Hash
+
+ data = raw['data'] || raw # sometimes it's with data, sometimes it isn't
if data.fetch('sectionErrorKeys', []).count == 0 and
data.fetch('sectionInfoKeys', []).count == 0 and
data.fetch('sectionWarningKeys', []).count == 0
@@ -98,14 +104,17 @@
errors = handle_response_hash(data)
errors = errors + data.fetch('sectionErrorKeys') if data['sectionErrorKeys']
# Sometimes there is a different kind of error in the JSON response
- different_error = data.fetch('messages', {}).fetch('error', nil)
+ # e.g. {"warn"=>nil, "error"=>["operation_failed"], "info"=>nil}
+ different_error = raw.fetch('messages', {}).fetch('error', nil)
errors << different_error if different_error
- raise errors.join(' ') if errors.count > 0 # they are separated by `.` by default
+ if errors.count > 0 # they are separated by `.` by default
+ raise ITunesConnectError.new(errors.join(' '))
+ end
puts data['sectionInfoKeys'] if data['sectionInfoKeys']
puts data['sectionWarningKeys'] if data['sectionWarningKeys']
return data
@@ -192,11 +201,11 @@
req.url "ra/apps/version/save/#{app_id}?v=#{v_text}"
req.body = data.to_json
req.headers['Content-Type'] = 'application/json'
end
- handle_itc_response(r.body['data'])
+ handle_itc_response(r.body)
end
#####################################################
# @!group Build Trains
#####################################################
@@ -215,12 +224,93 @@
req.url "ra/apps/#{app_id}/trains/"
req.body = data.to_json
req.headers['Content-Type'] = 'application/json'
end
- handle_itc_response(r.body['data'])
+ handle_itc_response(r.body)
end
+
+ def remove_testflight_build_from_review!(app_id: nil, train: nil, build_number: nil)
+ r = request(:post) do |req|
+ req.url "ra/apps/#{app_id}/trains/#{train}/builds/#{build_number}/reject"
+ req.body = {}.to_json
+ req.headers['Content-Type'] = 'application/json'
+ end
+ handle_itc_response(r.body)
+ end
+
+ def submit_testflight_build_for_review!(# Required:
+ app_id: nil,
+ train: nil,
+ build_number: nil,
+ cancel_other_submissions: false,
+
+ # Required Metadata:
+ changelog: nil,
+ description: nil,
+ feedback_email: nil,
+ marketing_url: nil,
+ first_name: nil,
+ last_name: nil,
+ review_email: nil,
+ phone_number: nil,
+
+ # Optional Metadata:
+ privacy_policy_url: nil,
+ review_notes: nil,
+ review_user_name: nil,
+ review_password: nil,
+ encryption: false)
+
+ start_url = "ra/apps/#{app_id}/trains/#{train}/builds/#{build_number}/submit/start"
+ r = request(:get) do |req|
+ req.url start_url
+ req.headers['Content-Type'] = 'application/json'
+ end
+ handle_itc_response(r.body)
+
+ build_info = r.body['data']
+ # Now fill in the values provided by the user
+
+ # First the localised values:
+ build_info['testInfo']['details'].each do |current|
+ current['whatsNew']['value'] = changelog
+ current['description']['value'] = description
+ current['feedbackEmail']['value'] = feedback_email
+ current['marketingUrl']['value'] = marketing_url
+ current['privacyPolicyUrl']['value'] = privacy_policy_url
+ current["pageLanguageValue"] = current['language'] # could iTunes Connect be any more buggy? This is required for some reason
+ end
+ build_info['testInfo']['reviewFirstName']['value'] = first_name
+ build_info['testInfo']['reviewLastName']['value'] = last_name
+ build_info['testInfo']['reviewPhone']['value'] = phone_number
+ build_info['testInfo']['reviewEmail']['value'] = review_email
+ build_info['testInfo']['reviewUserName']['value'] = review_user_name
+ build_info['testInfo']['reviewPassword']['value'] = review_password
+
+ r = request(:post) do |req| # same URL, but a POST request
+ req.url start_url
+ req.body = build_info.to_json
+ req.headers['Content-Type'] = 'application/json'
+ end
+ handle_itc_response(r.body)
+
+ encryption_info = r.body['data']
+ if encryption_info['exportComplianceRequired']
+ # only sometimes this is required
+
+ encryption_info['usesEncryption']['value'] = encryption
+
+ r = request(:post) do |req|
+ req.url "ra/apps/#{app_id}/trains/#{train}/builds/#{build_number}/submit/complete"
+ req.body = encryption_info.to_json
+ req.headers['Content-Type'] = 'application/json'
+ end
+
+ handle_itc_response(r.body)
+ end
+ end
#####################################################
# @!group Submit for Review
#####################################################
@@ -231,11 +321,11 @@
req.url "ra/apps/#{app_id}/version/submit/#{stage}"
req.body = data.to_json
req.headers['Content-Type'] = 'application/json'
end
- handle_itc_response(r.body['data'])
+ handle_itc_response(r.body)
parse_response(r, 'data')
end
#####################################################
# @!group Testers
@@ -308,10 +398,11 @@
lastName: {
value: tester.last_name
},
testing: {
value: false
- },
+ },
+ userName: tester.email,
testerId: tester.tester_id
}
]
r = request(:post) do |req|
\ No newline at end of file