rhoconnect 4.0.4 → 5.1.1
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.
- checksums.yaml +5 -13
- data/CHANGELOG.md +54 -5
- data/CREDITS +219 -219
- data/Gemfile +2 -2
- data/Gemfile.lock +68 -79
- data/Rakefile +1 -2
- data/bench/benchapp/spec/models/ruby/mock_adapter_spec.rb +17 -17
- data/bench/benchapp/spec/models/ruby/queue_mock_adapter_spec.rb +17 -17
- data/bench/benchapp/spec/spec_helper.rb +3 -3
- data/bench/blobapp/spec/models/ruby/blob_adapter_spec.rb +17 -17
- data/bench/blobapp/spec/spec_helper.rb +3 -3
- data/bench/lib/bench/runner.rb +1 -69
- data/bench/lib/bench.rb +18 -18
- data/bench/spec/mock_adapter_spec.rb +54 -55
- data/bench/spec/mock_client_spec.rb +47 -48
- data/bench/spec/result_spec.rb +41 -44
- data/bench/spec/utils_spec.rb +24 -25
- data/commands/generators/app.rb +7 -5
- data/commands/generators/controller.rb +7 -5
- data/commands/generators/model.rb +7 -5
- data/commands/generators/source.rb +7 -5
- data/commands/parser.rb +1 -1
- data/commands/redis/redis_download.rb +1 -1
- data/doc/async-jobs.txt +9 -9
- data/doc/supported-platforms.txt +0 -2
- data/generators/rhoconnect.rb +92 -212
- data/generators/templates/application/rcgemfile +3 -3
- data/generators/templates/application/spec/application_controller_spec.rb +14 -16
- data/generators/templates/application/spec/js_spec.rb +20 -20
- data/generators/templates/application/spec/spec_helper.rb +1 -1
- data/generators/templates/source/controllers/ruby/controller_spec.rb +18 -19
- data/generators/templates/source/models/ruby/model_spec.rb +17 -17
- data/install.sh +10 -21
- data/installer/unix-like/rho_connect_install_constants.rb +5 -5
- data/installer/unix-like/rho_connect_install_installers.rb +4 -4
- data/installer/utils/constants.rb +6 -6
- data/installer/utils/nix_install_test.rb +29 -29
- data/installer/utils/package_upload/repos.rake +16 -26
- data/js-adapters/node.rb +4 -4
- data/js-adapters/node_channel.rb +4 -8
- data/lib/rhoconnect/db_adapter.rb +13 -13
- data/lib/rhoconnect/handler/changes/engine.rb +1 -1
- data/lib/rhoconnect/jobs/bulk_data_job.rb +29 -29
- data/lib/rhoconnect/license.rb +7 -7
- data/lib/rhoconnect/model/helpers/find_duplicates_on_update.rb +13 -13
- data/lib/rhoconnect/ping/apple.rb +4 -4
- data/lib/rhoconnect/server.rb +2 -2
- data/lib/rhoconnect/source.rb +2 -2
- data/lib/rhoconnect/store.rb +12 -6
- data/lib/rhoconnect/utilities.rb +2 -2
- data/lib/rhoconnect/version.rb +1 -1
- data/lib/rhoconnect.rb +6 -4
- data/rhoconnect.gemspec +5 -6
- data/spec/api/api_helper.rb +1 -1
- data/spec/api/app/fast_delete_spec.rb +22 -22
- data/spec/api/app/fast_insert_spec.rb +23 -23
- data/spec/api/app/fast_update_spec.rb +63 -63
- data/spec/api/app/push_deletes_spec.rb +11 -13
- data/spec/api/app/push_objects_spec.rb +39 -39
- data/spec/api/client/client_get_db_doc_spec.rb +29 -29
- data/spec/api/client/client_set_db_doc_spec.rb +11 -11
- data/spec/api/client/get_client_params_spec.rb +29 -29
- data/spec/api/client/list_client_docs_spec.rb +32 -34
- data/spec/api/client/reset_spec.rb +30 -30
- data/spec/api/readstate/set_refresh_time_spec.rb +43 -43
- data/spec/api/source/get_source_params_spec.rb +32 -34
- data/spec/api/source/list_sources_spec.rb +13 -13
- data/spec/api/source/update_source_params_spec.rb +19 -19
- data/spec/api/store/get_db_doc_spec.rb +27 -27
- data/spec/api/store/set_db_doc_spec.rb +38 -38
- data/spec/api/system/adapter_spec.rb +27 -29
- data/spec/api/system/get_license_info_spec.rb +11 -11
- data/spec/api/system/login_spec.rb +37 -37
- data/spec/api/system/reset_spec.rb +15 -15
- data/spec/api/system/stats_spec.rb +70 -71
- data/spec/api/user/create_user_spec.rb +37 -37
- data/spec/api/user/delete_client_spec.rb +7 -7
- data/spec/api/user/delete_user_spec.rb +62 -62
- data/spec/api/user/list_clients_spec.rb +24 -24
- data/spec/api/user/list_source_docs_spec.rb +29 -29
- data/spec/api/user/list_users_spec.rb +22 -22
- data/spec/api/user/ping_spec.rb +18 -18
- data/spec/api/user/show_user_spec.rb +10 -10
- data/spec/api/user/update_user_spec.rb +43 -43
- data/spec/api/user/user_get_db_doc_spec.rb +12 -12
- data/spec/api/user/user_set_db_doc_spec.rb +37 -37
- data/spec/api_token_spec.rb +8 -8
- data/spec/app_spec.rb +18 -17
- data/spec/apps/jstestapp/settings/settings.yml +2 -0
- data/spec/async_spec.rb +9 -11
- data/spec/bulk_data/bulk_data_spec.rb +120 -120
- data/spec/cli/cli_spec.rb +50 -53
- data/spec/client_spec.rb +105 -105
- data/spec/client_sync_spec.rb +529 -528
- data/spec/controllers/js_base_spec.rb +147 -141
- data/spec/doc/doc_spec.rb +51 -52
- data/spec/document_spec.rb +58 -58
- data/spec/dynamic_adapter_spec.rb +33 -36
- data/spec/generator/generator_spec.rb +76 -42
- data/spec/jobs/bulk_data_job_spec.rb +101 -102
- data/spec/jobs/ping_job_spec.rb +176 -177
- data/spec/jobs/source_job_spec.rb +24 -25
- data/spec/license_spec.rb +54 -55
- data/spec/models/js_base_spec.rb +121 -120
- data/spec/perf/bulk_data_perf_spec.rb +23 -24
- data/spec/perf/perf_spec_helper.rb +7 -7
- data/spec/perf/store_perf_spec.rb +139 -140
- data/spec/ping/apple_spec.rb +65 -65
- data/spec/ping/gcm_spec.rb +83 -84
- data/spec/ping/rhoconnect_push_spec.rb +52 -53
- data/spec/predefined_adapters/rho_internal_bench_adapter_controller_js_spec.rb +100 -101
- data/spec/predefined_adapters/rho_internal_js_bench_adapter_js_spec.rb +29 -31
- data/spec/read_state_spec.rb +24 -25
- data/spec/rhoconnect_spec.rb +7 -7
- data/spec/server/server_spec.rb +664 -662
- data/spec/server/stats_spec.rb +12 -12
- data/spec/source_adapter_spec.rb +124 -125
- data/spec/source_spec.rb +148 -149
- data/spec/source_sync_spec.rb +736 -736
- data/spec/spec_helper.rb +4 -5
- data/spec/stats/record_spec.rb +22 -21
- data/spec/store_orm_spec.rb +48 -48
- data/spec/store_spec.rb +428 -426
- data/spec/support/shared_examples.rb +5 -7
- data/spec/sync_states_spec.rb +67 -67
- data/spec/test_methods_spec.rb +121 -123
- data/spec/testdata/10000-data.txt +0 -0
- data/spec/testdata/5000-data.txt +0 -0
- data/spec/user_spec.rb +102 -102
- data/tasks/redis.rake +3 -3
- metadata +154 -195
- data/bench/benchapp/tmp/pids/passenger.9292.pid.lock +0 -0
- data/bench/benchapp/tmp/restart.txt +0 -0
- data/bench/blobapp/settings/license.key.bak +0 -2
- data/bench/blobapp/tmp/restart.txt +0 -0
- data/bench/lib/testdata/1-data.txt +0 -0
- data/bench/lib/testdata/10-data.txt +0 -0
- data/bench/lib/testdata/2-data.txt +0 -0
- data/bench/lib/testdata/250-data.txt +0 -0
- data/bench/lib/testdata/5-blob_data.txt +0 -0
- data/bench/lib/testdata/5-data.txt +0 -0
- data/bench/lib/testdata/50-data.txt +0 -0
- data/bench/lib/testdata/500-data.txt +0 -0
- data/doc/protocol.html +0 -1993
- data/spec/coverage/rcov/assets/0.2.3/jquery-1.3.2.min.js +0 -19
- data/spec/coverage/rcov/assets/0.2.3/jquery.tablesorter.min.js +0 -15
- data/spec/coverage/rcov/assets/0.2.3/print.css +0 -12
- data/spec/coverage/rcov/assets/0.2.3/rcov.js +0 -42
- data/spec/coverage/rcov/assets/0.2.3/screen.css +0 -270
- data/spec/coverage/rcov/index.html +0 -88
- data/spec/generator/generator_spec_helper.rb +0 -9
data/spec/server/server_spec.rb
CHANGED
|
@@ -6,764 +6,766 @@ require File.join(File.dirname(__FILE__),'..','..','lib','rhoconnect','server.rb
|
|
|
6
6
|
describe "Server" do
|
|
7
7
|
include Rack::Test::Methods
|
|
8
8
|
include Rhoconnect
|
|
9
|
+
include_examples "SharedRhoconnectHelper", :rhoconnect_data => true
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
end
|
|
11
|
+
before(:each) do
|
|
12
|
+
Rhoconnect::Server.set :secret, "secure!"
|
|
13
|
+
Rhoconnect::Server.use Rack::Static, :urls => ["/data"],
|
|
14
|
+
:root => File.expand_path(File.join(File.dirname(__FILE__),'..','apps','rhotestapp'))
|
|
15
|
+
end
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
def app
|
|
18
|
+
@app ||= Rack::URLMap.new Rhoconnect.url_map
|
|
19
|
+
end
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
it "should show status page" do
|
|
22
|
+
get '/'
|
|
23
|
+
last_response.status.should == 302
|
|
24
|
+
end
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
it "should login if content-type contains extra parameters" do
|
|
27
|
+
post "/rc/#{Rhoconnect::API_VERSION}/system/login", {"login" => 'rhoadmin', "password" => ''}.to_json, {'CONTENT_TYPE'=>'application/json; charset=UTF-8'}
|
|
28
|
+
last_response.should be_ok
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should fail to login if wrong content-type" do
|
|
32
|
+
post "/rc/#{Rhoconnect::API_VERSION}/system/login", {"login" => 'rhoadmin', "password" => ''}.to_json, {'CONTENT_TYPE'=>'application/x-www-form-urlencoded'}
|
|
33
|
+
last_response.should_not be_ok
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should login as rhoadmin user" do
|
|
37
|
+
post "/rc/#{Rhoconnect::API_VERSION}/system/login", "login" => 'rhoadmin', "password" => ''
|
|
38
|
+
last_response.should be_ok
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should extract api token from the header" do
|
|
42
|
+
post "/rc/#{Rhoconnect::API_VERSION}/system/login", "login" => 'rhoadmin', "password" => ''
|
|
43
|
+
last_response.should be_ok
|
|
44
|
+
api_token = last_response.body
|
|
45
|
+
|
|
46
|
+
get "/rc/#{Rhoconnect::API_VERSION}/system/license", {}, {Rhoconnect::API_TOKEN_HEADER => api_token}
|
|
47
|
+
last_response.should be_ok
|
|
48
|
+
JSON.parse(last_response.body).should == {
|
|
49
|
+
"available" => 9,
|
|
50
|
+
"issued" => "Fri Apr 23 17:20:13 -0700 2010",
|
|
51
|
+
"seats" => 10,
|
|
52
|
+
"rhoconnect_version" => "Version 1",
|
|
53
|
+
"licensee" => "Rhomobile" }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should respond with 404 if controller name is not specified" do
|
|
57
|
+
get "/app/#{Rhoconnect::API_VERSION}/"
|
|
58
|
+
last_response.status.should == 404
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should have default session secret" do
|
|
62
|
+
Rhoconnect::Server.secret.should == "secure!"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "should update session secret to default" do
|
|
66
|
+
Rhoconnect::Server.set :secret, "<changeme>"
|
|
67
|
+
Rhoconnect::Server.secret.should == "<changeme>"
|
|
68
|
+
allow(Rhoconnect::Server).to receive(:log).with(any_args())
|
|
69
|
+
check_default_secret!("<changeme>")
|
|
70
|
+
Rhoconnect::Server.set :secret, "secure!"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe "helpers" do
|
|
74
|
+
before(:each) do
|
|
75
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
|
|
29
76
|
end
|
|
30
77
|
|
|
31
|
-
it "should
|
|
32
|
-
|
|
33
|
-
last_response.
|
|
78
|
+
it "should return nil if params[:source_name] is missing" do
|
|
79
|
+
get "/application"
|
|
80
|
+
last_response.status.should == 500
|
|
34
81
|
end
|
|
82
|
+
end
|
|
35
83
|
|
|
36
|
-
|
|
37
|
-
|
|
84
|
+
describe "auth routes" do
|
|
85
|
+
it "should login user with correct username,password" do
|
|
86
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
|
|
38
87
|
last_response.should be_ok
|
|
39
88
|
end
|
|
40
89
|
|
|
41
|
-
it "should
|
|
42
|
-
|
|
90
|
+
it "should login user with correct username,password old route and deprecation warning" do
|
|
91
|
+
do_post "/application/clientlogin", "login" => @u.login, "password" => 'testpass'
|
|
43
92
|
last_response.should be_ok
|
|
44
|
-
|
|
93
|
+
last_response.headers["Warning"].index('deprecated').should_not == nil
|
|
94
|
+
end
|
|
45
95
|
|
|
46
|
-
|
|
96
|
+
it "should login user with correct username,password if backend service defined" do
|
|
97
|
+
stub_request(:post, "http://test.com/rhoconnect/authenticate").to_return(:body => "lucas")
|
|
98
|
+
Rhoconnect.appserver = 'http://test.com'
|
|
99
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => 'lucas', "password" => 'testpass'
|
|
47
100
|
last_response.should be_ok
|
|
48
|
-
JSON.parse(last_response.body).should == {
|
|
49
|
-
"available" => 9,
|
|
50
|
-
"issued" => "Fri Apr 23 17:20:13 -0700 2010",
|
|
51
|
-
"seats" => 10,
|
|
52
|
-
"rhoconnect_version" => "Version 1",
|
|
53
|
-
"licensee" => "Rhomobile" }
|
|
54
101
|
end
|
|
55
102
|
|
|
56
|
-
it "should
|
|
57
|
-
|
|
58
|
-
last_response.status.should ==
|
|
103
|
+
it "should return 401 and LoginException messsage from authenticate" do
|
|
104
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'wrongpass'
|
|
105
|
+
last_response.status.should == 401
|
|
106
|
+
last_response.body.should == 'login exception'
|
|
59
107
|
end
|
|
60
108
|
|
|
61
|
-
it "should
|
|
62
|
-
Rhoconnect::
|
|
109
|
+
it "should return 500 and Exception messsage from authenticate" do
|
|
110
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'server error'
|
|
111
|
+
last_response.status.should == 500
|
|
112
|
+
last_response.body.should == 'server error'
|
|
63
113
|
end
|
|
64
114
|
|
|
65
|
-
it "should
|
|
66
|
-
Rhoconnect::
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
check_default_secret!("<changeme>")
|
|
70
|
-
Rhoconnect::Server.set :secret, "secure!"
|
|
115
|
+
it "should return 401 and no messsage from authenticate if no exception raised" do
|
|
116
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'wrongpassnomsg'
|
|
117
|
+
last_response.status.should == 401
|
|
118
|
+
last_response.body.should == "Unable to authenticate '#{@u.login}'"
|
|
71
119
|
end
|
|
72
120
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
121
|
+
it "should create unknown user through delegated authentication" do
|
|
122
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => 'newuser', "password" => 'testpass'
|
|
123
|
+
User.is_exist?('newuser').should == true
|
|
124
|
+
@a.users.members.sort.should == ['newuser','testuser']
|
|
125
|
+
end
|
|
77
126
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
127
|
+
it "should create a different username through delegated authentication" do
|
|
128
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => 'newuser', "password" => 'diffuser'
|
|
129
|
+
User.is_exist?('different').should == true
|
|
130
|
+
@a.users.members.sort.should == ['different','testuser']
|
|
82
131
|
end
|
|
83
132
|
|
|
84
|
-
|
|
85
|
-
it "should
|
|
133
|
+
context "rps authenticate" do
|
|
134
|
+
it "should authenticate user with rps route" do
|
|
135
|
+
# RPS login should always come after normal login
|
|
86
136
|
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
it "should login user with correct username,password old route and deprecation warning" do
|
|
91
|
-
do_post "/application/clientlogin", "login" => @u.login, "password" => 'testpass'
|
|
92
|
-
last_response.should be_ok
|
|
93
|
-
last_response.headers["Warning"].index('deprecated').should_not == nil
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
it "should login user with correct username,password if backend service defined" do
|
|
97
|
-
stub_request(:post, "http://test.com/rhoconnect/authenticate").to_return(:body => "lucas")
|
|
98
|
-
Rhoconnect.appserver = 'http://test.com'
|
|
99
|
-
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => 'lucas', "password" => 'testpass'
|
|
100
|
-
last_response.should be_ok
|
|
137
|
+
authorize 'rpsuser', 'secret'
|
|
138
|
+
get "/rc/#{Rhoconnect::API_VERSION}/app/rps_login", {}
|
|
139
|
+
last_response.status.should == 204
|
|
101
140
|
end
|
|
141
|
+
end
|
|
102
142
|
|
|
103
|
-
|
|
104
|
-
|
|
143
|
+
context "rps app authenticate" do
|
|
144
|
+
it "should authenticate rhoconnect app with correct push server credentials" do
|
|
145
|
+
# Test app push server settings are
|
|
146
|
+
# :push_server: http://user:pwd@localhost:8675
|
|
147
|
+
authorize 'user', 'pwd'
|
|
148
|
+
get "/rc/#{Rhoconnect::API_VERSION}/system/rps_login", {}
|
|
149
|
+
last_response.status.should == 204
|
|
150
|
+
end
|
|
151
|
+
it "should not authenticate rhoconnect app with invalid rhoconnect push server credentials" do
|
|
152
|
+
authorize 'someappname', ''
|
|
153
|
+
get "/rc/#{Rhoconnect::API_VERSION}/system/rps_login", {}
|
|
105
154
|
last_response.status.should == 401
|
|
106
|
-
last_response.body.should == 'login exception'
|
|
107
155
|
end
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
last_response.status.should == 500
|
|
112
|
-
last_response.body.should == 'server error'
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
it "should return 401 and no messsage from authenticate if no exception raised" do
|
|
116
|
-
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'wrongpassnomsg'
|
|
156
|
+
it "should not authenticate rhoconnect app with invalid basic Authorization header in request" do
|
|
157
|
+
# Basic Authorization header is missing
|
|
158
|
+
get "/rc/#{Rhoconnect::API_VERSION}/system/rps_login", {}
|
|
117
159
|
last_response.status.should == 401
|
|
118
|
-
last_response.body.should == "Unable to authenticate '#{@u.login}'"
|
|
119
160
|
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
120
163
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
end
|
|
164
|
+
describe "controller custom routes" do
|
|
165
|
+
before(:each) do
|
|
166
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
|
|
167
|
+
end
|
|
126
168
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
@a.users.members.sort.should == ['different','testuser']
|
|
169
|
+
it "should register custom_route in DefaultServer and process it" do
|
|
170
|
+
Rhoconnect::Server.api4 '', "/my_custom_route", :get do
|
|
171
|
+
"Hello World!"
|
|
131
172
|
end
|
|
132
173
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
|
|
137
|
-
authorize 'rpsuser', 'secret'
|
|
138
|
-
get "/rc/#{Rhoconnect::API_VERSION}/app/rps_login", {}
|
|
139
|
-
last_response.status.should == 204
|
|
140
|
-
end
|
|
141
|
-
end
|
|
174
|
+
get "/my_custom_route", {}
|
|
175
|
+
last_response.body.should == "Hello World!"
|
|
176
|
+
end
|
|
142
177
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
# :push_server: http://user:pwd@localhost:8675
|
|
147
|
-
authorize 'user', 'pwd'
|
|
148
|
-
get "/rc/#{Rhoconnect::API_VERSION}/system/rps_login", {}
|
|
149
|
-
last_response.status.should == 204
|
|
150
|
-
end
|
|
151
|
-
it "should not authenticate rhoconnect app with invalid rhoconnect push server credentials" do
|
|
152
|
-
authorize 'someappname', ''
|
|
153
|
-
get "/rc/#{Rhoconnect::API_VERSION}/system/rps_login", {}
|
|
154
|
-
last_response.status.should == 401
|
|
155
|
-
end
|
|
156
|
-
it "should not authenticate rhoconnect app with invalid basic Authorization header in request" do
|
|
157
|
-
# Basic Authorization header is missing
|
|
158
|
-
get "/rc/#{Rhoconnect::API_VERSION}/system/rps_login", {}
|
|
159
|
-
last_response.status.should == 401
|
|
160
|
-
end
|
|
178
|
+
it "should register custom_route in SimpleAdapter controller and process it" do
|
|
179
|
+
SimpleAdapterController.get '/my_custom_route', {:client_required => true, :source_required => true} do
|
|
180
|
+
"Hello World!"
|
|
161
181
|
end
|
|
182
|
+
get "/app/#{Rhoconnect::API_VERSION}/SimpleAdapter/my_custom_route", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
183
|
+
last_response.body.should == "Hello World!"
|
|
162
184
|
end
|
|
163
185
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
186
|
+
it "should register custom_route in SimpleAdapter controller, require client condition and return error if client is missing" do
|
|
187
|
+
SimpleAdapterController.get '/my_custom_route_with_client', {:client_required => true, :source_required => true} do
|
|
188
|
+
"Hello World!"
|
|
167
189
|
end
|
|
190
|
+
get "/app/#{Rhoconnect::API_VERSION}/SimpleAdapter/my_custom_route_with_client", {}
|
|
191
|
+
last_response.body.should == "Unknown client"
|
|
192
|
+
last_response.status.should == 500
|
|
193
|
+
end
|
|
194
|
+
end
|
|
168
195
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
get "/my_custom_route", {}
|
|
175
|
-
last_response.body.should == "Hello World!"
|
|
176
|
-
end
|
|
196
|
+
describe "client management routes" do
|
|
197
|
+
before(:each) do
|
|
198
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
|
|
199
|
+
end
|
|
177
200
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
201
|
+
it "should respond to clientcreate" do
|
|
202
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/clients", 'device_type' => 'Android'
|
|
203
|
+
last_response.should be_ok
|
|
204
|
+
last_response.content_type.should =~ /application\/json/
|
|
205
|
+
id = JSON.parse(last_response.body)['client']['client_id']
|
|
206
|
+
id.length.should == 32
|
|
207
|
+
JSON.parse(last_response.body).should ==
|
|
208
|
+
{"client"=>{"client_id"=>id}}
|
|
209
|
+
c = Client.load(id,{:source_name => '*'})
|
|
210
|
+
c.user_id.should == 'testuser'
|
|
211
|
+
c.device_type.should == 'Android'
|
|
212
|
+
end
|
|
185
213
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
214
|
+
it "should respond to clientcreate with old route and deprecation warning" do
|
|
215
|
+
get "/application/clientcreate?device_type=Android"
|
|
216
|
+
last_response.should be_ok
|
|
217
|
+
last_response.headers["Warning"].index('deprecated').should_not == nil
|
|
218
|
+
last_response.content_type.should =~ /application\/json/
|
|
219
|
+
id = JSON.parse(last_response.body)['client']['client_id']
|
|
220
|
+
id.length.should == 32
|
|
221
|
+
JSON.parse(last_response.body).should ==
|
|
222
|
+
{"client"=>{"client_id"=>id}}
|
|
223
|
+
c = Client.load(id,{:source_name => '*'})
|
|
224
|
+
c.user_id.should == 'testuser'
|
|
225
|
+
c.device_type.should == 'Android'
|
|
194
226
|
end
|
|
195
227
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
228
|
+
it "should respond to clientregister" do
|
|
229
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/clients/#{@c.id}/register",
|
|
230
|
+
"device_type" => "iPhone", "device_pin" => 'abcd'
|
|
231
|
+
last_response.should be_ok
|
|
232
|
+
@c.device_type.should == 'Apple'
|
|
233
|
+
@c.device_pin.should == 'abcd'
|
|
234
|
+
@c.id.length.should == 32
|
|
235
|
+
end
|
|
200
236
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
237
|
+
it "should respond to clientregister without clientcreate" do
|
|
238
|
+
Store.flush_data("client*")
|
|
239
|
+
client_id = @c.id.clone
|
|
240
|
+
@c = nil
|
|
241
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/clients/#{client_id}/register",
|
|
242
|
+
"device_type" => "iPhone", "device_pin" => 'abcd'
|
|
243
|
+
last_response.should be_ok
|
|
244
|
+
@c = Client.load(client_id, {:source_name => '*'})
|
|
245
|
+
@c.device_type.should == 'iPhone'
|
|
246
|
+
@c.device_pin.should == 'abcd'
|
|
247
|
+
@c.id.length.should == 32
|
|
248
|
+
end
|
|
213
249
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
id = JSON.parse(last_response.body)['client']['client_id']
|
|
220
|
-
id.length.should == 32
|
|
221
|
-
JSON.parse(last_response.body).should ==
|
|
222
|
-
{"client"=>{"client_id"=>id}}
|
|
223
|
-
c = Client.load(id,{:source_name => '*'})
|
|
224
|
-
c.user_id.should == 'testuser'
|
|
225
|
-
c.device_type.should == 'Android'
|
|
226
|
-
end
|
|
250
|
+
it "should respond to clientreset" do
|
|
251
|
+
set_doc_state(@c, :cd => @data)
|
|
252
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/clients/#{@c.id}/reset", {}
|
|
253
|
+
verify_doc_result(@c, :cd => {})
|
|
254
|
+
end
|
|
227
255
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
@c.id.length.should == 32
|
|
235
|
-
end
|
|
256
|
+
it "should respond to clientreset with old route and deprecation warning" do
|
|
257
|
+
set_doc_state(@c, :cd => @data)
|
|
258
|
+
get "/application/clientreset", 'client_id' => @c.id
|
|
259
|
+
last_response.headers["Warning"].index('deprecated').should_not == nil
|
|
260
|
+
verify_doc_result(@c, :cd => {})
|
|
261
|
+
end
|
|
236
262
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
263
|
+
it "should respond to clientreset with individual adapters" do
|
|
264
|
+
@c.source_name = 'SimpleAdapter'
|
|
265
|
+
set_doc_state(@c, :cd => @data)
|
|
266
|
+
@c.source_name = 'SampleAdapter'
|
|
267
|
+
set_doc_state(@c, :cd => @data)
|
|
268
|
+
sources = [{'name' => 'SimpleAdapter'}]
|
|
269
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/clients/#{@c.id}/reset", 'sources' => sources
|
|
270
|
+
last_response.should be_ok
|
|
271
|
+
@c.source_name = 'SampleAdapter'
|
|
272
|
+
verify_doc_result(@c, :cd => @data)
|
|
273
|
+
@c.source_name = 'SimpleAdapter'
|
|
274
|
+
verify_doc_result(@c, :cd => {})
|
|
275
|
+
end
|
|
249
276
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
277
|
+
it "should switch client user if client user_id doesn't match session user" do
|
|
278
|
+
set_test_data('test_db_storage',@data)
|
|
279
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
280
|
+
JSON.parse(last_response.body).last['insert'].should == @data
|
|
281
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => 'user2', "password" => 'testpass'
|
|
282
|
+
data = {'1'=>@product1,'2'=>@product2}
|
|
283
|
+
set_test_data('test_db_storage',data)
|
|
284
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
285
|
+
JSON.parse(last_response.body).last['insert'].should == data
|
|
286
|
+
end
|
|
255
287
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
288
|
+
it "should return error on routes if client doesn't exist" do
|
|
289
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}",{}, {Rhoconnect::CLIENT_ID_HEADER => "BrokenClient"}
|
|
290
|
+
last_response.body.should == "Unknown client"
|
|
291
|
+
last_response.status.should == 500
|
|
292
|
+
end
|
|
293
|
+
end
|
|
262
294
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
set_doc_state(@c, :cd => @data)
|
|
268
|
-
sources = [{'name' => 'SimpleAdapter'}]
|
|
269
|
-
do_post "/rc/#{Rhoconnect::API_VERSION}/clients/#{@c.id}/reset", 'sources' => sources
|
|
270
|
-
last_response.should be_ok
|
|
271
|
-
@c.source_name = 'SampleAdapter'
|
|
272
|
-
verify_doc_result(@c, :cd => @data)
|
|
273
|
-
@c.source_name = 'SimpleAdapter'
|
|
274
|
-
verify_doc_result(@c, :cd => {})
|
|
275
|
-
end
|
|
295
|
+
describe "source routes" do
|
|
296
|
+
before(:each) do
|
|
297
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
|
|
298
|
+
end
|
|
276
299
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
JSON.parse(last_response.body).last['insert'].should == data
|
|
286
|
-
end
|
|
300
|
+
it "should post records for create" do
|
|
301
|
+
@product1['_id'] = '1'
|
|
302
|
+
params = {'create'=>{'1'=>@product1}}
|
|
303
|
+
do_post "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", params, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
304
|
+
last_response.should be_ok
|
|
305
|
+
last_response.body.should == ''
|
|
306
|
+
verify_result("test_create_storage" => {'1'=>@product1})
|
|
307
|
+
end
|
|
287
308
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
309
|
+
it "should post records for update" do
|
|
310
|
+
params = {'update' => @product1}
|
|
311
|
+
do_put "/app/#{Rhoconnect::API_VERSION}/#{@s.name}/1", params, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
312
|
+
last_response.should be_ok
|
|
313
|
+
last_response.body.should == ''
|
|
314
|
+
verify_result("test_update_storage" => {'1'=>@product1})
|
|
293
315
|
end
|
|
294
316
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
317
|
+
it "should post records for update using the old route and have the deprecation warning" do
|
|
318
|
+
params = {'update'=>{'1'=>@product1},:client_id => @c.id,:source_name => @s.name,
|
|
319
|
+
:version => Rhoconnect::SYNC_VERSION}
|
|
320
|
+
do_post "/application", params
|
|
321
|
+
last_response.should be_ok
|
|
322
|
+
last_response.body.should == ''
|
|
323
|
+
last_response.headers["Warning"].index('deprecated').should_not == nil
|
|
324
|
+
verify_result("test_update_storage" => {'1'=>@product1})
|
|
325
|
+
end
|
|
299
326
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
end
|
|
327
|
+
it "should post records for delete" do
|
|
328
|
+
set_doc_state(@c, :cd => @data)
|
|
329
|
+
delete "/app/#{Rhoconnect::API_VERSION}/#{@s.name}/1", {}, { Rhoconnect::CLIENT_ID_HEADER => @c.id }
|
|
330
|
+
last_response.should be_ok
|
|
331
|
+
last_response.body.should == ''
|
|
332
|
+
verify_result("test_delete_storage" => {'1'=>@product1})
|
|
333
|
+
end
|
|
308
334
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
335
|
+
it "should post records for delete using the old route with deprecation warning" do
|
|
336
|
+
params = {'delete'=>{'1'=>@product1},:client_id => @c.id,:source_name => @s.name,
|
|
337
|
+
:version => Rhoconnect::SYNC_VERSION}
|
|
338
|
+
do_post "/api/application/queue_updates", params
|
|
339
|
+
last_response.should be_ok
|
|
340
|
+
last_response.headers["Warning"].index('deprecated').should_not == nil
|
|
341
|
+
last_response.body.should == ''
|
|
342
|
+
verify_result("test_delete_storage" => {'1'=>@product1})
|
|
343
|
+
end
|
|
316
344
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
last_response.headers["Warning"].index('deprecated').should_not == nil
|
|
324
|
-
verify_result("test_update_storage" => {'1'=>@product1})
|
|
325
|
-
end
|
|
345
|
+
it "should handle client posting broken json" do
|
|
346
|
+
broken_json = "{\"foo\":\"bar\"\"}"
|
|
347
|
+
do_post "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", broken_json, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
348
|
+
last_response.status.should == 500
|
|
349
|
+
last_response.body.should == "Server error while processing client data"
|
|
350
|
+
end
|
|
326
351
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
verify_result("test_delete_storage" => {'1'=>@product1})
|
|
333
|
-
end
|
|
352
|
+
it "should not login if login is empty" do
|
|
353
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/login", ''
|
|
354
|
+
last_response.status.should == 401
|
|
355
|
+
last_response.body.should == "Unable to authenticate ''"
|
|
356
|
+
end
|
|
334
357
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
358
|
+
it "should resend page if page exists and no token provided" do
|
|
359
|
+
expected = {'1'=>@product1}
|
|
360
|
+
set_test_data('test_db_storage',{'1'=>@product1,'2'=>@product2,'4'=>@product4})
|
|
361
|
+
params = {'name' => 'iPhone'}
|
|
362
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {:query => params}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
363
|
+
last_response.should be_ok
|
|
364
|
+
last_response.content_type.should =~ /application\/json/
|
|
365
|
+
token = @c.get_value(:page_token)
|
|
366
|
+
last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token
|
|
367
|
+
last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 1.to_s
|
|
368
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION}, {"token"=>token},
|
|
369
|
+
{"count"=>1}, {"progress_count"=>0},{"total_count"=>1},{'insert'=>expected}]
|
|
370
|
+
# this should re-send the page
|
|
371
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {:query => params}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
372
|
+
last_response.should be_ok
|
|
373
|
+
last_response.content_type.should =~ /application\/json/
|
|
374
|
+
token1 = @c.get_value(:page_token)
|
|
375
|
+
token1.should == token
|
|
376
|
+
last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token1
|
|
377
|
+
last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 1.to_s
|
|
378
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION}, {"token"=>token1},
|
|
379
|
+
{"count"=>1}, {"progress_count"=>0},{"total_count"=>1},{'insert'=>expected}]
|
|
380
|
+
# this should ack_token
|
|
381
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {:token => token, :query => params}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
382
|
+
last_response.should be_ok
|
|
383
|
+
last_response.content_type.should =~ /application\/json/
|
|
384
|
+
last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == ""
|
|
385
|
+
last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 0.to_s
|
|
386
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION}, {"token"=>""},
|
|
387
|
+
{"count"=>0}, {"progress_count"=>0},{"total_count"=>1},{}]
|
|
388
|
+
@c.get_data(:page).should == {}
|
|
389
|
+
@c.get_value(:page_token).should be_nil
|
|
390
|
+
end
|
|
344
391
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
392
|
+
it "should get inserts json" do
|
|
393
|
+
data = {'1'=>@product1,'2'=>@product2}
|
|
394
|
+
set_test_data('test_db_storage',data)
|
|
395
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
396
|
+
last_response.should be_ok
|
|
397
|
+
last_response.content_type.should =~ /application\/json/
|
|
398
|
+
token = @c.get_value(:page_token)
|
|
399
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION}, {"token"=>token},
|
|
400
|
+
{"count"=>2}, {"progress_count"=>0},{"total_count"=>2},{'insert'=>data}]
|
|
401
|
+
end
|
|
351
402
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
403
|
+
it "should get inserts json with the old route and show deprecation warning" do
|
|
404
|
+
data = {'1'=>@product1,'2'=>@product2}
|
|
405
|
+
set_test_data('test_db_storage',data)
|
|
406
|
+
get "/application",:client_id => @c.id,:source_name => @s.name,:version => Rhoconnect::SYNC_VERSION
|
|
407
|
+
last_response.should be_ok
|
|
408
|
+
last_response.headers["Warning"].index('deprecated').should_not == nil
|
|
409
|
+
last_response.content_type.should =~ /application\/json/
|
|
410
|
+
token = @c.get_value(:page_token)
|
|
411
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>token},
|
|
412
|
+
{"count"=>2}, {"progress_count"=>0},{"total_count"=>2},{'insert'=>data}]
|
|
413
|
+
end
|
|
357
414
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {:query => params}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
372
|
-
last_response.should be_ok
|
|
373
|
-
last_response.content_type.should =~ /application\/json/
|
|
374
|
-
token1 = @c.get_value(:page_token)
|
|
375
|
-
token1.should == token
|
|
376
|
-
last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token1
|
|
377
|
-
last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 1.to_s
|
|
378
|
-
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION}, {"token"=>token1},
|
|
379
|
-
{"count"=>1}, {"progress_count"=>0},{"total_count"=>1},{'insert'=>expected}]
|
|
380
|
-
# this should ack_token
|
|
381
|
-
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {:token => token, :query => params}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
382
|
-
last_response.should be_ok
|
|
383
|
-
last_response.content_type.should =~ /application\/json/
|
|
384
|
-
last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == ""
|
|
385
|
-
last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 0.to_s
|
|
386
|
-
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION}, {"token"=>""},
|
|
387
|
-
{"count"=>0}, {"progress_count"=>0},{"total_count"=>1},{}]
|
|
388
|
-
@c.get_data(:page).should == {}
|
|
389
|
-
@c.get_value(:page_token).should be_nil
|
|
390
|
-
end
|
|
415
|
+
it "should get inserts json and confirm token" do
|
|
416
|
+
data = {'1'=>@product1,'2'=>@product2}
|
|
417
|
+
set_test_data('test_db_storage',data)
|
|
418
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
419
|
+
last_response.should be_ok
|
|
420
|
+
token = @c.get_value(:page_token)
|
|
421
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>token},
|
|
422
|
+
{"count"=>2}, {"progress_count"=>0}, {"total_count"=>2},{'insert'=>data}]
|
|
423
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {:token => token}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
424
|
+
last_response.should be_ok
|
|
425
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>''},
|
|
426
|
+
{"count"=>0}, {"progress_count"=>0}, {"total_count"=>2},{}]
|
|
427
|
+
end
|
|
391
428
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
429
|
+
# check custom partitions
|
|
430
|
+
it "should return data for user with custom partition name" do
|
|
431
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => 'cus_user1', "password" => 'testpass'
|
|
432
|
+
@c_fields = {
|
|
433
|
+
:device_type => 'Apple',
|
|
434
|
+
:device_pin => 'abcd',
|
|
435
|
+
:device_port => '3333',
|
|
436
|
+
:user_id => 'cus_user1',
|
|
437
|
+
:app_id => @a.id
|
|
438
|
+
}
|
|
439
|
+
@c = Client.create(@c_fields,{:source_name => @s_fields[:name]})
|
|
440
|
+
@s = Source.load('SampleAdapter', {:user_id => 'cus_user1', :app_id => APP_NAME})
|
|
441
|
+
|
|
442
|
+
data = {'1'=>@product1,'2'=>@product2}
|
|
443
|
+
set_test_data('test_db_storage',data)
|
|
444
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
445
|
+
last_response.should be_ok
|
|
446
|
+
token = @c.get_value(:page_token)
|
|
447
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>token},
|
|
448
|
+
{"count"=>2}, {"progress_count"=>0}, {"total_count"=>2},{'insert'=>data}]
|
|
449
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {:token => token}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
450
|
+
last_response.should be_ok
|
|
451
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>''},
|
|
452
|
+
{"count"=>0}, {"progress_count"=>0}, {"total_count"=>2},{}]
|
|
453
|
+
@s.docname(:md).should == "source:#{@s.app.id}:custom_partition:SampleAdapter:md"
|
|
454
|
+
verify_doc_result(@s, :md => data)
|
|
455
|
+
end
|
|
402
456
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
last_response.should be_ok
|
|
408
|
-
last_response.headers["Warning"].index('deprecated').should_not == nil
|
|
409
|
-
last_response.content_type.should =~ /application\/json/
|
|
410
|
-
token = @c.get_value(:page_token)
|
|
411
|
-
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>token},
|
|
412
|
-
{"count"=>2}, {"progress_count"=>0},{"total_count"=>2},{'insert'=>data}]
|
|
413
|
-
end
|
|
457
|
+
it "should create source for dynamic adapter if source_name is unknown" do
|
|
458
|
+
get "/app/#{Rhoconnect::API_VERSION}/Broken", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
459
|
+
last_response.status.should == 200
|
|
460
|
+
end
|
|
414
461
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
last_response.should be_ok
|
|
420
|
-
token = @c.get_value(:page_token)
|
|
421
|
-
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>token},
|
|
422
|
-
{"count"=>2}, {"progress_count"=>0}, {"total_count"=>2},{'insert'=>data}]
|
|
423
|
-
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {:token => token}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
424
|
-
last_response.should be_ok
|
|
425
|
-
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>''},
|
|
426
|
-
{"count"=>0}, {"progress_count"=>0}, {"total_count"=>2},{}]
|
|
427
|
-
end
|
|
462
|
+
it "should create source for dynamic adapter if source_name is unknown using the old route" do
|
|
463
|
+
get "/api/application/query", {:source_name => @s_fields[:name], :client_id => @c.id}
|
|
464
|
+
last_response.status.should == 200
|
|
465
|
+
end
|
|
428
466
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
:device_type => 'Apple',
|
|
434
|
-
:device_pin => 'abcd',
|
|
435
|
-
:device_port => '3333',
|
|
436
|
-
:user_id => 'cus_user1',
|
|
437
|
-
:app_id => @a.id
|
|
438
|
-
}
|
|
439
|
-
@c = Client.create(@c_fields,{:source_name => @s_fields[:name]})
|
|
440
|
-
@s = Source.load('SampleAdapter', {:user_id => 'cus_user1', :app_id => APP_NAME})
|
|
441
|
-
|
|
442
|
-
data = {'1'=>@product1,'2'=>@product2}
|
|
443
|
-
set_test_data('test_db_storage',data)
|
|
444
|
-
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
445
|
-
last_response.should be_ok
|
|
446
|
-
token = @c.get_value(:page_token)
|
|
447
|
-
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>token},
|
|
448
|
-
{"count"=>2}, {"progress_count"=>0}, {"total_count"=>2},{'insert'=>data}]
|
|
449
|
-
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {:token => token}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
450
|
-
last_response.should be_ok
|
|
451
|
-
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>''},
|
|
452
|
-
{"count"=>0}, {"progress_count"=>0}, {"total_count"=>2},{}]
|
|
453
|
-
@s.docname(:md).should == "source:#{@s.app.id}:custom_partition:SampleAdapter:md"
|
|
454
|
-
verify_doc_result(@s, :md => data)
|
|
455
|
-
end
|
|
467
|
+
it "should get deletes json" do
|
|
468
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
|
469
|
+
data = {'1'=>@product1,'2'=>@product2}
|
|
470
|
+
set_test_data('test_db_storage',data)
|
|
456
471
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
472
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
473
|
+
last_response.should be_ok
|
|
474
|
+
token = @c.get_value(:page_token)
|
|
475
|
+
last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token
|
|
476
|
+
last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 2.to_s
|
|
477
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>token},
|
|
478
|
+
{"count"=>2}, {"progress_count"=>0}, {"total_count"=>2},{'insert'=>data}]
|
|
461
479
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
last_response.status.should == 200
|
|
465
|
-
end
|
|
480
|
+
Store.flush_data('test_db_storage')
|
|
481
|
+
@s.read_state.refresh_time = Time.now.to_i
|
|
466
482
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token
|
|
476
|
-
last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 2.to_s
|
|
477
|
-
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>token},
|
|
478
|
-
{"count"=>2}, {"progress_count"=>0}, {"total_count"=>2},{'insert'=>data}]
|
|
479
|
-
|
|
480
|
-
Store.flush_data('test_db_storage')
|
|
481
|
-
@s.read_state.refresh_time = Time.now.to_i
|
|
482
|
-
|
|
483
|
-
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}",{:token => token}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
484
|
-
last_response.should be_ok
|
|
485
|
-
token = @c.get_value(:page_token)
|
|
486
|
-
last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token
|
|
487
|
-
last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 2.to_s
|
|
488
|
-
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>token},
|
|
489
|
-
{"count"=>2}, {"progress_count"=>0}, {"total_count"=>0},{'delete'=>data}]
|
|
490
|
-
end
|
|
483
|
+
get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}",{:token => token}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
484
|
+
last_response.should be_ok
|
|
485
|
+
token = @c.get_value(:page_token)
|
|
486
|
+
last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token
|
|
487
|
+
last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 2.to_s
|
|
488
|
+
JSON.parse(last_response.body).should == [{'version'=>Rhoconnect::SYNC_VERSION},{"token"=>token},
|
|
489
|
+
{"count"=>2}, {"progress_count"=>0}, {"total_count"=>0},{'delete'=>data}]
|
|
490
|
+
end
|
|
491
491
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
492
|
+
it "should get search results using the old route with deprecation warning" do
|
|
493
|
+
sources = [{:name=>'SampleAdapter'}]
|
|
494
|
+
Store.put_data('test_db_storage',@data)
|
|
495
|
+
params = {:client_id => @c.id,:sources => sources,:search => {'name' => 'iPhone'},
|
|
496
|
+
:version => Rhoconnect::SYNC_VERSION}
|
|
497
|
+
get "/api/application/search",params
|
|
498
|
+
last_response.headers['Warning'].index('deprecated').should_not == nil
|
|
499
|
+
last_response.content_type.should =~ /application\/json/
|
|
500
|
+
token = @c.get_value(:search_token)
|
|
501
|
+
last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token
|
|
502
|
+
last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 1.to_s
|
|
503
|
+
JSON.parse(last_response.body).should == [[{'version'=>Rhoconnect::SYNC_VERSION},{'token'=>token},
|
|
504
|
+
{'source'=>sources[0][:name]},{'count'=>1},{'insert'=>{'1'=>@product1}}]]
|
|
505
|
+
end
|
|
506
506
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
507
|
+
it "should get search results" do
|
|
508
|
+
sources = [{:name=>'SampleAdapter'}]
|
|
509
|
+
Store.put_data('test_db_storage',@data)
|
|
510
|
+
params = {:sources => sources,:search => {'name' => 'iPhone'}}
|
|
511
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/search",params, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
512
|
+
last_response.content_type.should =~ /application\/json/
|
|
513
|
+
token = @c.get_value(:search_token)
|
|
514
|
+
JSON.parse(last_response.body).should == [[{'version'=>Rhoconnect::SYNC_VERSION},{'token'=>token},
|
|
515
|
+
{'source'=>sources[0][:name]},{'count'=>1},{'insert'=>{'1'=>@product1}}]]
|
|
516
|
+
end
|
|
517
517
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
518
|
+
it "should get search results with error" do
|
|
519
|
+
sources = [{:name=>'SampleAdapter'}]
|
|
520
|
+
msg = "Error during search"
|
|
521
|
+
error = set_test_data('test_db_storage',@data,msg,'search error')
|
|
522
|
+
params = {:sources => sources,:search => {'name' => 'iPhone'}}
|
|
523
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/search", params, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
524
|
+
JSON.parse(last_response.body).should == [[{'version'=>Rhoconnect::SYNC_VERSION},{'source'=>sources[0][:name]},
|
|
525
|
+
{'search-error'=>{'search-error'=>{'message'=>msg}}}]]
|
|
526
|
+
verify_doc_result(@c, :search => {})
|
|
527
|
+
end
|
|
528
528
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
529
|
+
it "should get multiple source search results" do
|
|
530
|
+
Store.put_data('test_db_storage',@data)
|
|
531
|
+
sources = [{:name=>'SimpleAdapter'},{:name=>'SampleAdapter'}]
|
|
532
|
+
params = {:sources => sources,:search => {'search' => 'bar'}}
|
|
533
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/search", params, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
534
|
+
@c.source_name = 'SimpleAdapter'
|
|
535
|
+
token1 = @c.get_value(:search_token)
|
|
536
|
+
@c.source_name = 'SampleAdapter'
|
|
537
|
+
token = @c.get_value(:search_token)
|
|
538
|
+
JSON.parse(last_response.body).should == [
|
|
539
|
+
[{'version'=>Rhoconnect::SYNC_VERSION},{'token'=>token1},{"source"=>"SimpleAdapter"},
|
|
540
|
+
{"count"=>1}, {"insert"=>{'obj'=>{'foo'=>'bar'}}}],
|
|
541
|
+
[{'version'=>Rhoconnect::SYNC_VERSION},{'token'=>token},{"source"=>"SampleAdapter"},
|
|
542
|
+
{"count"=>1}, {"insert"=>{'1'=>@product1}}]]
|
|
543
|
+
verify_doc_result(@c, {:search => {'1'=>@product1},
|
|
544
|
+
:search_errors => {}})
|
|
545
|
+
end
|
|
546
546
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
547
|
+
it "should handle search for pass through" do
|
|
548
|
+
sources = [{'name'=>'SampleAdapter'}]
|
|
549
|
+
set_state('test_db_storage' => @data)
|
|
550
|
+
@s.pass_through = 'true'
|
|
551
|
+
params = {:sources => sources, :search => {'name' => 'iPhone'}}
|
|
552
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/search", params, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
553
|
+
token = @c.get_value(:search_token)
|
|
554
|
+
JSON.parse(last_response.body).should == [[{'version'=>Rhoconnect::SYNC_VERSION},{'token'=>token},
|
|
555
|
+
{'source'=>sources[0]['name']},{'count'=>1},{'insert'=>{'1'=>@product1}}]]
|
|
556
|
+
verify_doc_result(@c, {:search => {},
|
|
557
|
+
:search_errors => {}})
|
|
558
|
+
end
|
|
559
559
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
560
|
+
it "should handle multiple source search with one source returning nothing" do
|
|
561
|
+
set_test_data('test_db_storage',@data)
|
|
562
|
+
sources = [{'name'=>'SimpleAdapter'},{'name'=>'SampleAdapter'}]
|
|
563
|
+
params = {:sources => sources,:search => {'name' => 'iPhone'}}
|
|
564
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/search", params, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
565
|
+
@c.source_name = 'SimpleAdapter'
|
|
566
|
+
token1 = @c.get_value(:search_token)
|
|
567
|
+
token1.should be_nil
|
|
568
|
+
@c.source_name = 'SampleAdapter'
|
|
569
|
+
token = @c.get_value(:search_token)
|
|
570
|
+
JSON.parse(last_response.body).should == [[],[{'version'=>Rhoconnect::SYNC_VERSION},{'token'=>token},
|
|
571
|
+
{"source"=>"SampleAdapter"},{"count"=>1},{"insert"=>{'1'=>@product1}}]]
|
|
572
|
+
end
|
|
573
573
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
end
|
|
574
|
+
it "should handle search and ack of search results" do
|
|
575
|
+
set_test_data('test_db_storage',@data)
|
|
576
|
+
sources = [{'name'=>'SimpleAdapter'},{'name'=>'SampleAdapter'}]
|
|
577
|
+
params = {:sources => sources,:search => {'search'=>'bar'}}
|
|
578
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/search", params, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
579
|
+
@c.source_name = 'SimpleAdapter'
|
|
580
|
+
token = @c.get_value(:search_token)
|
|
581
|
+
token.should_not be_nil
|
|
582
|
+
sources[0]['token'] = token
|
|
583
|
+
@c.get_data(:search).should == {'obj'=>{'foo'=>'bar'}}
|
|
584
|
+
@c.source_name = 'SampleAdapter'
|
|
585
|
+
token1 = @c.get_value(:search_token)
|
|
586
|
+
token1.should_not be_nil
|
|
587
|
+
sources[1]['token'] = token1
|
|
588
|
+
@c.get_data(:search).should == {'1'=>@product1}
|
|
589
|
+
# do ack on multiple sources
|
|
590
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/search", params, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
591
|
+
@c.source_name = 'SimpleAdapter'
|
|
592
|
+
token = @c.get_value(:search_token)
|
|
593
|
+
token.should be_nil
|
|
594
|
+
@c.get_data(:search).should == {}
|
|
595
|
+
@c.source_name = 'SampleAdapter'
|
|
596
|
+
token1 = @c.get_value(:search_token)
|
|
597
|
+
token1.should be_nil
|
|
598
|
+
@c.get_data(:search).should == {}
|
|
600
599
|
end
|
|
600
|
+
end
|
|
601
601
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
602
|
+
describe "bulk data routes" do
|
|
603
|
+
before(:each) do
|
|
604
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
|
|
605
|
+
end
|
|
606
606
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
607
|
+
after(:each) do
|
|
608
|
+
delete_data_directory
|
|
609
|
+
end
|
|
610
610
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
611
|
+
it "should make initial bulk data request (which creates Resque job) and receive wait (and no deprecation warning)" do
|
|
612
|
+
set_state('test_db_storage' => @data)
|
|
613
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
614
|
+
last_response.should be_ok
|
|
615
|
+
last_response.body.should == {:result => :wait}.to_json
|
|
616
|
+
warning_header = last_response.headers['Warning']
|
|
617
|
+
warning_header.should == nil or warning_header.index('deprecated').should == nil
|
|
618
|
+
Resque.peek(:bulk_data).should == {"args"=>
|
|
619
|
+
[{"data_name"=>File.join(@a_fields[:name],@u_fields[:login],@u_fields[:login])}],
|
|
620
|
+
"class"=>"Rhoconnect::BulkDataJob"}
|
|
621
|
+
end
|
|
622
622
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
623
|
+
it "should make old-way initial bulk data request and receive wait along with deprecation warning" do
|
|
624
|
+
set_state('test_db_storage' => @data)
|
|
625
|
+
get "/application/bulk_data", :partition => :user, :client_id => @c.id
|
|
626
|
+
last_response.should be_ok
|
|
627
|
+
last_response.body.should == {:result => :wait}.to_json
|
|
628
|
+
last_response.headers['Warning'].index('deprecated').should_not == nil
|
|
629
|
+
end
|
|
630
630
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
631
|
+
it "should make old-way initial bulk data request and receive wait along with deprecation warning (Sources sent as String)" do
|
|
632
|
+
set_state('test_db_storage' => @data)
|
|
633
|
+
get "/application/bulk_data?sources=FixedSchemaAdapter,SampleAdapter", :partition => :user, :client_id => @c.id
|
|
634
|
+
last_response.should be_ok
|
|
635
|
+
last_response.body.should == {:result => :wait}.to_json
|
|
636
|
+
last_response.headers['Warning'].index('deprecated').should_not == nil
|
|
637
|
+
end
|
|
638
638
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
639
|
+
it "should receive url when bulk data is available" do
|
|
640
|
+
set_state('test_db_storage' => @data)
|
|
641
|
+
@a.sources.delete('JsSample')
|
|
642
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
643
|
+
do_bulk_data_job("data_name" => bulk_data_docname(@a.id,@u.id))
|
|
644
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
645
|
+
last_response.should be_ok
|
|
646
|
+
data = BulkData.load(bulk_data_docname(@a.id,@u.id))
|
|
647
|
+
last_response.body.should == {:result => :url,
|
|
648
|
+
:url => data.url}.to_json
|
|
649
|
+
validate_db(data,{@s.name => @data, 'FixedSchemaAdapter' => @data})
|
|
650
|
+
end
|
|
651
651
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
652
|
+
it "should download bulk data file" do
|
|
653
|
+
set_state('test_db_storage' => @data)
|
|
654
|
+
@a.sources.delete('JsSample')
|
|
655
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
656
|
+
do_bulk_data_job("data_name" => bulk_data_docname(@a.id,@u.id))
|
|
657
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
658
|
+
JSON.parse(last_response.body).should == {'result' => 'url',
|
|
659
|
+
'url' => BulkData.load(bulk_data_docname(@a.id,@u.id)).url}
|
|
660
|
+
get JSON.parse(last_response.body)["url"]
|
|
661
|
+
last_response.should be_ok
|
|
662
|
+
File.open('test.data','wb') {|f| f.puts last_response.body}
|
|
663
|
+
validate_db_file('test.data',[@s.name,'FixedSchemaAdapter'],{@s.name => @data, 'FixedSchemaAdapter' => @data})
|
|
664
|
+
File.delete('test.data')
|
|
665
|
+
verify_doc_result(@c, :cd => @data)
|
|
666
|
+
verify_doc_result(@s, {:md => @data,
|
|
667
|
+
:md_copy => @data})
|
|
668
|
+
end
|
|
668
669
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
670
|
+
it "should receive nop when no sources are available for partition" do
|
|
671
|
+
set_state('test_db_storage' => @data)
|
|
672
|
+
Source.load('SimpleAdapter',@s_params).partition = :user
|
|
673
|
+
@a.sources.delete('OtherAdapter')
|
|
674
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :app}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
675
|
+
last_response.should be_ok
|
|
676
|
+
last_response.body.should == {:result => :nop}.to_json
|
|
677
|
+
end
|
|
677
678
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
679
|
+
it "should create bulk data job app partition with partition sources" do
|
|
680
|
+
@s.partition = :app
|
|
681
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :app}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
682
|
+
last_response.should be_ok
|
|
683
|
+
last_response.body.should == {:result => :wait}.to_json
|
|
684
|
+
warning_header = last_response.headers['Warning']
|
|
685
|
+
warning_header.should == nil or warning_header.index('deprecated').should == nil
|
|
686
|
+
Resque.peek(:bulk_data).should == {"args"=>
|
|
687
|
+
[{"data_name"=>File.join(@a_fields[:name],@a_fields[:name])}],
|
|
688
|
+
"class"=>"Rhoconnect::BulkDataJob"}
|
|
689
|
+
end
|
|
689
690
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
end
|
|
697
|
-
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
698
|
-
JSON.parse(last_response.body).should == {'result' => 'url', 'url' => ''}
|
|
691
|
+
it "should return empty bulk data url if there are errors in query" do
|
|
692
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
693
|
+
do_bulk_data_job("data_name" => bulk_data_docname(@a.id,@u.id))
|
|
694
|
+
operation = 'query'
|
|
695
|
+
@s.lock(:errors) do
|
|
696
|
+
@s.put_data(:errors,{"#{operation}-error"=>{'message'=>"Some exception message"}}, true)
|
|
699
697
|
end
|
|
698
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
699
|
+
JSON.parse(last_response.body).should == {'result' => 'url', 'url' => ''}
|
|
700
|
+
end
|
|
700
701
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
702
|
+
it "should return bulk data url for completed bulk data app partition" do
|
|
703
|
+
set_state('test_db_storage' => @data)
|
|
704
|
+
@s.partition = :app
|
|
705
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :app}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
706
|
+
do_bulk_data_job("data_name" => bulk_data_docname(@a.id,"*"))
|
|
707
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :app}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
708
|
+
JSON.parse(last_response.body).should == {'result' => 'url',
|
|
709
|
+
'url' => BulkData.load(bulk_data_docname(@a.id,"*")).url}
|
|
710
|
+
@c.source_name = @s.name
|
|
711
|
+
verify_doc_result(@c, :cd => @data)
|
|
712
|
+
verify_doc_result(@s, {:md => @data,
|
|
713
|
+
:md_copy => @data})
|
|
714
|
+
end
|
|
714
715
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
716
|
+
it "should return bulk data url for completed bulk data with bulk_sync_only source" do
|
|
717
|
+
set_state('test_db_storage' => @data)
|
|
718
|
+
@a.sources.delete('JsSample')
|
|
719
|
+
@s.sync_type = :bulk_sync_only
|
|
720
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
721
|
+
do_bulk_data_job("data_name" => bulk_data_docname(@a.id,@u.id))
|
|
722
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
723
|
+
JSON.parse(last_response.body).should == {'result' => 'url',
|
|
724
|
+
'url' => BulkData.load(bulk_data_docname(@a.id,@u.id)).url}
|
|
725
|
+
@c.source_name = @s.name
|
|
726
|
+
verify_doc_result(@c, :cd => {})
|
|
727
|
+
verify_doc_result(@s, {:md => @data,
|
|
728
|
+
:md_copy => {}})
|
|
729
|
+
end
|
|
728
730
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
731
|
+
it "should create bulk data job if no file exists" do
|
|
732
|
+
set_state('test_db_storage' => @data)
|
|
733
|
+
@a.sources.delete('JsSample')
|
|
734
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
735
|
+
do_bulk_data_job("data_name" => bulk_data_docname(@a.id,@u.id))
|
|
736
|
+
data = BulkData.load(bulk_data_docname(@a.id,@u.id))
|
|
737
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
738
|
+
JSON.parse(last_response.body).should == {'result' => 'url', 'url' => data.url}
|
|
739
|
+
File.delete(data.dbfile)
|
|
740
|
+
post "/rc/#{Rhoconnect::API_VERSION}/app/bulk_data", {:partition => :user}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
741
|
+
JSON.parse(last_response.body).should == {'result' => 'wait'}
|
|
742
|
+
Resque.peek(:bulk_data).should == {"args"=>
|
|
743
|
+
[{"data_name"=>bulk_data_docname(@a.id,@u.id)}], "class"=>"Rhoconnect::BulkDataJob"}
|
|
742
744
|
end
|
|
745
|
+
end
|
|
743
746
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
end
|
|
747
|
+
describe "blob sync" do
|
|
748
|
+
before(:each) do
|
|
749
|
+
do_post "/rc/#{Rhoconnect::API_VERSION}/app/login", "login" => @u.login, "password" => 'testpass'
|
|
750
|
+
end
|
|
751
|
+
it "should upload blob in multipart post" do
|
|
752
|
+
file1,file2 = 'upload1.txt','upload2.txt'
|
|
753
|
+
@product1['txtfile-rhoblob'] = file1
|
|
754
|
+
@product1['_id'] = 'tempobj1'
|
|
755
|
+
@product2['txtfile-rhoblob'] = file2
|
|
756
|
+
@product2['_id'] = 'tempobj2'
|
|
757
|
+
cud = {'create'=>{'1'=>@product1,'2'=>@product2},
|
|
758
|
+
:blob_fields => ['txtfile-rhoblob']}.to_json
|
|
759
|
+
post "/app/#{Rhoconnect::API_VERSION}/#{@s.name}",
|
|
760
|
+
{:cud => cud,'txtfile-rhoblob-1' =>
|
|
761
|
+
Rack::Test::UploadedFile.new(File.join(File.dirname(__FILE__),'..','testdata',file1), "application/octet-stream"),
|
|
762
|
+
'txtfile-rhoblob-2' =>
|
|
763
|
+
Rack::Test::UploadedFile.new(File.join(File.dirname(__FILE__),'..','testdata',file2), "application/octet-stream")}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
|
|
764
|
+
last_response.should be_ok
|
|
765
|
+
data = Store.get_data('test_create_storage')
|
|
766
|
+
data.size.should == 2
|
|
767
|
+
data.each do |id,obj|
|
|
768
|
+
File.exists?(obj['txtfile-rhoblob']).should == true
|
|
767
769
|
end
|
|
768
770
|
end
|
|
769
771
|
end
|