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 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
- def update(attribs)
63
- self.class.fields.each do |field|
64
- if field[:name] != 'name' and field[:name] != 'rho__id'
65
- redis.del field_key(field[:name])
66
- end
67
- end
68
- self.class.populate_attributes(self,attribs)
69
- end
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
- return unless self.is_exist?(id)
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)
@@ -88,7 +88,13 @@ module Rhosync
88
88
  end
89
89
 
90
90
  def api_user
91
- request_action == 'get_api_token' ? current_user : ApiToken.load(params[:api_token]).user
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.switch_user(current_user.login) unless @client.user_id == current_user.login
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
- logout
208
- do_login
215
+ catch_all do
216
+ logout
217
+ do_login
218
+ end
209
219
  end
210
220
 
211
221
  get '/application/clientcreate' do
212
- content_type :json
213
- client = Client.create(:user_id => current_user.id,:app_id => current_app.id)
214
- client.update_fields(params)
215
- { "client" => { "client_id" => client.id.to_s } }.merge!(source_config).to_json
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
- current_client.update_fields(params)
220
- source_config.to_json
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
- ClientSync.reset(current_client)
225
- source_config.to_json
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
@@ -1,51 +1,117 @@
1
1
  module Rhosync
2
- class Source < Model
3
- field :source_id,:integer
4
- field :name,:string
5
- field :url,:string
6
- field :login,:string
7
- field :password,:string
8
- field :priority,:integer
9
- field :callback_url,:string
10
- field :poll_interval,:integer
11
- field :partition_type,:string
12
- field :sync_type,:string
13
- field :belongs_to,:string
14
- field :has_many,:string
15
- field :queue,:string
16
- field :query_queue,:string
17
- field :cud_queue,:string
18
- attr_accessor :app_id, :user_id
19
- validates_presence_of :name #, :source_id
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] ||= :user
90
+ fields[:partition_type] = fields[:partition_type] ? fields[:partition_type].to_sym : :user
30
91
  fields[:poll_interval] ||= 300
31
- fields[:sync_type] ||= :incremental
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
- super(fields,params)
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(id,params)
108
+ def self.load(obj_id,params)
45
109
  validate_attributes(params)
46
- super(id,params)
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 = owner.has_many.length > 0 ? 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 ||= User.load(self.user_id)
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 ||= App.load(self.app_id)
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
- @read_state ||= ReadState.load(id)
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
- super
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]
@@ -1,3 +1,3 @@
1
1
  module Rhosync
2
- VERSION = '2.1.3'
2
+ VERSION = '2.1.6'
3
3
  end
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
- if Source.is_exist?(source_name)
97
- s = Source.load(source_name,{:app_id => app.name,:user_id => '*'})
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).should == [
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('',@api_token,"SampleAdapter").should == [
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
@@ -4,6 +4,10 @@ describe "BulkData" 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
  after(:each) do
8
12
  delete_data_directory
9
13
  end
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]
@@ -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
@@ -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)
@@ -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
@@ -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
- set_state(@s.docname(:md) => @data)
67
+ key = @s.docname('*')
68
+ set_state(key => @data)
51
69
  @s.delete
52
- verify_result(@s.docname(:md) => {})
53
- Store.db.keys(@s.docname('*')).should == []
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 == 'default'
74
- s.query_queue.should == 'query'
75
- s.cud_queue.should == 'cud'
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"
@@ -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],@s_params)
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.load(@s_fields[:name],@s_params)
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
@@ -5,6 +5,7 @@ describe "Sync Server States" 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
  @cs = ClientSync.new(@s,@c,2)
9
10
  end
10
11
 
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: 13
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 1
9
- - 3
10
- version: 2.1.3
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-05 00:00:00 -07:00
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.6.2
575
+ rubygems_version: 1.8.3
578
576
  signing_key:
579
577
  specification_version: 3
580
578
  summary: RhoSync Synchronization Framework