rpush 5.0.0 → 5.1.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 +4 -4
 - data/CHANGELOG.md +16 -2
 - data/lib/rpush/cli.rb +1 -1
 - data/lib/rpush/client/active_model.rb +1 -1
 - data/lib/rpush/client/active_model/apns/notification.rb +9 -1
 - data/lib/rpush/client/active_model/apns/notification_payload_size_validator.rb +15 -0
 - data/lib/rpush/client/active_model/apns2/notification.rb +14 -0
 - data/lib/rpush/client/active_record.rb +1 -0
 - data/lib/rpush/client/active_record/apns/active_record_serializable_notification.rb +65 -0
 - data/lib/rpush/client/active_record/apns/notification.rb +1 -57
 - data/lib/rpush/client/active_record/apns2/notification.rb +4 -1
 - data/lib/rpush/client/redis/apns2/notification.rb +1 -0
 - data/lib/rpush/client/redis/pushy/notification.rb +0 -1
 - data/lib/rpush/daemon/apns2/delivery.rb +6 -1
 - data/lib/rpush/daemon/apnsp8/delivery.rb +7 -2
 - data/lib/rpush/daemon/store/active_record/reconnectable.rb +1 -1
 - data/lib/rpush/version.rb +1 -1
 - data/spec/functional/apns2_spec.rb +36 -0
 - data/spec/support/simplecov_helper.rb +1 -1
 - data/spec/unit/client/active_record/adm/app_spec.rb +2 -54
 - data/spec/unit/client/active_record/adm/notification_spec.rb +2 -39
 - data/spec/unit/client/active_record/apns/app_spec.rb +3 -26
 - data/spec/unit/client/active_record/apns/feedback_spec.rb +1 -5
 - data/spec/unit/client/active_record/apns/notification_spec.rb +29 -293
 - data/spec/unit/client/active_record/apns2/app_spec.rb +4 -0
 - data/spec/unit/client/active_record/apns2/notification_spec.rb +65 -0
 - data/spec/unit/client/active_record/app_spec.rb +1 -26
 - data/spec/unit/client/active_record/gcm/app_spec.rb +3 -1
 - data/spec/unit/client/active_record/gcm/notification_spec.rb +6 -88
 - data/spec/unit/client/active_record/notification_spec.rb +3 -11
 - data/spec/unit/client/active_record/pushy/app_spec.rb +2 -13
 - data/spec/unit/client/active_record/pushy/notification_spec.rb +2 -55
 - data/spec/unit/client/active_record/shared/app.rb +14 -0
 - data/spec/unit/{notification_shared.rb → client/active_record/shared/notification.rb} +12 -7
 - data/spec/unit/client/active_record/wns/badge_notification_spec.rb +1 -11
 - data/spec/unit/client/active_record/wns/raw_notification_spec.rb +3 -12
 - data/spec/unit/client/active_record/wpns/app_spec.rb +3 -1
 - data/spec/unit/client/active_record/wpns/notification_spec.rb +2 -17
 - data/spec/unit/client/redis/adm/app_spec.rb +5 -0
 - data/spec/unit/client/redis/adm/notification_spec.rb +5 -0
 - data/spec/unit/client/redis/apns/app_spec.rb +5 -0
 - data/spec/unit/client/redis/apns/feedback_spec.rb +5 -0
 - data/spec/unit/client/redis/apns/notification_spec.rb +50 -0
 - data/spec/unit/client/redis/apns2/app_spec.rb +4 -0
 - data/spec/unit/client/redis/apns2/notification_spec.rb +50 -0
 - data/spec/unit/client/redis/app_spec.rb +5 -0
 - data/spec/unit/client/redis/gcm/app_spec.rb +5 -0
 - data/spec/unit/client/redis/gcm/notification_spec.rb +5 -0
 - data/spec/unit/client/redis/notification_spec.rb +5 -0
 - data/spec/unit/client/redis/pushy/app_spec.rb +5 -0
 - data/spec/unit/client/redis/pushy/notification_spec.rb +5 -0
 - data/spec/unit/client/redis/wns/badge_notification_spec.rb +5 -0
 - data/spec/unit/client/redis/wns/raw_notification_spec.rb +22 -0
 - data/spec/unit/client/redis/wpns/app_spec.rb +5 -0
 - data/spec/unit/client/redis/wpns/notification_spec.rb +5 -0
 - data/spec/unit/client/shared/adm/app.rb +51 -0
 - data/spec/unit/client/shared/adm/notification.rb +39 -0
 - data/spec/unit/client/shared/apns/app.rb +29 -0
 - data/spec/unit/client/shared/apns/feedback.rb +9 -0
 - data/spec/unit/client/shared/apns/notification.rb +262 -0
 - data/spec/unit/client/shared/app.rb +17 -0
 - data/spec/unit/client/shared/gcm/app.rb +4 -0
 - data/spec/unit/client/shared/gcm/notification.rb +77 -0
 - data/spec/unit/client/shared/notification.rb +10 -0
 - data/spec/unit/client/shared/pushy/app.rb +17 -0
 - data/spec/unit/client/shared/pushy/notification.rb +55 -0
 - data/spec/unit/client/shared/wns/badge_notification.rb +15 -0
 - data/spec/unit/client/shared/wns/raw_notification.rb +21 -0
 - data/spec/unit/client/shared/wpns/app.rb +4 -0
 - data/spec/unit/client/shared/wpns/notification.rb +18 -0
 - data/spec/unit/daemon/shared/store.rb +312 -0
 - data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +7 -7
 - data/spec/unit/daemon/store/active_record_spec.rb +2 -290
 - data/spec/unit/daemon/store/redis_spec.rb +2 -291
 - data/spec/unit_spec_helper.rb +3 -0
 - metadata +89 -10
 - data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +0 -16
 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: US-ASCII
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "unit_spec_helper"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe Rpush::Client::Redis::Apns::Notification do
         
     | 
| 
      
 6 
     | 
    
         
            +
              it_behaves_like 'Rpush::Client::Apns::Notification'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              it "should validate the length of the binary conversion of the notification" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                notification = described_class.new
         
     | 
| 
      
 10 
     | 
    
         
            +
                notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development')
         
     | 
| 
      
 11 
     | 
    
         
            +
                notification.device_token = "a" * 108
         
     | 
| 
      
 12 
     | 
    
         
            +
                notification.alert = ""
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                notification.alert << "a" until notification.payload.bytesize == 2048
         
     | 
| 
      
 15 
     | 
    
         
            +
                expect(notification.valid?).to be_truthy
         
     | 
| 
      
 16 
     | 
    
         
            +
                expect(notification.errors[:base]).to be_empty
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                notification.alert << "a"
         
     | 
| 
      
 19 
     | 
    
         
            +
                expect(notification.valid?).to be_falsey
         
     | 
| 
      
 20 
     | 
    
         
            +
                expect(notification.errors[:base].include?("APN notification cannot be larger than 2048 bytes. Try condensing your alert and device attributes.")).to be_truthy
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              it "should default the sound to 'default'" do
         
     | 
| 
      
 24 
     | 
    
         
            +
                notification = described_class.new
         
     | 
| 
      
 25 
     | 
    
         
            +
                expect(notification.sound).to eq('default')
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              # skipping these tests because data= for redis doesn't merge existing data
         
     | 
| 
      
 29 
     | 
    
         
            +
              xit 'does not overwrite the mutable-content flag when setting attributes for the device' do
         
     | 
| 
      
 30 
     | 
    
         
            +
                notification.mutable_content = true
         
     | 
| 
      
 31 
     | 
    
         
            +
                notification.data = { 'hi' => 'mom' }
         
     | 
| 
      
 32 
     | 
    
         
            +
                expect(notification.as_json['aps']['mutable-content']).to eq 1
         
     | 
| 
      
 33 
     | 
    
         
            +
                expect(notification.as_json['hi']).to eq 'mom'
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              xit 'does not overwrite the content-available flag when setting attributes for the device' do
         
     | 
| 
      
 37 
     | 
    
         
            +
                notification.content_available = true
         
     | 
| 
      
 38 
     | 
    
         
            +
                notification.data = { 'hi' => 'mom' }
         
     | 
| 
      
 39 
     | 
    
         
            +
                expect(notification.as_json['aps']['content-available']).to eq 1
         
     | 
| 
      
 40 
     | 
    
         
            +
                expect(notification.as_json['hi']).to eq 'mom'
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              # redis does not use alert_is_json - unclear if that is a bug or desired behavior
         
     | 
| 
      
 44 
     | 
    
         
            +
              xit 'does confuse a JSON looking string as JSON if the alert_is_json attribute is not present' do
         
     | 
| 
      
 45 
     | 
    
         
            +
                notification = described_class.new
         
     | 
| 
      
 46 
     | 
    
         
            +
                allow(notification).to receive_messages(has_attribute?: false)
         
     | 
| 
      
 47 
     | 
    
         
            +
                notification.alert = "{\"one\":2}"
         
     | 
| 
      
 48 
     | 
    
         
            +
                expect(notification.alert).to eq('one' => 2)
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            end if redis?
         
     | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: US-ASCII
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "unit_spec_helper"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe Rpush::Client::Redis::Apns2::Notification do
         
     | 
| 
      
 6 
     | 
    
         
            +
              it_behaves_like 'Rpush::Client::Apns::Notification'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              it "should validate the length of the binary conversion of the notification" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                notification = described_class.new
         
     | 
| 
      
 10 
     | 
    
         
            +
                notification.app = Rpush::Apns2::App.create(name: 'test', environment: 'development')
         
     | 
| 
      
 11 
     | 
    
         
            +
                notification.device_token = "a" * 108
         
     | 
| 
      
 12 
     | 
    
         
            +
                notification.alert = ""
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                notification.alert << "a" until notification.payload.bytesize == 4096
         
     | 
| 
      
 15 
     | 
    
         
            +
                expect(notification.valid?).to be_truthy
         
     | 
| 
      
 16 
     | 
    
         
            +
                expect(notification.errors[:base]).to be_empty
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                notification.alert << "a"
         
     | 
| 
      
 19 
     | 
    
         
            +
                expect(notification.valid?).to be_falsey
         
     | 
| 
      
 20 
     | 
    
         
            +
                expect(notification.errors[:base].include?("APN notification cannot be larger than 4096 bytes. Try condensing your alert and device attributes.")).to be_truthy
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              it "should default the sound to 'default'" do
         
     | 
| 
      
 24 
     | 
    
         
            +
                notification = described_class.new
         
     | 
| 
      
 25 
     | 
    
         
            +
                expect(notification.sound).to eq('default')
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              # skipping these tests because data= for redis doesn't merge existing data
         
     | 
| 
      
 29 
     | 
    
         
            +
              xit 'does not overwrite the mutable-content flag when setting attributes for the device' do
         
     | 
| 
      
 30 
     | 
    
         
            +
                notification.mutable_content = true
         
     | 
| 
      
 31 
     | 
    
         
            +
                notification.data = { 'hi' => 'mom' }
         
     | 
| 
      
 32 
     | 
    
         
            +
                expect(notification.as_json['aps']['mutable-content']).to eq 1
         
     | 
| 
      
 33 
     | 
    
         
            +
                expect(notification.as_json['hi']).to eq 'mom'
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              xit 'does not overwrite the content-available flag when setting attributes for the device' do
         
     | 
| 
      
 37 
     | 
    
         
            +
                notification.content_available = true
         
     | 
| 
      
 38 
     | 
    
         
            +
                notification.data = { 'hi' => 'mom' }
         
     | 
| 
      
 39 
     | 
    
         
            +
                expect(notification.as_json['aps']['content-available']).to eq 1
         
     | 
| 
      
 40 
     | 
    
         
            +
                expect(notification.as_json['hi']).to eq 'mom'
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              # redis does not use alert_is_json - unclear if that is a bug or desired behavior
         
     | 
| 
      
 44 
     | 
    
         
            +
              xit 'does confuse a JSON looking string as JSON if the alert_is_json attribute is not present' do
         
     | 
| 
      
 45 
     | 
    
         
            +
                notification = described_class.new
         
     | 
| 
      
 46 
     | 
    
         
            +
                allow(notification).to receive_messages(has_attribute?: false)
         
     | 
| 
      
 47 
     | 
    
         
            +
                notification.alert = "{\"one\":2}"
         
     | 
| 
      
 48 
     | 
    
         
            +
                expect(notification.alert).to eq('one' => 2)
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            end if redis?
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'unit_spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe Rpush::Client::Redis::Wns::RawNotification do
         
     | 
| 
      
 4 
     | 
    
         
            +
              it_behaves_like 'Rpush::Client::Wns::RawNotification'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              subject(:notification) do
         
     | 
| 
      
 7 
     | 
    
         
            +
                notif = described_class.new
         
     | 
| 
      
 8 
     | 
    
         
            +
                notif.app = Rpush::Wns::App.create!(name: "MyApp", client_id: "someclient", client_secret: "somesecret")
         
     | 
| 
      
 9 
     | 
    
         
            +
                notif.uri = 'https://db5.notify.windows.com/?token=TOKEN'
         
     | 
| 
      
 10 
     | 
    
         
            +
                notif.data = { foo: 'foo', bar: 'bar' }
         
     | 
| 
      
 11 
     | 
    
         
            +
                notif
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              # This fails because the length validation is only on active record
         
     | 
| 
      
 15 
     | 
    
         
            +
              # Attempting to move to active model in rails 6 fails
         
     | 
| 
      
 16 
     | 
    
         
            +
              # because wns_notification#as_json is not defined
         
     | 
| 
      
 17 
     | 
    
         
            +
              # and the active_model#as_json version results in a stack level too deep error
         
     | 
| 
      
 18 
     | 
    
         
            +
              xit 'does not allow the size of payload over 5 KB' do
         
     | 
| 
      
 19 
     | 
    
         
            +
                allow(notification).to receive(:payload_data_size) { 5121 }
         
     | 
| 
      
 20 
     | 
    
         
            +
                expect(notification.valid?).to be(false)
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end if redis?
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'unit_spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            shared_examples 'Rpush::Client::Adm::App' do
         
     | 
| 
      
 4 
     | 
    
         
            +
              subject { described_class.new(name: 'test', environment: 'development', client_id: 'CLIENT_ID', client_secret: 'CLIENT_SECRET') }
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              it 'should be valid if properly instantiated' do
         
     | 
| 
      
 7 
     | 
    
         
            +
                expect(subject).to be_valid
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              it 'should be invalid if name' do
         
     | 
| 
      
 11 
     | 
    
         
            +
                subject.name = nil
         
     | 
| 
      
 12 
     | 
    
         
            +
                expect(subject).not_to be_valid
         
     | 
| 
      
 13 
     | 
    
         
            +
                expect(subject.errors[:name]).to eq ["can't be blank"]
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              it 'should be invalid if missing client_id' do
         
     | 
| 
      
 17 
     | 
    
         
            +
                subject.client_id = nil
         
     | 
| 
      
 18 
     | 
    
         
            +
                expect(subject).not_to be_valid
         
     | 
| 
      
 19 
     | 
    
         
            +
                expect(subject.errors[:client_id]).to eq ["can't be blank"]
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              it 'should be invalid if missing client_secret' do
         
     | 
| 
      
 23 
     | 
    
         
            +
                subject.client_secret = nil
         
     | 
| 
      
 24 
     | 
    
         
            +
                expect(subject).not_to be_valid
         
     | 
| 
      
 25 
     | 
    
         
            +
                expect(subject.errors[:client_secret]).to eq ["can't be blank"]
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              describe '#access_token_expired?' do
         
     | 
| 
      
 29 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 30 
     | 
    
         
            +
                  Timecop.freeze(Time.now)
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                after do
         
     | 
| 
      
 34 
     | 
    
         
            +
                  Timecop.return
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                it 'should return true if access_token_expiration is nil' do
         
     | 
| 
      
 38 
     | 
    
         
            +
                  expect(subject.access_token_expired?).to eq(true)
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                it 'should return true if expired' do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  subject.access_token_expiration = Time.now - 5.minutes
         
     | 
| 
      
 43 
     | 
    
         
            +
                  expect(subject.access_token_expired?).to eq(true)
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                it 'should return false if not expired' do
         
     | 
| 
      
 47 
     | 
    
         
            +
                  subject.access_token_expiration = Time.now + 5.minutes
         
     | 
| 
      
 48 
     | 
    
         
            +
                  expect(subject.access_token_expired?).to eq(false)
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'unit_spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            shared_examples 'Rpush::Client::Adm::Notification' do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:app) { Rpush::Adm::App.create!(name: 'test', client_id: 'CLIENT_ID', client_secret: 'CLIENT_SECRET') }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:notification) { described_class.new }
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              it "has a 'data' payload limit of 6144 bytes" do
         
     | 
| 
      
 8 
     | 
    
         
            +
                notification.data = { key: "a" * 6144 }
         
     | 
| 
      
 9 
     | 
    
         
            +
                expect(notification.valid?).to eq(false)
         
     | 
| 
      
 10 
     | 
    
         
            +
                expect(notification.errors[:base]).to eq ["Notification payload data cannot be larger than 6144 bytes."]
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              it 'limits the number of registration ids to 100' do
         
     | 
| 
      
 14 
     | 
    
         
            +
                notification.registration_ids = ['a'] * (100 + 1)
         
     | 
| 
      
 15 
     | 
    
         
            +
                expect(notification.valid?).to eq(false)
         
     | 
| 
      
 16 
     | 
    
         
            +
                expect(notification.errors[:base]).to eq ["Number of registration_ids cannot be larger than 100."]
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              it 'validates data can be blank if collapse_key is set' do
         
     | 
| 
      
 20 
     | 
    
         
            +
                notification.app = app
         
     | 
| 
      
 21 
     | 
    
         
            +
                notification.registration_ids = ['a']
         
     | 
| 
      
 22 
     | 
    
         
            +
                notification.collapse_key = 'test'
         
     | 
| 
      
 23 
     | 
    
         
            +
                notification.data = nil
         
     | 
| 
      
 24 
     | 
    
         
            +
                expect(notification.valid?).to eq(true)
         
     | 
| 
      
 25 
     | 
    
         
            +
                expect(notification.errors[:data]).to be_empty
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              it 'validates data is present if collapse_key is not set' do
         
     | 
| 
      
 29 
     | 
    
         
            +
                notification.collapse_key = nil
         
     | 
| 
      
 30 
     | 
    
         
            +
                notification.data = nil
         
     | 
| 
      
 31 
     | 
    
         
            +
                expect(notification.valid?).to eq(false)
         
     | 
| 
      
 32 
     | 
    
         
            +
                expect(notification.errors[:data]).to eq ['must be set unless collapse_key is specified']
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              it 'includes expiresAfter in the payload' do
         
     | 
| 
      
 36 
     | 
    
         
            +
                notification.expiry = 100
         
     | 
| 
      
 37 
     | 
    
         
            +
                expect(notification.as_json['expiresAfter']).to eq 100
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'unit_spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            shared_examples 'Rpush::Client::Apns::App' do
         
     | 
| 
      
 4 
     | 
    
         
            +
              it 'does not validate an app with an invalid certificate' do
         
     | 
| 
      
 5 
     | 
    
         
            +
                app = described_class.new(name: 'test', environment: 'development', certificate: 'foo')
         
     | 
| 
      
 6 
     | 
    
         
            +
                app.valid?
         
     | 
| 
      
 7 
     | 
    
         
            +
                expect(app.errors[:certificate]).to eq ['value must contain a certificate and a private key.']
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              it 'validates a certificate without a password' do
         
     | 
| 
      
 11 
     | 
    
         
            +
                app = described_class.new name: 'test', environment: 'development', certificate: TEST_CERT
         
     | 
| 
      
 12 
     | 
    
         
            +
                app.valid?
         
     | 
| 
      
 13 
     | 
    
         
            +
                expect(app.errors[:certificate]).to eq []
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              it 'validates a certificate with a password' do
         
     | 
| 
      
 17 
     | 
    
         
            +
                app = described_class.new name: 'test', environment: 'development',
         
     | 
| 
      
 18 
     | 
    
         
            +
                                          certificate: TEST_CERT_WITH_PASSWORD, password: 'fubar'
         
     | 
| 
      
 19 
     | 
    
         
            +
                app.valid?
         
     | 
| 
      
 20 
     | 
    
         
            +
                expect(app.errors[:certificate]).to eq []
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              it 'validates a certificate with an incorrect password' do
         
     | 
| 
      
 24 
     | 
    
         
            +
                app = described_class.new name: 'test', environment: 'development',
         
     | 
| 
      
 25 
     | 
    
         
            +
                                          certificate: TEST_CERT_WITH_PASSWORD, password: 'incorrect'
         
     | 
| 
      
 26 
     | 
    
         
            +
                app.valid?
         
     | 
| 
      
 27 
     | 
    
         
            +
                expect(app.errors[:certificate]).to eq ['value must contain a certificate and a private key.']
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'unit_spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            shared_examples 'Rpush::Client::Apns::Feedback' do
         
     | 
| 
      
 4 
     | 
    
         
            +
              it 'validates the format of the device_token' do
         
     | 
| 
      
 5 
     | 
    
         
            +
                notification = described_class.new(device_token: "{$%^&*()}")
         
     | 
| 
      
 6 
     | 
    
         
            +
                expect(notification.valid?).to be_falsey
         
     | 
| 
      
 7 
     | 
    
         
            +
                expect(notification.errors[:device_token]).to include('is invalid')
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,262 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: US-ASCII
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "unit_spec_helper"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            shared_examples 'Rpush::Client::Apns::Notification' do
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:notification) { described_class.new }
         
     | 
| 
      
 7 
     | 
    
         
            +
              let(:app) { Rpush::Apns::App.create!(name: 'my_app', environment: 'development', certificate: TEST_CERT) }
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              it "should validate the format of the device_token" do
         
     | 
| 
      
 10 
     | 
    
         
            +
                notification = described_class.new(device_token: "{$%^&*()}")
         
     | 
| 
      
 11 
     | 
    
         
            +
                expect(notification.valid?).to be_falsey
         
     | 
| 
      
 12 
     | 
    
         
            +
                expect(notification.errors[:device_token].include?("is invalid")).to be_truthy
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              it "should store long alerts" do
         
     | 
| 
      
 16 
     | 
    
         
            +
                notification.app = app
         
     | 
| 
      
 17 
     | 
    
         
            +
                notification.device_token = "a" * 108
         
     | 
| 
      
 18 
     | 
    
         
            +
                notification.alert = "*" * 300
         
     | 
| 
      
 19 
     | 
    
         
            +
                expect(notification.valid?).to be_truthy
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                notification.save!
         
     | 
| 
      
 22 
     | 
    
         
            +
                notification.reload
         
     | 
| 
      
 23 
     | 
    
         
            +
                expect(notification.alert).to eq("*" * 300)
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              it "should default the expiry to 1 day" do
         
     | 
| 
      
 27 
     | 
    
         
            +
                expect(notification.expiry).to eq 1.day.to_i
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              describe "when assigning the device token" do
         
     | 
| 
      
 31 
     | 
    
         
            +
                it "should strip spaces from the given string" do
         
     | 
| 
      
 32 
     | 
    
         
            +
                  notification = described_class.new(device_token: "o m g")
         
     | 
| 
      
 33 
     | 
    
         
            +
                  expect(notification.device_token).to eq "omg"
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                it "should strip chevrons from the given string" do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  notification = described_class.new(device_token: "<omg>")
         
     | 
| 
      
 38 
     | 
    
         
            +
                  expect(notification.device_token).to eq "omg"
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              describe "as_json" do
         
     | 
| 
      
 43 
     | 
    
         
            +
                it "should include the alert if present" do
         
     | 
| 
      
 44 
     | 
    
         
            +
                  notification = described_class.new(alert: "hi mom")
         
     | 
| 
      
 45 
     | 
    
         
            +
                  expect(notification.as_json["aps"]["alert"]).to eq "hi mom"
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                it "should not include the alert key if the alert is not present" do
         
     | 
| 
      
 49 
     | 
    
         
            +
                  notification = described_class.new(alert: nil)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  expect(notification.as_json["aps"].key?("alert")).to be_falsey
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                it "should encode the alert as JSON if it is a Hash" do
         
     | 
| 
      
 54 
     | 
    
         
            +
                  notification = described_class.new(alert: { 'body' => "hi mom", 'alert-loc-key' => "View" })
         
     | 
| 
      
 55 
     | 
    
         
            +
                  expect(notification.as_json["aps"]["alert"]).to eq('body' => "hi mom", 'alert-loc-key' => "View")
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                it "should include the badge if present" do
         
     | 
| 
      
 59 
     | 
    
         
            +
                  notification = described_class.new(badge: 6)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  expect(notification.as_json["aps"]["badge"]).to eq 6
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                it "should not include the badge key if the badge is not present" do
         
     | 
| 
      
 64 
     | 
    
         
            +
                  notification = described_class.new(badge: nil)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  expect(notification.as_json["aps"].key?("badge")).to be_falsey
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                it "should include the sound if present" do
         
     | 
| 
      
 69 
     | 
    
         
            +
                  notification = described_class.new(sound: "my_sound.aiff")
         
     | 
| 
      
 70 
     | 
    
         
            +
                  expect(notification.as_json["aps"]["sound"]).to eq "my_sound.aiff"
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                it "should not include the sound key if the sound is not present" do
         
     | 
| 
      
 74 
     | 
    
         
            +
                  notification = described_class.new(sound: nil)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  expect(notification.as_json["aps"].key?("sound")).to be_falsey
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                it "should encode the sound as JSON if it is a Hash" do
         
     | 
| 
      
 79 
     | 
    
         
            +
                  notification = described_class.new(sound: { 'name' => "my_sound.aiff", 'critical' => 1, 'volume' => 0.5 })
         
     | 
| 
      
 80 
     | 
    
         
            +
                  expect(notification.as_json["aps"]["sound"]).to eq('name' => "my_sound.aiff", 'critical' => 1, 'volume' => 0.5)
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                it "should include attributes for the device" do
         
     | 
| 
      
 84 
     | 
    
         
            +
                  notification = described_class.new
         
     | 
| 
      
 85 
     | 
    
         
            +
                  notification.data = { 'omg' => 'lol', 'wtf' => 'dunno' }
         
     | 
| 
      
 86 
     | 
    
         
            +
                  expect(notification.as_json["omg"]).to eq "lol"
         
     | 
| 
      
 87 
     | 
    
         
            +
                  expect(notification.as_json["wtf"]).to eq "dunno"
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                it "should allow attributes to include a hash" do
         
     | 
| 
      
 91 
     | 
    
         
            +
                  notification = described_class.new
         
     | 
| 
      
 92 
     | 
    
         
            +
                  notification.data = { 'omg' => { 'ilike' => 'hashes' } }
         
     | 
| 
      
 93 
     | 
    
         
            +
                  expect(notification.as_json["omg"]["ilike"]).to eq "hashes"
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
              describe 'MDM' do
         
     | 
| 
      
 98 
     | 
    
         
            +
                let(:magic) { 'abc123' }
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                before do
         
     | 
| 
      
 101 
     | 
    
         
            +
                  notification.device_token = "a" * 108
         
     | 
| 
      
 102 
     | 
    
         
            +
                  notification.id = 1234
         
     | 
| 
      
 103 
     | 
    
         
            +
                end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                it 'includes the mdm magic in the payload' do
         
     | 
| 
      
 106 
     | 
    
         
            +
                  notification.mdm = magic
         
     | 
| 
      
 107 
     | 
    
         
            +
                  expect(notification.as_json).to eq('mdm' => magic)
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                it 'does not include aps attribute' do
         
     | 
| 
      
 111 
     | 
    
         
            +
                  notification.alert = "i'm doomed"
         
     | 
| 
      
 112 
     | 
    
         
            +
                  notification.mdm = magic
         
     | 
| 
      
 113 
     | 
    
         
            +
                  expect(notification.as_json.key?('aps')).to be_falsey
         
     | 
| 
      
 114 
     | 
    
         
            +
                end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                it 'can be converted to binary' do
         
     | 
| 
      
 117 
     | 
    
         
            +
                  notification.mdm = magic
         
     | 
| 
      
 118 
     | 
    
         
            +
                  expect(notification.to_binary).to be_present
         
     | 
| 
      
 119 
     | 
    
         
            +
                end
         
     | 
| 
      
 120 
     | 
    
         
            +
              end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
              describe 'mutable-content' do
         
     | 
| 
      
 123 
     | 
    
         
            +
                it 'includes mutable-content in the payload' do
         
     | 
| 
      
 124 
     | 
    
         
            +
                  notification.mutable_content = true
         
     | 
| 
      
 125 
     | 
    
         
            +
                  expect(notification.as_json['aps']['mutable-content']).to eq 1
         
     | 
| 
      
 126 
     | 
    
         
            +
                end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                it 'does not include content-available in the payload if not set' do
         
     | 
| 
      
 129 
     | 
    
         
            +
                  expect(notification.as_json['aps'].key?('mutable-content')).to be_falsey
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                it 'does not include mutable-content as a non-aps attribute' do
         
     | 
| 
      
 133 
     | 
    
         
            +
                  notification.mutable_content = true
         
     | 
| 
      
 134 
     | 
    
         
            +
                  expect(notification.as_json.key?('mutable-content')).to be_falsey
         
     | 
| 
      
 135 
     | 
    
         
            +
                end
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                it 'does not overwrite existing attributes for the device' do
         
     | 
| 
      
 138 
     | 
    
         
            +
                  notification.data = { 'hi' => 'mom' }
         
     | 
| 
      
 139 
     | 
    
         
            +
                  notification.mutable_content = true
         
     | 
| 
      
 140 
     | 
    
         
            +
                  expect(notification.as_json['aps']['mutable-content']).to eq 1
         
     | 
| 
      
 141 
     | 
    
         
            +
                  expect(notification.as_json['hi']).to eq 'mom'
         
     | 
| 
      
 142 
     | 
    
         
            +
                end
         
     | 
| 
      
 143 
     | 
    
         
            +
              end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
              describe 'content-available' do
         
     | 
| 
      
 146 
     | 
    
         
            +
                it 'includes content-available in the payload' do
         
     | 
| 
      
 147 
     | 
    
         
            +
                  notification.content_available = true
         
     | 
| 
      
 148 
     | 
    
         
            +
                  expect(notification.as_json['aps']['content-available']).to eq 1
         
     | 
| 
      
 149 
     | 
    
         
            +
                end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                it 'does not include content-available in the payload if not set' do
         
     | 
| 
      
 152 
     | 
    
         
            +
                  expect(notification.as_json['aps'].key?('content-available')).to be_falsey
         
     | 
| 
      
 153 
     | 
    
         
            +
                end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                it 'does not include content-available as a non-aps attribute' do
         
     | 
| 
      
 156 
     | 
    
         
            +
                  notification.content_available = true
         
     | 
| 
      
 157 
     | 
    
         
            +
                  expect(notification.as_json.key?('content-available')).to be_falsey
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                it 'does not overwrite existing attributes for the device' do
         
     | 
| 
      
 161 
     | 
    
         
            +
                  notification.data = { 'hi' => 'mom' }
         
     | 
| 
      
 162 
     | 
    
         
            +
                  notification.content_available = true
         
     | 
| 
      
 163 
     | 
    
         
            +
                  expect(notification.as_json['aps']['content-available']).to eq 1
         
     | 
| 
      
 164 
     | 
    
         
            +
                  expect(notification.as_json['hi']).to eq 'mom'
         
     | 
| 
      
 165 
     | 
    
         
            +
                end
         
     | 
| 
      
 166 
     | 
    
         
            +
              end
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
              describe 'url-args' do
         
     | 
| 
      
 169 
     | 
    
         
            +
                it 'includes url-args in the payload' do
         
     | 
| 
      
 170 
     | 
    
         
            +
                  notification.url_args = ['url-arg-1']
         
     | 
| 
      
 171 
     | 
    
         
            +
                  expect(notification.as_json['aps']['url-args']).to eq ['url-arg-1']
         
     | 
| 
      
 172 
     | 
    
         
            +
                end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                it 'does not include url-args in the payload if not set' do
         
     | 
| 
      
 175 
     | 
    
         
            +
                  expect(notification.as_json['aps'].key?('url-args')).to be_falsey
         
     | 
| 
      
 176 
     | 
    
         
            +
                end
         
     | 
| 
      
 177 
     | 
    
         
            +
              end
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
              describe 'category' do
         
     | 
| 
      
 180 
     | 
    
         
            +
                it 'includes category in the payload' do
         
     | 
| 
      
 181 
     | 
    
         
            +
                  notification.category = 'INVITE_CATEGORY'
         
     | 
| 
      
 182 
     | 
    
         
            +
                  expect(notification.as_json['aps']['category']).to eq 'INVITE_CATEGORY'
         
     | 
| 
      
 183 
     | 
    
         
            +
                end
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                it 'does not include category in the payload if not set' do
         
     | 
| 
      
 186 
     | 
    
         
            +
                  expect(notification.as_json['aps'].key?('category')).to be_falsey
         
     | 
| 
      
 187 
     | 
    
         
            +
                end
         
     | 
| 
      
 188 
     | 
    
         
            +
              end
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
              describe 'to_binary' do
         
     | 
| 
      
 191 
     | 
    
         
            +
                before do
         
     | 
| 
      
 192 
     | 
    
         
            +
                  notification.device_token = "a" * 108
         
     | 
| 
      
 193 
     | 
    
         
            +
                  notification.id = 1234
         
     | 
| 
      
 194 
     | 
    
         
            +
                end
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                it 'uses APNS_PRIORITY_CONSERVE_POWER if content-available is the only key' do
         
     | 
| 
      
 197 
     | 
    
         
            +
                  notification.alert = nil
         
     | 
| 
      
 198 
     | 
    
         
            +
                  notification.badge = nil
         
     | 
| 
      
 199 
     | 
    
         
            +
                  notification.sound = nil
         
     | 
| 
      
 200 
     | 
    
         
            +
                  notification.content_available = true
         
     | 
| 
      
 201 
     | 
    
         
            +
                  bytes = notification.to_binary.bytes.to_a[-4..-1]
         
     | 
| 
      
 202 
     | 
    
         
            +
                  expect(bytes.first).to eq 5 # priority item ID
         
     | 
| 
      
 203 
     | 
    
         
            +
                  expect(bytes.last).to eq described_class::APNS_PRIORITY_CONSERVE_POWER
         
     | 
| 
      
 204 
     | 
    
         
            +
                end
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
                it 'uses APNS_PRIORITY_IMMEDIATE if content-available is not the only key' do
         
     | 
| 
      
 207 
     | 
    
         
            +
                  notification.alert = "New stuff!"
         
     | 
| 
      
 208 
     | 
    
         
            +
                  notification.badge = nil
         
     | 
| 
      
 209 
     | 
    
         
            +
                  notification.sound = nil
         
     | 
| 
      
 210 
     | 
    
         
            +
                  notification.content_available = true
         
     | 
| 
      
 211 
     | 
    
         
            +
                  bytes = notification.to_binary.bytes.to_a[-4..-1]
         
     | 
| 
      
 212 
     | 
    
         
            +
                  expect(bytes.first).to eq 5 # priority item ID
         
     | 
| 
      
 213 
     | 
    
         
            +
                  expect(bytes.last).to eq described_class::APNS_PRIORITY_IMMEDIATE
         
     | 
| 
      
 214 
     | 
    
         
            +
                end
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                it "should correctly convert the notification to binary" do
         
     | 
| 
      
 217 
     | 
    
         
            +
                  notification.sound = "1.aiff"
         
     | 
| 
      
 218 
     | 
    
         
            +
                  notification.badge = 3
         
     | 
| 
      
 219 
     | 
    
         
            +
                  notification.alert = "Don't panic Mr Mainwaring, don't panic!"
         
     | 
| 
      
 220 
     | 
    
         
            +
                  notification.data = { hi: :mom }
         
     | 
| 
      
 221 
     | 
    
         
            +
                  notification.expiry = 86_400 # 1 day
         
     | 
| 
      
 222 
     | 
    
         
            +
                  notification.priority = described_class::APNS_PRIORITY_IMMEDIATE
         
     | 
| 
      
 223 
     | 
    
         
            +
                  notification.app = app
         
     | 
| 
      
 224 
     | 
    
         
            +
                  now = Time.now
         
     | 
| 
      
 225 
     | 
    
         
            +
                  allow(Time).to receive_messages(now: now)
         
     | 
| 
      
 226 
     | 
    
         
            +
                  expect(notification.to_binary).to eq "\x02\x00\x00\x00\xAF\x01\x00 \xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\x02\x00a{\"aps\":{\"alert\":\"Don't panic Mr Mainwaring, don't panic!\",\"badge\":3,\"sound\":\"1.aiff\"},\"hi\":\"mom\"}\x03\x00\x04\x00\x00\x04\xD2\x04\x00\x04#{[now.to_i + 86_400].pack('N')}\x05\x00\x01\n"
         
     | 
| 
      
 227 
     | 
    
         
            +
                end
         
     | 
| 
      
 228 
     | 
    
         
            +
              end
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
              describe "bug #31" do
         
     | 
| 
      
 231 
     | 
    
         
            +
                it 'does not confuse a JSON looking string as JSON' do
         
     | 
| 
      
 232 
     | 
    
         
            +
                  notification = described_class.new
         
     | 
| 
      
 233 
     | 
    
         
            +
                  notification.alert = "{\"one\":2}"
         
     | 
| 
      
 234 
     | 
    
         
            +
                  expect(notification.alert).to eq "{\"one\":2}"
         
     | 
| 
      
 235 
     | 
    
         
            +
                end
         
     | 
| 
      
 236 
     | 
    
         
            +
              end
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
              describe "bug #35" do
         
     | 
| 
      
 239 
     | 
    
         
            +
                it "should limit payload size to 256 bytes but not the entire packet" do
         
     | 
| 
      
 240 
     | 
    
         
            +
                  notification = described_class.new.tap do |n|
         
     | 
| 
      
 241 
     | 
    
         
            +
                    n.device_token = "a" * 108
         
     | 
| 
      
 242 
     | 
    
         
            +
                    n.alert = "a" * 210
         
     | 
| 
      
 243 
     | 
    
         
            +
                    n.app = app
         
     | 
| 
      
 244 
     | 
    
         
            +
                  end
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
                  expect(notification.to_binary(for_validation: true).bytesize).to be > 256
         
     | 
| 
      
 247 
     | 
    
         
            +
                  expect(notification.payload.bytesize).to be < 256
         
     | 
| 
      
 248 
     | 
    
         
            +
                  expect(notification).to be_valid
         
     | 
| 
      
 249 
     | 
    
         
            +
                end
         
     | 
| 
      
 250 
     | 
    
         
            +
              end
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
              describe 'thread-id' do
         
     | 
| 
      
 253 
     | 
    
         
            +
                it 'includes thread-id in the payload' do
         
     | 
| 
      
 254 
     | 
    
         
            +
                  notification.thread_id = 'THREAD-ID'
         
     | 
| 
      
 255 
     | 
    
         
            +
                  expect(notification.as_json['aps']['thread-id']).to eq 'THREAD-ID'
         
     | 
| 
      
 256 
     | 
    
         
            +
                end
         
     | 
| 
      
 257 
     | 
    
         
            +
             
     | 
| 
      
 258 
     | 
    
         
            +
                it 'does not include thread-id in the payload if not set' do
         
     | 
| 
      
 259 
     | 
    
         
            +
                  expect(notification.as_json['aps']).to_not have_key('thread-id')
         
     | 
| 
      
 260 
     | 
    
         
            +
                end
         
     | 
| 
      
 261 
     | 
    
         
            +
              end
         
     | 
| 
      
 262 
     | 
    
         
            +
            end
         
     |