opium 1.2.3 → 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/opium/file.rb +1 -1
- data/lib/opium/model/connectable.rb +43 -36
- data/lib/opium/model/field.rb +14 -10
- data/lib/opium/model/fieldable.rb +14 -14
- data/lib/opium/model.rb +6 -5
- data/lib/opium/schema.rb +48 -0
- data/lib/opium/version.rb +1 -1
- data/lib/opium.rb +2 -1
- data/spec/opium/file_spec.rb +7 -0
- data/spec/opium/schema_spec.rb +142 -0
- data/spec/opium_spec.rb +2 -2
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20938c9338f0dea54366b7ae20a74a5e416c1b3e
|
4
|
+
data.tar.gz: 901e5c2f20e9db92da93f2e32fd0c64bc6323269
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 812b467de4ac66ffedd6b3bf7be8965b09af23a3a9bd8253dfac3ecf4cc7dc1608458bb27e3f116142ef77d220f83c3b4b6d1d4d11230859c0fbef1d9021a89f
|
7
|
+
data.tar.gz: f5f78274f8963237dee6db4dd81d27e383d3440a550f7a5105e0ae2ce3769ec5b71d13149d79d6ffe56839dac0c727061d872ec695ac289ae299539f773d0811
|
data/CHANGELOG.md
CHANGED
data/lib/opium/file.rb
CHANGED
@@ -21,7 +21,7 @@ module Opium
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def to_ruby( object )
|
24
|
-
return
|
24
|
+
return if object.nil? || object == ''
|
25
25
|
return object if object.is_a?( self )
|
26
26
|
object = ::JSON.parse( object ) if object.is_a?( String )
|
27
27
|
if object.is_a?( Hash ) && (has_key_of_value( object, :__type, 'File' ) || has_keys( object, :url, :name ))
|
@@ -5,19 +5,19 @@ module Opium
|
|
5
5
|
module Model
|
6
6
|
module Connectable
|
7
7
|
extend ActiveSupport::Concern
|
8
|
-
|
8
|
+
|
9
9
|
included do
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
class ParseError < StandardError
|
13
13
|
def initialize( code, error )
|
14
14
|
super( error )
|
15
15
|
@code = code
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
attr_reader :code
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
module ClassMethods
|
22
22
|
def connection
|
23
23
|
@@connection ||= Faraday.new( url: 'https://api.parse.com/1/' ) do |faraday|
|
@@ -30,20 +30,20 @@ module Opium
|
|
30
30
|
faraday.adapter Faraday.default_adapter
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def reset_connection!
|
35
35
|
@@connection = nil
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def object_prefix
|
39
39
|
@object_prefix ||= 'classes'
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# Parse doesn't route User objects through /classes/, instead treating them as a top-level class.
|
43
43
|
def no_object_prefix!
|
44
44
|
@object_prefix = ''
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def as_resource( name, &block )
|
48
48
|
fail ArgumentError, 'no block given' unless block_given?
|
49
49
|
@masked_resource_name = name.to_s.freeze
|
@@ -51,13 +51,13 @@ module Opium
|
|
51
51
|
ensure
|
52
52
|
@masked_resource_name = nil
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
def resource_name( resource_id = nil )
|
56
56
|
return @masked_resource_name if @masked_resource_name
|
57
57
|
@resource_name ||= Pathname.new( object_prefix ).join( map_name_to_resource( model_name ) )
|
58
58
|
( resource_id ? @resource_name.join( resource_id ) : @resource_name ).to_s
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
def http_get( options = {} )
|
62
62
|
http( :get, options ) do |request|
|
63
63
|
options.fetch(:query, {}).each do |key, value|
|
@@ -65,38 +65,42 @@ module Opium
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
def http_post( data, options = {} )
|
70
70
|
http( :post, deeply_merge( options, content_type_json ), &infuse_request_with( data ) )
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
def http_put( id, data, options = {} )
|
74
|
-
http( :put, deeply_merge( options, content_type_json, id: id ), &infuse_request_with( data ) )
|
74
|
+
http( :put, deeply_merge( options, content_type_json, id: id ), &infuse_request_with( data ) )
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
def http_delete( id, options = {} )
|
78
78
|
http( :delete, deeply_merge( options, id: id ) )
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
def requires_heightened_privileges!
|
82
82
|
@requires_heightened_privileges = true
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
def requires_heightened_privileges?
|
86
86
|
!@requires_heightened_privileges.nil?
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
alias_method :has_heightened_privileges?, :requires_heightened_privileges?
|
90
|
-
|
90
|
+
|
91
91
|
def with_heightened_privileges(&block)
|
92
92
|
previous, @requires_heightened_privileges = @requires_heightened_privileges, true
|
93
93
|
block.call if block_given?
|
94
94
|
ensure
|
95
95
|
@requires_heightened_privileges = previous
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
|
+
def no_really_i_need_master!
|
99
|
+
@always_heightened_privileges = true
|
100
|
+
end
|
101
|
+
|
98
102
|
private
|
99
|
-
|
103
|
+
|
100
104
|
def http( method, options, &block )
|
101
105
|
check_for_error( options ) do
|
102
106
|
if options[:sent_headers]
|
@@ -109,43 +113,46 @@ module Opium
|
|
109
113
|
end
|
110
114
|
end
|
111
115
|
end
|
112
|
-
|
116
|
+
|
113
117
|
def deeply_merge( *args )
|
114
118
|
args.reduce {|a, e| a.deep_merge e }
|
115
119
|
end
|
116
|
-
|
120
|
+
|
117
121
|
def content_type_json
|
118
122
|
@content_type_json ||= { headers: { content_type: 'application/json' } }
|
119
123
|
end
|
120
|
-
|
124
|
+
|
121
125
|
def map_name_to_resource( model_name )
|
122
126
|
name = model_name.name.demodulize
|
123
127
|
@object_prefix.empty? ? name.tableize : name
|
124
128
|
end
|
125
|
-
|
129
|
+
|
126
130
|
def infuse_request_with( data )
|
127
131
|
lambda do |request|
|
128
132
|
request.body = data
|
129
133
|
end
|
130
134
|
end
|
131
|
-
|
135
|
+
|
132
136
|
def apply_headers_to_request( method, options, &further_operations )
|
133
137
|
lambda do |request|
|
134
138
|
request.headers.update options[:headers] if options[:headers]
|
135
139
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
request.headers[:x_parse_rest_api_key] = Opium.config.api_key unless added_master_key
|
144
|
-
|
140
|
+
if use_master_key?( request, method )
|
141
|
+
request.headers[:x_parse_master_key] = Opium.config.master_key
|
142
|
+
else
|
143
|
+
request.headers[:x_parse_rest_api_key] = Opium.config.api_key
|
144
|
+
end
|
145
|
+
|
145
146
|
further_operations.call( request ) if block_given?
|
146
147
|
end
|
147
148
|
end
|
148
|
-
|
149
|
+
|
150
|
+
def use_master_key?( request, method )
|
151
|
+
!request.headers[:x_parse_session_token] &&
|
152
|
+
( @always_heightened_privileges || method != :get ) &&
|
153
|
+
requires_heightened_privileges? && Opium.config.master_key
|
154
|
+
end
|
155
|
+
|
149
156
|
def check_for_error( options = {}, &block )
|
150
157
|
fail ArgumentError, 'no block given' unless block_given?
|
151
158
|
result = yield
|
@@ -161,4 +168,4 @@ module Opium
|
|
161
168
|
end
|
162
169
|
end
|
163
170
|
end
|
164
|
-
end
|
171
|
+
end
|
data/lib/opium/model/field.rb
CHANGED
@@ -4,9 +4,9 @@ module Opium
|
|
4
4
|
def initialize(name, type, default, readonly, as)
|
5
5
|
self.name, self.type, self.default, self.readonly, self.as = name, type, default, readonly, as
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
attr_reader :name, :type, :readonly, :as
|
9
|
-
|
9
|
+
|
10
10
|
def default( context = nil )
|
11
11
|
if @default.respond_to? :call
|
12
12
|
params = []
|
@@ -16,30 +16,34 @@ module Opium
|
|
16
16
|
@default
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def contextual_default_value( context = nil)
|
21
21
|
type.to_ruby( default( context ) )
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def readonly?
|
25
25
|
self.readonly == true
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def relation?
|
29
29
|
self.type == Relation
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def virtual?
|
33
33
|
relation? || self.type == Reference
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def name_to_parse
|
37
37
|
@name_to_parse ||= (self.as || self.name).to_s.camelize(:lower)
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
|
+
def name_to_ruby
|
41
|
+
@name_to_ruby ||= (self.as || self.name).to_s.underscore
|
42
|
+
end
|
43
|
+
|
40
44
|
private
|
41
|
-
|
45
|
+
|
42
46
|
attr_writer :name, :type, :default, :readonly, :as
|
43
47
|
end
|
44
48
|
end
|
45
|
-
end
|
49
|
+
end
|
@@ -4,13 +4,13 @@ module Opium
|
|
4
4
|
module Model
|
5
5
|
module Fieldable
|
6
6
|
extend ActiveSupport::Concern
|
7
|
-
|
7
|
+
|
8
8
|
included do
|
9
9
|
field :id, type: String, readonly: true, as: :object_id
|
10
10
|
field :created_at, type: DateTime, readonly: true
|
11
11
|
field :updated_at, type: DateTime, readonly: true
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
module ClassMethods
|
15
15
|
def field( name, options = {} )
|
16
16
|
create_field_from( name.to_sym, options ).tap do |field|
|
@@ -18,38 +18,38 @@ module Opium
|
|
18
18
|
create_field_setter_for( field )
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def has_field?( field_name )
|
23
23
|
fields.key? field_name
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
alias_method :field?, :has_field?
|
27
|
-
|
27
|
+
|
28
28
|
def fields
|
29
29
|
@fields ||= {}.with_indifferent_access
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def ruby_canonical_field_names
|
33
33
|
@ruby_canonical_field_names ||= {}.with_indifferent_access
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def parse_canonical_field_names
|
37
37
|
@parse_canonical_field_names ||= {}.with_indifferent_access
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def default_attributes( context = nil )
|
41
41
|
fields.transform_values {|field| field.contextual_default_value( context ) }.with_indifferent_access
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
private
|
45
|
-
|
45
|
+
|
46
46
|
def create_field_from( name, options )
|
47
47
|
field = Field.new( name, options[:type] || Object, options[:default], options[:readonly] || false, options[:as] )
|
48
48
|
ruby_canonical_field_names[name] = ruby_canonical_field_names[field.name_to_parse] = name.to_s
|
49
49
|
parse_canonical_field_names[name] = parse_canonical_field_names[field.name_to_parse] = field.name_to_parse.to_s
|
50
50
|
fields[name] = field
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
def create_field_getter_for( field )
|
54
54
|
class_eval do
|
55
55
|
define_attribute_methods [field.name]
|
@@ -58,7 +58,7 @@ module Opium
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
def create_field_setter_for( field )
|
63
63
|
class_eval do
|
64
64
|
define_method("#{ field.name }=") do |value|
|
@@ -66,7 +66,7 @@ module Opium
|
|
66
66
|
send( "#{ field.name }_will_change!" ) unless self.attributes[field.name] == converted
|
67
67
|
if field.relation?
|
68
68
|
converted = field.contextual_default_value( self ) unless converted
|
69
|
-
converted.owner ||= self
|
69
|
+
converted.owner ||= self
|
70
70
|
converted.metadata ||= self.class.relations[field.name]
|
71
71
|
end
|
72
72
|
self.attributes[field.name] = converted
|
@@ -77,4 +77,4 @@ module Opium
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
80
|
-
end
|
80
|
+
end
|
data/lib/opium/model.rb
CHANGED
@@ -3,6 +3,7 @@ require 'active_support/core_ext/string'
|
|
3
3
|
require 'active_support/core_ext/hash/indifferent_access'
|
4
4
|
require 'active_support/core_ext/hash/deep_merge'
|
5
5
|
require 'active_support/core_ext/hash/transform_values'
|
6
|
+
require 'active_support/core_ext/enumerable'
|
6
7
|
require 'active_support/inflector'
|
7
8
|
require 'opium/model/connectable'
|
8
9
|
require 'opium/model/persistable'
|
@@ -23,9 +24,9 @@ require 'opium/model/kaminari'
|
|
23
24
|
module Opium
|
24
25
|
module Model
|
25
26
|
extend ActiveSupport::Concern
|
26
|
-
|
27
|
+
|
27
28
|
include ActiveModel::Model
|
28
|
-
|
29
|
+
|
29
30
|
included do
|
30
31
|
include Connectable
|
31
32
|
include Persistable
|
@@ -42,14 +43,14 @@ module Opium
|
|
42
43
|
include Relatable
|
43
44
|
include GlobalID::Identification if defined?( GlobalID )
|
44
45
|
end
|
45
|
-
|
46
|
+
|
46
47
|
def initialize( attributes = {} )
|
47
48
|
self.attributes = attributes
|
48
49
|
end
|
49
|
-
|
50
|
+
|
50
51
|
def inspect
|
51
52
|
inspected_fields = self.attributes.map {|k, v| [k, v.inspect].join(': ')}.join(', ')
|
52
53
|
"#<#{self.class.model_name} #{inspected_fields}>"
|
53
54
|
end
|
54
55
|
end
|
55
|
-
end
|
56
|
+
end
|
data/lib/opium/schema.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Opium
|
2
|
+
class Schema
|
3
|
+
include Opium::Model::Connectable
|
4
|
+
|
5
|
+
requires_heightened_privileges!
|
6
|
+
no_really_i_need_master!
|
7
|
+
no_object_prefix!
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def all
|
11
|
+
http_get[:results].map {|schema| new( schema ) }.index_by(&:class_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def find( model_name, options = {} )
|
15
|
+
result = http_get( options.merge id: model_name )
|
16
|
+
options[:sent_headers] ? result : new( result )
|
17
|
+
end
|
18
|
+
|
19
|
+
def model_name
|
20
|
+
@model_name ||= ActiveModel::Name.new( self, nil, self.name )
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
attr_reader :class_name, :fields
|
26
|
+
|
27
|
+
def initialize( attributes = {} )
|
28
|
+
attributes.deep_symbolize_keys.tap do |a|
|
29
|
+
@class_name = a[:className]
|
30
|
+
@fields = ( a[:fields] || {} ).map do |field_name, options|
|
31
|
+
Opium::Model::Field.new( field_name, options[:type], nil, false, nil )
|
32
|
+
end.index_by(&:name_to_ruby)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def save
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def model
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/opium/version.rb
CHANGED
data/lib/opium.rb
CHANGED
data/spec/opium/file_spec.rb
CHANGED
@@ -132,6 +132,13 @@ describe Opium::File do
|
|
132
132
|
it { expect( result ).to be_a Opium::File }
|
133
133
|
end
|
134
134
|
|
135
|
+
context 'when given an empty string' do
|
136
|
+
let(:object) { '' }
|
137
|
+
|
138
|
+
it { expect { result }.to_not raise_exception }
|
139
|
+
it { expect( result ).to be_nil }
|
140
|
+
end
|
141
|
+
|
135
142
|
context 'when not given a hash' do
|
136
143
|
let(:object) { 42 }
|
137
144
|
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Opium::Schema do
|
4
|
+
before do
|
5
|
+
stub_const( 'Game', Class.new do |klass|
|
6
|
+
include Opium::Model
|
7
|
+
field :name, type: String
|
8
|
+
field :current_price, type: Float
|
9
|
+
end )
|
10
|
+
stub_const( 'Player', Class.new do |klass|
|
11
|
+
include Opium::Model
|
12
|
+
field :player_tag, type: String
|
13
|
+
field :player_score, type: Integer
|
14
|
+
end )
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:game_schema) do
|
18
|
+
{
|
19
|
+
className: 'Game',
|
20
|
+
fields: {
|
21
|
+
objectId: { type: 'String' },
|
22
|
+
name: { type: 'String' },
|
23
|
+
current_price: { type: 'Number' },
|
24
|
+
createdAt: { type: 'Date' },
|
25
|
+
updatedAt: { type: 'Date' }
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:player_schema) do
|
31
|
+
{
|
32
|
+
className: 'Player',
|
33
|
+
fields: {
|
34
|
+
objectId: { type: 'String' },
|
35
|
+
player_tag: { type: 'String' },
|
36
|
+
player_score: { type: 'Number' },
|
37
|
+
createdAt: { type: 'Date' },
|
38
|
+
updatedAt: { type: 'Date' }
|
39
|
+
}
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
it { expect( described_class ).to respond_to( :connection, :http_get ) }
|
44
|
+
it { expect( described_class ).to have_heightened_privileges }
|
45
|
+
it { expect( described_class.object_prefix ).to be_blank }
|
46
|
+
|
47
|
+
it { expect( described_class ).to respond_to( :find ).with( 1 ).argument }
|
48
|
+
it { expect( described_class ).to respond_to( :all ) }
|
49
|
+
it { is_expected.to respond_to( :save, :delete, :model, :fields, :class_name ) }
|
50
|
+
|
51
|
+
describe '.find' do
|
52
|
+
let(:result) { described_class.find( model_name, options ) }
|
53
|
+
let(:options) { {} }
|
54
|
+
|
55
|
+
context 'with a sent_headers option' do
|
56
|
+
let(:model_name) { 'NoOp' }
|
57
|
+
let(:options) { { sent_headers: true } }
|
58
|
+
|
59
|
+
it { expect { result }.to_not raise_exception }
|
60
|
+
it { expect( result.keys ).to include('X-Parse-Master-Key') }
|
61
|
+
it { expect( result.keys ).to_not include('X-Parse-Rest-Api-Key') }
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with a valid model name' do
|
65
|
+
let(:model_name) { 'Game' }
|
66
|
+
|
67
|
+
before do
|
68
|
+
stub_request(:get, "https://api.parse.com/1/schemas/Game").
|
69
|
+
with(headers: {'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Master-Key'=>'PARSE_MASTER_KEY'}).
|
70
|
+
to_return(status: 200, body: game_schema.to_json, headers: { content_type: 'application/json' })
|
71
|
+
end
|
72
|
+
|
73
|
+
it { expect { result }.to_not raise_exception }
|
74
|
+
it { expect( result ).to be_a( Opium::Schema ) }
|
75
|
+
it('sets the correct model name from the results') { expect( result.class_name ).to eq 'Game' }
|
76
|
+
it { expect( result.fields ).to be_a Hash }
|
77
|
+
it { expect( result.fields.values ).to all( be_a Opium::Model::Field ) }
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'with an invalid model name' do
|
81
|
+
let(:model_name) { 'DoesNotExist' }
|
82
|
+
|
83
|
+
before do
|
84
|
+
stub_request(:get, "https://api.parse.com/1/schemas/DoesNotExist").
|
85
|
+
with(headers: {'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Master-Key'=>'PARSE_MASTER_KEY'}).
|
86
|
+
to_return(status: 400, body: {
|
87
|
+
code: 103, error: 'class DoesNotExist does not exist'
|
88
|
+
}.to_json, headers: { content_type: 'application/json' })
|
89
|
+
end
|
90
|
+
|
91
|
+
it { expect { result }.to raise_exception( Opium::Model::Connectable::ParseError ) }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '.all' do
|
96
|
+
let(:result) { described_class.all }
|
97
|
+
|
98
|
+
context 'when there are no classes' do
|
99
|
+
before do
|
100
|
+
stub_request(:get, "https://api.parse.com/1/schemas").
|
101
|
+
with(headers: {'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Master-Key'=>'PARSE_MASTER_KEY'}).
|
102
|
+
to_return(status: 200, body: {
|
103
|
+
results: []
|
104
|
+
}.to_json, headers: { content_type: 'application/json' })
|
105
|
+
end
|
106
|
+
|
107
|
+
it { expect( result ).to be_empty }
|
108
|
+
it { expect( result ).to be_a( Hash ) }
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when there are multiple classes' do
|
112
|
+
before do
|
113
|
+
stub_request(:get, "https://api.parse.com/1/schemas").
|
114
|
+
with(headers: {'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Master-Key'=>'PARSE_MASTER_KEY'}).
|
115
|
+
to_return(status: 200, body: {
|
116
|
+
results: [
|
117
|
+
game_schema,
|
118
|
+
player_schema
|
119
|
+
]
|
120
|
+
}.to_json, headers: { content_type: 'application/json' })
|
121
|
+
end
|
122
|
+
|
123
|
+
let(:expected_keys) { [ 'Game', 'Player' ] }
|
124
|
+
|
125
|
+
it { expect( result ).to_not be_empty }
|
126
|
+
it { expect( result.keys ).to include( *expected_keys ) }
|
127
|
+
it { expect( result.values ).to all( be_a( Opium::Schema ) ) }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#save' do
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#delete' do
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
describe '#fields' do
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|
data/spec/opium_spec.rb
CHANGED
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.2.
|
4
|
+
version: 1.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Bowers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -302,6 +302,7 @@ files:
|
|
302
302
|
- lib/opium/model/scopable.rb
|
303
303
|
- lib/opium/model/serialization.rb
|
304
304
|
- lib/opium/railtie.rb
|
305
|
+
- lib/opium/schema.rb
|
305
306
|
- lib/opium/user.rb
|
306
307
|
- lib/opium/version.rb
|
307
308
|
- opium.gemspec
|
@@ -345,6 +346,7 @@ files:
|
|
345
346
|
- spec/opium/model/scopable_spec.rb
|
346
347
|
- spec/opium/model/serialization_spec.rb
|
347
348
|
- spec/opium/model_spec.rb
|
349
|
+
- spec/opium/schema_spec.rb
|
348
350
|
- spec/opium/user_spec.rb
|
349
351
|
- spec/opium_spec.rb
|
350
352
|
- spec/spec_helper.rb
|
@@ -368,7 +370,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
368
370
|
version: '0'
|
369
371
|
requirements: []
|
370
372
|
rubyforge_project:
|
371
|
-
rubygems_version: 2.4.
|
373
|
+
rubygems_version: 2.4.5.1
|
372
374
|
signing_key:
|
373
375
|
specification_version: 4
|
374
376
|
summary: An Object Parse.com Mapping technology for defining models.
|
@@ -413,6 +415,7 @@ test_files:
|
|
413
415
|
- spec/opium/model/scopable_spec.rb
|
414
416
|
- spec/opium/model/serialization_spec.rb
|
415
417
|
- spec/opium/model_spec.rb
|
418
|
+
- spec/opium/schema_spec.rb
|
416
419
|
- spec/opium/user_spec.rb
|
417
420
|
- spec/opium_spec.rb
|
418
421
|
- spec/spec_helper.rb
|