parse-ruby-client 0.1.5 → 0.1.6

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/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