parse-ruby-client 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -58,6 +58,9 @@ module Parse
58
58
  KEY_OP = "__op"
59
59
  KEY_INCREMENT = "Increment"
60
60
  KEY_DECREMENT = "Decrement"
61
+ KEY_DELETE = "Delete"
62
+
63
+ DELETE_OP = { KEY_OP => KEY_DELETE }
61
64
 
62
65
  # The JSON key used to identify the datatype of a special value.
63
66
  KEY_TYPE = "__type"
@@ -66,7 +69,7 @@ module Parse
66
69
  # increment/decrement API call.
67
70
  KEY_AMOUNT = "amount"
68
71
 
69
- RESERVED_KEYS = [ KEY_CLASS_NAME, KEY_CREATED_AT, KEY_OBJECT_ID, KEY_UPDATED_AT]
72
+ RESERVED_KEYS = [ KEY_CLASS_NAME, KEY_CREATED_AT, KEY_OBJECT_ID, KEY_UPDATED_AT]
70
73
 
71
74
  # Other Constants
72
75
  # ----------------------------------------
@@ -111,6 +114,8 @@ module Parse
111
114
 
112
115
  KEY_USER_SESSION_TOKEN = "sessionToken"
113
116
 
117
+ CLOUD_FUNCTIONS_PATH = "functions"
118
+
114
119
  # URI Helpers
115
120
  # ----------------------------------------
116
121
 
@@ -144,5 +149,9 @@ module Parse
144
149
  def Protocol.push_uri
145
150
  "/#{VERSION}/push"
146
151
  end
152
+
153
+ def Protocol.cloud_function_uri(function_name)
154
+ "/#{VERSION}/#{CLOUD_FUNCTIONS_PATH}/#{function_name}"
155
+ end
147
156
  end
148
157
  end
data/lib/parse/push.rb CHANGED
@@ -28,6 +28,7 @@ module Parse
28
28
 
29
29
  if @where
30
30
  body.merge!({ :where => @where })
31
+ body.delete :channel
31
32
  end
32
33
 
33
34
  body.merge!({ :expiration_time_interval => @expiration_time_interval }) if @expiration_time_interval
data/lib/parse/query.rb CHANGED
@@ -83,6 +83,7 @@ module Parse
83
83
  def in_query(field, query)
84
84
  query_hash = {Parse::Protocol::KEY_CLASS_NAME => query.class_name, "where" => query.where}
85
85
  add_constraint(field, "$inQuery" => query_hash)
86
+ self
86
87
  end
87
88
 
88
89
  def count
@@ -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.3"
8
+ s.version = "0.1.4"
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-09-20"
12
+ s.date = "2012-10-09"
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,8 +25,24 @@ Gem::Specification.new do |s|
25
25
  "Rakefile",
26
26
  "VERSION",
27
27
  "example.rb",
28
+ "fixtures/vcr_cassettes/test_cloud_function.yml",
29
+ "fixtures/vcr_cassettes/test_created_at.yml",
30
+ "fixtures/vcr_cassettes/test_deep_parse.yml",
31
+ "fixtures/vcr_cassettes/test_destroy.yml",
32
+ "fixtures/vcr_cassettes/test_get.yml",
33
+ "fixtures/vcr_cassettes/test_new_object.yml",
34
+ "fixtures/vcr_cassettes/test_nils_delete_keys.yml",
35
+ "fixtures/vcr_cassettes/test_object_id.yml",
36
+ "fixtures/vcr_cassettes/test_parse_delete.yml",
37
+ "fixtures/vcr_cassettes/test_pointer.yml",
38
+ "fixtures/vcr_cassettes/test_server_update.yml",
39
+ "fixtures/vcr_cassettes/test_simple_save.yml",
40
+ "fixtures/vcr_cassettes/test_update.yml",
41
+ "fixtures/vcr_cassettes/test_updated_at.yml",
42
+ "fixtures/vcr_cassettes/test_user_save.yml",
28
43
  "lib/parse-ruby-client.rb",
29
44
  "lib/parse/client.rb",
45
+ "lib/parse/cloud.rb",
30
46
  "lib/parse/datatypes.rb",
31
47
  "lib/parse/error.rb",
32
48
  "lib/parse/object.rb",
@@ -40,8 +56,10 @@ Gem::Specification.new do |s|
40
56
  "pkg/parse-ruby-client-0.0.2.gem",
41
57
  "pkg/parse-ruby-client-1-0.0.1.gem",
42
58
  "pkg/parse-ruby-client.gem",
59
+ "test/cloud_functions/MyCloudCode/cloud/main.js",
43
60
  "test/helper.rb",
44
61
  "test/test_client.rb",
62
+ "test/test_cloud.rb",
45
63
  "test/test_datatypes.rb",
46
64
  "test/test_init.rb",
47
65
  "test/test_object.rb",
@@ -60,32 +78,35 @@ Gem::Specification.new do |s|
60
78
 
61
79
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
62
80
  s.add_runtime_dependency(%q<patron>, [">= 0"])
63
- s.add_runtime_dependency(%q<vcr>, [">= 0"])
81
+ s.add_development_dependency(%q<bundler>, ["~> 1.1.5"])
64
82
  s.add_development_dependency(%q<shoulda>, [">= 0"])
65
83
  s.add_development_dependency(%q<test-unit>, ["= 2.5.0"])
66
84
  s.add_development_dependency(%q<mocha>, ["= 0.12.0"])
67
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
68
85
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
69
86
  s.add_development_dependency(%q<rcov>, [">= 0"])
87
+ s.add_development_dependency(%q<webmock>, [">= 0"])
88
+ s.add_development_dependency(%q<vcr>, [">= 0"])
70
89
  else
71
90
  s.add_dependency(%q<patron>, [">= 0"])
72
- s.add_dependency(%q<vcr>, [">= 0"])
91
+ s.add_dependency(%q<bundler>, ["~> 1.1.5"])
73
92
  s.add_dependency(%q<shoulda>, [">= 0"])
74
93
  s.add_dependency(%q<test-unit>, ["= 2.5.0"])
75
94
  s.add_dependency(%q<mocha>, ["= 0.12.0"])
76
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
77
95
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
78
96
  s.add_dependency(%q<rcov>, [">= 0"])
97
+ s.add_dependency(%q<webmock>, [">= 0"])
98
+ s.add_dependency(%q<vcr>, [">= 0"])
79
99
  end
80
100
  else
81
101
  s.add_dependency(%q<patron>, [">= 0"])
82
- s.add_dependency(%q<vcr>, [">= 0"])
102
+ s.add_dependency(%q<bundler>, ["~> 1.1.5"])
83
103
  s.add_dependency(%q<shoulda>, [">= 0"])
84
104
  s.add_dependency(%q<test-unit>, ["= 2.5.0"])
85
105
  s.add_dependency(%q<mocha>, ["= 0.12.0"])
86
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
87
106
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
88
107
  s.add_dependency(%q<rcov>, [">= 0"])
108
+ s.add_dependency(%q<webmock>, [">= 0"])
109
+ s.add_dependency(%q<vcr>, [">= 0"])
89
110
  end
90
111
  end
91
112
 
@@ -0,0 +1,4 @@
1
+ Parse.Cloud.define('trivial', function(request, response) {
2
+ console.log(request);
3
+ response.success(request.params);
4
+ });
data/test/helper.rb CHANGED
@@ -10,6 +10,14 @@ end
10
10
  require 'test/unit'
11
11
  require 'shoulda'
12
12
  require 'mocha'
13
+ require 'vcr'
14
+ require 'webmock/test_unit'
15
+
16
+ VCR.configure do |c|
17
+ c.cassette_library_dir = 'fixtures/vcr_cassettes'
18
+ c.hook_into :webmock # or :fakeweb
19
+ c.allow_http_connections_when_no_cassette = true
20
+ end
13
21
 
14
22
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
23
  $LOAD_PATH.unshift(File.dirname(__FILE__))
data/test/test_client.rb CHANGED
@@ -6,56 +6,64 @@ class TestClient < Test::Unit::TestCase
6
6
  end
7
7
 
8
8
  def test_simple_save
9
- test_save = Parse::Object.new "TestSave"
10
- test_save["foo"] = "bar"
11
- test_save.save
9
+ VCR.use_cassette('test_simple_save', :record => :new_episodes) do
10
+ test_save = Parse::Object.new "TestSave"
11
+ test_save["foo"] = "bar"
12
+ test_save.save
12
13
 
13
- assert_equal test_save["foo"], "bar"
14
- assert_equal test_save[Parse::Protocol::KEY_CREATED_AT].class, String
15
- assert_equal test_save[Parse::Protocol::KEY_OBJECT_ID].class, String
14
+ assert_equal test_save["foo"], "bar"
15
+ assert_equal test_save[Parse::Protocol::KEY_CREATED_AT].class, String
16
+ assert_equal test_save[Parse::Protocol::KEY_OBJECT_ID].class, String
17
+ end
16
18
  end
17
19
 
18
20
  def test_update
19
- foo = Parse::Object.new "TestSave"
20
- foo["age"] = 20
21
- foo.save
21
+ VCR.use_cassette('test_update', :record => :new_episodes) do
22
+ foo = Parse::Object.new "TestSave"
23
+ foo["age"] = 20
24
+ foo.save
22
25
 
23
- assert_equal foo["age"], 20
24
- assert_equal foo[Parse::Protocol::KEY_UPDATED_AT], nil
26
+ assert_equal foo["age"], 20
27
+ assert_equal foo[Parse::Protocol::KEY_UPDATED_AT], nil
25
28
 
26
- foo["age"] = 40
27
- orig = foo.dup
28
- foo.save
29
+ foo["age"] = 40
30
+ orig = foo.dup
31
+ foo.save
29
32
 
30
- assert_equal foo["age"], 40
31
- assert_equal foo[Parse::Protocol::KEY_UPDATED_AT].class, String
33
+ assert_equal foo["age"], 40
34
+ assert_equal foo[Parse::Protocol::KEY_UPDATED_AT].class, String
32
35
 
33
- # only difference should be updatedAt
34
- orig_assoc = orig.reject{|k,v| k == Parse::Protocol::KEY_UPDATED_AT}.to_a
35
- foo_assoc = foo.reject{|k,v| k == Parse::Protocol::KEY_UPDATED_AT}.to_a
36
- assert_equal foo_assoc, orig_assoc
36
+ # only difference should be updatedAt
37
+ orig_assoc = orig.reject{|k,v| k == Parse::Protocol::KEY_UPDATED_AT}.to_a
38
+ foo_assoc = foo.reject{|k,v| k == Parse::Protocol::KEY_UPDATED_AT}.to_a
39
+ assert_equal foo_assoc, orig_assoc
40
+ end
37
41
  end
38
42
 
39
43
  def test_server_update
40
- foo = Parse::Object.new("TestSave").save
41
- foo["name"] = 'john'
42
- foo.save
44
+ VCR.use_cassette('test_server_update', :record => :new_episodes) do
45
+ foo = Parse::Object.new("TestSave").save
46
+ foo["name"] = 'john'
47
+ foo.save
43
48
 
44
- bar = Parse.get("TestSave",foo.id) # pull it from the server
45
- assert_equal bar["name"], 'john'
46
- bar["name"] = 'dave'
47
- bar.save
49
+ bar = Parse.get("TestSave",foo.id) # pull it from the server
50
+ assert_equal bar["name"], 'john'
51
+ bar["name"] = 'dave'
52
+ bar.save
48
53
 
49
- bat = Parse.get("TestSave",foo.id)
50
- assert_equal bat["name"], 'dave'
54
+ bat = Parse.get("TestSave",foo.id)
55
+ assert_equal bat["name"], 'dave'
56
+ end
51
57
  end
52
58
 
53
59
  def test_destroy
54
- d = Parse::Object.new "toBeDeleted"
55
- d["foo"] = "bar"
56
- d.save
57
- d.parse_delete
60
+ VCR.use_cassette('test_destroy', :record => :new_episodes) do
61
+ d = Parse::Object.new "toBeDeleted"
62
+ d["foo"] = "bar"
63
+ d.save
64
+ d.parse_delete
58
65
 
59
- assert_equal d.keys.length, 0
66
+ assert_equal d.keys.length, 0
67
+ end
60
68
  end
61
69
  end
@@ -0,0 +1,29 @@
1
+ require 'helper'
2
+
3
+ Parse.init
4
+
5
+ class TestCloud < Test::Unit::TestCase
6
+ # functions stored in test/cloud_functions/MyCloudCode
7
+ # see https://parse.com/docs/cloud_code_guide to learn how to use Parse Cloud Code
8
+ #
9
+ # Parse.Cloud.define('trivial', function(request, response) {
10
+ # response.success(request.params);
11
+ # });
12
+
13
+ def setup
14
+ Parse.init
15
+ end
16
+
17
+ def test_cloud_function_initialize
18
+ assert_not_equal nil, Parse::Cloud::Function.new("trivial")
19
+ end
20
+
21
+ def test_cloud_function
22
+ VCR.use_cassette('test_cloud_function', :record => :new_episodes) do
23
+ function = Parse::Cloud::Function.new("trivial")
24
+ params = {"foo" => "bar"}
25
+ resp = function.call(params)
26
+ assert_equal resp, params
27
+ end
28
+ end
29
+ end
data/test/test_object.rb CHANGED
@@ -6,73 +6,97 @@ class TestObject < Test::Unit::TestCase
6
6
  end
7
7
 
8
8
  def test_new?
9
- post = Parse::Object.new "Post"
10
- assert_equal post.new?, true
11
- post.save
12
- assert_equal post.new?, false
9
+ VCR.use_cassette('test_new_object', :record => :new_episodes) do
10
+ post = Parse::Object.new "Post"
11
+ assert_equal post.new?, true
12
+ post.save
13
+ assert_equal post.new?, false
14
+ end
13
15
  end
14
16
 
15
- def test_id
16
- post = Parse::Object.new "Post"
17
- assert_equal post.id, nil
18
- post["title"] = "hello world"
19
- post.save
20
- assert_equal post.id.class, String
17
+ def test_object_id
18
+ VCR.use_cassette('test_object_id', :record => :new_episodes) do
19
+ post = Parse::Object.new "Post"
20
+ assert_equal post.id, nil
21
+ post["title"] = "hello world"
22
+ post.save
23
+ assert_equal post.id.class, String
24
+ end
21
25
  end
22
26
 
23
27
  def test_pointer
24
- post = Parse::Object.new "Post"
25
- assert_nil post.pointer
28
+ VCR.use_cassette('test_pointer', :record => :new_episodes) do
29
+ post = Parse::Object.new "Post"
30
+ assert_nil post.pointer
26
31
 
27
- post.save
28
- pointer = post.pointer
29
- assert_equal pointer.class_name, post.class_name
30
- assert_equal pointer.parse_object_id, post.parse_object_id
32
+ post.save
33
+ pointer = post.pointer
34
+ assert_equal pointer.class_name, post.class_name
35
+ assert_equal pointer.parse_object_id, post.parse_object_id
36
+ end
31
37
  end
32
38
 
33
39
  def test_created_at
34
- post = Parse::Object.new "Post"
35
- assert_equal post.created_at, nil
36
- post.save
37
- assert_equal post.created_at.class, DateTime
40
+ VCR.use_cassette('test_created_at', :record => :new_episodes) do
41
+ post = Parse::Object.new "Post"
42
+ assert_equal post.created_at, nil
43
+ post.save
44
+ assert_equal post.created_at.class, DateTime
45
+ end
38
46
  end
39
47
 
40
48
  def test_updated_at
41
- post = Parse::Object.new "Post"
42
- assert_equal post.updated_at, nil
43
- post["title"] = "hello"
44
- post.save
45
- assert_equal post.updated_at, nil
46
- post["title"] = "hello 2"
47
- post.save
48
- assert_equal post.updated_at.class, DateTime
49
+ VCR.use_cassette('test_updated_at', :record => :new_episodes) do
50
+ post = Parse::Object.new "Post"
51
+ assert_equal post.updated_at, nil
52
+ post["title"] = "hello"
53
+ post.save
54
+ assert_equal post.updated_at, nil
55
+ post["title"] = "hello 2"
56
+ post.save
57
+ assert_equal post.updated_at.class, DateTime
58
+ end
49
59
  end
50
60
 
51
61
  def test_parse_delete
52
- post = Parse::Object.new "Post"
53
- post.save
54
- assert_equal post.id.class, String
62
+ VCR.use_cassette('test_parse_delete', :record => :new_episodes) do
63
+ post = Parse::Object.new "Post"
64
+ post.save
65
+ assert_equal post.id.class, String
55
66
 
56
- q = Parse.get("Post", post.id)
57
- assert_equal q.id, post.id
67
+ q = Parse.get("Post", post.id)
68
+ assert_equal q.id, post.id
58
69
 
59
- post.parse_delete
70
+ post.parse_delete
60
71
 
61
- assert_raise Parse::ParseError do
62
- q = Parse.get("Post", post.id)
72
+ assert_raise Parse::ParseError do
73
+ q = Parse.get("Post", post.id)
74
+ end
63
75
  end
64
76
  end
65
77
 
66
78
  def test_deep_parse
67
- other = Parse::Object.new "Post"
68
- other.save
69
- post = Parse::Object.new "Post"
70
- post["other"] = other.pointer
71
- post.save
79
+ VCR.use_cassette('test_deep_parse', :record => :new_episodes) do
80
+ other = Parse::Object.new "Post"
81
+ other.save
82
+ post = Parse::Object.new "Post"
83
+ post["other"] = other.pointer
84
+ post.save
72
85
 
73
- q = Parse.get("Post", post.id)
74
- assert_equal Parse::Pointer, q["other"].class
75
- assert_equal other.pointer, q["other"]
86
+ q = Parse.get("Post", post.id)
87
+ assert_equal Parse::Pointer, q["other"].class
88
+ assert_equal other.pointer, q["other"]
89
+ end
76
90
  end
77
91
 
92
+ def test_nils_delete_keys
93
+ VCR.use_cassette('test_nils_delete_keys', :record => :new_episodes) do
94
+ post = Parse::Object.new "Post"
95
+ post["title"] = "hello"
96
+ post.save
97
+ post["title"] = nil
98
+ post.save
99
+ assert_false post.refresh.keys.include?("title")
100
+ end
101
+ end
78
102
  end
data/test/test_push.rb CHANGED
@@ -6,21 +6,19 @@ class TestPush < Test::Unit::TestCase
6
6
  Parse.init
7
7
  end
8
8
 
9
- def test_save
9
+ def test_save_without_where
10
10
  data = {:foo => 'bar',
11
11
  :alert => 'message'}
12
12
  pf_push = Parse::Push.new(data, "some_chan")
13
13
  pf_push.type = 'ios'
14
14
 
15
15
  query = Parse::Query.new(Parse::Protocol::CLASS_INSTALLATION).eq('deviceToken', 'baz')
16
- pf_push.where = query.where
17
16
 
18
17
  Parse::Client.any_instance.expects(:request).with do |uri, method, body, query|
19
18
  hash = JSON.parse(body)
20
19
  assert_equal :post, method
21
20
  assert has_entries('type' => 'ios', 'channel' => "some_chan").matches?([hash])
22
21
  assert has_entries('foo' => 'bar', 'alert' => 'message').matches?([hash['data']])
23
- assert has_entries('deviceToken' => 'baz').matches?([hash['where']])
24
22
  assert_nil query
25
23
  true
26
24
  end.returns({}.to_json)
@@ -29,4 +27,23 @@ class TestPush < Test::Unit::TestCase
29
27
  end
30
28
 
31
29
 
30
+ def test_save_with_where_removes_channel
31
+ data = {:foo => 'bar',
32
+ :alert => 'message'}
33
+ pf_push = Parse::Push.new(data, "some_chan")
34
+ pf_push.type = 'ios'
35
+
36
+ query = Parse::Query.new(Parse::Protocol::CLASS_INSTALLATION).eq('deviceToken', 'baz')
37
+ pf_push.where = query.where
38
+
39
+ Parse::Client.any_instance.expects(:request).with do |uri, method, body, query|
40
+ hash = JSON.parse(body)
41
+ assert_false has_entries('channel' => "some_chan").matches?([hash])
42
+ assert has_entries('deviceToken' => 'baz').matches?([hash['where']])
43
+ true
44
+ end.returns({}.to_json)
45
+
46
+ pf_push.save
47
+ end
48
+
32
49
  end