opium 1.5.4 → 1.5.5
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/.travis.yml +1 -0
- data/CHANGELOG.md +5 -0
- data/README.md +24 -0
- data/lib/opium/model/attributable.rb +11 -12
- data/lib/opium/user.rb +10 -9
- data/lib/opium/version.rb +1 -1
- data/spec/opium/model/attributable_spec.rb +17 -10
- data/spec/opium/model/serialization_spec.rb +20 -5
- data/spec/opium/user_spec.rb +59 -56
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b53eb8b7bd8065147581a1ad93cc314190142304
|
4
|
+
data.tar.gz: 19898ad35c81040d44ba9765cf66319c1a4a6bc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3979d70c2107f4865da5804cddf925c7731c098f6f0dfab6180cc2388d598021937d6d441752f7a2fb8d795855357f9fe0c0b4a50bd937cd6d1bc5fb3c4114c
|
7
|
+
data.tar.gz: 1351e6632df54fdf436c0c1358387d24629022fe47e00afcfd9c5efed9958c252a041cc61058ea05cdb5054dda64c205dfd72de69f57271614c737200a9cba5f
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 1.5.5
|
2
|
+
### Resolved Issues
|
3
|
+
- Attributable no longer stores unknown fields within the attributes hash of the object; rather, a new accessor is created on the fly for the class to store that data. This should prevent serialization from breaking on unknown fields with more recent versions of ActiveModel.
|
4
|
+
- User should not be storing any data other than its known fields. This was primarily an issue with the find by session token endpoint, which is now mysteriously embedding `__type` and `className` into the results.
|
5
|
+
|
1
6
|
## 1.5.4
|
2
7
|
### Resolved Issues
|
3
8
|
- #55: Opium::Installation was not properly using the master key for performing queries. Parse requires the presence of the master key to perform any sort of non-id query on installations.
|
data/README.md
CHANGED
@@ -465,10 +465,22 @@ player.high_scores.include?( score3 ) # true, as the above setter updates play
|
|
465
465
|
|
466
466
|
### Querying data
|
467
467
|
|
468
|
+
Models can be searched for via one of two different methods: by their associated `id` field value, or by criteria defining the attributes a model must have to be part of a match set.
|
469
|
+
|
468
470
|
#### Find by id
|
469
471
|
|
472
|
+
IDs in Parse should be unique within a given model class. As such, finding by id always returns, at most, one result: the model instance associated with the provided id.
|
473
|
+
|
474
|
+
`Opium::Model` provides a single class method, `find` for performing an id search. It accepts a single parameter, `id`, being a string representing the id to look for. Should a matching model exist, it will be the return value of the method; otherwise, an exception is raised. Any class which mixes in `Opium::Model` has access to this method.
|
475
|
+
|
476
|
+
```ruby
|
477
|
+
score = HighScore.find( 'd3ADb3Ef' )
|
478
|
+
```
|
479
|
+
|
470
480
|
#### Criteria & Scopes
|
471
481
|
|
482
|
+
While `find` is useful if a model id is already available, it is more often desirable to perform a query across more and varied content stored within the model. This is where criteria come into play.
|
483
|
+
|
472
484
|
#### Kaminari support
|
473
485
|
|
474
486
|
Opium comes with support for [Kaminari](https://rubygems.org/gems/kaminari). To ensure that Opium loads itself correctly, please specify it _after_ Kaminari within your Gemfile:
|
@@ -507,6 +519,18 @@ Note that note all of these data are supported on all platforms.
|
|
507
519
|
|
508
520
|
Once the push has be configured as desired, it can be sent out by triggering the `create` method, which will either raise an error on failure or return true on success. Note that a truthy return value does not necessarily indicate that Parse has successfully sent any notifications; rather it merely indicates that Parse has successfully received the push request and did not find anything egregious in it.
|
509
521
|
|
522
|
+
In the following example, a push is scheduled for a day in the future which targets some channels.
|
523
|
+
|
524
|
+
```ruby
|
525
|
+
p = Opium::Push.new(
|
526
|
+
alert: 'Be sure to watch our eSports tournament on Twitch!',
|
527
|
+
push_at: 1.day.from_now,
|
528
|
+
expiration_interval: 1.day,
|
529
|
+
channels: %w[ Gaming eSports Tournaments ]
|
530
|
+
)
|
531
|
+
p.create
|
532
|
+
```
|
533
|
+
|
510
534
|
### Advanced Targeting
|
511
535
|
|
512
536
|
## Contributing
|
@@ -2,40 +2,39 @@ module Opium
|
|
2
2
|
module Model
|
3
3
|
module Attributable
|
4
4
|
extend ActiveSupport::Concern
|
5
|
-
|
5
|
+
|
6
6
|
included do
|
7
7
|
include ActiveModel::ForbiddenAttributesProtection
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def initialize( attributes = {} )
|
11
11
|
super( self.class.default_attributes( self ).merge attributes )
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def attributes
|
15
15
|
@attributes ||= {}.with_indifferent_access
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def attributes=(values)
|
19
19
|
sanitize_for_mass_assignment( rubyize_field_names( values ) ).each do |k, v|
|
20
20
|
field_info, setter = self.class.fields[k], :"#{k}="
|
21
|
-
|
22
|
-
send(
|
23
|
-
else
|
24
|
-
attributes[k] = v
|
21
|
+
unless field_info.present? || self.respond_to?( setter )
|
22
|
+
self.class.send(:attr_accessor, k)
|
25
23
|
end
|
24
|
+
send( setter, v )
|
26
25
|
end
|
27
26
|
end
|
28
|
-
|
27
|
+
|
29
28
|
def attributes_to_parse( options = {} )
|
30
29
|
options[:except] ||= self.class.fields.values.select {|f| f.readonly? || f.virtual? }.map {|f| f.name} if options[:not_readonly]
|
31
30
|
Hash[*self.as_json( options ).flat_map {|k, v| [self.class.fields[k].name_to_parse, self.class.fields[k].type.to_parse(v)]}]
|
32
31
|
end
|
33
|
-
|
32
|
+
|
34
33
|
private
|
35
|
-
|
34
|
+
|
36
35
|
def rubyize_field_names( hash )
|
37
36
|
hash.transform_keys {|k| self.class.ruby_canonical_field_names[k] || k}
|
38
37
|
end
|
39
38
|
end
|
40
39
|
end
|
41
|
-
end
|
40
|
+
end
|
data/lib/opium/user.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
module Opium
|
2
2
|
class User
|
3
3
|
include Opium::Model
|
4
|
-
|
4
|
+
|
5
5
|
field :username, type: String
|
6
6
|
field :password, type: String
|
7
7
|
field :email, type: String
|
8
8
|
field :email_verified, type: Boolean, readonly: true
|
9
9
|
field :session_token, type: String, readonly: true
|
10
|
-
|
10
|
+
|
11
11
|
no_object_prefix!
|
12
12
|
requires_heightened_privileges!
|
13
13
|
add_header_to [:put, :delete], :x_parse_session_token, :session_token.to_proc
|
14
|
-
|
14
|
+
|
15
15
|
class << self
|
16
16
|
# Note that this will eat any ParseErrors which get raised, and not perform any logging.
|
17
17
|
def authenticate( username, password )
|
@@ -19,26 +19,27 @@ module Opium
|
|
19
19
|
rescue Opium::Model::Connectable::ParseError => e
|
20
20
|
nil
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def authenticate!( username, password )
|
24
24
|
new( as_resource('login') { http_get query: { username: username, password: password } } )
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def find_by_session_token( token )
|
28
|
-
|
28
|
+
data = http_get id: 'me', headers: { x_parse_session_token: token }
|
29
|
+
new( data.slice( *fields.keys ) )
|
29
30
|
end
|
30
31
|
end
|
31
|
-
|
32
|
+
|
32
33
|
def reset_password
|
33
34
|
reset_password!
|
34
35
|
rescue => e
|
35
36
|
self.errors.add( :email, e.to_s )
|
36
37
|
false
|
37
38
|
end
|
38
|
-
|
39
|
+
|
39
40
|
def reset_password!
|
40
41
|
fail KeyError, 'an email address is required to reset password' unless email
|
41
42
|
self.class.as_resource('requestPasswordReset') { self.class.http_post data: email }.empty?
|
42
43
|
end
|
43
44
|
end
|
44
|
-
end
|
45
|
+
end
|
data/lib/opium/version.rb
CHANGED
@@ -10,41 +10,48 @@ describe Opium::Model::Attributable do
|
|
10
10
|
attr_accessor :not_a_field
|
11
11
|
end )
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
subject { Book.new( title: 'Little Brother', id: 'abc123', created_at: Time.now, genre: :sci_fi ) }
|
15
|
-
|
15
|
+
|
16
16
|
describe '#attributes_to_parse' do
|
17
17
|
context 'when called with no parameters' do
|
18
18
|
it 'has all fields present, with names and values converted to parse' do
|
19
19
|
expect( subject.attributes_to_parse ).to eq( 'objectId' => 'abc123', 'title' => 'Little Brother', 'genre' => 'sci_fi', 'createdAt' => subject.created_at.to_parse, 'updatedAt' => nil )
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
context 'when called with except' do
|
24
24
|
it 'excludes the excepted fields' do
|
25
25
|
expect( subject.attributes_to_parse( except: [:id, :updated_at] ) ).to eq( 'title' => 'Little Brother', 'genre' => 'sci_fi', 'createdAt' => subject.created_at.to_parse )
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
context 'when called with not_readonly' do
|
30
30
|
it 'excludes all readonly fields' do
|
31
31
|
expect( subject.attributes_to_parse( not_readonly: true ) ).to eq( 'title' => 'Little Brother', 'genre' => 'sci_fi' )
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
describe '#attributes=' do
|
37
|
-
it '
|
37
|
+
it 'does not store unrecognized fields in the attributes hash' do
|
38
38
|
expect { subject.attributes = { unknownField: 42 } }.to_not raise_exception
|
39
|
-
expect( subject.attributes ).
|
40
|
-
expect( subject.attributes['unknownField'] ).
|
39
|
+
expect( subject.attributes ).to_not have_key('unknownField')
|
40
|
+
expect( subject.attributes['unknownField'] ).to_not eq 42
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it 'calls relevant setters rather for non fields if they exist' do
|
44
44
|
expect { subject.attributes = { not_a_field: 42 } }.to_not raise_exception
|
45
45
|
expect( subject.not_a_field ).to eq 42
|
46
46
|
expect( subject.attributes ).to_not have_key('not_a_field')
|
47
47
|
end
|
48
|
+
|
49
|
+
it 'creates an accessor for unknown fields' do
|
50
|
+
expect { subject.attributes = { unknown: 42 } }.to_not raise_exception
|
51
|
+
expect( subject ).to respond_to( :unknown, :unknown= )
|
52
|
+
expect( subject.unknown ).to eq 42
|
53
|
+
expect( subject.attributes ).to_not have_key('unknown')
|
54
|
+
end
|
48
55
|
end
|
49
56
|
end
|
50
|
-
end
|
57
|
+
end
|
@@ -8,12 +8,12 @@ describe Opium::Model::Serialization do
|
|
8
8
|
field :price
|
9
9
|
end
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it { model.should respond_to( :include_root_in_json ) }
|
13
13
|
it "include_root_in_json should default to false" do
|
14
14
|
model.include_root_in_json.should == false
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
describe "instance" do
|
18
18
|
describe "with no data" do
|
19
19
|
let( :params ) { { "id" => nil, "created_at" => nil, "updated_at" => nil, "name" => nil, "price" => nil } }
|
@@ -25,7 +25,7 @@ describe Opium::Model::Serialization do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
describe "with partial data" do
|
30
30
|
let( :params ) { { "name" => "test", "price" => nil } }
|
31
31
|
subject { model.new( name: "test" ) }
|
@@ -36,7 +36,7 @@ describe Opium::Model::Serialization do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
describe "with full data" do
|
41
41
|
let( :params ) { { "name" => "test", "price" => 75.0 } }
|
42
42
|
subject { model.new( params ) }
|
@@ -47,5 +47,20 @@ describe Opium::Model::Serialization do
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
describe 'with non field data' do
|
52
|
+
let( :params ) { {'name' => 'test', 'price' => 75.0, 'extra' => true} }
|
53
|
+
subject { model.new( params ) }
|
54
|
+
it { expect { subject.as_json }.to_not raise_exception }
|
55
|
+
|
56
|
+
describe '#to_json' do
|
57
|
+
let(:result) { JSON.parse(subject.to_json) }
|
58
|
+
|
59
|
+
it 'only has field values' do
|
60
|
+
expect( result ).to include( 'name', 'price' )
|
61
|
+
expect( result ).to_not include( 'extra' )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
50
65
|
end
|
51
|
-
end
|
66
|
+
end
|
data/spec/opium/user_spec.rb
CHANGED
@@ -3,17 +3,17 @@ require 'spec_helper'
|
|
3
3
|
describe Opium::User do
|
4
4
|
before do
|
5
5
|
stub_request(:get, 'https://api.parse.com/1/login?password=swordfish&username=username').to_return(
|
6
|
-
status: 200,
|
7
|
-
body: {
|
8
|
-
username: 'username',
|
9
|
-
createdAt: '2014-11-01T12:00:30Z',
|
6
|
+
status: 200,
|
7
|
+
body: {
|
8
|
+
username: 'username',
|
9
|
+
createdAt: '2014-11-01T12:00:30Z',
|
10
10
|
updatedAt: '2015-02-10T16:37:23Z',
|
11
11
|
objectId: 'abcd1234',
|
12
12
|
sessionToken: 'super-secret-session-id'
|
13
13
|
}.to_json,
|
14
14
|
headers: { 'Content-Type' => 'application/json' }
|
15
15
|
)
|
16
|
-
|
16
|
+
|
17
17
|
stub_request(:get, 'https://api.parse.com/1/login?password=deadbeef&username=username').to_return(
|
18
18
|
status: 404,
|
19
19
|
body: {
|
@@ -22,145 +22,148 @@ describe Opium::User do
|
|
22
22
|
}.to_json,
|
23
23
|
headers: { 'Content-Type' => 'application/json' }
|
24
24
|
)
|
25
|
-
|
25
|
+
|
26
26
|
stub_request(:post, "https://api.parse.com/1/requestPasswordReset").with(
|
27
27
|
body: "{\"data\":\"user@email.com\"}",
|
28
28
|
headers: { 'Content-Type'=>'application/json' }
|
29
29
|
).to_return(
|
30
30
|
status: 200,
|
31
|
-
body: "{}",
|
31
|
+
body: "{}",
|
32
32
|
headers: {'Content-Type' => 'application/json'}
|
33
33
|
)
|
34
|
-
|
34
|
+
|
35
35
|
stub_request(:get, "https://api.parse.com/1/users/me").
|
36
36
|
with( headers: {'X-Parse-Session-Token'=>'super-secret-session-id'} ).
|
37
37
|
to_return(
|
38
|
-
:status => 200,
|
38
|
+
:status => 200,
|
39
39
|
:body => {
|
40
|
-
username: 'username',
|
41
|
-
createdAt: '2014-11-01T12:00:30Z',
|
40
|
+
username: 'username',
|
41
|
+
createdAt: '2014-11-01T12:00:30Z',
|
42
42
|
updatedAt: '2015-02-10T16:37:23Z',
|
43
|
-
objectId: 'abcd1234'
|
44
|
-
|
43
|
+
objectId: 'abcd1234',
|
44
|
+
__type: 'Object',
|
45
|
+
className: '_User'
|
46
|
+
}.to_json,
|
45
47
|
headers: { 'Content-Type' => 'application/json' }
|
46
48
|
)
|
47
|
-
|
49
|
+
|
48
50
|
stub_request(:get, "https://api.parse.com/1/users/me").
|
49
51
|
with( headers: {'X-Parse-Session-Token'=>'never-been-given-out'}).
|
50
52
|
to_return(
|
51
|
-
status: 404,
|
53
|
+
status: 404,
|
52
54
|
body: {
|
53
55
|
code: 101,
|
54
56
|
error: 'invalid session'
|
55
|
-
}.to_json,
|
57
|
+
}.to_json,
|
56
58
|
headers: { 'Content-Type' => 'application/json' }
|
57
59
|
)
|
58
60
|
end
|
59
|
-
|
61
|
+
|
60
62
|
it { described_class.should respond_to( :authenticate, :authenticate! ).with(2).arguments }
|
61
63
|
it { described_class.should respond_to( :find_by_session_token ).with(1).argument }
|
62
64
|
it { described_class.should respond_to( :object_prefix ) }
|
63
|
-
|
65
|
+
|
64
66
|
it { should be_an( Opium::Model ) }
|
65
|
-
|
67
|
+
|
66
68
|
[:username, :password, :email, :email_verified, :session_token].each do |field_name|
|
67
69
|
it { described_class.fields.should have_key( field_name ) }
|
68
70
|
end
|
69
|
-
|
71
|
+
|
70
72
|
it { described_class.fields[:session_token].should be_readonly }
|
71
73
|
it { expect( described_class.fields[:email_verified] ).to be_readonly }
|
72
74
|
it { described_class.object_prefix.should be_empty }
|
73
75
|
it { described_class.resource_name.should == 'users' }
|
74
76
|
it { expect( described_class.requires_heightened_privileges? ).to be_truthy }
|
75
|
-
|
77
|
+
|
76
78
|
describe '.authenticate' do
|
77
79
|
context 'with a good login' do
|
78
80
|
it 'should return an Opium::User matching the credentials' do
|
79
81
|
expect { described_class.authenticate( 'username', 'swordfish' ) }.to_not raise_exception
|
80
|
-
|
82
|
+
|
81
83
|
login = described_class.authenticate( 'username', 'swordfish' )
|
82
|
-
|
83
|
-
login.should_not be_nil
|
84
|
-
login.should be_a( described_class )
|
85
|
-
login.username.should == 'username'
|
84
|
+
|
85
|
+
login.should_not be_nil
|
86
|
+
login.should be_a( described_class )
|
87
|
+
login.username.should == 'username'
|
86
88
|
login.session_token.should_not be_nil
|
87
89
|
end
|
88
90
|
|
89
91
|
end
|
90
|
-
|
92
|
+
|
91
93
|
context 'with a bad login' do
|
92
94
|
let(:login) { described_class.authenticate( 'username', 'deadbeef' ) }
|
93
|
-
|
95
|
+
|
94
96
|
it { expect { login }.to_not raise_exception }
|
95
97
|
it { login.should be_nil }
|
96
98
|
end
|
97
99
|
end
|
98
|
-
|
100
|
+
|
99
101
|
describe '.authenticate!' do
|
100
102
|
context 'with a good login' do
|
101
103
|
it { expect { described_class.authenticate!( 'username', 'swordfish' ) }.to_not raise_exception }
|
102
104
|
end
|
103
|
-
|
105
|
+
|
104
106
|
context 'with a bad login' do
|
105
107
|
it { expect { described_class.authenticate!( 'username', 'deadbeef' ) }.to raise_exception }
|
106
108
|
end
|
107
109
|
end
|
108
|
-
|
110
|
+
|
109
111
|
describe '.find_by_session_token' do
|
110
112
|
context 'without a token' do
|
111
113
|
it { expect { described_class.find_by_session_token( nil ) }.to raise_exception }
|
112
114
|
end
|
113
|
-
|
115
|
+
|
114
116
|
context 'with a valid token' do
|
115
117
|
let(:current_user) { described_class.find_by_session_token( 'super-secret-session-id' ) }
|
116
|
-
|
118
|
+
|
117
119
|
it { expect { current_user }.to_not raise_exception }
|
118
120
|
it { current_user.should be_a( described_class ) }
|
121
|
+
it { expect( current_user ).to_not respond_to( :__type, :className ) }
|
119
122
|
end
|
120
|
-
|
123
|
+
|
121
124
|
context 'with an invalid token' do
|
122
125
|
it { expect { described_class.find_by_session_token( 'never-been-given-out' ) }.to raise_exception(Opium::Model::Connectable::ParseError) }
|
123
126
|
end
|
124
127
|
end
|
125
|
-
|
128
|
+
|
126
129
|
context 'with a logged in user' do
|
127
130
|
subject { Opium::User.new( id: 'abcd1234', session_token: 'super-secret-session-id', usernmae: 'user', email: 'user@email.com' ) }
|
128
|
-
|
131
|
+
|
129
132
|
it { should respond_to( :reset_password, :reset_password! ) }
|
130
|
-
|
133
|
+
|
131
134
|
describe '#reset_password' do
|
132
135
|
context 'without an email' do
|
133
136
|
before { subject.email = nil }
|
134
137
|
after { subject.email = 'user@example.com' }
|
135
|
-
|
138
|
+
|
136
139
|
it { expect { subject.reset_password }.to_not raise_exception }
|
137
|
-
it do
|
140
|
+
it do
|
138
141
|
subject.reset_password.should == false
|
139
142
|
subject.errors.should_not be_empty
|
140
143
|
end
|
141
144
|
end
|
142
|
-
|
145
|
+
|
143
146
|
context 'with an email' do
|
144
147
|
it { expect { subject.reset_password }.to_not raise_exception }
|
145
148
|
it { subject.reset_password.should == true }
|
146
149
|
end
|
147
150
|
end
|
148
|
-
|
151
|
+
|
149
152
|
describe '#reset_password!' do
|
150
153
|
describe 'without an email' do
|
151
154
|
before { subject.email = nil }
|
152
155
|
after { subject.email = 'user@example.com' }
|
153
|
-
|
156
|
+
|
154
157
|
it { expect { subject.reset_password! }.to raise_exception }
|
155
158
|
end
|
156
|
-
|
159
|
+
|
157
160
|
context 'with an email' do
|
158
161
|
it { expect { subject.reset_password! }.to_not raise_exception }
|
159
162
|
it { subject.reset_password!.should == true }
|
160
163
|
end
|
161
164
|
end
|
162
165
|
end
|
163
|
-
|
166
|
+
|
164
167
|
shared_examples_for 'a varying privileges user' do |method, header_target|
|
165
168
|
describe "##{method}" do
|
166
169
|
let( :request ) { subject.send( method, sent_headers: true ) }
|
@@ -168,47 +171,47 @@ describe Opium::User do
|
|
168
171
|
request
|
169
172
|
subject.send( :sent_headers )
|
170
173
|
end
|
171
|
-
|
174
|
+
|
172
175
|
context 'with a session token' do
|
173
176
|
subject { Opium::User.new( id: 'abcd1234', session_token: 'super-secret-session-id', usernmae: 'user', email: 'user@email.com' ) }
|
174
|
-
|
177
|
+
|
175
178
|
it { expect( Opium::User.get_header_for( *header_target, subject ) ).to_not be_empty }
|
176
|
-
|
179
|
+
|
177
180
|
it { expect( sent_headers ).to be_a( Hash ) }
|
178
181
|
it { expect( sent_headers.keys ).to include( 'X-Parse-Application-Id', 'X-Parse-Rest-Api-Key', 'X-Parse-Session-Token' ) }
|
179
182
|
it { expect( sent_headers.keys ).to_not include( 'X-Parse-Master-Key' ) }
|
180
183
|
end
|
181
|
-
|
184
|
+
|
182
185
|
context 'without a session token' do
|
183
186
|
subject { Opium::User.new( id: 'abcd1234', session_token: nil, username: 'user', email: 'user@email.com' ) }
|
184
|
-
|
187
|
+
|
185
188
|
it { expect( Opium::User.get_header_for( *header_target, subject ) ).to be_empty }
|
186
|
-
|
189
|
+
|
187
190
|
it { expect( sent_headers ).to be_a( Hash ) }
|
188
191
|
it { expect( sent_headers.keys ).to include( 'X-Parse-Application-Id', 'X-Parse-Master-Key' ) }
|
189
192
|
it { expect( sent_headers.keys ).to_not include( 'X-Parse-Rest-Api-Key, X-Parse-Session-Token' ) }
|
190
193
|
end
|
191
194
|
end
|
192
195
|
end
|
193
|
-
|
196
|
+
|
194
197
|
it_behaves_like 'a varying privileges user', :save, [:put, :update]
|
195
198
|
it_behaves_like 'a varying privileges user', :delete, [:delete, :delete]
|
196
|
-
|
199
|
+
|
197
200
|
context 'within a subclass' do
|
198
201
|
before do
|
199
202
|
stub_const( 'SpecialUser', Class.new(Opium::User) do
|
200
203
|
field :has_web_access, type: Opium::Boolean
|
201
204
|
end )
|
202
205
|
end
|
203
|
-
|
206
|
+
|
204
207
|
subject { SpecialUser }
|
205
|
-
|
208
|
+
|
206
209
|
it { is_expected.to be <= Opium::User }
|
207
210
|
it { is_expected.to respond_to( :field, :fields ) }
|
208
211
|
it { expect( subject.fields.keys ).to include( 'username', 'password', 'email', 'has_web_access' ) }
|
209
|
-
|
212
|
+
|
210
213
|
it { expect( subject ).to have_heightened_privileges }
|
211
214
|
it { expect( subject.object_prefix ).to be_empty }
|
212
215
|
it { expect( subject.resource_name ).to eq 'users' }
|
213
216
|
end
|
214
|
-
end
|
217
|
+
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.5
|
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-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -375,7 +375,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
375
375
|
version: '0'
|
376
376
|
requirements: []
|
377
377
|
rubyforge_project:
|
378
|
-
rubygems_version: 2.
|
378
|
+
rubygems_version: 2.6.11
|
379
379
|
signing_key:
|
380
380
|
specification_version: 4
|
381
381
|
summary: An Object Parse.com Mapping technology for defining models.
|