parse-ruby-client 0.1.14 → 0.1.15
Sign up to get free protection for your applications and to get access to all the features.
- 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
|