rhoconnect 4.0.0 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/CHANGELOG.md +8 -0
  2. data/Gemfile.lock +16 -18
  3. data/Rakefile +4 -4
  4. data/bench/benchapp/Rakefile +10 -16
  5. data/bench/blobapp/Rakefile +9 -18
  6. data/bench/distr_bench/distr_bench_main +1 -1
  7. data/bench/distr_bench/run_distr_client.sh +2 -1
  8. data/bench/lib/bench.rb +1 -1
  9. data/bench/lib/bench/cli.rb +2 -0
  10. data/bench/lib/bench/distr_runner.rb +5 -5
  11. data/bench/lib/bench/test_data.rb +2 -2
  12. data/bench/scripts/test_query_script.rb +7 -6
  13. data/bin/rhoconnect +2 -0
  14. data/bin/rhoconnect-benchmark +13 -1
  15. data/commands/redis/redis_download.rb +1 -1
  16. data/commands/rhoconnect/routes.rb +12 -0
  17. data/doc/authentication.txt +1 -1
  18. data/doc/command-line.txt +1 -1
  19. data/doc/deploying.txt +2 -2
  20. data/doc/migration.txt +21 -12
  21. data/doc/push-client-setup-android.txt +1 -1
  22. data/doc/push-client-setup-rps.txt +3 -1
  23. data/doc/supported-platforms.txt +14 -7
  24. data/examples/simple/Rakefile +0 -1
  25. data/generators/rhoconnect.rb +15 -3
  26. data/generators/templates/application/Rakefile +1 -2
  27. data/js-adapters/ballroom.js +36 -9
  28. data/js-adapters/node.rb +8 -2
  29. data/js-adapters/node_channel.rb +10 -6
  30. data/js-adapters/rhoconnect_helpers.js +4 -0
  31. data/js-adapters/router.js +5 -3
  32. data/js-adapters/server.js +1 -1
  33. data/lib/rhoconnect.rb +9 -5
  34. data/lib/rhoconnect/api_token.rb +1 -2
  35. data/lib/rhoconnect/client.rb +1 -1
  36. data/lib/rhoconnect/controller/js_base.rb +7 -2
  37. data/lib/rhoconnect/model/base.rb +1 -1
  38. data/lib/rhoconnect/predefined_adapters/controllers/js/rho_internal_js_bench_adapter_controller.js +12 -0
  39. data/lib/rhoconnect/predefined_adapters/models/js/rho_internal_js_bench_adapter.js +107 -0
  40. data/lib/rhoconnect/source.rb +5 -0
  41. data/lib/rhoconnect/store.rb +3 -0
  42. data/lib/rhoconnect/version.rb +1 -1
  43. data/lib/rhoconnect/web-console/server.rb +1 -2
  44. data/rhoconnect.gemspec +0 -1
  45. data/spec/apps/jstestapp/Rakefile +1 -0
  46. data/spec/apps/jstestapp/config.ru +16 -0
  47. data/spec/apps/jstestapp/controllers/js/application_controller.js +18 -0
  48. data/spec/apps/jstestapp/settings/license.key +1 -0
  49. data/spec/apps/jstestapp/settings/settings.yml +13 -0
  50. data/spec/controllers/js_base_spec.rb +129 -97
  51. data/spec/predefined_adapters/rho_internal_bench_adapter_controller_js_spec.rb +111 -0
  52. data/spec/predefined_adapters/rho_internal_js_bench_adapter_js_spec.rb +44 -0
  53. data/spec/spec_helper.rb +4 -0
  54. data/tasks/redis.rake +9 -127
  55. metadata +19 -20
  56. data/lib/rhoconnect/tasks.rb +0 -315
@@ -1,5 +1,5 @@
1
1
  var ballroom = require('./ballroom');
2
- var channel = process.argv[2] + "RedisSUB";
2
+ var channel = process.argv[2] + "-RedisSUB";
3
3
 
4
4
  ballroom.listen(channel);
5
5
  ballroom.register();
@@ -2,6 +2,7 @@ require 'redis'
2
2
  require 'cgi'
3
3
  require 'json'
4
4
  require 'base64'
5
+ require 'securerandom'
5
6
  require 'zip/zip'
6
7
  require 'yaml'
7
8
  require 'rhoconnect/license'
@@ -55,7 +56,7 @@ module Rhoconnect
55
56
  :log_disabled, :license, :bulk_sync_poll_interval, :stats, :appserver, :api_token,
56
57
  :raise_on_expired_lock, :lock_duration, :cookie_expire, :predefined_sources,
57
58
  :connection_pool_size, :connection_pool_timeout, :redis_timeout, :store_key_ttl,
58
- :disable_resque_console, :disable_rc_console, :use_node, :restart_node_on_error
59
+ :disable_resque_console, :disable_rc_console, :use_node, :restart_node_on_error, :redis_url
59
60
  end
60
61
 
61
62
  # this mixin adds the controller into the Application's URL Map
@@ -69,10 +70,13 @@ module Rhoconnect
69
70
  # Rhoconnect API version
70
71
  def add_to_url_map(subclass)
71
72
  @controllers_map ||= Set.new
72
- #puts " adding to URL map #{subclass.name}"
73
73
  @controllers_map << subclass
74
74
  end
75
75
 
76
+ def remove_from_url_map(subclass)
77
+ @controllers_map.delete(subclass) if @controllers_map
78
+ end
79
+
76
80
  def url_map
77
81
  @controllers_map ||= Set.new
78
82
  app_url_map = {}
@@ -288,9 +292,9 @@ _MIGRATE_TO_NEW_RHOCONNECT
288
292
  [res[0], res[1], res[2]]
289
293
  end
290
294
 
291
- # Get random UUID string
292
- def get_random_uuid
293
- UUIDTools::UUID.random_create.to_s.gsub(/\-/,'')
295
+ # Get secure random string
296
+ def get_random_identifier
297
+ SecureRandom.hex
294
298
  end
295
299
 
296
300
  # Generates new token (64-bit integer) based on # of
@@ -1,4 +1,3 @@
1
- require 'uuidtools'
2
1
  module Rhoconnect
3
2
  class ApiToken < StoreOrm
4
3
  field :value,:string
@@ -6,7 +5,7 @@ module Rhoconnect
6
5
  validates_presence_of :user_id
7
6
 
8
7
  def self.create(fields)
9
- fields[:value] = fields[:value] || get_random_uuid
8
+ fields[:value] = fields[:value] || get_random_identifier
10
9
  fields[:id] = fields[:value]
11
10
  super(fields)
12
11
  end
@@ -44,7 +44,7 @@ module Rhoconnect
44
44
 
45
45
  def self.create(fields,params={})
46
46
  Rhoconnect.license.check_and_use_seat
47
- fields[:id] ||= get_random_uuid
47
+ fields[:id] ||= get_random_identifier
48
48
  res = super(fields,params)
49
49
  user = User.load(fields[:user_id])
50
50
  user.clients << res.id
@@ -11,7 +11,7 @@ module Rhoconnect
11
11
  Rhoconnect::DefaultServer.helpers Rhoconnect::Controller::JsBaseHelpers
12
12
 
13
13
  helpers Rhoconnect::Controller::JsBaseHelpers
14
- register Rhoconnect::Handler::PluginCallbacks
14
+ #register Rhoconnect::Handler::PluginCallbacks
15
15
 
16
16
  # source name is available inherently from controller
17
17
  before do
@@ -32,6 +32,11 @@ module Rhoconnect
32
32
  Rhoconnect.add_to_url_map(klass)
33
33
  process_defaults(klass,val['defaults'])
34
34
  process_routes(klass,val['routes'])
35
+
36
+ # add PluginCallback routes (but only for Adapter Controllers)
37
+ unless controller_name == "ApplicationController"
38
+ klass.register Rhoconnect::Handler::PluginCallbacks
39
+ end
35
40
  end
36
41
  end
37
42
 
@@ -74,7 +79,7 @@ module Rhoconnect
74
79
  :route => 'request'
75
80
  }
76
81
  json[:user] = @model.current_user.login if @model
77
- return_value = NodeChannel.publish_channel_and_wait(json,@model)
82
+ return_value = NodeChannel.publish_channel_and_wait(json,@model || self)
78
83
  if finish_block
79
84
  self.send(finish_block, return_value)
80
85
  else
@@ -123,7 +123,7 @@ module Rhoconnect
123
123
  end
124
124
 
125
125
  def before_query
126
- @tmp_docname = :md.to_s + get_random_uuid
126
+ @tmp_docname = :md.to_s + get_random_identifier
127
127
  @stash_size = 0
128
128
  end
129
129
 
@@ -0,0 +1,12 @@
1
+ var app = require('ballroom');
2
+ var rc_helpers = require('rhoconnect_helpers');
3
+ //var RhoInternalJsBenchAdapter = require('../../models/js/rho_internal_js_bench_adapter');
4
+
5
+ app.controllerName('RhoInternalJsBenchAdapter');
6
+ app.registerHandler('sync');
7
+
8
+ // app.post('/',{}, function(req,resp){
9
+ // console.log("inside of controller post");
10
+ // var result = {'id':req.params};
11
+ // resp.send(result);
12
+ // });
@@ -0,0 +1,107 @@
1
+ var rc = require('rhoconnect_helpers');
2
+ var Store = rc.Store;
3
+
4
+ var RhoInternalJsBenchAdapter = function() {
5
+
6
+ this.query = function(resp){
7
+ rc.source(resp,function(resp){
8
+ var source = resp.result;
9
+ var result;
10
+ var db_name = get_db_name(source);
11
+ resp.params = db_name;
12
+ if(source.simulate_time > 0){
13
+ setTimeout(rc.Store.getData(resp,function(resp){
14
+ resp.send(resp.result);
15
+ }), source.simulate_time);
16
+ }
17
+ else{
18
+ rc.Store.getData(resp,function(resp){
19
+ resp.send(resp.result);
20
+ });
21
+ }
22
+ });
23
+ };
24
+
25
+ this.create = function(resp){
26
+ var hsh = resp.params.create_object;
27
+ var mockId2 = hsh["mock_id"];
28
+ rc.source(resp,function(resp){
29
+ var source = resp.result;
30
+ var create_hash = {}
31
+ create_hash[mockId2] = hsh;
32
+ var p = [get_db_name(source),create_hash,true];
33
+ resp.params = p;
34
+ rc.Store.putData(resp,function(resp){
35
+ console.log(JSON.stringify(resp));
36
+ resp.send(mockId2);
37
+ });
38
+ });
39
+ };
40
+
41
+ this.update = function(resp){
42
+ var id = resp.params["id"];
43
+ var update_hash = resp.params["update_object"];
44
+
45
+ rc.source(resp,function(resp){
46
+ var source = resp.result;
47
+ var db = get_db_name(source);
48
+ resp.params = db;
49
+ rc.Store.getData(resp,function(resp){
50
+ var data = resp.result;
51
+ //console.log("data_raw is"+JSON.stringify(data));
52
+ if(data == null || JSON.stringify(data) === "{}"){
53
+ new rc.Exception(resp, 'there is no data to update.');
54
+ }
55
+ for(var key in update_hash){
56
+ data[id][key] = update_hash[key];
57
+ }
58
+ //console.log("data is"+JSON.stringify(data));
59
+ resp.params = [db,data];
60
+ rc.Store.putData(resp,function(resp){
61
+ resp.send(id);
62
+ });
63
+ });
64
+
65
+ });
66
+ };
67
+
68
+ this.del = function(resp){
69
+ var id = resp.params["id"];
70
+ var delete_hash = resp.params["delete_object"];
71
+ rc.source(resp,function(resp){
72
+ var source = resp.result;
73
+ var del_obj = {}
74
+ del_obj[id] = delete_hash
75
+ resp.params = [get_db_name(source),del_obj];
76
+ rc.Store.deleteData(resp,function(resp){
77
+ resp.send(id);
78
+ });
79
+ });
80
+ };
81
+
82
+ this.login = function(resp){
83
+ resp.send(true);
84
+ };
85
+
86
+ this.logoff = function(resp){
87
+ resp.send(true);
88
+ };
89
+
90
+ this.sync = function(resp){
91
+ console.log("called sync");
92
+ };
93
+
94
+
95
+ function get_db_name(source){
96
+ var res;
97
+ if(source.user_id.substring(0,2) == 'nq')
98
+ res = "test_db_storage:"+source.app_id + ":nquser";
99
+ else if(source.user_id.substring(0,2) == 'mq')
100
+ res = "test_db_storage:"+source.app_id+":mquser";
101
+ else
102
+ res = "test_db_storage:"+source.app_id+":benchuser";
103
+ return res;
104
+ }
105
+
106
+ };
107
+ module.exports = new RhoInternalJsBenchAdapter();
@@ -124,6 +124,11 @@ module Rhoconnect
124
124
  update_fields(fields)
125
125
  end
126
126
 
127
+ def to_hash
128
+ res = super
129
+ res.merge({:user_id=>self.user_id,:app_id=>self.app_id})
130
+ end
131
+
127
132
  def self.set_defaults(fields)
128
133
  fields[:url] ||= ''
129
134
  fields[:login] ||= ''
@@ -874,11 +874,13 @@ module Rhoconnect
874
874
  def _get_redis(server=nil)
875
875
  url = ENV[REDIS_URL] || ENV[REDISTOGO_URL] || nil
876
876
  if url
877
+ Rhoconnect.redis_url = url
877
878
  ConnectionPool::Wrapper.new(:size => Rhoconnect.connection_pool_size,
878
879
  :timeout => Rhoconnect.connection_pool_timeout) do
879
880
  Redis.connect(:url => url, :timeout => Rhoconnect.redis_timeout, :thread_safe => true)
880
881
  end
881
882
  elsif server and server.is_a?(String)
883
+ Rhoconnect.redis_url = "redis://#{server}"
882
884
  host,port,db,password = server.split(':')
883
885
  ConnectionPool::Wrapper.new(:size => Rhoconnect.connection_pool_size,
884
886
  :timeout => Rhoconnect.connection_pool_timeout) do
@@ -888,6 +890,7 @@ module Rhoconnect
888
890
  elsif server and (server.is_a?(Redis) or server.is_a?(ConnectionPool::Wrapper))
889
891
  server
890
892
  else
893
+ Rhoconnect.redis_url = "redis://localhost:6379"
891
894
  ConnectionPool::Wrapper.new(:size => 5, :timeout => 30) do
892
895
  Redis.connect(:timeout => 30, :thread_safe => true)
893
896
  end
@@ -1,3 +1,3 @@
1
1
  module Rhoconnect
2
- VERSION = '4.0.0'
2
+ VERSION = '4.0.1'
3
3
  end
@@ -30,8 +30,7 @@ module RhoconnectConsole
30
30
  @token = session[:token] if ENV['INSTANCE_ID']
31
31
  @heroku = RestClient.get('http://nav.heroku.com/v1/providers/header') if @token
32
32
  @version = Rhoconnect::VERSION
33
- @domain = ENV['RHODES_URL'] || request.host_with_port
34
- @domain += "/application" if @domain and !ENV['RHODES_URL']
33
+ @domain = "#{request.scheme}://#{request.host_with_port}"
35
34
  erb :index
36
35
  end
37
36
 
@@ -45,7 +45,6 @@ Gem::Specification.new do |s|
45
45
  s.add_dependency('rake', '~> 10.0.0')
46
46
  s.add_dependency('json', '~> 1.7.7')
47
47
  s.add_dependency('rubyzip', '~> 0.9.4')
48
- s.add_dependency('uuidtools', '>= 2.1.1')
49
48
  s.add_dependency('connection_pool', '~> 1.0.0')
50
49
  s.add_dependency('redis', '>= 3.0.1')
51
50
  s.add_dependency('resque', '>= 1.22.0')
@@ -0,0 +1 @@
1
+ # Dummy Rakefile for testing...
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rhoconnect/application/init'
3
+
4
+ # secret is generated along with the app
5
+ Rhoconnect::Server.set :secret, 'not a secret'
6
+
7
+ # !!! Add your custom initializers and overrides here !!!
8
+ # For example, uncomment the following line to enable Stats
9
+ #Rhoconnect::Server.enable :stats
10
+ # uncomment the following line to disable Resque Front-end console
11
+ #Rhoconnect.disable_resque_console = true
12
+ # uncomment the following line to disable Rhoconnect Front-end console
13
+ #Rhoconnect.disable_rc_console = true
14
+
15
+ # run RhoConnect Application
16
+ run Rhoconnect.app
@@ -0,0 +1,18 @@
1
+ var app = require('ballroom');
2
+ var rc = require('rhoconnect_helpers');
3
+ var Store = rc.Store;
4
+ app.controllerName('Application');
5
+
6
+ app.post('/login',{'rc_handler':'authenticate'}, function(req,resp){
7
+ console.log("inside application_controller.js");
8
+ var login = req.params.login;
9
+ var password = req.params.password;
10
+ if(login === 'storeapitest') {
11
+ resp.params = ['loginkey',login]
12
+ Store.putValue(resp, function(resp){
13
+ resp.send(true);
14
+ });
15
+ } else {
16
+ resp.send(true);
17
+ }
18
+ });
@@ -0,0 +1 @@
1
+ 858fc60fadfde40273d0ac505906969318aa4931d1a2c4aeb24d98393c74379f60e226651601969874257f7f1fbda9b099ecd551a641519aa46819947fda0191
@@ -0,0 +1,13 @@
1
+ :sources:
2
+ :development:
3
+ :licensefile: settings/license.key
4
+ :redis: localhost:6379
5
+ :syncserver: http://localhost:9292/
6
+ :test:
7
+ :licensefile: settings/license.key
8
+ :redis: localhost:6379
9
+ :syncserver: http://localhost:9292/
10
+ :production:
11
+ :licensefile: settings/license.key
12
+ :redis: localhost:6379
13
+ :syncserver: http://localhost:9292/
@@ -8,113 +8,145 @@ describe "Rhoconnect::Controller::JsBase" do
8
8
 
9
9
  it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => true do
10
10
  def app
11
- @app ||= Rack::URLMap.new Rhoconnect.url_map
11
+ @app = Rack::URLMap.new Rhoconnect.url_map
12
12
  end
13
13
 
14
- before(:each) do
15
- Rhoconnect::Server.set :environment, :test
16
- Rhoconnect::Server.set :secret, "secure!"
17
- Rhoconnect.use_node = true
18
- Rhoconnect.bootstrap(get_testapp_path)
19
- do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
20
- end
21
-
22
- after(:each) do
23
- Rhoconnect::Node.kill_process
24
- end
25
-
26
- it "should get / of js controller with route overridden" do
27
- get '/app/v1/JsSample', {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
28
- last_response.should be_ok
29
- body = JSON.parse(last_response.body)
30
- body[2]['count'].should == 1
31
- body.last['insert'].should == {'1' => {'name' => 'iPhone'}}
32
- end
33
-
34
- it "should get /custom_route of js controller" do
35
- get '/app/v1/JsSample/custom_route', {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
36
- last_response.body.should == 'testuser'
37
- end
38
-
39
- it "should get /source from custom route" do
40
- get '/app/v1/JsSample/custom_route2', {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
41
- last_response.body.should == 'JsSample'
42
- end
43
-
44
- it "should get stash_result from js model" do
45
- pending "stash_result not supported yet"
46
- get '/app/v1/JsSample/custom_route3',{}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
47
- res = JSON.parse(last_response.body)
48
- res[2]["count"].should == 1
14
+ def remove_application_controller
15
+ Object.send(:remove_const, :ApplicationController) rescue nil
49
16
  end
50
17
 
51
- it "should register sync route" do
52
- get '/app/v1/Sample2', {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
53
- res = JSON.parse(last_response.body)
54
- res[2]["count"].should == 1
18
+ after(:all) do
19
+ Rhoconnect.use_node = false
55
20
  end
56
21
 
57
- it "should post to js controller" do
58
- hsh = {'1'=>{'name'=>'testname','price'=>'$199'}}
59
- post '/app/v1/JsSample',hsh, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
60
- last_response.should be_ok
61
- end
62
-
63
- it "should put to js controller" do
64
- put '/app/v1/JsSample/2', {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
65
- last_response.body.should == ''
66
- end
67
-
68
- it "should delete to js controller" do
69
- @c1 = Client.create({:user_id => @u.id,:app_id => @a.id},{:source_name => 'JsSample'})
70
- set_doc_state(@c1, :cd => @data)
71
- delete '/app/v1/JsSample/2', {}, {Rhoconnect::CLIENT_ID_HEADER => @c1.id}
72
- last_response.should be_ok
73
- end
74
-
75
- it "should call route that overrides default option" do
76
- get '/app/v1/JsSample/no_client_route', {}
77
- last_response.should be_ok
78
- last_response.body.should == 'no client required!'
79
- end
80
-
81
- it "should upload blob in multipart post" do
82
- file1,file2 = 'upload1.txt'
83
- @product1['txtfile-rhoblob'] = file1
84
- @product1['_id'] = 'tempobj1'
85
- cud = {'create'=>{'1'=>{'name'=>'hello'}},
86
- :blob_fields => ['txtfile-rhoblob']}.to_json
87
- post "/app/#{Rhoconnect::API_VERSION}/JsSample",
88
- {:cud => cud,'txtfile-rhoblob-1' =>
89
- Rack::Test::UploadedFile.new(File.join(File.dirname(__FILE__),'..','testdata',file1), "application/octet-stream")},
90
- {Rhoconnect::CLIENT_ID_HEADER => @c.id}
91
- last_response.should be_ok
92
- get "/app/#{Rhoconnect::API_VERSION}/JsSample", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
93
- json = JSON.parse(last_response.body)
94
- json[5]['links'].should == { "1" => { "l" => "blob_created" } }
95
- json[5]['delete'].should == { "blob_created" => { "name" => "hello", "txtfile-rhoblob" => "blob_created" } }
22
+ def bootstrap_rhoconnect(jsapp = false)
23
+ Rhoconnect::Server.set :environment, :test
24
+ Rhoconnect::Server.set :secret, "secure!"
25
+ Rhoconnect.use_node = true
26
+ if jsapp
27
+ Rhoconnect.bootstrap(get_jstestapp_path)
28
+ else
29
+ Rhoconnect.bootstrap(get_testapp_path)
30
+ end
31
+ # reload ruby controllers
32
+ Dir[File.join(Rhoconnect.app_directory,'controllers','ruby','*.rb')].each do |controller_file|
33
+ load controller_file
34
+ end
96
35
  end
97
36
 
98
- it "should push_objects to js controller" do
99
- s = Source.load('JsSample', @s_params)
100
- data = {'1' => @product1, '2' => @product2, '3' => @product3}
101
- post "/app/#{Rhoconnect::API_VERSION}/JsSample/push_objects",
102
- {:user_id => @u.id, :objects => data}, {Rhoconnect::API_TOKEN_HEADER => @api_token}
103
- last_response.should be_ok
104
- verify_doc_result(s, {:md => data, :md_size=>'3'})
37
+ describe "ApplicationController" do
38
+ after(:each) do
39
+ Rhoconnect.remove_from_url_map(ApplicationController)
40
+ remove_application_controller
41
+ end
42
+
43
+ it "should call Store api in ApplicationController" do
44
+ Rhoconnect.remove_from_url_map(ApplicationController)
45
+ remove_application_controller
46
+ bootstrap_rhoconnect(true)
47
+ do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => 'storeapitest', "password" => 'testpass'
48
+ Store.get_value('loginkey').should == 'storeapitest'
49
+ end
105
50
  end
106
51
 
107
- it "should push_deletes to js controller" do
108
- data = {'1' => @product1, '2' => @product2, '3' => @product3}
109
- s = Source.load('JsSample',@s_params)
110
- set_doc_state(s, {:md => data, :md_size => '3'})
111
- data.delete('2')
112
- post "/app/#{Rhoconnect::API_VERSION}/JsSample/push_deletes",
113
- {:user_id => @u.id, :objects => ['2']}, {Rhoconnect::API_TOKEN_HEADER => @api_token}
114
- last_response.should be_ok
115
- verify_doc_result(s, {:md => data, :md_size=>'2'})
52
+ describe "Named Controller" do
53
+
54
+ before(:each) do
55
+ bootstrap_rhoconnect
56
+ do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
57
+ end
58
+
59
+ it "should get / of js controller with route overridden" do
60
+ get '/app/v1/JsSample', {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
61
+ last_response.should be_ok
62
+ body = JSON.parse(last_response.body)
63
+ body[2]['count'].should == 1
64
+ body.last['insert'].should == {'1' => {'name' => 'iPhone'}}
65
+ end
66
+
67
+ it "should get /custom_route of js controller" do
68
+ get '/app/v1/JsSample/custom_route', {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
69
+ last_response.body.should == 'testuser'
70
+ end
71
+
72
+ it "should get /source from custom route" do
73
+ get '/app/v1/JsSample/custom_route2', {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
74
+ last_response.body.should == 'JsSample'
75
+ end
76
+
77
+ it "should get stash_result from js model" do
78
+ pending "stash_result not supported yet"
79
+ get '/app/v1/JsSample/custom_route3',{}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
80
+ res = JSON.parse(last_response.body)
81
+ res[2]["count"].should == 1
82
+ end
83
+
84
+ it "should register sync route" do
85
+ get '/app/v1/Sample2', {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
86
+ res = JSON.parse(last_response.body)
87
+ res[2]["count"].should == 1
88
+ end
89
+
90
+ it "should post to js controller" do
91
+ hsh = {'1'=>{'name'=>'testname','price'=>'$199'}}
92
+ post '/app/v1/JsSample',hsh, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
93
+ last_response.should be_ok
94
+ end
95
+
96
+ it "should put to js controller" do
97
+ put '/app/v1/JsSample/2', {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
98
+ last_response.body.should == ''
99
+ end
100
+
101
+ it "should delete to js controller" do
102
+ @c1 = Client.create({:user_id => @u.id,:app_id => @a.id},{:source_name => 'JsSample'})
103
+ set_doc_state(@c1, :cd => @data)
104
+ delete '/app/v1/JsSample/2', {}, {Rhoconnect::CLIENT_ID_HEADER => @c1.id}
105
+ last_response.should be_ok
106
+ end
107
+
108
+ it "should call route that overrides default option" do
109
+ get '/app/v1/JsSample/no_client_route', {}
110
+ last_response.should be_ok
111
+ last_response.body.should == 'no client required!'
112
+ end
113
+
114
+ it "should upload blob in multipart post" do
115
+ file1,file2 = 'upload1.txt'
116
+ @product1['txtfile-rhoblob'] = file1
117
+ @product1['_id'] = 'tempobj1'
118
+ cud = {'create'=>{'1'=>{'name'=>'hello'}},
119
+ :blob_fields => ['txtfile-rhoblob']}.to_json
120
+ post "/app/#{Rhoconnect::API_VERSION}/JsSample",
121
+ {:cud => cud,'txtfile-rhoblob-1' =>
122
+ Rack::Test::UploadedFile.new(File.join(File.dirname(__FILE__),'..','testdata',file1), "application/octet-stream")},
123
+ {Rhoconnect::CLIENT_ID_HEADER => @c.id}
124
+ last_response.should be_ok
125
+ get "/app/#{Rhoconnect::API_VERSION}/JsSample", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
126
+ json = JSON.parse(last_response.body)
127
+ json[5]['links'].should == { "1" => { "l" => "blob_created" } }
128
+ json[5]['delete'].should == { "blob_created" => { "name" => "hello", "txtfile-rhoblob" => "blob_created" } }
129
+ end
130
+
131
+ it "should push_objects to js controller" do
132
+ s = Source.load('JsSample', @s_params)
133
+ data = {'1' => @product1, '2' => @product2, '3' => @product3}
134
+ post "/app/#{Rhoconnect::API_VERSION}/JsSample/push_objects",
135
+ {:user_id => @u.id, :objects => data}, {Rhoconnect::API_TOKEN_HEADER => @api_token}
136
+ last_response.should be_ok
137
+ verify_doc_result(s, {:md => data, :md_size=>'3'})
138
+ end
139
+
140
+ it "should push_deletes to js controller" do
141
+ data = {'1' => @product1, '2' => @product2, '3' => @product3}
142
+ s = Source.load('JsSample',@s_params)
143
+ set_doc_state(s, {:md => data, :md_size => '3'})
144
+ data.delete('2')
145
+ post "/app/#{Rhoconnect::API_VERSION}/JsSample/push_deletes",
146
+ {:user_id => @u.id, :objects => ['2']}, {Rhoconnect::API_TOKEN_HEADER => @api_token}
147
+ last_response.should be_ok
148
+ verify_doc_result(s, {:md => data, :md_size=>'2'})
149
+ end
116
150
  end
117
-
118
- it "should register deprecated_route"
119
151
  end
120
152
  end