parse-ruby-client 0.1.14 → 0.1.15
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.
- data/.travis.yml +3 -2
- data/Gemfile +12 -12
- data/Gemfile.lock +26 -12
- data/OLD_README.md +255 -0
- data/README.md +1038 -144
- data/Rakefile +2 -10
- data/VERSION +1 -1
- data/features.md +11 -11
- data/fixtures/vcr_cassettes/test_acls_arent_objects.yml +180 -0
- data/fixtures/vcr_cassettes/test_array_add.yml +20 -20
- data/fixtures/vcr_cassettes/test_array_add_pointerizing.yml +239 -0
- data/fixtures/vcr_cassettes/test_array_add_unique.yml +180 -0
- data/fixtures/vcr_cassettes/test_batch_create_object.yml +53 -80
- data/fixtures/vcr_cassettes/test_batch_delete_object.yml +303 -428
- data/fixtures/vcr_cassettes/test_batch_run.yml +53 -74
- data/fixtures/vcr_cassettes/test_batch_update_object.yml +303 -432
- data/fixtures/vcr_cassettes/test_circular_save.yml +121 -0
- data/fixtures/vcr_cassettes/test_created_at.yml +53 -74
- data/fixtures/vcr_cassettes/test_decrement.yml +121 -0
- data/fixtures/vcr_cassettes/test_deep_parse.yml +154 -218
- data/fixtures/vcr_cassettes/test_destroy.yml +104 -144
- data/fixtures/vcr_cassettes/test_eq_pointerize.yml +239 -0
- data/fixtures/vcr_cassettes/test_equality.yml +180 -0
- data/fixtures/vcr_cassettes/test_get.yml +104 -146
- data/fixtures/vcr_cassettes/test_get_missing.yml +60 -0
- data/fixtures/vcr_cassettes/test_include.yml +27 -27
- data/fixtures/vcr_cassettes/test_new_model.yml +53 -146
- data/fixtures/vcr_cassettes/test_new_object.yml +53 -74
- data/fixtures/vcr_cassettes/test_nils_delete_keys.yml +155 -216
- data/fixtures/vcr_cassettes/test_parse_delete.yml +204 -284
- data/fixtures/vcr_cassettes/test_pointer.yml +53 -74
- data/fixtures/vcr_cassettes/test_save_with_sub_objects.yml +298 -0
- data/fixtures/vcr_cassettes/test_saving_boolean_values.yml +121 -0
- data/fixtures/vcr_cassettes/test_server_update.yml +257 -358
- data/fixtures/vcr_cassettes/test_simple_save.yml +53 -74
- data/fixtures/vcr_cassettes/test_text_file_save.yml +53 -161
- data/fixtures/vcr_cassettes/test_update.yml +104 -144
- data/fixtures/vcr_cassettes/test_updated_at.yml +104 -144
- data/fixtures/vcr_cassettes/test_user_save.yml +10 -10
- data/lib/parse/client.rb +43 -6
- data/lib/parse/datatypes.rb +14 -35
- data/lib/parse/error.rb +8 -0
- data/lib/parse/object.rb +25 -20
- data/lib/parse/protocol.rb +3 -4
- data/lib/parse/query.rb +10 -9
- data/lib/parse/util.rb +36 -2
- data/parse-ruby-client.gemspec +22 -18
- data/test/helper.rb +33 -5
- data/test/test_batch.rb +1 -4
- data/test/test_client.rb +59 -7
- data/test/test_cloud.rb +3 -7
- data/test/test_datatypes.rb +6 -7
- data/test/test_file.rb +9 -10
- data/test/test_model.rb +1 -4
- data/test/test_object.rb +148 -6
- data/test/test_push.rb +1 -5
- data/test/test_query.rb +13 -3
- data/test/test_throttle.rb +1 -3
- data/test/test_user.rb +1 -5
- metadata +23 -19
- data/fixtures/vcr_cassettes/test_array_add_relation.yml +0 -321
- data/fixtures/vcr_cassettes/test_cloud_function.yml +0 -81
- data/fixtures/vcr_cassettes/test_file_save.yml +0 -87
- data/fixtures/vcr_cassettes/test_image_file_associate_with_object.yml +0 -2034
- data/fixtures/vcr_cassettes/test_image_file_save.yml +0 -1957
- data/fixtures/vcr_cassettes/test_object_id.yml +0 -83
- data/fixtures/vcr_cassettes/test_request_batch.yml +0 -62
data/lib/parse/error.rb
CHANGED
data/lib/parse/object.rb
CHANGED
@@ -20,6 +20,16 @@ module Parse
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
def eql?(other)
|
24
|
+
Parse.object_pointer_equality?(self, other)
|
25
|
+
end
|
26
|
+
|
27
|
+
alias == eql?
|
28
|
+
|
29
|
+
def hash
|
30
|
+
Parse.object_pointer_hash(self)
|
31
|
+
end
|
32
|
+
|
23
33
|
def uri
|
24
34
|
Protocol.class_uri @class_name, @parse_object_id
|
25
35
|
end
|
@@ -56,9 +66,10 @@ module Parse
|
|
56
66
|
if k.is_a? Symbol
|
57
67
|
k = k.to_s
|
58
68
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
69
|
+
|
70
|
+
if k != Parse::Protocol::KEY_TYPE
|
71
|
+
self[k] = v
|
72
|
+
end
|
62
73
|
end
|
63
74
|
|
64
75
|
self
|
@@ -73,13 +84,17 @@ module Parse
|
|
73
84
|
Protocol::RESERVED_KEYS.each { |k| without_reserved.delete(k) }
|
74
85
|
|
75
86
|
without_relations = without_reserved
|
76
|
-
without_relations.each
|
87
|
+
without_relations.each do |k,v|
|
77
88
|
if v.is_a? Hash
|
78
89
|
if v[Protocol::KEY_TYPE] == Protocol::TYPE_RELATION
|
79
90
|
without_relations.delete(k)
|
80
91
|
end
|
81
92
|
end
|
82
|
-
|
93
|
+
end
|
94
|
+
|
95
|
+
without_relations.each do |k, v|
|
96
|
+
without_relations[k] = Parse.pointerize_value(v)
|
97
|
+
end
|
83
98
|
|
84
99
|
without_relations
|
85
100
|
end
|
@@ -105,7 +120,8 @@ module Parse
|
|
105
120
|
data = Parse.client.request(self.uri, method, body)
|
106
121
|
|
107
122
|
if data
|
108
|
-
|
123
|
+
# array operations can return mutated view of array which needs to be parsed
|
124
|
+
parse Parse.parse_json(class_name, data)
|
109
125
|
end
|
110
126
|
|
111
127
|
if @class_name == Parse::Protocol::CLASS_USER
|
@@ -119,7 +135,7 @@ module Parse
|
|
119
135
|
|
120
136
|
def as_json(*a)
|
121
137
|
Hash[self.map do |key, value|
|
122
|
-
value = if value
|
138
|
+
value = if !value.nil?
|
123
139
|
value.respond_to?(:as_json) ? value.as_json : value
|
124
140
|
else
|
125
141
|
Protocol::DELETE_OP
|
@@ -190,13 +206,6 @@ module Parse
|
|
190
206
|
# return nil
|
191
207
|
#end
|
192
208
|
|
193
|
-
#if amount != 0
|
194
|
-
# op = amount > 0 ? Protocol::OP_INCREMENT : Protocol::OP_DECREMENT
|
195
|
-
# body = "{\"#{field}\": {\"#{Protocol::KEY_OP}\": \"#{op}\", \"#{Protocol::KEY_AMOUNT}\" : #{amount.abs}}}"
|
196
|
-
# data = Parse.client.request( self.uri, :put, body)
|
197
|
-
# parse data
|
198
|
-
#end
|
199
|
-
#self
|
200
209
|
body = {field => Parse::Increment.new(amount)}.to_json
|
201
210
|
data = Parse.client.request(self.uri, :put, body)
|
202
211
|
parse data
|
@@ -206,11 +215,7 @@ module Parse
|
|
206
215
|
# Decrement the given field by an amount, which defaults to 1. Saves immediately to reflect decremented
|
207
216
|
# A synonym for increment(field, -amount).
|
208
217
|
def decrement(field, amount = 1)
|
209
|
-
|
210
|
-
body = {field => Parse::Decrement.new(amount)}.to_json
|
211
|
-
data = Parse.client.request(self.uri, :put, body)
|
212
|
-
parse data
|
213
|
-
self
|
218
|
+
increment(field, -amount)
|
214
219
|
end
|
215
220
|
|
216
221
|
private
|
@@ -221,7 +226,7 @@ module Parse
|
|
221
226
|
if @parse_object_id
|
222
227
|
@op_fields[field] ||= ArrayOp.new(operation, [])
|
223
228
|
raise "only one operation type allowed per array #{field}" if @op_fields[field].operation != operation
|
224
|
-
@op_fields[field].objects << value
|
229
|
+
@op_fields[field].objects << Parse.pointerize_value(value)
|
225
230
|
end
|
226
231
|
|
227
232
|
# parse doesn't return column values on initial POST creation so we must maintain them ourselves
|
data/lib/parse/protocol.rb
CHANGED
@@ -59,7 +59,6 @@ module Parse
|
|
59
59
|
KEY_OP = "__op"
|
60
60
|
|
61
61
|
KEY_INCREMENT = "Increment"
|
62
|
-
KEY_DECREMENT = "Decrement"
|
63
62
|
KEY_DELETE = "Delete"
|
64
63
|
|
65
64
|
# array ops
|
@@ -86,9 +85,6 @@ module Parse
|
|
86
85
|
# Operation name for incrementing an objects field value remotely
|
87
86
|
OP_INCREMENT = "Increment"
|
88
87
|
|
89
|
-
# Operation name for decrementing an objects field value remotely
|
90
|
-
OP_DECREMENT = "Decrement"
|
91
|
-
|
92
88
|
# The data type name for special JSON objects representing a full object
|
93
89
|
TYPE_OBJECT = "Object"
|
94
90
|
|
@@ -127,7 +123,10 @@ module Parse
|
|
127
123
|
|
128
124
|
BATCH_REQUEST_URI = "batch"
|
129
125
|
|
126
|
+
ERROR_INTERNAL = 1
|
130
127
|
ERROR_TIMEOUT = 124
|
128
|
+
ERROR_EXCEEDED_BURST_LIMIT = 155
|
129
|
+
ERROR_OBJECT_NOT_FOUND_FOR_GET = 101
|
131
130
|
|
132
131
|
# URI Helpers
|
133
132
|
# ----------------------------------------
|
data/lib/parse/query.rb
CHANGED
@@ -42,12 +42,12 @@ module Parse
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def eq(field, value)
|
45
|
-
add_constraint field, value
|
45
|
+
add_constraint field, Parse.pointerize_value(value)
|
46
46
|
self
|
47
47
|
end
|
48
48
|
|
49
49
|
def not_eq(field, value)
|
50
|
-
add_constraint field, { "$ne" => value }
|
50
|
+
add_constraint field, { "$ne" => Parse.pointerize_value(value) }
|
51
51
|
self
|
52
52
|
end
|
53
53
|
|
@@ -57,37 +57,37 @@ module Parse
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def less_than(field, value)
|
60
|
-
add_constraint field, { "$lt" => value }
|
60
|
+
add_constraint field, { "$lt" => Parse.pointerize_value(value) }
|
61
61
|
self
|
62
62
|
end
|
63
63
|
|
64
64
|
def less_eq(field, value)
|
65
|
-
add_constraint field, { "$lte" => value }
|
65
|
+
add_constraint field, { "$lte" => Parse.pointerize_value(value) }
|
66
66
|
self
|
67
67
|
end
|
68
68
|
|
69
69
|
def greater_than(field, value)
|
70
|
-
add_constraint field, { "$gt" => value }
|
70
|
+
add_constraint field, { "$gt" => Parse.pointerize_value(value) }
|
71
71
|
self
|
72
72
|
end
|
73
73
|
|
74
74
|
def greater_eq(field, value)
|
75
|
-
add_constraint field, { "$gte" => value }
|
75
|
+
add_constraint field, { "$gte" => Parse.pointerize_value(value) }
|
76
76
|
self
|
77
77
|
end
|
78
78
|
|
79
79
|
def value_in(field, values)
|
80
|
-
add_constraint field, { "$in" => values }
|
80
|
+
add_constraint field, { "$in" => values.map { |v| Parse.pointerize_value(v) } }
|
81
81
|
self
|
82
82
|
end
|
83
83
|
|
84
84
|
def value_not_in(field, values)
|
85
|
-
add_constraint field, { "$nin" => values }
|
85
|
+
add_constraint field, { "$nin" => values.map { |v| Parse.pointerize_value(v) } }
|
86
86
|
self
|
87
87
|
end
|
88
88
|
|
89
89
|
def related_to(field,value)
|
90
|
-
h = {"object" => value, "key" => field}
|
90
|
+
h = {"object" => Parse.pointerize_value(value), "key" => field}
|
91
91
|
add_constraint("$relatedTo", h )
|
92
92
|
end
|
93
93
|
|
@@ -123,6 +123,7 @@ module Parse
|
|
123
123
|
query = { "where" => CGI.escape(where_as_json.to_json) }
|
124
124
|
set_order(query)
|
125
125
|
[:count, :limit, :skip, :include].each {|a| merge_attribute(a, query)}
|
126
|
+
Parse.client.logger.info{"Parse query for #{uri} #{CGI.unescape(query.inspect)}"}
|
126
127
|
response = Parse.client.request uri, :get, nil, query
|
127
128
|
Parse.parse_json class_name, response
|
128
129
|
end
|
data/lib/parse/util.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'pp'
|
2
1
|
module Parse
|
3
2
|
|
4
3
|
# Parse a JSON representation into a fully instantiated
|
@@ -22,8 +21,10 @@ module Parse
|
|
22
21
|
parse_datatype obj
|
23
22
|
elsif obj.size == 1 && obj.has_key?(Protocol::KEY_RESULTS) && obj[Protocol::KEY_RESULTS].is_a?(Array)
|
24
23
|
obj[Protocol::KEY_RESULTS].collect { |o| parse_json(class_name, o) }
|
25
|
-
|
24
|
+
elsif class_name # otherwise it must be a regular object, so deep parse it avoiding re-JSON.parsing raw Strings
|
26
25
|
Parse::Object.new class_name, Hash[obj.map{|k,v| [k, parse_json(nil, v)]}]
|
26
|
+
else # plain old hash
|
27
|
+
obj
|
27
28
|
end
|
28
29
|
|
29
30
|
# primitive
|
@@ -50,4 +51,37 @@ module Parse
|
|
50
51
|
Parse::Object.new obj[Protocol::KEY_CLASS_NAME], Hash[obj.map{|k,v| [k, parse_json(nil, v)]}]
|
51
52
|
end
|
52
53
|
end
|
54
|
+
|
55
|
+
def Parse.pointerize_value(obj)
|
56
|
+
if obj.kind_of?(Parse::Object)
|
57
|
+
obj.pointer
|
58
|
+
elsif obj.is_a?(Array)
|
59
|
+
obj.map do |v|
|
60
|
+
Parse.pointerize_value(v)
|
61
|
+
end
|
62
|
+
elsif obj.is_a?(Hash)
|
63
|
+
Hash[obj.map do |k, v|
|
64
|
+
[k, Parse.pointerize_value(v)]
|
65
|
+
end]
|
66
|
+
else
|
67
|
+
obj
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def Parse.object_pointer_equality?(a, b)
|
72
|
+
classes = [Parse::Object, Parse::Pointer]
|
73
|
+
return false unless classes.any? { |c| a.kind_of?(c) } && classes.any? { |c| b.kind_of?(c) }
|
74
|
+
return true if a.equal?(b)
|
75
|
+
return false if a.new? || b.new?
|
76
|
+
|
77
|
+
a.class_name == b.class_name && a.id == b.id
|
78
|
+
end
|
79
|
+
|
80
|
+
def Parse.object_pointer_hash(v)
|
81
|
+
if v.new?
|
82
|
+
v.object_id
|
83
|
+
else
|
84
|
+
v.class_name.hash ^ v.id.hash
|
85
|
+
end
|
86
|
+
end
|
53
87
|
end
|
data/parse-ruby-client.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "parse-ruby-client"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.15"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alan deLevie", "Adam Alpern"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-05-22"
|
13
13
|
s.description = "A simple Ruby client for the parse.com REST API"
|
14
14
|
s.email = "adelevie@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -21,33 +21,37 @@ Gem::Specification.new do |s|
|
|
21
21
|
"Gemfile",
|
22
22
|
"Gemfile.lock",
|
23
23
|
"LICENSE.txt",
|
24
|
+
"OLD_README.md",
|
24
25
|
"README.md",
|
25
26
|
"Rakefile",
|
26
27
|
"VERSION",
|
27
28
|
"example.rb",
|
28
29
|
"features.md",
|
30
|
+
"fixtures/vcr_cassettes/test_acls_arent_objects.yml",
|
29
31
|
"fixtures/vcr_cassettes/test_array_add.yml",
|
30
|
-
"fixtures/vcr_cassettes/
|
32
|
+
"fixtures/vcr_cassettes/test_array_add_pointerizing.yml",
|
33
|
+
"fixtures/vcr_cassettes/test_array_add_unique.yml",
|
31
34
|
"fixtures/vcr_cassettes/test_batch_create_object.yml",
|
32
35
|
"fixtures/vcr_cassettes/test_batch_delete_object.yml",
|
33
36
|
"fixtures/vcr_cassettes/test_batch_run.yml",
|
34
37
|
"fixtures/vcr_cassettes/test_batch_update_object.yml",
|
35
|
-
"fixtures/vcr_cassettes/
|
38
|
+
"fixtures/vcr_cassettes/test_circular_save.yml",
|
36
39
|
"fixtures/vcr_cassettes/test_created_at.yml",
|
40
|
+
"fixtures/vcr_cassettes/test_decrement.yml",
|
37
41
|
"fixtures/vcr_cassettes/test_deep_parse.yml",
|
38
42
|
"fixtures/vcr_cassettes/test_destroy.yml",
|
39
|
-
"fixtures/vcr_cassettes/
|
43
|
+
"fixtures/vcr_cassettes/test_eq_pointerize.yml",
|
44
|
+
"fixtures/vcr_cassettes/test_equality.yml",
|
40
45
|
"fixtures/vcr_cassettes/test_get.yml",
|
41
|
-
"fixtures/vcr_cassettes/
|
42
|
-
"fixtures/vcr_cassettes/test_image_file_save.yml",
|
46
|
+
"fixtures/vcr_cassettes/test_get_missing.yml",
|
43
47
|
"fixtures/vcr_cassettes/test_include.yml",
|
44
48
|
"fixtures/vcr_cassettes/test_new_model.yml",
|
45
49
|
"fixtures/vcr_cassettes/test_new_object.yml",
|
46
50
|
"fixtures/vcr_cassettes/test_nils_delete_keys.yml",
|
47
|
-
"fixtures/vcr_cassettes/test_object_id.yml",
|
48
51
|
"fixtures/vcr_cassettes/test_parse_delete.yml",
|
49
52
|
"fixtures/vcr_cassettes/test_pointer.yml",
|
50
|
-
"fixtures/vcr_cassettes/
|
53
|
+
"fixtures/vcr_cassettes/test_save_with_sub_objects.yml",
|
54
|
+
"fixtures/vcr_cassettes/test_saving_boolean_values.yml",
|
51
55
|
"fixtures/vcr_cassettes/test_server_update.yml",
|
52
56
|
"fixtures/vcr_cassettes/test_simple_save.yml",
|
53
57
|
"fixtures/vcr_cassettes/test_text_file_save.yml",
|
@@ -98,35 +102,35 @@ Gem::Specification.new do |s|
|
|
98
102
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
99
103
|
s.add_runtime_dependency(%q<patron>, [">= 0"])
|
100
104
|
s.add_runtime_dependency(%q<iron_mq>, [">= 0"])
|
101
|
-
s.add_development_dependency(%q<bundler>, ["
|
105
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
102
106
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
103
107
|
s.add_development_dependency(%q<test-unit>, ["= 2.5.0"])
|
104
108
|
s.add_development_dependency(%q<mocha>, ["= 0.12.0"])
|
105
|
-
s.add_development_dependency(%q<jeweler>, ["
|
106
|
-
s.add_development_dependency(%q<
|
109
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
110
|
+
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
107
111
|
s.add_development_dependency(%q<webmock>, [">= 0"])
|
108
112
|
s.add_development_dependency(%q<vcr>, [">= 0"])
|
109
113
|
else
|
110
114
|
s.add_dependency(%q<patron>, [">= 0"])
|
111
115
|
s.add_dependency(%q<iron_mq>, [">= 0"])
|
112
|
-
s.add_dependency(%q<bundler>, ["
|
116
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
113
117
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
114
118
|
s.add_dependency(%q<test-unit>, ["= 2.5.0"])
|
115
119
|
s.add_dependency(%q<mocha>, ["= 0.12.0"])
|
116
|
-
s.add_dependency(%q<jeweler>, ["
|
117
|
-
s.add_dependency(%q<
|
120
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
121
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
118
122
|
s.add_dependency(%q<webmock>, [">= 0"])
|
119
123
|
s.add_dependency(%q<vcr>, [">= 0"])
|
120
124
|
end
|
121
125
|
else
|
122
126
|
s.add_dependency(%q<patron>, [">= 0"])
|
123
127
|
s.add_dependency(%q<iron_mq>, [">= 0"])
|
124
|
-
s.add_dependency(%q<bundler>, ["
|
128
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
125
129
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
126
130
|
s.add_dependency(%q<test-unit>, ["= 2.5.0"])
|
127
131
|
s.add_dependency(%q<mocha>, ["= 0.12.0"])
|
128
|
-
s.add_dependency(%q<jeweler>, ["
|
129
|
-
s.add_dependency(%q<
|
132
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
133
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
130
134
|
s.add_dependency(%q<webmock>, [">= 0"])
|
131
135
|
s.add_dependency(%q<vcr>, [">= 0"])
|
132
136
|
end
|
data/test/helper.rb
CHANGED
@@ -7,21 +7,49 @@ rescue Bundler::BundlerError => e
|
|
7
7
|
$stderr.puts "Run `bundle install` to install missing gems"
|
8
8
|
exit e.status_code
|
9
9
|
end
|
10
|
+
|
11
|
+
require 'simplecov'
|
12
|
+
SimpleCov.start do
|
13
|
+
add_filter "/test/"
|
14
|
+
end if ENV["COVERAGE"]
|
15
|
+
|
10
16
|
require 'test/unit'
|
11
17
|
require 'shoulda'
|
12
18
|
require 'mocha'
|
13
19
|
require 'vcr'
|
14
20
|
require 'webmock/test_unit'
|
15
21
|
|
22
|
+
require 'simplecov'
|
23
|
+
SimpleCov.start if ENV['COVERAGE']
|
24
|
+
|
25
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
26
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
27
|
+
require 'parse-ruby-client'
|
28
|
+
|
29
|
+
YAML::ENGINE.yamler='syck' # get ascii strings as strings in fixtures
|
30
|
+
|
16
31
|
VCR.configure do |c|
|
17
32
|
c.cassette_library_dir = 'fixtures/vcr_cassettes'
|
18
33
|
c.hook_into :webmock # or :fakeweb
|
19
34
|
c.allow_http_connections_when_no_cassette = true
|
20
|
-
|
35
|
+
c.filter_sensitive_data("<COOKIE-KEY>") { |i| [i.response.headers['Set-Cookie']].flatten.compact.first }
|
21
36
|
|
22
|
-
|
23
|
-
|
24
|
-
|
37
|
+
def filter_sensitive_header(c, header)
|
38
|
+
c.filter_sensitive_data("<#{header}>") do |interaction|
|
39
|
+
if v = interaction.request.headers.detect{|k,_| k.casecmp(header) == 0}
|
40
|
+
v.last.first
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
filter_sensitive_header(c, Parse::Protocol::HEADER_APP_ID)
|
46
|
+
filter_sensitive_header(c, Parse::Protocol::HEADER_API_KEY)
|
47
|
+
filter_sensitive_header(c, Parse::Protocol::HEADER_MASTER_KEY)
|
48
|
+
filter_sensitive_header(c, Parse::Protocol::HEADER_SESSION_TOKEN)
|
49
|
+
end
|
25
50
|
|
26
|
-
class Test::Unit::TestCase
|
51
|
+
class ParseTestCase < Test::Unit::TestCase
|
52
|
+
def setup
|
53
|
+
@client = Parse.init(:logger => Logger.new(STDERR).tap{|l| l.level = Logger::ERROR})
|
54
|
+
end
|
27
55
|
end
|
data/test/test_batch.rb
CHANGED
data/test/test_client.rb
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
class TestClient <
|
4
|
-
def setup
|
5
|
-
@client = Parse.init
|
6
|
-
end
|
3
|
+
class TestClient < ParseTestCase
|
7
4
|
|
8
|
-
def
|
9
|
-
VCR.use_cassette('
|
5
|
+
def test_retries
|
6
|
+
VCR.use_cassette('test_retries', :record => :new_episodes) do
|
10
7
|
response = mock()
|
11
8
|
response.stubs(:body).returns({'code' => Parse::Protocol::ERROR_TIMEOUT}.to_json)
|
12
|
-
response.stubs(:status).returns(
|
9
|
+
response.stubs(:status).returns(500)
|
13
10
|
@client.session.expects(:request).times(@client.max_retries + 1).returns(response)
|
14
11
|
assert_raise do
|
15
12
|
@client.request(nil)
|
@@ -17,6 +14,54 @@ class TestClient < Test::Unit::TestCase
|
|
17
14
|
end
|
18
15
|
end
|
19
16
|
|
17
|
+
def test_retries_json_error
|
18
|
+
VCR.use_cassette('test_retries_json_error', :record => :new_episodes) do
|
19
|
+
bad_response = mock()
|
20
|
+
bad_response.stubs(:body).returns("<HTML>this is not json</HTML>")
|
21
|
+
bad_response.stubs(:status).returns(500)
|
22
|
+
|
23
|
+
good_response = mock()
|
24
|
+
good_response.stubs(:body).returns('{"foo":100}')
|
25
|
+
good_response.stubs(:status).returns(200)
|
26
|
+
@client.session.expects(:request).twice.returns(bad_response, good_response)
|
27
|
+
|
28
|
+
assert_equal({ "foo" => 100 }, @client.request(nil))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_retries_server_error
|
33
|
+
VCR.use_cassette('test_retries_server_error', :record => :new_episodes) do
|
34
|
+
bad_response = mock()
|
35
|
+
bad_response.stubs(:body).returns("{}")
|
36
|
+
bad_response.stubs(:status).returns(500)
|
37
|
+
|
38
|
+
good_response = mock()
|
39
|
+
good_response.stubs(:body).returns('{"foo":100}')
|
40
|
+
good_response.stubs(:status).returns(200)
|
41
|
+
@client.session.expects(:request).twice.returns(bad_response, good_response)
|
42
|
+
|
43
|
+
assert_equal({ "foo" => 100 }, @client.request(nil))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_empty_response
|
48
|
+
VCR.use_cassette('test_empty_response', :record => :new_episodes) do
|
49
|
+
bad_response = mock()
|
50
|
+
bad_response.stubs(:body).returns('')
|
51
|
+
JSON.stubs(:parse).returns(nil) # some json parsers return nil instead of raising
|
52
|
+
bad_response.stubs(:status).returns(403)
|
53
|
+
|
54
|
+
@client.session.stubs(:request).returns(bad_response)
|
55
|
+
|
56
|
+
begin
|
57
|
+
@client.request(nil)
|
58
|
+
raise "client error response should have raised"
|
59
|
+
rescue Parse::ParseProtocolError => e
|
60
|
+
assert_equal "HTTP Status 403 Body ", e.error
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
20
65
|
def test_simple_save
|
21
66
|
VCR.use_cassette('test_simple_save', :record => :new_episodes) do
|
22
67
|
test_save = Parse::Object.new "TestSave"
|
@@ -78,4 +123,11 @@ class TestClient < Test::Unit::TestCase
|
|
78
123
|
assert_equal d.keys.length, 0
|
79
124
|
end
|
80
125
|
end
|
126
|
+
|
127
|
+
def test_get_missing
|
128
|
+
VCR.use_cassette('test_get_missing', :record => :new_episodes) do
|
129
|
+
e = assert_raise(Parse::ParseProtocolError) { Parse.get("SomeClass", "someIdThatDoesNotExist") }
|
130
|
+
assert_equal "101: object not found for get: SomeClass:someIdThatDoesNotExist", e.message
|
131
|
+
end
|
132
|
+
end
|
81
133
|
end
|