diff --git a/.gitignore b/.gitignore index 9ed7adab..5fe00639 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ pkg/* build/ .DS_Store .repl_history +provisioning diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 00000000..79a61441 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.4.4 diff --git a/Gemfile.lock b/Gemfile.lock index 765cc595..fa0b179c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,14 +6,164 @@ PATH GEM remote: https://rubygems.org/ specs: + CFPropertyList (3.0.2) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + atomos (0.1.3) + babosa (1.0.3) bacon (1.2.0) + claide (1.0.3) + colored (1.2) + colored2 (3.1.2) + commander-fastlane (4.4.6) + highline (~> 1.7.2) + declarative (0.0.10) + declarative-option (0.1.0) + digest-crc (0.4.1) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) + dotenv (2.7.5) + emoji_regex (1.0.1) + excon (0.71.0) + faraday (0.17.1) + multipart-post (>= 1.2, < 3) + faraday-cookie_jar (0.0.6) + faraday (>= 0.7.4) + http-cookie (~> 1.0.0) + faraday_middleware (0.13.1) + faraday (>= 0.7.4, < 1.0) + fastimage (2.1.7) + fastlane (2.137.0) + CFPropertyList (>= 2.3, < 4.0.0) + addressable (>= 2.3, < 3.0.0) + babosa (>= 1.0.2, < 2.0.0) + bundler (>= 1.12.0, < 3.0.0) + colored + commander-fastlane (>= 4.4.6, < 5.0.0) + dotenv (>= 2.1.1, < 3.0.0) + emoji_regex (>= 0.1, < 2.0) + excon (>= 0.45.0, < 1.0.0) + faraday (~> 0.17) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 0.13.1) + fastimage (>= 2.1.0, < 3.0.0) + gh_inspector (>= 1.1.2, < 2.0.0) + google-api-client (>= 0.21.2, < 0.24.0) + google-cloud-storage (>= 1.15.0, < 2.0.0) + highline (>= 1.7.2, < 2.0.0) + json (< 3.0.0) + jwt (~> 2.1.0) + mini_magick (>= 4.9.4, < 5.0.0) + multi_xml (~> 0.5) + multipart-post (~> 2.0.0) + plist (>= 3.1.0, < 4.0.0) + public_suffix (~> 2.0.0) + rubyzip (>= 1.3.0, < 2.0.0) + security (= 0.1.3) + simctl (~> 1.6.3) + slack-notifier (>= 2.0.0, < 3.0.0) + terminal-notifier (>= 2.0.0, < 3.0.0) + terminal-table (>= 1.4.5, < 2.0.0) + tty-screen (>= 0.6.3, < 1.0.0) + tty-spinner (>= 0.8.0, < 1.0.0) + word_wrap (~> 1.0.0) + xcodeproj (>= 1.8.1, < 2.0.0) + xcpretty (~> 0.3.0) + xcpretty-travis-formatter (>= 0.0.3) + gh_inspector (1.1.3) + google-api-client (0.23.9) + addressable (~> 2.5, >= 2.5.1) + googleauth (>= 0.5, < 0.7.0) + httpclient (>= 2.8.1, < 3.0) + mime-types (~> 3.0) + representable (~> 3.0) + retriable (>= 2.0, < 4.0) + signet (~> 0.9) + google-cloud-core (1.4.1) + google-cloud-env (~> 1.0) + google-cloud-env (1.3.0) + faraday (~> 0.11) + google-cloud-storage (1.16.0) + digest-crc (~> 0.4) + google-api-client (~> 0.23) + google-cloud-core (~> 1.2) + googleauth (>= 0.6.2, < 0.10.0) + googleauth (0.6.7) + faraday (~> 0.12) + jwt (>= 1.4, < 3.0) + memoist (~> 0.16) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (~> 0.7) + highline (1.7.10) + http-cookie (1.0.3) + domain_name (~> 0.5) + httpclient (2.8.3) + json (2.3.0) + jwt (2.1.0) + memoist (0.16.2) metaclass (0.0.4) + mime-types (3.3) + mime-types-data (~> 3.2015) + mime-types-data (3.2019.1009) + mini_magick (4.9.5) mocha (0.14.0) metaclass (~> 0.0.1) - mocha-on-bacon (0.2.2) + mocha-on-bacon (0.2.3) mocha (>= 0.13.0) - rake (10.4.2) - webstub (1.1.2) + motion-provisioning (1.0.2) + fastlane (~> 2.113) + highline (>= 1.7.2, < 2.0.0) + multi_json (1.14.1) + multi_xml (0.6.0) + multipart-post (2.0.0) + nanaimo (0.2.6) + naturally (2.2.0) + os (1.0.1) + plist (3.5.0) + public_suffix (2.0.5) + rake (10.5.0) + representable (3.0.4) + declarative (< 0.1.0) + declarative-option (< 0.2.0) + uber (< 0.2.0) + retriable (3.1.2) + rouge (2.0.7) + rubyzip (1.3.0) + security (0.1.3) + signet (0.12.0) + addressable (~> 2.3) + faraday (~> 0.9) + jwt (>= 1.5, < 3.0) + multi_json (~> 1.10) + simctl (1.6.6) + CFPropertyList + naturally + slack-notifier (2.3.2) + terminal-notifier (2.0.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + tty-cursor (0.7.0) + tty-screen (0.7.0) + tty-spinner (0.9.2) + tty-cursor (~> 0.7) + uber (0.1.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.6) + unicode-display_width (1.6.0) + webstub (1.1.6) + word_wrap (1.0.0) + xcodeproj (1.14.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.2.6) + xcpretty (0.3.0) + rouge (~> 2.0.7) + xcpretty-travis-formatter (1.0.0) + xcpretty (~> 0.2, >= 0.0.7) PLATFORMS ruby @@ -23,6 +173,7 @@ DEPENDENCIES bubble-wrap! mocha (~> 0.11) mocha-on-bacon (~> 0.2) + motion-provisioning (~> 1.0.2) rake (~> 10.0) webstub (~> 1.1) diff --git a/README.md b/README.md index 0928f8bb..70eb3628 100644 --- a/README.md +++ b/README.md @@ -689,7 +689,11 @@ BW::Mail.compose( html: false, subject: "My Subject", message: "This is my message. It isn't very long.", - animated: false + animated: false, + attachments: [ + {data: nsdata-object, mime_type: "mime/type", file_name: "file.name"}, + ... + ] ) do |result, error| result.sent? # => boolean result.canceled? # => boolean diff --git a/Rakefile b/Rakefile index b33eb4cd..315af4b5 100644 --- a/Rakefile +++ b/Rakefile @@ -11,6 +11,7 @@ Bundler.require require 'bubble-wrap/all' require 'bubble-wrap/test' +require 'motion-provisioning' module Motion module Project @@ -36,6 +37,17 @@ Motion::Project::App.setup do |app| app.info_plist['NSLocationAlwaysUsageDescription'] = 'Description' app.info_plist['NSLocationWhenInUseUsageDescription'] = 'Description' + app.codesign_certificate = MotionProvisioning.certificate( + platform: :ios, + type: :development + ) + app.provisioning_profile = MotionProvisioning.profile( + bundle_identifier: app.identifier, + app_name: app.name, + platform: :ios, + type: :development + ) + app.spec_files -= Dir.glob("./spec/motion/**/osx/**.rb") end diff --git a/bubble-wrap.gemspec b/bubble-wrap.gemspec index 0102907d..50d5440a 100644 --- a/bubble-wrap.gemspec +++ b/bubble-wrap.gemspec @@ -22,4 +22,5 @@ Gem::Specification.new do |gem| gem.add_development_dependency 'bacon', '~> 1.2' gem.add_development_dependency 'rake', '~> 10.0' gem.add_development_dependency 'webstub', '~> 1.1' + gem.add_development_dependency 'motion-provisioning', '~> 1.0.2' end diff --git a/motion/mail/mail.rb b/motion/mail/mail.rb index d6d5fb15..e2632f21 100644 --- a/motion/mail/mail.rb +++ b/motion/mail/mail.rb @@ -14,7 +14,11 @@ module Mail # html: false, # subject: "My Subject", # message: "This is my message. It isn't very long.", - # animated: false + # animated: false, + # attachments: [ { data: nsdata-object1, mime_type: "xxx1/yyy1", file_name: "aaa1.bb1"}, + # { data: nsdata-object2, mime_type: "xxx2/yyy2", file_name: "aaa2.bb2"}, + # ... + # ] # ) do |result, error| # result.sent? # => boolean # result.canceled? # => boolean @@ -30,7 +34,8 @@ def compose(options = {}, &callback) to: [], cc: [], bcc: [], - subject: 'Contact' + subject: 'Contact', + attachments: [] }.merge(options) @delegate = options[:delegate] @@ -58,7 +63,9 @@ def create_mail_controller(options = {}) mail_controller.setBccRecipients(Array(options[:bcc])) mail_controller.setSubject(options[:subject]) mail_controller.setMessageBody(options[:message], isHTML: !!options[:html]) - + options[:attachments].each do |ad| + mail_controller.addAttachmentData(ad[:data], mimeType: ad[:mime_type], fileName: ad[:file_name]) + end mail_controller end diff --git a/spec/motion/mail/mail_spec.rb b/spec/motion/mail/mail_spec.rb index e428fda0..b3b99255 100644 --- a/spec/motion/mail/mail_spec.rb +++ b/spec/motion/mail/mail_spec.rb @@ -12,7 +12,7 @@ def presentViewController(modal, animated: animated, completion: completion) # This of course breaks MFMailComposeViewController from actually working, # but it's testable. class MFMailComposeViewController - attr_accessor :toRecipients, :ccRecipients, :bccRecipients, :subject, :message, :html + attr_accessor :toRecipients, :ccRecipients, :bccRecipients, :subject, :message, :html, :attachments def setToRecipients(r) self.toRecipients = r @@ -34,6 +34,14 @@ def setMessageBody(message, isHTML: html) self.message = message self.html = html end + + def addAttachmentData(d, mimeType: mt, fileName: fn) + if self.attachments == nil + self.attachments = [] + end + self.attachments << {:data => d, :mime_type => mt, :file_name => fn} + end + end describe BW::Mail do @@ -48,7 +56,12 @@ def setMessageBody(message, isHTML: html) html: false, subject: "My Subject", message: "This is my message. It isn't very long.", - animated: false + animated: false, + attachments: [ + {data: "mock dataset A", mime_type: "mock/typeA", file_name: "mock_name_A"}, + {data: "mock dataset B", mime_type: "mock/typeB", file_name: "mock_name_B"}, + {data: "mock dataset C", mime_type: "mock/typeC", file_name: "mock_name_C"}, + ] } end @@ -118,6 +131,7 @@ def setMessageBody(message, isHTML: html) BubbleWrap::Mail.compose @standard_mail_options end + it "should create a mail controller with the right animation" do @view_controller.expectation = lambda { |mail_controller, animated| animated.should.be.false @@ -125,6 +139,54 @@ def setMessageBody(message, isHTML: html) BubbleWrap::Mail.compose @standard_mail_options end + + it "should create a mail controller with an array of attachments" do + @view_controller.expectation = lambda { |mail_controller, animated| + mail_controller.attachments.should.be.kind_of(Array) + } + + BubbleWrap::Mail.compose @standard_mail_options + end + + it "should create a mail controller with the right number of attachments" do + @view_controller.expectation = lambda { |mail_controller, animated| + mail_controller.attachments.size.should == 3 + } + + BubbleWrap::Mail.compose @standard_mail_options + end + + it "should create a mail controller with several attachments, the first of which is a hash of attachments" do + @view_controller.expectation = lambda { |mail_controller, animated| + mail_controller.attachments.first.should.be.kind_of(Hash) + } + + BubbleWrap::Mail.compose @standard_mail_options + end + + it "should create a mail controller with several attachments, the last of which has 3 keys" do + @view_controller.expectation = lambda { |mail_controller, animated| + mail_controller.attachments.last.keys.size.should == 3 + } + + BubbleWrap::Mail.compose @standard_mail_options + end + + it "should create a mail controller with several attachments, the last of which has a first key :data" do + @view_controller.expectation = lambda { |mail_controller, animated| + mail_controller.attachments.last.keys.first.should == :data + } + + BubbleWrap::Mail.compose @standard_mail_options + end + + it "should create a mail controller with several attachments, the second of which has the expected mime-type" do + @view_controller.expectation = lambda { |mail_controller, animated| + mail_controller.attachments.first[:mime_type] == "mock/typeA" + } + + BubbleWrap::Mail.compose @standard_mail_options + end end end