rhosync 2.1.3 → 2.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +9 -0
- data/lib/rhosync/api/list_sources.rb +1 -1
- data/lib/rhosync/jobs/bulk_data_job.rb +2 -2
- data/lib/rhosync/model.rb +10 -10
- data/lib/rhosync/server.rb +28 -12
- data/lib/rhosync/source.rb +110 -34
- data/lib/rhosync/version.rb +1 -1
- data/lib/rhosync.rb +3 -7
- data/spec/api/get_source_params_spec.rb +7 -5
- data/spec/api/push_deletes_spec.rb +1 -0
- data/spec/api/push_objects_spec.rb +1 -0
- data/spec/api/rhosync_api_spec.rb +8 -5
- data/spec/bulk_data/bulk_data_spec.rb +4 -0
- data/spec/client_spec.rb +4 -0
- data/spec/client_sync_spec.rb +11 -10
- data/spec/document_spec.rb +4 -0
- data/spec/jobs/source_job_spec.rb +4 -0
- data/spec/server/server_spec.rb +6 -0
- data/spec/source_adapter_spec.rb +2 -0
- data/spec/source_spec.rb +27 -7
- data/spec/source_sync_spec.rb +3 -2
- data/spec/spec_helper.rb +2 -3
- data/spec/sync_states_spec.rb +1 -0
- metadata +5 -7
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 2.1.6
|
2
|
+
* #13830841 - fixed issue where current_user.login doesn't match @source.user_id
|
3
|
+
|
4
|
+
## 2.1.5
|
5
|
+
* #13578473 - fixed "undefined method `user_id' for nil:NilClass" error in server.rb
|
6
|
+
|
7
|
+
## 2.1.4
|
8
|
+
* #13354369 - bug fix "rhosync bootstrap process shouldn't store sources in redis"
|
9
|
+
|
1
10
|
## 2.1.3
|
2
11
|
* #4398193 - ping should only send push messages to unique device pin list
|
3
12
|
* #13022667 - settings.yml doesn't work for setting external Redis instances
|
@@ -6,7 +6,7 @@ Server.api :list_sources do |params,user|
|
|
6
6
|
res = []
|
7
7
|
sources.each do |name|
|
8
8
|
s = Source.load(name,{:app_id => APP_NAME,:user_id => '*'})
|
9
|
-
if s.partition_type and s.partition_type == params[:partition_type]
|
9
|
+
if s.partition_type and s.partition_type == params[:partition_type].to_sym
|
10
10
|
res << name
|
11
11
|
end
|
12
12
|
end
|
@@ -122,8 +122,8 @@ module Rhosync
|
|
122
122
|
values (?,?,?,?,?,?,?,?,?,?)") do |stmt|
|
123
123
|
sources_refs.each do |source_name,ref|
|
124
124
|
s = ref[:source]
|
125
|
-
stmt.execute(s.source_id,s.name,s.priority,s.partition_type,
|
126
|
-
s.sync_type,refs_to_s(ref[:refs]),s.get_value(:metadata),s.schema,s.blob_attribs,s.has_many)
|
125
|
+
stmt.execute(s.source_id,s.name,s.priority,s.partition_type.to_s,
|
126
|
+
s.sync_type.to_s,refs_to_s(ref[:refs]),s.get_value(:metadata),s.schema,s.blob_attribs,s.has_many)
|
127
127
|
end
|
128
128
|
end
|
129
129
|
end
|
data/lib/rhosync/model.rb
CHANGED
@@ -59,14 +59,15 @@ module Rhosync
|
|
59
59
|
res
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
62
|
+
# TODO: not used anymore
|
63
|
+
# def update(attribs)
|
64
|
+
# self.class.fields.each do |field|
|
65
|
+
# if field[:name] != 'name' and field[:name] != 'rho__id'
|
66
|
+
# redis.del field_key(field[:name])
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
# self.class.populate_attributes(self,attribs)
|
70
|
+
# end
|
70
71
|
|
71
72
|
protected
|
72
73
|
def prefix #:nodoc:
|
@@ -111,8 +112,7 @@ module Rhosync
|
|
111
112
|
end
|
112
113
|
|
113
114
|
def load(id, params={})
|
114
|
-
|
115
|
-
populate_attributes(self.with_key(id),params)
|
115
|
+
populate_attributes(self.with_key(id),params) if self.is_exist?(id)
|
116
116
|
end
|
117
117
|
|
118
118
|
def populate_attributes(obj,attribs)
|
data/lib/rhosync/server.rb
CHANGED
@@ -88,7 +88,13 @@ module Rhosync
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def api_user
|
91
|
-
request_action == 'get_api_token'
|
91
|
+
if request_action == 'get_api_token'
|
92
|
+
current_user
|
93
|
+
else
|
94
|
+
u = ApiToken.load(params[:api_token])
|
95
|
+
raise "Wrong API token - #{params[:api_token].inspect}" unless u
|
96
|
+
u.user
|
97
|
+
end
|
92
98
|
end
|
93
99
|
|
94
100
|
def current_app
|
@@ -113,7 +119,9 @@ module Rhosync
|
|
113
119
|
if @client.nil? and params[:client_id]
|
114
120
|
@client = Client.load(params[:client_id].to_s,
|
115
121
|
params[:source_name] ? {:source_name => current_source.name} : {:source_name => '*'})
|
116
|
-
@client
|
122
|
+
if @client and current_user and @client.user_id != current_user.login
|
123
|
+
@client.switch_user(current_user.login)
|
124
|
+
end
|
117
125
|
@client
|
118
126
|
end
|
119
127
|
end
|
@@ -204,25 +212,33 @@ module Rhosync
|
|
204
212
|
end
|
205
213
|
|
206
214
|
post '/application/clientlogin' do
|
207
|
-
|
208
|
-
|
215
|
+
catch_all do
|
216
|
+
logout
|
217
|
+
do_login
|
218
|
+
end
|
209
219
|
end
|
210
220
|
|
211
221
|
get '/application/clientcreate' do
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
222
|
+
catch_all do
|
223
|
+
content_type :json
|
224
|
+
client = Client.create(:user_id => current_user.id,:app_id => current_app.id)
|
225
|
+
client.update_fields(params)
|
226
|
+
{ "client" => { "client_id" => client.id.to_s } }.merge!(source_config).to_json
|
227
|
+
end
|
216
228
|
end
|
217
229
|
|
218
230
|
post '/application/clientregister' do
|
219
|
-
|
220
|
-
|
231
|
+
catch_all do
|
232
|
+
current_client.update_fields(params)
|
233
|
+
source_config.to_json
|
234
|
+
end
|
221
235
|
end
|
222
236
|
|
223
237
|
get '/application/clientreset' do
|
224
|
-
|
225
|
-
|
238
|
+
catch_all do
|
239
|
+
ClientSync.reset(current_client)
|
240
|
+
source_config.to_json
|
241
|
+
end
|
226
242
|
end
|
227
243
|
|
228
244
|
# Member routes
|
data/lib/rhosync/source.rb
CHANGED
@@ -1,51 +1,117 @@
|
|
1
1
|
module Rhosync
|
2
|
-
class
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
2
|
+
class MemoryModel
|
3
|
+
@@model_data = {}
|
4
|
+
@@string_fields = []
|
5
|
+
@@integer_fields = []
|
6
|
+
attr_accessor :id
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :validates_presence
|
10
|
+
|
11
|
+
def define_fields(string_fields = [], integer_fields = [])
|
12
|
+
@@string_fields,@@integer_fields = string_fields,integer_fields
|
13
|
+
integer_fields.each do |attrib|
|
14
|
+
define_method("#{attrib}=") do |value|
|
15
|
+
value = (value.nil?) ? nil : value.to_i
|
16
|
+
instance_variable_set(:"@#{attrib}", value)
|
17
|
+
end
|
18
|
+
define_method("#{attrib}") do
|
19
|
+
instance_variable_get(:"@#{attrib}")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
string_fields.each do |attrib|
|
23
|
+
define_method("#{attrib}=") do |value|
|
24
|
+
instance_variable_set(:"@#{attrib}", value)
|
25
|
+
end
|
26
|
+
define_method("#{attrib}") do
|
27
|
+
instance_variable_get(:"@#{attrib}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
@@string_fields << :id
|
31
|
+
@@string_fields << :rho__id
|
32
|
+
end
|
33
|
+
|
34
|
+
def validates_presence_of(*names)
|
35
|
+
self.validates_presence ||= []
|
36
|
+
names.each do |name|
|
37
|
+
self.validates_presence << name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def is_exist?(id)
|
42
|
+
!@@model_data[id.to_sym].nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
def class_prefix(classname)
|
46
|
+
classname.to_s.
|
47
|
+
sub(%r{(.*::)}, '').
|
48
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
49
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
50
|
+
downcase
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_array
|
55
|
+
res = []
|
56
|
+
@@string_fields.each do |field|
|
57
|
+
res << {"name" => field, "value" => send(field.to_sym), "type" => "string"}
|
58
|
+
end
|
59
|
+
@@integer_fields.each do |field|
|
60
|
+
res << {"name" => field, "value" => send(field.to_sym), "type" => "integer"}
|
61
|
+
end
|
62
|
+
res
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Source < MemoryModel
|
67
|
+
attr_accessor :app_id, :user_id, :rho__id
|
68
|
+
|
69
|
+
validates_presence_of :name
|
20
70
|
|
21
71
|
include Document
|
22
72
|
include LockOps
|
73
|
+
|
74
|
+
# source fields
|
75
|
+
define_fields([:name, :url, :login, :password, :callback_url, :partition_type, :sync_type,
|
76
|
+
:queue, :query_queue, :cud_queue, :belongs_to, :has_many], [:source_id, :priority, :poll_interval])
|
77
|
+
|
78
|
+
def initialize(fields)
|
79
|
+
fields.each do |name,value|
|
80
|
+
arg = "#{name}=".to_sym
|
81
|
+
self.send(arg, value) if self.respond_to?(arg)
|
82
|
+
end
|
83
|
+
end
|
23
84
|
|
24
85
|
def self.set_defaults(fields)
|
25
86
|
fields[:url] ||= ''
|
26
87
|
fields[:login] ||= ''
|
27
88
|
fields[:password] ||= ''
|
28
89
|
fields[:priority] ||= 3
|
29
|
-
fields[:partition_type]
|
90
|
+
fields[:partition_type] = fields[:partition_type] ? fields[:partition_type].to_sym : :user
|
30
91
|
fields[:poll_interval] ||= 300
|
31
|
-
fields[:sync_type]
|
92
|
+
fields[:sync_type] = fields[:sync_type] ? fields[:sync_type].to_sym : :incremental
|
93
|
+
fields[:id] = fields[:name]
|
94
|
+
fields[:rho__id] = fields[:name]
|
32
95
|
fields[:belongs_to] = fields[:belongs_to].to_json if fields[:belongs_to]
|
33
96
|
fields[:schema] = fields[:schema].to_json if fields[:schema]
|
34
97
|
end
|
35
98
|
|
36
99
|
def self.create(fields,params)
|
37
100
|
fields = fields.with_indifferent_access # so we can access hash keys as symbols
|
38
|
-
# validate_attributes(params)
|
39
|
-
fields[:id] = fields[:name]
|
40
101
|
set_defaults(fields)
|
41
|
-
|
102
|
+
obj = new(fields)
|
103
|
+
obj.assign_args(params)
|
104
|
+
@@model_data[obj.rho__id.to_sym] = obj
|
105
|
+
obj
|
42
106
|
end
|
43
107
|
|
44
|
-
def self.load(
|
108
|
+
def self.load(obj_id,params)
|
45
109
|
validate_attributes(params)
|
46
|
-
|
110
|
+
obj = @@model_data[obj_id.to_sym]
|
111
|
+
obj.assign_args(params) if obj
|
112
|
+
obj
|
47
113
|
end
|
48
|
-
|
114
|
+
|
49
115
|
def self.update_associations(sources)
|
50
116
|
params = {:app_id => APP_NAME,:user_id => '*'}
|
51
117
|
sources.each { |source| Source.load(source, params).has_many = nil }
|
@@ -58,7 +124,8 @@ module Rhosync
|
|
58
124
|
attrib = entry.keys[0]
|
59
125
|
model = entry[attrib]
|
60
126
|
owner = Source.load(model, params)
|
61
|
-
owner.has_many
|
127
|
+
owner.has_many ||= ''
|
128
|
+
owner.has_many = owner.has_many+',' if owner.has_many.length > 0
|
62
129
|
owner.has_many += [source,attrib].join(',')
|
63
130
|
end
|
64
131
|
else
|
@@ -68,6 +135,16 @@ module Rhosync
|
|
68
135
|
end
|
69
136
|
end
|
70
137
|
|
138
|
+
def self.delete_all
|
139
|
+
@@model_data.each { |k,v| v.delete }
|
140
|
+
@@model_data = {}
|
141
|
+
end
|
142
|
+
|
143
|
+
def assign_args(params)
|
144
|
+
self.user_id = params[:user_id]
|
145
|
+
self.app_id = params[:app_id]
|
146
|
+
end
|
147
|
+
|
71
148
|
def blob_attribs
|
72
149
|
return '' unless self.schema
|
73
150
|
schema = JSON.parse(self.schema)
|
@@ -82,7 +159,7 @@ module Rhosync
|
|
82
159
|
def update(fields)
|
83
160
|
fields = fields.with_indifferent_access # so we can access hash keys as symbols
|
84
161
|
self.class.set_defaults(fields)
|
85
|
-
super(fields)
|
162
|
+
#super(fields)
|
86
163
|
end
|
87
164
|
|
88
165
|
def clone(src_doctype,dst_doctype)
|
@@ -91,12 +168,12 @@ module Rhosync
|
|
91
168
|
|
92
169
|
# Return the user associated with a source
|
93
170
|
def user
|
94
|
-
@user
|
171
|
+
@user = User.load(self.user_id)
|
95
172
|
end
|
96
173
|
|
97
174
|
# Return the app the source belongs to
|
98
175
|
def app
|
99
|
-
@app
|
176
|
+
@app = App.load(self.app_id)
|
100
177
|
end
|
101
178
|
|
102
179
|
def schema
|
@@ -106,8 +183,7 @@ module Rhosync
|
|
106
183
|
def read_state
|
107
184
|
id = {:app_id => self.app_id,:user_id => user_by_partition,
|
108
185
|
:source_name => self.name}
|
109
|
-
|
110
|
-
@read_state ||= ReadState.create(id)
|
186
|
+
ReadState.load(id) || ReadState.create(id)
|
111
187
|
end
|
112
188
|
|
113
189
|
def doc_suffix(doctype)
|
@@ -116,7 +192,7 @@ module Rhosync
|
|
116
192
|
|
117
193
|
def delete
|
118
194
|
flash_data('*')
|
119
|
-
|
195
|
+
@@model_data.delete(rho__id.to_sym) if rho__id
|
120
196
|
end
|
121
197
|
|
122
198
|
def partition
|
@@ -144,7 +220,7 @@ module Rhosync
|
|
144
220
|
end
|
145
221
|
yield client_id,params if need_refresh
|
146
222
|
end
|
147
|
-
|
223
|
+
|
148
224
|
private
|
149
225
|
def self.validate_attributes(params)
|
150
226
|
raise ArgumentError.new('Missing required attribute user_id') unless params[:user_id]
|
data/lib/rhosync/version.rb
CHANGED
data/lib/rhosync.rb
CHANGED
@@ -91,15 +91,11 @@ module Rhosync
|
|
91
91
|
app = App.create(:name => app_name)
|
92
92
|
end
|
93
93
|
sources = config[:sources] || []
|
94
|
+
Source.delete_all
|
94
95
|
sources.each do |source_name,fields|
|
95
96
|
check_for_schema_field!(fields)
|
96
|
-
|
97
|
-
|
98
|
-
s.update(fields)
|
99
|
-
else
|
100
|
-
fields[:name] = source_name
|
101
|
-
Source.create(fields,{:app_id => app.name})
|
102
|
-
end
|
97
|
+
fields[:name] = source_name
|
98
|
+
Source.create(fields,{:app_id => app.name})
|
103
99
|
unless app.sources.members.include?(source_name)
|
104
100
|
app.sources << source_name
|
105
101
|
end
|
@@ -5,13 +5,14 @@ describe "RhosyncApiGetSourceParams" do
|
|
5
5
|
|
6
6
|
it "should list source attributes" do
|
7
7
|
post "/api/get_source_params", {:api_token => @api_token, :source_id =>"SampleAdapter"}
|
8
|
-
JSON.parse(last_response.body).
|
8
|
+
result = JSON.parse(last_response.body).sort {|x,y| y["name"] <=> x["name"] }
|
9
|
+
result.should == [
|
9
10
|
{"name"=>"rho__id", "value"=>"SampleAdapter", "type"=>"string"},
|
10
11
|
{"name"=>"source_id", "value"=>nil, "type"=>"integer"},
|
11
12
|
{"name"=>"name", "value"=>"SampleAdapter", "type"=>"string"},
|
12
|
-
{"name"=>"url", "value"=>"", "type"=>"string"},
|
13
|
-
{"name"=>"login", "value"=>"", "type"=>"string"},
|
14
|
-
{"name"=>"password", "value"=>"", "type"=>"string"},
|
13
|
+
{"name"=>"url", "value"=>"http://example.com", "type"=>"string"},
|
14
|
+
{"name"=>"login", "value"=>"testuser", "type"=>"string"},
|
15
|
+
{"name"=>"password", "value"=>"testpass", "type"=>"string"},
|
15
16
|
{"name"=>"priority", "value"=>3, "type"=>"integer"},
|
16
17
|
{"name"=>"callback_url", "value"=>nil, "type"=>"string"},
|
17
18
|
{"name"=>"poll_interval", "value"=>300, "type"=>"integer"},
|
@@ -19,9 +20,10 @@ describe "RhosyncApiGetSourceParams" do
|
|
19
20
|
{"name"=>"sync_type", "value"=>"incremental", "type"=>"string"},
|
20
21
|
{"name"=>"belongs_to", "type"=>"string", "value"=>nil},
|
21
22
|
{"name"=>"has_many", "type"=>"string", "value"=>"FixedSchemaAdapter,brand"},
|
23
|
+
{"name"=>"id", "value"=>"SampleAdapter", "type"=>"string"},
|
22
24
|
{"name"=>"queue", "value"=>nil, "type"=>"string"},
|
23
25
|
{"name"=>"query_queue", "value"=>nil, "type"=>"string"},
|
24
|
-
{"name"=>"cud_queue", "value"=>nil, "type"=>"string"}]
|
26
|
+
{"name"=>"cud_queue", "value"=>nil, "type"=>"string"}].sort {|x,y| y["name"] <=> x["name"] }
|
25
27
|
end
|
26
28
|
|
27
29
|
end
|
@@ -5,6 +5,7 @@ describe "RhosyncApiPushDeletes" do
|
|
5
5
|
|
6
6
|
it "should delete object from :md" do
|
7
7
|
data = {'1' => @product1, '2' => @product2, '3' => @product3}
|
8
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
8
9
|
set_state(@s.docname(:md) => data)
|
9
10
|
data.delete('2')
|
10
11
|
post "/api/push_deletes", :api_token => @api_token,
|
@@ -14,6 +14,7 @@ describe "RhosyncApiPushObjects" do
|
|
14
14
|
it "should push updates to existing objects to rhosync's :md" do
|
15
15
|
data = {'1' => @product1, '2' => @product2, '3' => @product3}
|
16
16
|
update = {'price' => '0.99', 'new_field' => 'value'}
|
17
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
17
18
|
set_state(@s.docname(:md) => data)
|
18
19
|
update.each do |key,value|
|
19
20
|
data['2'][key] = value
|
@@ -152,13 +152,15 @@ describe "RhosyncApi" do
|
|
152
152
|
end
|
153
153
|
|
154
154
|
it "should list source attributes using direct api call" do
|
155
|
-
RhosyncApi::get_source_params(
|
155
|
+
result = RhosyncApi::get_source_params(
|
156
|
+
'',@api_token,"SampleAdapter").sort {|x,y| y["name"] <=> x["name"] }
|
157
|
+
result.should == [
|
156
158
|
{"name"=>"rho__id", "value"=>"SampleAdapter", "type"=>"string"},
|
157
159
|
{"name"=>"source_id", "value"=>nil, "type"=>"integer"},
|
158
160
|
{"name"=>"name", "value"=>"SampleAdapter", "type"=>"string"},
|
159
|
-
{"name"=>"url", "value"=>"", "type"=>"string"},
|
160
|
-
{"name"=>"login", "value"=>"", "type"=>"string"},
|
161
|
-
{"name"=>"password", "value"=>"", "type"=>"string"},
|
161
|
+
{"name"=>"url", "value"=>"http://example.com", "type"=>"string"},
|
162
|
+
{"name"=>"login", "value"=>"testuser", "type"=>"string"},
|
163
|
+
{"name"=>"password", "value"=>"testpass", "type"=>"string"},
|
162
164
|
{"name"=>"priority", "value"=>3, "type"=>"integer"},
|
163
165
|
{"name"=>"callback_url", "value"=>nil, "type"=>"string"},
|
164
166
|
{"name"=>"poll_interval", "value"=>300, "type"=>"integer"},
|
@@ -166,9 +168,10 @@ describe "RhosyncApi" do
|
|
166
168
|
{"name"=>"sync_type", "value"=>"incremental", "type"=>"string"},
|
167
169
|
{"name"=>"belongs_to", "type"=>"string", "value"=>nil},
|
168
170
|
{"name"=>"has_many", "type"=>"string", "value"=>"FixedSchemaAdapter,brand"},
|
171
|
+
{"name"=>"id", "value"=>"SampleAdapter", "type"=>"string"},
|
169
172
|
{"name"=>"queue", "value"=>nil, "type"=>"string"},
|
170
173
|
{"name"=>"query_queue", "value"=>nil, "type"=>"string"},
|
171
|
-
{"name"=>"cud_queue", "value"=>nil, "type"=>"string"}]
|
174
|
+
{"name"=>"cud_queue", "value"=>nil, "type"=>"string"}].sort {|x,y| y["name"] <=> x["name"] }
|
172
175
|
end
|
173
176
|
|
174
177
|
it "should list source attributes using rest call" do
|
data/spec/client_spec.rb
CHANGED
@@ -7,6 +7,10 @@ describe "Client" do
|
|
7
7
|
it_should_behave_like "SpecBootstrapHelper"
|
8
8
|
it_should_behave_like "SourceAdapterHelper"
|
9
9
|
|
10
|
+
before(:each) do
|
11
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
12
|
+
end
|
13
|
+
|
10
14
|
it "should create client with fields" do
|
11
15
|
@c.id.length.should == 32
|
12
16
|
@c.device_type.should == @c_fields[:device_type]
|
data/spec/client_sync_spec.rb
CHANGED
@@ -10,6 +10,7 @@ describe "ClientSync" do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
before(:each) do
|
13
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
13
14
|
@cs = ClientSync.new(@s,@c,2)
|
14
15
|
end
|
15
16
|
|
@@ -341,7 +342,7 @@ describe "ClientSync" do
|
|
341
342
|
token1.should be_nil
|
342
343
|
Store.get_data(@c.docname(:search)).should == {}
|
343
344
|
end
|
344
|
-
|
345
|
+
|
345
346
|
end
|
346
347
|
|
347
348
|
describe "page methods" do
|
@@ -354,40 +355,40 @@ describe "ClientSync" do
|
|
354
355
|
Store.get_value(@cs.client.docname(:cd_size)).to_i.should == 0
|
355
356
|
Store.get_data(@cs.client.docname(:page)).should == @expected
|
356
357
|
end
|
357
|
-
|
358
|
+
|
358
359
|
it "appends diff to the client document" do
|
359
360
|
@cd = {'3'=>@product3}
|
360
361
|
Store.put_data(@c.docname(:cd),@cd)
|
361
362
|
Store.get_data(@c.docname(:cd)).should == @cd
|
362
|
-
|
363
|
+
|
363
364
|
@page = {'1'=>@product1,'2'=>@product2}
|
364
365
|
@expected = {'1'=>@product1,'2'=>@product2,'3'=>@product3}
|
365
|
-
|
366
|
+
|
366
367
|
Store.put_data(@c.docname(:cd),@page,true).should == true
|
367
368
|
Store.get_data(@c.docname(:cd)).should == @expected
|
368
369
|
end
|
369
|
-
|
370
|
+
|
370
371
|
it "should return deleted objects in the client document" do
|
371
372
|
Store.put_data(@s.docname(:md),@data).should == true
|
372
373
|
Store.get_data(@s.docname(:md)).should == @data
|
373
|
-
|
374
|
+
|
374
375
|
@cd = {'1'=>@product1,'2'=>@product2,'3'=>@product3,'4'=>@product4}
|
375
376
|
Store.put_data(@cs.client.docname(:cd),@cd)
|
376
377
|
Store.get_data(@cs.client.docname(:cd)).should == @cd
|
377
|
-
|
378
|
+
|
378
379
|
@expected = {'4'=>@product4}
|
379
380
|
@cs.compute_deleted_page.should == @expected
|
380
381
|
Store.get_data(@cs.client.docname(:delete_page)).should == @expected
|
381
382
|
end
|
382
|
-
|
383
|
+
|
383
384
|
it "should delete objects from client document" do
|
384
385
|
Store.put_data(@s.docname(:md),@data).should == true
|
385
386
|
Store.get_data(@s.docname(:md)).should == @data
|
386
|
-
|
387
|
+
|
387
388
|
@cd = {'1'=>@product1,'2'=>@product2,'3'=>@product3,'4'=>@product4}
|
388
389
|
Store.put_data(@cs.client.docname(:cd),@cd)
|
389
390
|
Store.get_data(@cs.client.docname(:cd)).should == @cd
|
390
|
-
|
391
|
+
|
391
392
|
Store.delete_data(@cs.client.docname(:cd),@cs.compute_deleted_page).should == true
|
392
393
|
Store.get_data(@cs.client.docname(:cd)).should == @data
|
393
394
|
end
|
data/spec/document_spec.rb
CHANGED
@@ -4,6 +4,10 @@ describe "Document" do
|
|
4
4
|
it_should_behave_like "SpecBootstrapHelper"
|
5
5
|
it_should_behave_like "SourceAdapterHelper"
|
6
6
|
|
7
|
+
before(:each) do
|
8
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
9
|
+
end
|
10
|
+
|
7
11
|
it "should generate client docname" do
|
8
12
|
@c.docname(:foo).should == "client:#{@a.id}:#{@u.id}:#{@c.id}:#{@s_fields[:name]}:foo"
|
9
13
|
end
|
@@ -4,6 +4,10 @@ describe "SourceJob" do
|
|
4
4
|
it_should_behave_like "SpecBootstrapHelper"
|
5
5
|
it_should_behave_like "SourceAdapterHelper"
|
6
6
|
|
7
|
+
before(:each) do
|
8
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
9
|
+
end
|
10
|
+
|
7
11
|
it "should perform process_query" do
|
8
12
|
set_state('test_db_storage' => @data)
|
9
13
|
SourceJob.perform('query',@s.id,@s.app_id,@s.user_id,nil,nil)
|
data/spec/server/server_spec.rb
CHANGED
@@ -187,6 +187,12 @@ describe "Server" do
|
|
187
187
|
get "/application",:client_id => @c.id,:source_name => @s.name,:version => ClientSync::VERSION
|
188
188
|
JSON.parse(last_response.body).last['insert'].should == data
|
189
189
|
end
|
190
|
+
|
191
|
+
it "should return error on routes if client doesn't exist" do
|
192
|
+
get "/application",:client_id => "missingclient",:source_name => @s.name,:version => ClientSync::VERSION
|
193
|
+
last_response.body.should == "Unknown client"
|
194
|
+
last_response.status.should == 500
|
195
|
+
end
|
190
196
|
end
|
191
197
|
|
192
198
|
describe "source routes" do
|
data/spec/source_adapter_spec.rb
CHANGED
@@ -16,6 +16,7 @@ describe "SourceAdapter" do
|
|
16
16
|
it_should_behave_like "SourceAdapterHelper"
|
17
17
|
|
18
18
|
before(:each) do
|
19
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
19
20
|
@s.name = 'SimpleAdapter'
|
20
21
|
@sa = SourceAdapter.create(@s,nil)
|
21
22
|
end
|
@@ -37,6 +38,7 @@ describe "SourceAdapter" do
|
|
37
38
|
@s_fields[:name] = 'Broken'
|
38
39
|
broken_source = Source.create(@s_fields,@s_params)
|
39
40
|
lambda { SourceAdapter.create(broken_source) }.should raise_error(Exception)
|
41
|
+
broken_source.delete
|
40
42
|
end
|
41
43
|
|
42
44
|
it "should create SourceAdapter with trailing spaces" do
|
data/spec/source_spec.rb
CHANGED
@@ -4,6 +4,10 @@ describe "Source" do
|
|
4
4
|
it_should_behave_like "SpecBootstrapHelper"
|
5
5
|
it_should_behave_like "SourceAdapterHelper"
|
6
6
|
|
7
|
+
before(:each) do
|
8
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
9
|
+
end
|
10
|
+
|
7
11
|
it "should create and load source with @s_fields and @s_params" do
|
8
12
|
@s.name.should == @s_fields[:name]
|
9
13
|
@s.url.should == @s_fields[:url]
|
@@ -30,6 +34,7 @@ describe "Source" do
|
|
30
34
|
@s1.poll_interval.should == 300
|
31
35
|
@s1.app_id.should == @s_params[:app_id]
|
32
36
|
@s1.user_id.should == @s_params[:user_id]
|
37
|
+
# puts "#{@s1.inspect()}" # FIXME:
|
33
38
|
end
|
34
39
|
|
35
40
|
it "should create source with user" do
|
@@ -40,17 +45,31 @@ describe "Source" do
|
|
40
45
|
@s.app.name.should == @a_fields[:name]
|
41
46
|
@s.docname(:md).should == "source:#{@s.app.id}:#{@u.id}:#{@s_fields[:name]}:md"
|
42
47
|
end
|
48
|
+
|
49
|
+
it 'should return values that set by setter method' do
|
50
|
+
@s.login = "shurab"
|
51
|
+
@s.login.should == "shurab"
|
52
|
+
@s.poll_interval = 350
|
53
|
+
@s.poll_interval.should == 350
|
54
|
+
@s.poll_interval = nil
|
55
|
+
@s.poll_interval.should == nil
|
56
|
+
@s.url = nil
|
57
|
+
@s.url.should be_nil
|
58
|
+
end
|
43
59
|
|
44
60
|
it "should delete source" do
|
45
61
|
@s.delete
|
46
62
|
Source.is_exist?(@s_fields[:name]).should == false
|
63
|
+
@s = Source.create(@s_fields,@s_params)
|
47
64
|
end
|
48
65
|
|
49
66
|
it "should delete master and all documents associated with source" do
|
50
|
-
|
67
|
+
key = @s.docname('*')
|
68
|
+
set_state(key => @data)
|
51
69
|
@s.delete
|
52
|
-
verify_result(
|
53
|
-
Store.db.keys(
|
70
|
+
verify_result(key => {})
|
71
|
+
Store.db.keys(key).should == []
|
72
|
+
@s = Source.create(@s_fields,@s_params)
|
54
73
|
end
|
55
74
|
|
56
75
|
it "should create source with default partition user" do
|
@@ -68,16 +87,17 @@ describe "Source" do
|
|
68
87
|
@s_fields[:queue] = :default
|
69
88
|
@s_fields[:query_queue] = :query
|
70
89
|
@s_fields[:cud_queue] = :cud
|
71
|
-
Source.create(@s_fields,@s_params)
|
90
|
+
@s = Source.create(@s_fields,@s_params)
|
72
91
|
s = Source.load(@s_fields[:name],@s_params)
|
73
|
-
s.queue.should ==
|
74
|
-
s.query_queue.should ==
|
75
|
-
s.cud_queue.should ==
|
92
|
+
s.queue.should == :default
|
93
|
+
s.query_queue.should == :query
|
94
|
+
s.cud_queue.should == :cud
|
76
95
|
end
|
77
96
|
|
78
97
|
it "should add associations based on belongs_to field for a source" do
|
79
98
|
@s2 = Source.create({:name => 'SimpleAdapter'}, @s_params)
|
80
99
|
@s2.belongs_to = [{'product_id' => 'SampleAdapter'}].to_json
|
100
|
+
sf = Source.load(@s1.name,{:app_id => @a.id,:user_id => '*'})
|
81
101
|
Source.update_associations([@s.name,@s1.name, @s2.name])
|
82
102
|
s = Source.load(@s.name,{:app_id => @a.id,:user_id => '*'})
|
83
103
|
s.has_many.should == "#{@s1.name},brand,#{@s2.name},product_id"
|
data/spec/source_sync_spec.rb
CHANGED
@@ -5,6 +5,7 @@ describe "SourceSync" do
|
|
5
5
|
it_should_behave_like "SourceAdapterHelper"
|
6
6
|
|
7
7
|
before(:each) do
|
8
|
+
@s = Source.load(@s_fields[:name],@s_params)
|
8
9
|
@ss = SourceSync.new(@s)
|
9
10
|
end
|
10
11
|
|
@@ -51,7 +52,7 @@ describe "SourceSync" do
|
|
51
52
|
@ss.process_query
|
52
53
|
verify_result(@s.docname(:md) => expected)
|
53
54
|
end
|
54
|
-
|
55
|
+
|
55
56
|
it "should never call read on any call of process" do
|
56
57
|
@s.poll_interval = -1
|
57
58
|
Store.put_data('test_db_storage',{'1'=>@product1})
|
@@ -207,7 +208,7 @@ describe "SourceSync" do
|
|
207
208
|
|
208
209
|
describe "app-level partitioning" do
|
209
210
|
it "should create app-level masterdoc with '__shared__' docname" do
|
210
|
-
@s1 = Source.load(@s_fields[:name]
|
211
|
+
@s1 = Source.load(@s_fields[:name],{:user_id => "testuser",:app_id => @a.id})
|
211
212
|
@s1.partition = :app
|
212
213
|
@ss1 = SourceSync.new(@s1)
|
213
214
|
expected = {'1'=>@product1,'2'=>@product2}
|
data/spec/spec_helper.rb
CHANGED
@@ -209,6 +209,7 @@ describe "RhosyncHelper", :shared => true do
|
|
209
209
|
before(:each) do
|
210
210
|
Store.create
|
211
211
|
Store.db.flushdb
|
212
|
+
# Source.delete_all # TODO: should have this
|
212
213
|
end
|
213
214
|
end
|
214
215
|
|
@@ -284,10 +285,8 @@ describe "DBObjectsHelper", :shared => true do
|
|
284
285
|
:app_id => @a.id
|
285
286
|
}
|
286
287
|
@c = Client.create(@c_fields,{:source_name => @s_fields[:name]})
|
287
|
-
@s = Source.
|
288
|
-
@s = Source.create(@s_fields,@s_params) if @s.nil?
|
288
|
+
@s = Source.create(@s_fields,@s_params)
|
289
289
|
@s1 = Source.load('FixedSchemaAdapter',@s_params)
|
290
|
-
@s1 = Source.create({:name => 'FixedSchemaAdapter'},@s_params) if @s1.nil?
|
291
290
|
config = Rhosync.source_config["sources"]['FixedSchemaAdapter']
|
292
291
|
@s1.update(config)
|
293
292
|
@r = @s.read_state
|
data/spec/sync_states_spec.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rhosync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 2.1.
|
9
|
+
- 6
|
10
|
+
version: 2.1.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Rhomobile
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-05-
|
19
|
-
default_executable: rhosync
|
18
|
+
date: 2011-05-25 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: json
|
@@ -544,7 +543,6 @@ files:
|
|
544
543
|
- examples/simple/application.rb
|
545
544
|
- examples/simple/sources/sample_adapter.rb
|
546
545
|
- examples/simple/sources/simple_adapter.rb
|
547
|
-
has_rdoc: true
|
548
546
|
homepage: http://rhomobile.com/products/rhosync
|
549
547
|
licenses: []
|
550
548
|
|
@@ -574,7 +572,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
574
572
|
requirements: []
|
575
573
|
|
576
574
|
rubyforge_project:
|
577
|
-
rubygems_version: 1.
|
575
|
+
rubygems_version: 1.8.3
|
578
576
|
signing_key:
|
579
577
|
specification_version: 3
|
580
578
|
summary: RhoSync Synchronization Framework
|