opium 1.5.2 → 1.5.3
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 +6 -0
- data/README.md +9 -1
- data/lib/generators/opium/installation_generator.rb +16 -0
- data/lib/opium/installation.rb +22 -0
- data/lib/opium/push.rb +60 -12
- data/lib/opium/version.rb +1 -1
- data/lib/opium.rb +1 -0
- data/spec/opium/installation_spec.rb +54 -0
- data/spec/opium/push_spec.rb +192 -24
- data/spec/opium_spec.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb9239c124be4e458967d7fe92d4073ea2cb996b
|
4
|
+
data.tar.gz: ee2dd7e877cfcd1892659b8645daa4b08cc9fc99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 770af57f72afb14bcf366157f7c3f4b7c628b44e0877e382441f628d2c2379d5e1449c07e57b7f59af6e3f4bc211e616a3d60139facf12d5f8d05d5aaff341d2
|
7
|
+
data.tar.gz: 9fb435ce9b0acfe2ebb5a18282cc6e5adb684fe5e83a818322cab5d1f04c213fb6fcdc9ff835690e9670016302fd2004da30607cfa7693415b18ff7b0cee3973
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 1.5.3
|
2
|
+
### New Features
|
3
|
+
- #54: Installation queries are now supported by Opium::Push to perform a more finely targeted push.
|
4
|
+
- #55: Introduction of Opium::Installation, which allows for access and manipulation of Parse's Installation object.
|
5
|
+
- Opium::Push has an expanded set of attributes which may be set to further customize a push, including the ability to schedule a push for a particular time and expire pushes.
|
6
|
+
|
1
7
|
## 1.5.2
|
2
8
|
### Resolved Issues
|
3
9
|
- Push should now use the master key for creating notifications, rather than the REST API key.
|
data/README.md
CHANGED
@@ -56,12 +56,20 @@ A generator exists for creating new models; this should be invoked whenever `rai
|
|
56
56
|
$ rails g model game title:string price:float
|
57
57
|
```
|
58
58
|
|
59
|
-
A separate
|
59
|
+
A separate generator is available for creating a model to wrap Parse's User model:
|
60
60
|
|
61
61
|
```bash
|
62
62
|
$ rails g opium:user
|
63
63
|
```
|
64
64
|
|
65
|
+
Finally, another generator is available to further customize Parse's Installation model:
|
66
|
+
|
67
|
+
```bash
|
68
|
+
$ rails g opium:installation
|
69
|
+
```
|
70
|
+
|
71
|
+
Both of these latter two generators otherwise accept the same arguments as the generic model generator.
|
72
|
+
|
65
73
|
### Specifying a model
|
66
74
|
|
67
75
|
Models are defined by mixing in `Opium::Model` into a new class. Class names should match the names of the
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'generators/opium/model_generator'
|
3
|
+
|
4
|
+
module Opium
|
5
|
+
module Generators
|
6
|
+
class InstallationGenerator < ::Rails::Generators::Base
|
7
|
+
desc "Creates an Opium installation model"
|
8
|
+
|
9
|
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
10
|
+
|
11
|
+
def run_model_generator
|
12
|
+
generate 'model', *['installation', *attributes, '--parent=opium/installation']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Opium
|
2
|
+
class Installation
|
3
|
+
include Opium::Model
|
4
|
+
|
5
|
+
no_object_prefix!
|
6
|
+
requires_heightened_privileges!
|
7
|
+
|
8
|
+
field :badge, type: Integer
|
9
|
+
field :channels, type: Array
|
10
|
+
field :time_zone, type: String
|
11
|
+
field :device_type, type: Symbol, readonly: true
|
12
|
+
field :push_type, type: Symbol, readonly: true
|
13
|
+
field :gcm_sender_id, type: Integer
|
14
|
+
field :installation_id, type: String, readonly: true
|
15
|
+
field :device_token, type: String
|
16
|
+
field :channel_uris, type: Array
|
17
|
+
field :app_name, type: String
|
18
|
+
field :app_version, type: String
|
19
|
+
field :parse_version, type: String
|
20
|
+
field :app_identifier, type: String
|
21
|
+
end
|
22
|
+
end
|
data/lib/opium/push.rb
CHANGED
@@ -4,25 +4,46 @@ module Opium
|
|
4
4
|
class Push
|
5
5
|
include Opium::Model::Connectable
|
6
6
|
|
7
|
+
class << self
|
8
|
+
private
|
9
|
+
|
10
|
+
def attr_hash_accessors( hash_name, *methods )
|
11
|
+
methods.each do |method_name|
|
12
|
+
attr_hash_accessor( hash_name, method_name )
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def attr_hash_accessor( hash_name, method_name )
|
17
|
+
unless respond_to?( method_name )
|
18
|
+
define_method method_name do
|
19
|
+
self.send( hash_name )[ method_name ]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
setter = "#{ method_name }="
|
23
|
+
unless respond_to?( setter )
|
24
|
+
define_method setter do |value|
|
25
|
+
self.send( hash_name )[ method_name ] = value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
7
31
|
requires_heightened_privileges!
|
8
32
|
|
9
33
|
def initialize( attributes = {} )
|
10
34
|
self.channels = []
|
11
35
|
self.data = {}.with_indifferent_access
|
36
|
+
attributes.each {|k, v| self.send( "#{k}=", v )}
|
12
37
|
end
|
13
38
|
|
14
|
-
attr_accessor :channels, :data
|
39
|
+
attr_accessor :channels, :where, :data, :push_at, :expires_at, :expiration_interval
|
15
40
|
|
16
|
-
|
17
|
-
|
18
|
-
end
|
41
|
+
alias_method :criteria, :where
|
42
|
+
alias_method :criteria=, :where=
|
19
43
|
|
20
|
-
|
21
|
-
self.data[:alert] = value
|
22
|
-
end
|
44
|
+
attr_hash_accessors :data, :alert, :badge, :sound, :content_available, :category, :uri, :title
|
23
45
|
|
24
46
|
def create
|
25
|
-
fail ArgumentError, 'No channels were specified!' if channels.empty?
|
26
47
|
self.class.as_resource(:push) do
|
27
48
|
result = self.class.http_post post_data
|
28
49
|
result[:result]
|
@@ -32,10 +53,37 @@ module Opium
|
|
32
53
|
private
|
33
54
|
|
34
55
|
def post_data
|
35
|
-
{
|
36
|
-
|
37
|
-
|
38
|
-
|
56
|
+
{}.tap do |pd|
|
57
|
+
targetize!( pd )
|
58
|
+
schedulize!( pd )
|
59
|
+
pd[:data] = data
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def targetize!( hash )
|
64
|
+
if criteria
|
65
|
+
c = criteria
|
66
|
+
c = Installation.where( c ) unless c.is_a?( Opium::Model::Criteria )
|
67
|
+
c = c.and( channels: channels ) unless channels.empty?
|
68
|
+
hash[:where] = c.constraints[:where]
|
69
|
+
elsif !channels.empty?
|
70
|
+
hash[:channels] = channels
|
71
|
+
else
|
72
|
+
fail ArgumentError, 'No channels or criteria were specified!'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def schedulize!( hash )
|
77
|
+
fail ArgumentError, 'No scheduled time for #push_at specified!' if expiration_interval && !push_at
|
78
|
+
if push_at
|
79
|
+
fail ArgumentError, 'Can only schedule a push up to 2 weeks in advance!' if push_at > ( Time.now + ( 2 * 604800 ) )
|
80
|
+
fail ArgumentError, 'Cannot schedule pushes in the past... unless you are the Doctor' if push_at < Time.now
|
81
|
+
hash[:push_time] = push_at.iso8601
|
82
|
+
hash[:expiration_interval] = expiration_interval
|
83
|
+
elsif expires_at
|
84
|
+
fail ArgumentError, 'Cannot schedule expiration in the past... unless you have a TARDIS' if expires_at < Time.now
|
85
|
+
hash[:expiration_time] = expires_at.iso8601
|
86
|
+
end
|
39
87
|
end
|
40
88
|
end
|
41
89
|
end
|
data/lib/opium/version.rb
CHANGED
data/lib/opium.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Opium::Installation do
|
4
|
+
|
5
|
+
it { described_class.should respond_to( :object_prefix ) }
|
6
|
+
|
7
|
+
it { should be_an( Opium::Model ) }
|
8
|
+
|
9
|
+
it { expect( described_class ).to have_heightened_privileges }
|
10
|
+
|
11
|
+
describe '#object_prefix' do
|
12
|
+
it { expect( described_class.object_prefix ).to be_empty }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#resource_name' do
|
16
|
+
it { expect( described_class.resource_name ).to eq 'installations' }
|
17
|
+
end
|
18
|
+
|
19
|
+
%w{ badge channels time_zone device_type push_type gcm_sender_id
|
20
|
+
installation_id device_token channel_uris app_name app_version
|
21
|
+
parse_version app_identifier }.each do |field_name|
|
22
|
+
it { described_class.fields.should have_key( field_name ) }
|
23
|
+
end
|
24
|
+
|
25
|
+
%w{ device_type push_type installation_id }.each do |field_name|
|
26
|
+
describe "##{ field_name }" do
|
27
|
+
it { expect( described_class.fields[field_name] ).to be_readonly }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'within a subclass' do
|
32
|
+
before do
|
33
|
+
stub_const( 'SpecialInstallation', Class.new(Opium::Installation) do
|
34
|
+
field :has_web_access, type: Opium::Boolean
|
35
|
+
end )
|
36
|
+
end
|
37
|
+
|
38
|
+
subject { SpecialInstallation }
|
39
|
+
|
40
|
+
it { is_expected.to be <= Opium::Installation }
|
41
|
+
it { is_expected.to respond_to( :field, :fields ) }
|
42
|
+
it { expect( subject.fields.keys ).to include( 'badge', 'device_token', 'has_web_access' ) }
|
43
|
+
|
44
|
+
it { expect( subject ).to have_heightened_privileges }
|
45
|
+
|
46
|
+
describe '#object_prefix' do
|
47
|
+
it { expect( subject.object_prefix ).to be_empty }
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#resource_name' do
|
51
|
+
it { expect( subject.resource_name ).to eq 'installations' }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/spec/opium/push_spec.rb
CHANGED
@@ -5,73 +5,128 @@ describe Opium::Push do
|
|
5
5
|
|
6
6
|
it { expect( described_class ).to respond_to(:to_ruby, :to_parse).with(1).argument }
|
7
7
|
|
8
|
-
it { is_expected.to respond_to( :create, :channels, :data, :alert ) }
|
8
|
+
it { is_expected.to respond_to( :create, :channels, :where, :data, :alert, :badge, :sound, :content_available, :category, :uri, :title, :expires_at, :push_at, :expiration_interval ) }
|
9
9
|
|
10
|
-
|
10
|
+
shared_examples_for 'a push option getter' do |option, value|
|
11
11
|
let(:result) do
|
12
12
|
subject.data = data
|
13
|
-
subject.
|
13
|
+
subject.send(option)
|
14
14
|
end
|
15
15
|
|
16
16
|
context 'with no data' do
|
17
17
|
let(:data) { { } }
|
18
18
|
|
19
|
-
it
|
19
|
+
it "equals data[:#{ option }]" do
|
20
20
|
expect( result ).to be_nil
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
context
|
25
|
-
let(:data) { {
|
24
|
+
context "with a value" do
|
25
|
+
let(:data) { { option => value } }
|
26
26
|
|
27
|
-
it
|
28
|
-
expect( result ).to eq data[
|
27
|
+
it "equals data[:#{ option }]" do
|
28
|
+
expect( result ).to eq data[option]
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
|
33
|
+
shared_examples_for 'a push option setter' do |option, value|
|
34
34
|
let(:result) do
|
35
|
-
subject.
|
36
|
-
subject.data[
|
35
|
+
subject.send( "#{ option }=".to_sym, option_value )
|
36
|
+
subject.data[option]
|
37
37
|
end
|
38
38
|
|
39
39
|
context 'with nothing' do
|
40
|
-
let(:
|
40
|
+
let(:option_value) { nil }
|
41
41
|
|
42
|
-
it
|
42
|
+
it "equals data[:#{ option }]" do
|
43
43
|
expect( result ).to be_nil
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
context 'with
|
48
|
-
let(:
|
47
|
+
context 'with a value' do
|
48
|
+
let(:option_value) { value }
|
49
49
|
|
50
|
-
it
|
51
|
-
expect( result ).to eq
|
50
|
+
it "equals data[:#{ option }]" do
|
51
|
+
expect( result ).to eq option_value
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
{
|
57
|
+
alert: 'The sky is blue.',
|
58
|
+
badge: 'Increment',
|
59
|
+
sound: 'cheering.caf',
|
60
|
+
content_available: 1,
|
61
|
+
category: 'A category',
|
62
|
+
uri: 'https://example.com',
|
63
|
+
title: 'Current Weather'
|
64
|
+
}.each do |option, value|
|
65
|
+
describe "##{ option }" do
|
66
|
+
it_behaves_like 'a push option getter', option, value
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "##{ option }=" do
|
70
|
+
it_behaves_like 'a push option setter', option, value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
56
74
|
describe '#create' do
|
57
75
|
let(:result) do
|
58
|
-
|
59
|
-
push.channels = channels
|
60
|
-
push.alert = alert
|
61
|
-
end.create
|
76
|
+
push.create
|
62
77
|
end
|
63
78
|
|
79
|
+
let(:push) do
|
80
|
+
subject.tap do |p|
|
81
|
+
p.channels = channels if channels
|
82
|
+
p.where = criteria if criteria
|
83
|
+
p.alert = alert
|
84
|
+
p.push_at = push_at if push_at
|
85
|
+
p.expires_at = expires_at if expires_at
|
86
|
+
p.expiration_interval = expiration_interval if expiration_interval
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
let(:push_post_data) { push.send(:post_data) }
|
91
|
+
|
64
92
|
let(:alert) { 'Zoo animals are fighting!' }
|
93
|
+
let(:channels) { %w{ General } }
|
94
|
+
let(:criteria) { nil }
|
95
|
+
let(:push_at) { nil }
|
96
|
+
let(:expires_at) { nil }
|
97
|
+
let(:expiration_interval) { nil }
|
98
|
+
|
99
|
+
let(:one_day_ago) { Time.now - 86400 }
|
100
|
+
let(:one_day_from_now) { Time.now + 86400 }
|
101
|
+
let(:one_week) { 604800 }
|
102
|
+
let(:one_week_from_now) { Time.now + one_week }
|
103
|
+
let(:three_weeks_from_now) { Time.now + ( 3 * one_week ) }
|
65
104
|
|
66
105
|
before do
|
67
106
|
stub_request(:post, "https://api.parse.com/1/push").
|
68
107
|
with(body: "{\"channels\":[\"Penguins\",\"PolarBears\"],\"data\":{\"alert\":\"Zoo animals are fighting!\"}}",
|
69
|
-
|
70
|
-
to_return(:
|
108
|
+
headers: {'Content-Type'=>'application/json', 'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Master-Key' => 'PARSE_MASTER_KEY'}).
|
109
|
+
to_return(status: 200, body: { result: true }.to_json, headers: {content_type: 'application/json'})
|
110
|
+
|
111
|
+
stub_request(:post, "https://api.parse.com/1/push").
|
112
|
+
with(body: "{\"where\":{\"deviceType\":\"ios\"},\"data\":{\"alert\":\"Zoo animals are fighting!\"}}",
|
113
|
+
headers: {'Content-Type'=>'application/json', 'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Master-Key'=>'PARSE_MASTER_KEY'}).
|
114
|
+
to_return(status: 200, body: { result: true }.to_json, headers: { content_type: 'application/json' })
|
115
|
+
|
116
|
+
stub_request(:post, "https://api.parse.com/1/push").
|
117
|
+
with(body: "{\"where\":{\"deviceType\":\"ios\",\"channels\":[\"Penguins\",\"PolarBears\"]},\"data\":{\"alert\":\"Zoo animals are fighting!\"}}",
|
118
|
+
headers: {'Content-Type'=>'application/json', 'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Master-Key'=>'PARSE_MASTER_KEY'}).
|
119
|
+
to_return(status: 200, body: { result: true }.to_json, headers: { content_type: 'application/json' })
|
120
|
+
|
121
|
+
stub_request(:post, "https://api.parse.com/1/push").
|
122
|
+
with(body: "{\"where\":{\"deviceType\":\"ios\",\"badge\":{\"$lte\":5},\"channels\":[\"Penguins\",\"PolarBears\"]},\"data\":{\"alert\":\"Zoo animals are fighting!\"}}",
|
123
|
+
headers: {'Content-Type'=>'application/json', 'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Master-Key'=>'PARSE_MASTER_KEY'}).
|
124
|
+
to_return(status: 200, body: { result: true }.to_json, headers: { content_type: 'application/json' })
|
71
125
|
end
|
72
126
|
|
73
|
-
context 'with no channels' do
|
127
|
+
context 'with no channels or criteria' do
|
74
128
|
let(:channels) { [] }
|
129
|
+
let(:criteria) { nil }
|
75
130
|
|
76
131
|
it { expect { result }.to raise_exception( ArgumentError ) }
|
77
132
|
end
|
@@ -79,8 +134,121 @@ describe Opium::Push do
|
|
79
134
|
context 'with channels' do
|
80
135
|
let(:channels) { %w{ Penguins PolarBears } }
|
81
136
|
|
137
|
+
it 'sets the channels key' do
|
138
|
+
expect( push_post_data ).to include( channels: channels )
|
139
|
+
end
|
140
|
+
it 'does not set the where key' do
|
141
|
+
expect( push_post_data ).to_not include( :where )
|
142
|
+
end
|
143
|
+
it { expect { result }.to_not raise_exception }
|
144
|
+
it { expect( result ).to eq true }
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'with a criteria' do
|
148
|
+
let(:channels) { nil }
|
149
|
+
let(:criteria) { { device_type: :ios } }
|
150
|
+
|
151
|
+
it 'does not set the channels key' do
|
152
|
+
expect( push_post_data ).to_not include( :channels )
|
153
|
+
end
|
154
|
+
it 'sets the where key' do
|
155
|
+
expect( push_post_data ).to include( :where )
|
156
|
+
end
|
157
|
+
it 'sets the where key to a parse-friendly version' do
|
158
|
+
expect( push_post_data[:where] ).to eq( { 'deviceType' => :ios } )
|
159
|
+
end
|
160
|
+
|
161
|
+
it { expect { result }.to_not raise_exception }
|
162
|
+
it { expect( result ).to eq true }
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'with channels and a criteria' do
|
166
|
+
let(:channels) { %w{ Penguins PolarBears } }
|
167
|
+
let(:criteria) { { device_type: :ios } }
|
168
|
+
|
169
|
+
it 'does not set the channels key' do
|
170
|
+
expect( push_post_data ).to_not include( :channels )
|
171
|
+
end
|
172
|
+
it 'sets the where key' do
|
173
|
+
expect( push_post_data ).to include( :where )
|
174
|
+
end
|
175
|
+
it 'adds the channels to the criteria' do
|
176
|
+
expect( push_post_data[:where] ).to include( channels: channels )
|
177
|
+
end
|
178
|
+
|
179
|
+
it { expect { result }.to_not raise_exception }
|
180
|
+
it { expect( result ).to eq true }
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'with an installation criteria and channels' do
|
184
|
+
let(:channels) { %w{ Penguins PolarBears } }
|
185
|
+
let(:criteria) { Opium::Installation.where( device_type: :ios ).lte( badge: 5 ) }
|
186
|
+
|
187
|
+
it 'does not set the channels key' do
|
188
|
+
expect( push_post_data ).to_not include( :channels )
|
189
|
+
end
|
190
|
+
it 'sets the where key' do
|
191
|
+
expect( push_post_data ).to include( :where )
|
192
|
+
end
|
193
|
+
it 'adds the channels to the criteria' do
|
194
|
+
expect( push_post_data[:where] ).to include( channels: channels )
|
195
|
+
end
|
196
|
+
it 'uses the installation criterias constraints' do
|
197
|
+
expect( push_post_data[:where] ).to include( :badge )
|
198
|
+
expect( push_post_data[:where][:badge] ).to include( '$lte' => 5 )
|
199
|
+
end
|
200
|
+
|
82
201
|
it { expect { result }.to_not raise_exception }
|
83
202
|
it { expect( result ).to eq true }
|
84
203
|
end
|
204
|
+
|
205
|
+
context 'with a scheduled push' do
|
206
|
+
let(:push_at) { one_day_from_now }
|
207
|
+
|
208
|
+
it { expect { push_post_data }.not_to raise_exception }
|
209
|
+
it 'sets the proper push_time' do
|
210
|
+
expect( push_post_data ).to include( push_time: push_at.iso8601 )
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context 'with a scheduled push before now' do
|
215
|
+
let(:push_at) { one_day_ago }
|
216
|
+
|
217
|
+
it { expect { result }.to raise_exception( ArgumentError ) }
|
218
|
+
end
|
219
|
+
|
220
|
+
context 'with a scheduled push too long from now' do
|
221
|
+
let(:push_at) { three_weeks_from_now }
|
222
|
+
|
223
|
+
it { expect { result }.to raise_exception( ArgumentError ) }
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'with a scheduled push and an expiration inverval' do
|
227
|
+
let(:push_at) { one_day_from_now }
|
228
|
+
let(:expiration_interval) { one_week }
|
229
|
+
|
230
|
+
it { expect { push_post_data }.not_to raise_exception }
|
231
|
+
it 'sets the proper push_time' do
|
232
|
+
expect( push_post_data ).to include( push_time: push_at.iso8601 )
|
233
|
+
end
|
234
|
+
it 'sets the proper expiration_interval' do
|
235
|
+
expect( push_post_data ).to include( expiration_interval: expiration_interval )
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context 'without a scheduled push and with an expiration inverval' do
|
240
|
+
let(:expiration_interval) { one_week }
|
241
|
+
|
242
|
+
it { expect { result }.to raise_exception( ArgumentError ) }
|
243
|
+
end
|
244
|
+
|
245
|
+
context 'with an expiry' do
|
246
|
+
let(:expires_at) { one_week_from_now }
|
247
|
+
|
248
|
+
it { expect { push_post_data }.not_to raise_exception }
|
249
|
+
it 'sets the proper expiration_time' do
|
250
|
+
expect( push_post_data ).to include( expiration_time: expires_at.iso8601 )
|
251
|
+
end
|
252
|
+
end
|
85
253
|
end
|
86
254
|
end
|
data/spec/opium_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Opium do
|
4
|
-
it { expect( described_class.constants ).to include( :Model, :User, :File, :Config, :Schema, :Push ) }
|
4
|
+
it { expect( described_class.constants ).to include( :Model, :User, :Installation, :File, :Config, :Schema, :Push ) }
|
5
5
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Bowers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -252,6 +252,7 @@ files:
|
|
252
252
|
- README.md
|
253
253
|
- Rakefile
|
254
254
|
- lib/generators/opium/config_generator.rb
|
255
|
+
- lib/generators/opium/installation_generator.rb
|
255
256
|
- lib/generators/opium/model_generator.rb
|
256
257
|
- lib/generators/opium/templates/config.yml
|
257
258
|
- lib/generators/opium/templates/model.rb
|
@@ -277,6 +278,7 @@ files:
|
|
277
278
|
- lib/opium/extensions/time.rb
|
278
279
|
- lib/opium/extensions/true_class.rb
|
279
280
|
- lib/opium/file.rb
|
281
|
+
- lib/opium/installation.rb
|
280
282
|
- lib/opium/model.rb
|
281
283
|
- lib/opium/model/attributable.rb
|
282
284
|
- lib/opium/model/batchable.rb
|
@@ -324,6 +326,7 @@ files:
|
|
324
326
|
- spec/opium/extensions/symbol_spec.rb
|
325
327
|
- spec/opium/extensions/time_spec.rb
|
326
328
|
- spec/opium/file_spec.rb
|
329
|
+
- spec/opium/installation_spec.rb
|
327
330
|
- spec/opium/model/attributable_spec.rb
|
328
331
|
- spec/opium/model/batchable/batch_spec.rb
|
329
332
|
- spec/opium/model/batchable/operation_spec.rb
|
@@ -394,6 +397,7 @@ test_files:
|
|
394
397
|
- spec/opium/extensions/symbol_spec.rb
|
395
398
|
- spec/opium/extensions/time_spec.rb
|
396
399
|
- spec/opium/file_spec.rb
|
400
|
+
- spec/opium/installation_spec.rb
|
397
401
|
- spec/opium/model/attributable_spec.rb
|
398
402
|
- spec/opium/model/batchable/batch_spec.rb
|
399
403
|
- spec/opium/model/batchable/operation_spec.rb
|