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