parse-ruby-client 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -19,7 +19,7 @@ This currently depends on the gems 'json' and 'patron' for JSON support and HTTP
19
19
 
20
20
  ## Installation
21
21
 
22
- `gem "parse-ruby-client", "~> 0.1.4"`
22
+ `gem "parse-ruby-client", "~> 0.1.5"`
23
23
 
24
24
  ---
25
25
 
@@ -56,6 +56,8 @@ Parse.init_from_cloud_code("path/to/global.json")
56
56
 
57
57
  The path defaults to `"../config/global.json"`. So if you create a folder inside the root of a Cloud Code directory, and in that folder is a `.rb` file, just call `Parse.init_from_cloud_code` with no arguments and you're set.
58
58
 
59
+ With `Parse::init_from_cloud_code`, you can easily write Ruby [tests for Cloud Code functions](https://github.com/adelevie/ParseCloudTest).
60
+
59
61
  ## Creating and Saving Objects
60
62
 
61
63
  Create an instance of ```Parse::Object``` with your class name supplied as a string, set some keys, and call ```save()```.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.1.6
@@ -0,0 +1,121 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.parse.com/1/classes/Post
6
+ body:
7
+ encoding: UTF-8
8
+ string: "{\"chapters\":{\"__op\":\"Add\",\"objects\":[\"hello\"]}}"
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ User-Agent:
15
+ - Parse for Ruby, 0.0
16
+ X-Parse-Master-Key:
17
+ - ""
18
+ X-Parse-Rest-Api-Key:
19
+ - jYdptjS76YHikuIFfJEgHD8UMIjH6cp2rWz4fo2C
20
+ X-Parse-Application-Id:
21
+ - hnJRtntbYPvWfjqcqLZsdFaOKT0F3SfNU7Kc7woN
22
+ X-Parse-Session-Token:
23
+ - ""
24
+ Expect:
25
+ - ""
26
+ response:
27
+ status:
28
+ code: 201
29
+ message: Created
30
+ headers:
31
+ Access-Control-Allow-Origin:
32
+ - "*"
33
+ Access-Control-Request-Method:
34
+ - "*"
35
+ Cache-Control:
36
+ - no-cache
37
+ Content-Type:
38
+ - application/json; charset=utf-8
39
+ Date:
40
+ - Mon, 15 Oct 2012 12:59:15 GMT
41
+ Location:
42
+ - https://api.parse.com/1/classes/Post/ug80aldIcg
43
+ Server:
44
+ - nginx/1.2.2
45
+ Set-Cookie:
46
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMWQwOTljYjU4YzdhNzU3ODc1MzI1MGI1MzQ0YjMwMTE%3D--999bcf56a783c9a250636b41fc4b09c5b3aecce2; domain=.parse.com; path=/; expires=Sat, 15-Oct-2022 12:59:15 GMT; secure; HttpOnly
47
+ Status:
48
+ - 201 Created
49
+ X-Runtime:
50
+ - "0.018886"
51
+ X-Ua-Compatible:
52
+ - IE=Edge,chrome=1
53
+ Content-Length:
54
+ - "64"
55
+ Connection:
56
+ - keep-alive
57
+ body:
58
+ encoding: UTF-8
59
+ string: "{\"createdAt\":\"2012-10-15T12:59:15.263Z\",\"objectId\":\"ug80aldIcg\"}"
60
+ http_version:
61
+ recorded_at: Mon, 15 Oct 2012 12:59:16 GMT
62
+ - request:
63
+ method: put
64
+ uri: https://api.parse.com/1/classes/Post/ug80aldIcg
65
+ body:
66
+ encoding: UTF-8
67
+ string: "{\"chapters\":{\"__op\":\"Add\",\"objects\":[\"goodbye\"]}}"
68
+ headers:
69
+ Content-Type:
70
+ - application/json
71
+ Accept:
72
+ - application/json
73
+ User-Agent:
74
+ - Parse for Ruby, 0.0
75
+ X-Parse-Master-Key:
76
+ - ""
77
+ X-Parse-Rest-Api-Key:
78
+ - jYdptjS76YHikuIFfJEgHD8UMIjH6cp2rWz4fo2C
79
+ X-Parse-Application-Id:
80
+ - hnJRtntbYPvWfjqcqLZsdFaOKT0F3SfNU7Kc7woN
81
+ X-Parse-Session-Token:
82
+ - ""
83
+ Expect:
84
+ - ""
85
+ response:
86
+ status:
87
+ code: 200
88
+ message: OK
89
+ headers:
90
+ Access-Control-Allow-Origin:
91
+ - "*"
92
+ Access-Control-Request-Method:
93
+ - "*"
94
+ Cache-Control:
95
+ - max-age=0, private, must-revalidate
96
+ Content-Type:
97
+ - application/json; charset=utf-8
98
+ Date:
99
+ - Mon, 15 Oct 2012 17:47:28 GMT
100
+ Etag:
101
+ - "\"f99c943f91a9d6fc5e32e11d86b40755\""
102
+ Server:
103
+ - nginx/1.2.2
104
+ Set-Cookie:
105
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMjlkOGYxMGU3YjE4YzgxM2U1NzZjNGNkNmI2MDljZDY%3D--b4c3fa092802887988fae07911e78dce8d1fd453; domain=.parse.com; path=/; expires=Sat, 15-Oct-2022 17:47:28 GMT; secure; HttpOnly
106
+ Status:
107
+ - 200 OK
108
+ X-Runtime:
109
+ - "0.016753"
110
+ X-Ua-Compatible:
111
+ - IE=Edge,chrome=1
112
+ Content-Length:
113
+ - "71"
114
+ Connection:
115
+ - keep-alive
116
+ body:
117
+ encoding: ASCII-8BIT
118
+ string: "{\"chapters\":[\"hello\",\"goodbye\"],\"updatedAt\":\"2012-10-15T17:47:28.940Z\"}"
119
+ http_version:
120
+ recorded_at: Mon, 15 Oct 2012 17:47:30 GMT
121
+ recorded_with: VCR 2.0.1
@@ -214,6 +214,40 @@ module Parse
214
214
  end
215
215
  end
216
216
 
217
+ class ArrayOp
218
+ # '{"myArray": {"__op": "Add", "objects": ["something", "something else"] } }'
219
+ attr_accessor :operation
220
+ attr_accessor :objects
221
+
222
+ def initialize(operation, objects)
223
+ @operation = operation
224
+ @objects = objects
225
+ end
226
+
227
+ def eql?(other)
228
+ self.class.equal?(other.class) &&
229
+ operation == other.operation &&
230
+ objects == other.objects
231
+ end
232
+
233
+ alias == eql?
234
+
235
+ def hash
236
+ operation.hash ^ objects.hash
237
+ end
238
+
239
+ def as_json(*a)
240
+ {
241
+ Protocol::KEY_OP => operation,
242
+ Protocol::KEY_OBJECTS => @objects
243
+ }
244
+ end
245
+
246
+ def to_json(*a)
247
+ as_json.to_json(*a)
248
+ end
249
+ end
250
+
217
251
  # GeoPoint
218
252
  # ------------------------------------------------------------
219
253
 
data/lib/parse/object.rb CHANGED
@@ -14,6 +14,7 @@ module Parse
14
14
 
15
15
  def initialize(class_name, data = nil)
16
16
  @class_name = class_name
17
+ @op_fields = {}
17
18
  if data
18
19
  parse data
19
20
  end
@@ -84,7 +85,13 @@ module Parse
84
85
  # If the object has never been saved before, this will create
85
86
  # a new object, otherwise it will update the existing stored object.
86
87
  def save
87
- method = @parse_object_id ? :put : :post
88
+ if @parse_object_id
89
+ method = :put
90
+ self.merge!(@op_fields) # use operations instead of our own view of the columns
91
+ else
92
+ method = :post
93
+ end
94
+
88
95
  body = safe_json
89
96
  data = Parse.client.request(self.uri, method, body)
90
97
 
@@ -141,7 +148,19 @@ module Parse
141
148
  self
142
149
  end
143
150
 
144
- # Increment the given field by an amount, which defaults to 1.
151
+ def array_add(field, value)
152
+ array_op(field, Protocol::KEY_ADD, value)
153
+ end
154
+
155
+ def array_add_unique(field, value)
156
+ array_op(field, Protocol::KEY_ADD_UNIQUE, value)
157
+ end
158
+
159
+ def array_remove(field, value)
160
+ array_op(field, Protocol::KEY_REMOVE, value)
161
+ end
162
+
163
+ # Increment the given field by an amount, which defaults to 1. Saves immediately to reflect incremented
145
164
  def increment(field, amount = 1)
146
165
  #value = (self[field] || 0) + amount
147
166
  #self[field] = value
@@ -163,7 +182,7 @@ module Parse
163
182
  self
164
183
  end
165
184
 
166
- # Decrement the given field by an amount, which defaults to 1.
185
+ # Decrement the given field by an amount, which defaults to 1. Saves immediately to reflect decremented
167
186
  # A synonym for increment(field, -amount).
168
187
  def decrement(field, amount = 1)
169
188
  #increment field, -amount
@@ -173,6 +192,28 @@ module Parse
173
192
  self
174
193
  end
175
194
 
176
- end
195
+ private
196
+
197
+ def array_op(field, operation, value)
198
+ raise "field #{field} not an array" if self[field] && !self[field].is_a?(Array)
199
+
200
+ if @parse_object_id
201
+ @op_fields[field] ||= ArrayOp.new(operation, [])
202
+ raise "only one operation type allowed per array #{field}" if @op_fields[field].operation != operation
203
+ @op_fields[field].objects << value
204
+ end
177
205
 
206
+ # parse doesn't return column values on initial POST creation so we must maintain them ourselves
207
+ case operation
208
+ when Protocol::KEY_ADD
209
+ self[field] ||= []
210
+ self[field] << value
211
+ when Protocol::KEY_ADD_UNIQUE
212
+ self[field] ||= []
213
+ self[field] << value unless self[field].include?(value)
214
+ when Protocol::KEY_REMOVE
215
+ self[field].delete(value) if self[field]
216
+ end
217
+ end
218
+ end
178
219
  end
@@ -53,13 +53,19 @@ module Parse
53
53
  RESPONSE_KEY_RESULTS = "results"
54
54
  KEY_RESULTS = RESPONSE_KEY_RESULTS
55
55
 
56
- # The JSON key used to identify an operator in the increment/decrement
57
- # API call.
56
+ # The JSON key used to identify an operator
58
57
  KEY_OP = "__op"
58
+
59
59
  KEY_INCREMENT = "Increment"
60
60
  KEY_DECREMENT = "Decrement"
61
61
  KEY_DELETE = "Delete"
62
62
 
63
+ # array ops
64
+ KEY_OBJECTS = "objects"
65
+ KEY_ADD = "Add"
66
+ KEY_ADD_UNIQUE = "AddUnique"
67
+ KEY_REMOVE = "Remove"
68
+
63
69
  DELETE_OP = { KEY_OP => KEY_DELETE }
64
70
 
65
71
  # The JSON key used to identify the datatype of a special value.
data/lib/parse/query.rb CHANGED
@@ -85,6 +85,17 @@ module Parse
85
85
  add_constraint(field, "$inQuery" => query_hash)
86
86
  self
87
87
  end
88
+
89
+ def limit(num)
90
+ @limit = num
91
+ self
92
+ end
93
+
94
+ def order(field, order = :ascending)
95
+ @order_by = field
96
+ @order = order
97
+ self
98
+ end
88
99
 
89
100
  def count
90
101
  @count = true
data/lib/parse/user.rb CHANGED
@@ -19,21 +19,13 @@ module Parse
19
19
 
20
20
  def self.reset_password(email)
21
21
  body = {"email" => email}
22
- Parse.client.post(Parse::Protocol::PASSWORD_RESET_URI, body)
22
+ Parse.client.post(Parse::Protocol::PASSWORD_RESET_URI, body.to_json)
23
23
  end
24
24
 
25
25
  def initialize(data = nil)
26
- @class_name = Parse::Protocol::CLASS_USER
27
-
28
- #stringify symbol keys
29
26
  data["username"] = data[:username] if data[:username]
30
27
  data["password"] = data[:password] if data[:password]
31
-
32
- if data
33
- parse data
34
- end
35
-
36
- self
28
+ super(Parse::Protocol::CLASS_USER, data)
37
29
  end
38
30
 
39
31
  def uri
@@ -41,4 +33,4 @@ module Parse
41
33
  end
42
34
 
43
35
  end
44
- end
36
+ end
@@ -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.5"
8
+ s.version = "0.1.6"
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 = "2012-10-14"
12
+ s.date = "2013-01-05"
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 = [
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  "Rakefile",
26
26
  "VERSION",
27
27
  "example.rb",
28
+ "fixtures/vcr_cassettes/test_array_add.yml",
28
29
  "fixtures/vcr_cassettes/test_cloud_function.yml",
29
30
  "fixtures/vcr_cassettes/test_created_at.yml",
30
31
  "fixtures/vcr_cassettes/test_deep_parse.yml",
@@ -52,10 +53,6 @@ Gem::Specification.new do |s|
52
53
  "lib/parse/user.rb",
53
54
  "lib/parse/util.rb",
54
55
  "parse-ruby-client.gemspec",
55
- "pkg/parse-ruby-client-0.0.1.gem",
56
- "pkg/parse-ruby-client-0.0.2.gem",
57
- "pkg/parse-ruby-client-1-0.0.1.gem",
58
- "pkg/parse-ruby-client.gem",
59
56
  "test/cloud_functions/MyCloudCode/cloud/main.js",
60
57
  "test/config/global.json",
61
58
  "test/helper.rb",
data/test/test_object.rb CHANGED
@@ -107,4 +107,19 @@ class TestObject < Test::Unit::TestCase
107
107
  assert_false post.refresh.keys.include?("title")
108
108
  end
109
109
  end
110
+
111
+ def test_array_add
112
+ VCR.use_cassette('test_array_add', :record => :new_episodes) do
113
+ post = Parse::Object.new "Post"
114
+ post.array_add("chapters", "hello")
115
+ assert_equal ["hello"], post["chapters"]
116
+ post.save
117
+ assert_equal ["hello"], post["chapters"]
118
+
119
+ post.array_add("chapters", "goodbye")
120
+ assert_equal ["hello", "goodbye"], post["chapters"]
121
+ post.save
122
+ assert_equal ["hello", "goodbye"], post["chapters"]
123
+ end
124
+ end
110
125
  end
data/test/test_user.rb CHANGED
@@ -42,4 +42,20 @@ class TestUser < Test::Unit::TestCase
42
42
  #end
43
43
  end
44
44
 
45
+ def test_reset_password
46
+ u = "alan" + rand(10000000000000).to_s + "@gmail.com"
47
+ data = {
48
+ :username => u,
49
+ :password => "secret"
50
+ }
51
+
52
+ user = Parse::User.new(data)
53
+
54
+ user.save
55
+
56
+ reset_password = Parse::User.reset_password(u)
57
+
58
+ assert true
59
+ end
60
+
45
61
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parse-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-10-14 00:00:00.000000000 Z
13
+ date: 2013-01-05 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: patron
@@ -172,6 +172,7 @@ files:
172
172
  - Rakefile
173
173
  - VERSION
174
174
  - example.rb
175
+ - fixtures/vcr_cassettes/test_array_add.yml
175
176
  - fixtures/vcr_cassettes/test_cloud_function.yml
176
177
  - fixtures/vcr_cassettes/test_created_at.yml
177
178
  - fixtures/vcr_cassettes/test_deep_parse.yml
@@ -199,10 +200,6 @@ files:
199
200
  - lib/parse/user.rb
200
201
  - lib/parse/util.rb
201
202
  - parse-ruby-client.gemspec
202
- - pkg/parse-ruby-client-0.0.1.gem
203
- - pkg/parse-ruby-client-0.0.2.gem
204
- - pkg/parse-ruby-client-1-0.0.1.gem
205
- - pkg/parse-ruby-client.gem
206
203
  - test/cloud_functions/MyCloudCode/cloud/main.js
207
204
  - test/config/global.json
208
205
  - test/helper.rb
@@ -230,7 +227,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
230
227
  version: '0'
231
228
  segments:
232
229
  - 0
233
- hash: 2994353426493104333
230
+ hash: 456778675129303408
234
231
  required_rubygems_version: !ruby/object:Gem::Requirement
235
232
  none: false
236
233
  requirements:
Binary file
Binary file
Binary file
Binary file