opium 1.2.3 → 1.2.4
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 +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
|