rhosync 2.1.0.beta.1 → 2.1.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -6,6 +6,14 @@
6
6
  * #5821277 - http stats by source not showing
7
7
  * #5899454 - move lock prefix to beginning so we don't return stats keys with it
8
8
  * #5822966 - bulk sync data file cannot handle space in the username
9
+ * #6450519 - blob sync resend_page doesn't send metadata
10
+ * #4646791 - cryptic error message if client exists, but source name is bogus
11
+ * #6827511 - fill in schema column in bulk sync file sources table
12
+ * #4490679 - support schema method in source adapter (runtime schema for bulk data)
13
+ * #6573429 - if schema changed in any adapter, invalidate bulk data file
14
+ * #7034095 - don't ping device if device_pin is empty or nil
15
+ * #7089047 - fixed application.rb template store_blob method
16
+ * #7055889 - fixed schema tables should have 'object' primary key
9
17
 
10
18
  ## 2.0.9
11
19
  * #5154725 - stats framework
data/Rakefile CHANGED
@@ -18,7 +18,6 @@ begin
18
18
  :jobs => 'spec/jobs/*_spec.rb',
19
19
  :stats => 'spec/stats/*_spec.rb',
20
20
  :ping => 'spec/ping/*_spec.rb',
21
- :doc => 'spec/doc/*_spec.rb',
22
21
  :generator => 'spec/generator/*_spec.rb',
23
22
  :bench => 'bench/spec/*_spec.rb'
24
23
  }
@@ -37,6 +36,12 @@ begin
37
36
  t.rcov_opts = ['--exclude', 'spec/*,gems/*,apps/*,bench/spec/*,json/*']
38
37
  end
39
38
 
39
+ desc "Run doc generator - dumps out doc/protocol.html"
40
+ Spec::Rake::SpecTask.new('doc') do |t|
41
+ t.spec_files = FileList['spec/doc/*_spec.rb']
42
+ t.rcov = false
43
+ end
44
+
40
45
  rescue LoadError => e
41
46
  puts "rspec / rcov not available. Install with: "
42
47
  puts "gem install rspec rcov\n\n"
@@ -55,7 +60,7 @@ begin
55
60
  gemspec.homepage = %q{http://rhomobile.com/products/rhosync}
56
61
  gemspec.authors = ["Rhomobile"]
57
62
  gemspec.email = %q{dev@rhomobile.com}
58
- gemspec.version = Rhosync::VERSION
63
+ gemspec.version = '2.1.0.beta.2'
59
64
  gemspec.files = FileList["[A-Z]*", "{bench,bin,generators,lib,spec,tasks}/**/*"]
60
65
 
61
66
  # TODO: Due to https://www.pivotaltracker.com/story/show/3417862, we can't use JSON 1.4.3
@@ -67,7 +72,7 @@ begin
67
72
  gemspec.add_dependency "redis", "~>2.0.0"
68
73
  gemspec.add_dependency "resque", ">=1.9.7"
69
74
  gemspec.add_dependency "rest-client", ">=1.4.2"
70
- gemspec.add_dependency "sinatra", "~>1.0"
75
+ gemspec.add_dependency "sinatra", "~>1.1"
71
76
  gemspec.add_dependency "templater", "~>1.0.0"
72
77
  gemspec.add_dependency "rake", ">=0.8.7"
73
78
  gemspec.add_development_dependency "jeweler", ">=1.4.0"
@@ -18,7 +18,7 @@ class Application < Rhosync::Base
18
18
  # Override this by creating a copy of the file somewhere
19
19
  # and returning the path to that file (then don't call super!):
20
20
  # i.e. /mnt/myimages/soccer.png
21
- def store_blob(blob)
21
+ def store_blob(obj,field_name,blob)
22
22
  super #=> returns blob[:tempfile]
23
23
  end
24
24
  end
@@ -18,7 +18,7 @@ class Application < Rhosync::Base
18
18
  # Override this by creating a copy of the file somewhere
19
19
  # and returning the path to that file (then don't call super!):
20
20
  # i.e. /mnt/myimages/soccer.png
21
- def store_blob(blob)
21
+ def store_blob(obj,field_name,blob)
22
22
  super #=> returns blob[:tempfile]
23
23
  end
24
24
  end
@@ -18,7 +18,7 @@ class Application < Rhosync::Base
18
18
  # Override this by creating a copy of the file somewhere
19
19
  # and returning the path to that file (then don't call super!):
20
20
  # i.e. /mnt/myimages/soccer.png
21
- def store_blob(blob)
21
+ def store_blob(object,field_name,blob)
22
22
  super #=> returns blob[:tempfile]
23
23
  end
24
24
  end
@@ -40,7 +40,7 @@ class <%=class_name%> < SourceAdapter
40
40
  # TODO: write some code here if applicable
41
41
  # be sure to have a hash key and value for "object"
42
42
  # for now, we'll say that its OK to not have a delete operation
43
- # raise "Please provide some code to delete a single object in the backend application using the hash values in name_value_list"
43
+ # raise "Please provide some code to delete a single object in the backend application using the object_id"
44
44
  end
45
45
 
46
46
  def logoff
@@ -60,12 +60,15 @@ module Rhosync
60
60
  end
61
61
 
62
62
  def update_clientdoc(sources)
63
+ # TODO: We need to store schema info and data info in bulk data
64
+ # source masterdoc and source schema might have changed!
63
65
  sources.each do |source|
64
66
  s = Source.load(source,{:app_id => app_id,:user_id => user_id})
65
67
  unless s.sync_type.to_sym == :bulk_sync_only
66
68
  self.source_name = source
67
69
  Store.clone(s.docname(:md_copy),self.docname(:cd))
68
70
  end
71
+ self.put_value(:schema_sha1,s.get_value(:schema_sha1))
69
72
  end
70
73
  end
71
74
 
@@ -12,22 +12,30 @@ module Rhosync
12
12
  end
13
13
 
14
14
  def receive_cud(cud_params={},query_params=nil)
15
- _process_blobs(cud_params)
16
- processed = 0
17
- ['create','update','delete'].each do |op|
18
- key,value = op,cud_params[op]
19
- processed += _receive_cud(key,value) if value
15
+ if @source.is_pass_through
16
+ @source_sync.pass_through_cud(cud_params,query_params) if value
17
+ else
18
+ _process_blobs(cud_params)
19
+ processed = 0
20
+ ['create','update','delete'].each do |op|
21
+ key,value = op,cud_params[op]
22
+ processed += _receive_cud(key,value) if value
23
+ end
24
+ @source_sync.process_cud(@client.id) if processed > 0
20
25
  end
21
- @source_sync.process_cud(@client.id) if processed > 0
22
26
  end
23
27
 
24
28
  def send_cud(token=nil,query_params=nil)
25
29
  res = []
26
- if not _ack_token(token)
30
+ if not _ack_token(token) and not @source.is_pass_through?
27
31
  res = resend_page(token)
28
32
  else
29
- @source_sync.process_query(query_params)
30
- res = send_new_page
33
+ query_result = @source_sync.process_query(query_params)
34
+ if @source.is_pass_through?
35
+ res = send_pass_through_data(query_result)
36
+ else
37
+ res = send_new_page
38
+ end
31
39
  end
32
40
  _format_result(res[0],res[1],res[2],res[3])
33
41
  end
@@ -53,39 +61,85 @@ module Rhosync
53
61
  end
54
62
 
55
63
  def send_new_page
64
+ token,progress_count,total_count,res = '',0,0,{}
65
+ if schema_changed?
66
+ _expire_bulk_data
67
+ token = compute_token(@client.docname(:page_token))
68
+ res = {'schema-changed' => 'true'}
69
+ else
70
+ compute_errors_page
71
+ res = build_page do |r|
72
+ progress_count,total_count,r['insert'] = compute_page
73
+ r['delete'] = compute_deleted_page
74
+ r['links'] = compute_links_page
75
+ r['metadata'] = compute_metadata
76
+ end
77
+ if res['insert'] or res['delete'] or res['links']
78
+ token = compute_token(@client.docname(:page_token))
79
+ else
80
+ _delete_errors_page
81
+ end
82
+ @client.put_data(:cd,res['insert'],true)
83
+ @client.delete_data(:cd,res['delete'])
84
+ end
85
+ [token,progress_count,total_count,res]
86
+ end
87
+
88
+ def send_pass_through_data(data)
89
+ data ||= {}
90
+ data.each_key do |object_id|
91
+ data[object_id].each { |attrib,value| data[object_id][attrib] = '' if value.nil? }
92
+ end
93
+ token = ''
56
94
  compute_errors_page
57
- token,progress_count,total_count = '',0,0
58
95
  res = build_page do |r|
59
- progress_count,total_count,r['insert'] = compute_page
60
- r['delete'] = compute_deleted_page
61
- r['links'] = compute_links_page
96
+ r['insert'] = data
62
97
  r['metadata'] = compute_metadata
63
98
  end
64
- if res['insert'] or res['delete'] or res['links']
99
+ if res['insert']
65
100
  token = compute_token(@client.docname(:page_token))
66
101
  else
67
102
  _delete_errors_page
68
103
  end
69
- @client.put_data(:cd,res['insert'],true)
70
- @client.delete_data(:cd,res['delete'])
71
- [token,progress_count,total_count,res]
104
+ [token,0,data.size,res]
72
105
  end
73
106
 
74
107
  # Resend token for a client, also sends exceptions
75
108
  def resend_page(token=nil)
76
- token,progress_count,total_count = '',0,0
77
- res = build_page do |r|
78
- r['insert'] = @client.get_data(:page)
79
- r['delete'] = @client.get_data(:delete_page)
80
- r['links'] = @client.get_data(:create_links_page)
81
- r['metadata'] = compute_metadata
82
- progress_count = @client.get_value(:cd_size).to_i
83
- total_count = @client.get_value(:total_count_page).to_i
109
+ token,progress_count,total_count,res = '',0,0,{}
110
+ schema_page = @client.get_value(:schema_page)
111
+ if schema_page
112
+ res = {'schema-changed' => 'true'}
113
+ else
114
+ res = build_page do |r|
115
+ r['insert'] = @client.get_data(:page)
116
+ r['delete'] = @client.get_data(:delete_page)
117
+ r['links'] = @client.get_data(:create_links_page)
118
+ r['metadata'] = @client.get_value(:metadata_page)
119
+ progress_count = @client.get_value(:cd_size).to_i
120
+ total_count = @client.get_value(:total_count_page).to_i
121
+ end
84
122
  end
85
123
  token = @client.get_value(:page_token)
86
124
  [token,progress_count,total_count,res]
87
125
  end
88
126
 
127
+ # Checks if schema changed
128
+ def schema_changed?
129
+ schema_sha1 = @source.get_value(:schema_sha1)
130
+
131
+ if @client.get_value(:schema_sha1).nil?
132
+ @client.put_value(:schema_sha1,schema_sha1)
133
+ return false
134
+ elsif @client.get_value(:schema_sha1) == schema_sha1
135
+ return false
136
+ end
137
+
138
+ @client.put_value(:schema_sha1,schema_sha1)
139
+ @client.put_value(:schema_page,schema_sha1)
140
+ true
141
+ end
142
+
89
143
  # Computes the metadata sha1 and returns metadata if client's sha1 doesn't
90
144
  # match source's sha1
91
145
  def compute_metadata
@@ -94,9 +148,11 @@ module Rhosync
94
148
  end
95
149
  return if @client.get_value(:metadata_sha1) == metadata_sha1
96
150
  @client.put_value(:metadata_sha1,metadata_sha1)
151
+ @client.put_value(:metadata_page,metadata)
97
152
  metadata
98
153
  end
99
154
 
155
+
100
156
  # Computes diffs between master doc and client doc, trims it to page size,
101
157
  # stores page, and returns page as hash
102
158
  def compute_page
@@ -215,6 +271,14 @@ module Rhosync
215
271
  end
216
272
 
217
273
  private
274
+
275
+ # expires the bulk data for the client
276
+ def _expire_bulk_data
277
+ [:user,:app].each do |partition|
278
+ Rhosync.expire_bulk_data(@client.user_id,partition)
279
+ end
280
+ end
281
+
218
282
  def _resend_search_result
219
283
  res = @client.get_data(:search_page)
220
284
  _format_search_result(res,res.size)
@@ -234,8 +298,8 @@ module Rhosync
234
298
  def _do_search(params={})
235
299
  # call source adapter search unless client is sending token for ack
236
300
  search_params = params[:search] if params
237
- @source_sync.search(@client.id,search_params) if params.nil? or !params[:token]
238
- res,diffsize = compute_search
301
+ res = @source_sync.search(@client.id,search_params) if params.nil? or !params[:token]
302
+ res,diffsize = @source.is_pass_through? ? [res,res.size] : compute_search
239
303
  formatted_res = _format_search_result(res,diffsize)
240
304
  @client.flash_data('search*') if diffsize == 0
241
305
  formatted_res
@@ -250,7 +314,6 @@ module Rhosync
250
314
  else
251
315
  search_token = @client.get_value(:search_token)
252
316
  search_token ||= ''
253
- #res,diffsize = compute_search
254
317
  return [] if res.empty?
255
318
  [ {'version'=>VERSION},
256
319
  {'token' => search_token},
@@ -285,6 +348,8 @@ module Rhosync
285
348
  if stored_token
286
349
  if token and stored_token == token
287
350
  @client.put_value(:page_token,nil)
351
+ @client.flash_data(:schema_page)
352
+ @client.flash_data(:metadata_page)
288
353
  @client.flash_data(:create_links_page)
289
354
  @client.flash_data(:page)
290
355
  @client.flash_data(:delete_page)
@@ -55,7 +55,7 @@ module Rhosync
55
55
  data = source.get_data(:md)
56
56
  counter = {}
57
57
  columns,qm = [],[]
58
- create_table = ["\"object\" varchar"]
58
+ create_table = ["\"object\" varchar(255) PRIMARY KEY"]
59
59
  schema = JSON.parse(source.schema)
60
60
 
61
61
  db.transaction do |database|
@@ -84,7 +84,7 @@ module Rhosync
84
84
  schema['index'].each do |key,value|
85
85
  val2 = ""
86
86
  value.split(',').each do |col|
87
- val2 += ',' if val2.length() > 0
87
+ val2 += ',' if val2.length > 0
88
88
  val2 += "\"#{col}\""
89
89
  end
90
90
 
@@ -95,7 +95,7 @@ module Rhosync
95
95
  schema['unique_index'].each do |key,value|
96
96
  val2 = ""
97
97
  value.split(',').each do |col|
98
- val2 += ',' if val2.length() > 0
98
+ val2 += ',' if val2.length > 0
99
99
  val2 += "\"#{col}\""
100
100
  end
101
101
 
@@ -117,12 +117,12 @@ module Rhosync
117
117
  def self.populate_sources_table(db,sources_refs)
118
118
  db.transaction do |database|
119
119
  database.prepare("insert into sources
120
- (source_id,name,sync_priority,partition,sync_type,source_attribs,metadata,blob_attribs,associations)
121
- values (?,?,?,?,?,?,?,?,?)") do |stmt|
120
+ (source_id,name,sync_priority,partition,sync_type,source_attribs,metadata,schema,blob_attribs,associations)
121
+ values (?,?,?,?,?,?,?,?,?,?)") do |stmt|
122
122
  sources_refs.each do |source_name,ref|
123
123
  s = ref[:source]
124
124
  stmt.execute(s.source_id,s.name,s.priority,s.partition_type,
125
- s.sync_type,refs_to_s(ref[:refs]),s.get_value(:metadata),s.blob_attribs,s.has_many)
125
+ s.sync_type,refs_to_s(ref[:refs]),s.get_value(:metadata),s.schema,s.blob_attribs,s.has_many)
126
126
  end
127
127
  end
128
128
  end
@@ -11,7 +11,7 @@ module Rhosync
11
11
  client = Client.load(client_id,{:source_name => '*'})
12
12
  params.merge!('device_port' => client.device_port,
13
13
  'device_pin' => client.device_pin)
14
- if client.device_type and client.device_type.size > 0
14
+ if client.device_type and client.device_type.size > 0 and client.device_pin and client.device_pin.size > 0
15
15
  klass = Object.const_get(camelize(client.device_type.downcase))
16
16
  klass.ping(params) if klass
17
17
  else
@@ -24,6 +24,7 @@ module Rhosync
24
24
  end
25
25
 
26
26
  def self.c2d_message(params)
27
+ params.reject! {|k,v| v.nil? || v.length == 0}
27
28
  data = {}
28
29
  data['registration_id'] = params['device_pin']
29
30
  data['collapse_key'] = (rand * 100000000).to_i.to_s
@@ -100,8 +100,11 @@ module Rhosync
100
100
  user = current_user
101
101
  if params[:source_name] and user
102
102
  @source = Source.load(params[:source_name],
103
- {:user_id => user.login,:app_id => APP_NAME})
103
+ {:user_id => user.login,:app_id => APP_NAME})
104
+ raise "ERROR: Source '#{params[:source_name]}' requested by client doesn't exist.\n" unless @source
105
+ @source
104
106
  else
107
+ log "ERROR: Can't load source, no source_name provided.\n"
105
108
  nil
106
109
  end
107
110
  end
@@ -15,7 +15,7 @@ module Rhosync
15
15
  field :queue,:string
16
16
  field :query_queue,:string
17
17
  field :cud_queue,:string
18
- field :schema, :string
18
+ field :pass_through,:string
19
19
  attr_accessor :app_id, :user_id
20
20
  validates_presence_of :name #, :source_id
21
21
 
@@ -100,6 +100,10 @@ module Rhosync
100
100
  @app ||= App.load(self.app_id)
101
101
  end
102
102
 
103
+ def schema
104
+ @schema ||= self.get_value(:schema)
105
+ end
106
+
103
107
  def read_state
104
108
  id = {:app_id => self.app_id,:user_id => user_by_partition,
105
109
  :source_name => self.name}
@@ -142,6 +146,10 @@ module Rhosync
142
146
  yield client_id,params if need_refresh
143
147
  end
144
148
 
149
+ def is_pass_through?
150
+ self.pass_through and self.pass_through == 'true'
151
+ end
152
+
145
153
  private
146
154
  def self.validate_attributes(params)
147
155
  raise ArgumentError.new('Missing required attribute user_id') unless params[:user_id]
@@ -62,7 +62,12 @@ module Rhosync
62
62
  @tmp_docname = @source.docname(:md) + get_random_uuid
63
63
  @stash_size = 0
64
64
  params ? self.query(params) : self.query
65
- self.sync
65
+ if @source.is_pass_through?
66
+ @result
67
+ else
68
+ self.sync
69
+ true
70
+ end
66
71
  end
67
72
 
68
73
  def stash_result
@@ -73,9 +78,7 @@ module Rhosync
73
78
  end
74
79
 
75
80
  def expire_bulk_data(partition = :user)
76
- name = BulkData.get_name(partition,current_user.login)
77
- data = BulkData.load(name)
78
- data.refresh_time = Time.now.to_i if data
81
+ Rhosync.expire_bulk_data(current_user.login,partition)
79
82
  end
80
83
 
81
84
  def create(name_value_list); end
@@ -22,6 +22,33 @@ module Rhosync
22
22
  _measure_and_process_cud('delete',client_id)
23
23
  end
24
24
 
25
+ # Pass through CUD to adapter, no data stored
26
+ def pass_through_cud(cud_params,query_params)
27
+ res,processed_objects = {},[]
28
+ begin
29
+ ['create','update','delete'].each do |op|
30
+ key,objects = op,cud_params[op]
31
+ objects.each do |key,value|
32
+ case op
33
+ when 'create'
34
+ @adapter.send(op.to_sym,value)
35
+ when 'update'
36
+ value['id'] = key
37
+ @adapter.send(op.to_sym,value)
38
+ when 'delete'
39
+ @adapter.send(op.to_sym,key)
40
+ end
41
+ process_objects << key
42
+ end if objects
43
+ end
44
+ rescue Exception => e
45
+ log "Error in #{op} pass through method: #{e.message}"
46
+ res['error'] = { 'operation' => op, 'message' => e.message }
47
+ end
48
+ res['processed'] = process_objects
49
+ res.to_json
50
+ end
51
+
25
52
  # Read Operation; params are query arguments
26
53
  def read(client_id=nil,params=nil)
27
54
  _read('query',client_id,params)
@@ -59,13 +86,15 @@ module Rhosync
59
86
  end
60
87
 
61
88
  def do_query(params=nil)
89
+ result = nil
62
90
  @source.if_need_refresh do
63
91
  Stats::Record.update("source:query:#{@source.name}") do
64
92
  return if _auth_op('login') == false
65
- self.read(nil,params)
93
+ result = self.read(nil,params)
66
94
  _auth_op('logoff')
67
95
  end
68
96
  end
97
+ result
69
98
  end
70
99
 
71
100
  # Enqueue a job for the source based on job type
@@ -210,12 +239,12 @@ module Rhosync
210
239
  end
211
240
 
212
241
  # Metadata Operation; source adapter returns json
213
- def _get_metadata
214
- if @adapter.respond_to?(:metadata)
215
- metadata = @adapter.metadata
216
- if metadata
217
- @source.put_value(:metadata,metadata)
218
- @source.put_value(:metadata_sha1,Digest::SHA1.hexdigest(metadata))
242
+ def _get_data(method)
243
+ if @adapter.respond_to?(method)
244
+ data = @adapter.send(method)
245
+ if data
246
+ @source.put_value(method,data)
247
+ @source.put_value("#{method}_sha1",Digest::SHA1.hexdigest(data))
219
248
  end
220
249
  end
221
250
  end
@@ -223,17 +252,20 @@ module Rhosync
223
252
  # Read Operation; params are query arguments
224
253
  def _read(operation,client_id,params=nil)
225
254
  errordoc = nil
255
+ result = nil
226
256
  begin
227
257
  if operation == 'search'
228
258
  client = Client.load(client_id,{:source_name => @source.name})
229
259
  errordoc = client.docname(:search_errors)
230
260
  compute_token(client.docname(:search_token))
231
- @adapter.search(params)
261
+ result = @adapter.search(params)
232
262
  @adapter.save(client.docname(:search))
233
263
  else
234
264
  errordoc = @source.docname(:errors)
235
- _get_metadata
236
- @adapter.do_query(params)
265
+ [:metadata,:schema].each do |method|
266
+ _get_data(method)
267
+ end
268
+ result = @adapter.do_query(params)
237
269
  end
238
270
  # operation,sync succeeded, remove errors
239
271
  Store.lock(errordoc) do
@@ -246,7 +278,7 @@ module Rhosync
246
278
  Store.put_data(errordoc,{"#{operation}-error"=>{'message'=>e.message}},true)
247
279
  end
248
280
  end
249
- true
281
+ result
250
282
  end
251
283
  end
252
284
  end
@@ -1,3 +1,3 @@
1
1
  module Rhosync
2
- VERSION = '2.1.0.beta.1'
3
- end
2
+ VERSION = '2.1.0'
3
+ end
data/lib/rhosync.rb CHANGED
@@ -91,7 +91,8 @@ module Rhosync
91
91
  end
92
92
  sources = config[:sources] || []
93
93
  sources.each do |source_name,fields|
94
- if Source.is_exist?(source_name)
94
+ check_for_schema_field!(fields)
95
+ if Source.is_exist?(source_name)
95
96
  s = Source.load(source_name,{:app_id => app.name,:user_id => '*'})
96
97
  s.update(fields)
97
98
  else
@@ -143,6 +144,13 @@ module Rhosync
143
144
  log "*"*60
144
145
  end
145
146
  end
147
+
148
+ def check_for_schema_field!(fields)
149
+ if fields['schema']
150
+ log "ERROR: 'schema' field in settings.yml is not supported anymore, please use source adapter schema method!"
151
+ exit(1)
152
+ end
153
+ end
146
154
 
147
155
  # Serializes oav to set element
148
156
  def setelement(obj,attrib,value)
@@ -200,6 +208,12 @@ module Rhosync
200
208
  log "*"*60
201
209
  end
202
210
  end
211
+
212
+ def expire_bulk_data(username, partition = :user)
213
+ name = BulkData.get_name(partition,username)
214
+ data = BulkData.load(name)
215
+ data.refresh_time = Time.now.to_i if data
216
+ end
203
217
 
204
218
  def unzip_file(file_dir,params)
205
219
  uploaded_file = File.join(file_dir, params[:filename])
@@ -22,7 +22,7 @@ describe "RhosyncApiGetSourceParams" do
22
22
  {"name"=>"queue", "value"=>nil, "type"=>"string"},
23
23
  {"name"=>"query_queue", "value"=>nil, "type"=>"string"},
24
24
  {"name"=>"cud_queue", "value"=>nil, "type"=>"string"},
25
- {"name"=>"schema", "value"=>nil, "type"=>"string"}]
25
+ {"name"=>"pass_through", "value"=>nil, "type"=>"string"}]
26
26
  end
27
27
 
28
28
  end
@@ -169,7 +169,7 @@ describe "RhosyncApi" do
169
169
  {"name"=>"queue", "value"=>nil, "type"=>"string"},
170
170
  {"name"=>"query_queue", "value"=>nil, "type"=>"string"},
171
171
  {"name"=>"cud_queue", "value"=>nil, "type"=>"string"},
172
- {"name"=>"schema", "value"=>nil, "type"=>"string"}]
172
+ {"name"=>"pass_through", "value"=>nil, "type"=>"string"}]
173
173
  end
174
174
 
175
175
  it "should list source attributes using rest call" do
@@ -9,18 +9,6 @@
9
9
  sync_type: 'incremental'
10
10
  belongs_to:
11
11
  - brand: 'SampleAdapter'
12
- schema:
13
- version: '1.0'
14
- property:
15
- name: 'string'
16
- brand: 'string'
17
- price: 'string'
18
- image_url_cropped: 'blob,overwrite'
19
- image_url: 'blob'
20
- index:
21
- by_name_brand: 'name,brand'
22
- unique_index:
23
- by_price: 'price'
24
12
 
25
13
  :development:
26
14
  :licensefile: settings/license.key
@@ -6,4 +6,23 @@ class FixedSchemaAdapter < SourceAdapter
6
6
  def query(params=nil)
7
7
  @result = Store.get_data('test_db_storage')
8
8
  end
9
+
10
+ def schema
11
+ {
12
+ 'version' => '1.0',
13
+ 'property' => {
14
+ 'name' => 'string',
15
+ 'brand' => 'string',
16
+ 'price' => 'string',
17
+ 'image_url_cropped' => 'blob,overwrite',
18
+ 'image_url' => 'blob'
19
+ },
20
+ 'index' => {
21
+ 'by_name_brand' => 'name,brand'
22
+ },
23
+ 'unique_index' => {
24
+ 'by_price' => 'price'
25
+ }
26
+ }.to_json
27
+ end
9
28
  end
data/spec/client_spec.rb CHANGED
@@ -61,6 +61,16 @@ describe "Client" do
61
61
  @s.docname(:md_copy) => @data)
62
62
  end
63
63
 
64
+ it "should update client schema_sha1" do
65
+ set_state(@s.docname(:md_copy) => @data,
66
+ @s.docname(:schema_sha1) => 'foobar',
67
+ @c.docname(:cd) => {'foo' => {'bar' => 'abc'}})
68
+ @c.update_clientdoc([@s_fields[:name]])
69
+ verify_result(@c.docname(:cd) => @data,
70
+ @s.docname(:md_copy) => @data,
71
+ @c.docname(:schema_sha1) => 'foobar')
72
+ end
73
+
64
74
  describe "Client Stats" do
65
75
 
66
76
  before(:each) do
@@ -35,6 +35,19 @@ describe "ClientSync" do
35
35
  @cs.client.docname(:cd) => data)
36
36
  end
37
37
 
38
+ it "should handle send cud if pass_through is set" do
39
+ data = {'1'=>@product1,'2'=>@product2}
40
+ expected = {'insert'=>data}
41
+ set_test_data('test_db_storage',data)
42
+ @s.pass_through = 'true'
43
+ @cs.send_cud.should == [{'version'=>ClientSync::VERSION},
44
+ {'token'=>@c.get_value(:page_token)},
45
+ {'count'=>data.size},{'progress_count'=>data.size},
46
+ {'total_count'=>data.size},expected]
47
+ verify_result(@cs.client.docname(:page) => {},
48
+ @cs.client.docname(:cd) => {})
49
+ end
50
+
38
51
  it "should return read errors in send cud" do
39
52
  msg = "Error during query"
40
53
  data = {'1'=>@product1,'2'=>@product2}
@@ -405,6 +418,113 @@ describe "ClientSync" do
405
418
  Store.get_data(@cs.client.docname(:page)).should == {}
406
419
  @c.get_value(:page_token).should be_nil
407
420
  end
421
+
422
+ it "should send metadata with page" do
423
+ expected = {'1'=>@product1}
424
+ set_state('test_db_storage' => expected)
425
+ metadata = "{\"foo\":\"bar\"}"
426
+ mock_metadata_method([SampleAdapter]) do
427
+ result = @cs.send_cud
428
+ token = @c.get_value(:page_token)
429
+ result.should == [{"version"=>ClientSync::VERSION},{"token"=>token},
430
+ {"count"=>1}, {"progress_count"=>0},{"total_count"=>1},
431
+ {'metadata'=>metadata,'insert'=>expected}]
432
+ @c.get_value(:metadata_page).should == metadata
433
+ end
434
+ end
435
+
436
+ it "should send metadata with resend page" do
437
+ expected = {'1'=>@product1}
438
+ set_state('test_db_storage' => expected)
439
+ mock_metadata_method([SampleAdapter]) do
440
+ result = @cs.send_cud
441
+ token = @c.get_value(:page_token)
442
+ @cs.send_cud.should == [{"version"=>ClientSync::VERSION},{"token"=>token},
443
+ {"count"=>1}, {"progress_count"=>0},{"total_count"=>1},
444
+ {'metadata'=>"{\"foo\":\"bar\"}",'insert'=>expected}]
445
+ end
446
+ end
447
+
448
+ it "should ack metadata page with ack token" do
449
+ expected = {'1'=>@product1}
450
+ set_state('test_db_storage' => expected)
451
+ mock_metadata_method([SampleAdapter]) do
452
+ result = @cs.send_cud
453
+ token = @c.get_value(:page_token)
454
+ @cs.send_cud(token).should == [{"version"=>ClientSync::VERSION},{"token"=>""},
455
+ {"count"=>0}, {"progress_count"=>1},{"total_count"=>1},{}]
456
+ @c.get_value(:metadata_page).should be_nil
457
+ end
458
+ end
459
+
460
+ it "shouldn't send schema-changed if client schema sha1 is nil" do
461
+ expected = {'1'=>@product1}
462
+ set_state('test_db_storage' => expected)
463
+ mock_schema_method([SampleAdapter]) do
464
+ result = @cs.send_cud
465
+ token = @c.get_value(:page_token)
466
+ result.should == [{"version"=>ClientSync::VERSION},{"token"=>token},
467
+ {"count"=>1}, {"progress_count"=>0},{"total_count"=>1},{'insert'=>expected}]
468
+ @c.get_value(:schema_sha1).should == '8c148c8c1a66c7baf685c07d58bea360da87981b'
469
+ end
470
+ end
471
+
472
+ it "should send schema-changed instead of page" do
473
+ mock_schema_method([SampleAdapter]) do
474
+ @c.put_value(:schema_sha1,'foo')
475
+ result = @cs.send_cud
476
+ token = @c.get_value(:page_token)
477
+ result.should == [{"version"=>ClientSync::VERSION},{"token"=>token},
478
+ {"count"=>0}, {"progress_count"=>0},{"total_count"=>0},{'schema-changed'=>'true'}]
479
+ @c.get_value(:schema_page).should == '8c148c8c1a66c7baf685c07d58bea360da87981b'
480
+ @c.get_value(:schema_sha1).should == '8c148c8c1a66c7baf685c07d58bea360da87981b'
481
+ end
482
+ end
483
+
484
+ it "should re-send schema-changed if no token sent" do
485
+ mock_schema_method([SampleAdapter]) do
486
+ @c.put_value(:schema_sha1,'foo')
487
+ result = @cs.send_cud
488
+ token = @c.get_value(:page_token)
489
+ @cs.send_cud.should == [{"version"=>ClientSync::VERSION},{"token"=>token},
490
+ {"count"=>0}, {"progress_count"=>0},{"total_count"=>0},{'schema-changed'=>'true'}]
491
+ @c.get_value(:schema_page).should == '8c148c8c1a66c7baf685c07d58bea360da87981b'
492
+ @c.get_value(:schema_sha1).should == '8c148c8c1a66c7baf685c07d58bea360da87981b'
493
+ end
494
+ end
495
+
496
+ it "should ack schema-changed with token" do
497
+ mock_schema_method([SampleAdapter]) do
498
+ @c.put_value(:schema_sha1,'foo')
499
+ result = @cs.send_cud
500
+ token = @c.get_value(:page_token)
501
+ @cs.send_cud(token).should == [{"version"=>ClientSync::VERSION},{"token"=>""},
502
+ {"count"=>0}, {"progress_count"=>0},{"total_count"=>0},{}]
503
+ @c.get_value(:schema_page).should be_nil
504
+ @c.get_value(:schema_sha1).should == '8c148c8c1a66c7baf685c07d58bea360da87981b'
505
+ end
506
+ end
507
+
508
+ it "should expire bulk data if schema changed" do
509
+ docname = bulk_data_docname(@a.id,@u.id)
510
+ data = BulkData.create(:name => docname,
511
+ :state => :inprogress,
512
+ :app_id => @a.id,
513
+ :user_id => @u.id,
514
+ :sources => [@s_fields[:name]])
515
+ data.refresh_time = Time.now.to_i + 600
516
+ mock_schema_method([SampleAdapter]) do
517
+ @c.put_value(:schema_sha1,'foo')
518
+ result = @cs.send_cud
519
+ token = @c.get_value(:page_token)
520
+ @cs.send_cud(token).should == [{"version"=>ClientSync::VERSION},{"token"=>""},
521
+ {"count"=>0}, {"progress_count"=>0},{"total_count"=>0},{}]
522
+ @c.get_value(:schema_page).should be_nil
523
+ @c.get_value(:schema_sha1).should == '8c148c8c1a66c7baf685c07d58bea360da87981b'
524
+ data = BulkData.load(docname)
525
+ data.refresh_time.should <= Time.now.to_i
526
+ end
527
+ end
408
528
  end
409
529
 
410
530
  describe "bulk data" do
@@ -451,7 +571,6 @@ describe "ClientSync" do
451
571
  :app_id => @a.id,
452
572
  :user_id => name,
453
573
  :sources => [@s_fields[:name]])
454
- puts "data: #{data.inspect}"
455
574
  BulkDataJob.perform("data_name" => bulk_data_docname(@a.id,name))
456
575
  data = BulkData.load(bulk_data_docname(@a.id,name))
457
576
  data.url.should match /a%20b/
@@ -76,6 +76,25 @@ describe "BulkDataJob" do
76
76
  end
77
77
  end
78
78
 
79
+ it "should create sqlite data with source schema" do
80
+ set_state('test_db_storage' => @data)
81
+ mock_schema_method([SampleAdapter]) do
82
+ docname = bulk_data_docname(@a.id,@u.id)
83
+ data = BulkData.create(:name => docname,
84
+ :state => :inprogress,
85
+ :app_id => @a.id,
86
+ :user_id => @u.id,
87
+ :sources => [@s_fields[:name]])
88
+ BulkDataJob.perform("data_name" => data.name)
89
+ data = BulkData.load(docname)
90
+ data.completed?.should == true
91
+ verify_result(@s.docname(:md) => @data,
92
+ @s.docname(:schema) => "{\"property\":{\"brand\":\"string\",\"name\":\"string\"},\"version\":\"1.0\"}",
93
+ @s.docname(:md_copy) => @data)
94
+ validate_db(data,@s.name => @data).should == true
95
+ end
96
+ end
97
+
79
98
  it "should raise exception if hsqldata fails" do
80
99
  data = BulkData.create(:name => bulk_data_docname(@a.id,@u.id),
81
100
  :state => :inprogress,
@@ -32,4 +32,14 @@ describe "PingJob" do
32
32
  lambda { PingJob.perform(params) }.should_not raise_error
33
33
  end
34
34
 
35
+ it "should skip ping for empty device_pin" do
36
+ params = {"user_id" => @u.id, "api_token" => @api_token,
37
+ "sources" => [@s.name], "message" => 'hello world',
38
+ "vibrate" => '5', "badge" => '5', "sound" => 'hello.mp3'}
39
+ @c.device_type = 'blackberry'
40
+ @c.device_pin = nil
41
+ PingJob.should_receive(:log).once.with("Skipping ping for non-registered client_id '#{@c.id}'...")
42
+ lambda { PingJob.perform(params) }.should_not raise_error
43
+ end
44
+
35
45
  end
@@ -42,4 +42,14 @@ describe "Ping Android" do
42
42
  actual['collapse_key'] = "RAND_KEY" unless actual['collapse_key'].nil?
43
43
  actual.should == expected
44
44
  end
45
+
46
+ it "should trim empty or nil params from c2d_message" do
47
+ expected = {'registration_id' => @c.device_pin, 'collapse_key' => "RAND_KEY",
48
+ 'data.vibrate' => '5', 'data.do_sync' => '', 'data.sound' => "hello.mp3"}
49
+ params = {"device_pin" => @c.device_pin,
50
+ "sources" => [], "message" => '', "vibrate" => '5', "sound" => 'hello.mp3'}
51
+ actual = Android.c2d_message(params)
52
+ actual['collapse_key'] = "RAND_KEY" unless actual['collapse_key'].nil?
53
+ actual.should == expected
54
+ end
45
55
  end
data/spec/rhosync_spec.rb CHANGED
@@ -43,6 +43,18 @@ describe "Rhosync" do
43
43
  App.load(@test_app_name).sources.members.should == []
44
44
  end
45
45
 
46
+ it "should exit if schema config exists" do
47
+ config = Rhosync.get_config(get_testapp_path)
48
+ config[:sources]['FixedSchemaAdapter'].merge!(
49
+ 'schema' => {'property' => 'foo'}
50
+ )
51
+ Rhosync.stub!(:get_config).and_return(config)
52
+ Rhosync.should_receive(:log).once.with(
53
+ "ERROR: 'schema' field in settings.yml is not supported anymore, please use source adapter schema method!"
54
+ )
55
+ lambda { Rhosync.bootstrap(get_testapp_path) }.should raise_error(SystemExit)
56
+ end
57
+
46
58
  it "should add associations during bootstrap" do
47
59
  Rhosync.bootstrap(get_testapp_path)
48
60
  s = Source.load('SampleAdapter',{:app_id => @test_app_name,:user_id => '*'})
@@ -12,9 +12,7 @@ describe "Server" do
12
12
 
13
13
  include Rack::Test::Methods
14
14
  include Rhosync
15
-
16
- it_should_behave_like "DBObjectsHelper"
17
-
15
+
18
16
  before(:each) do
19
17
  require File.join(get_testapp_path,@test_app_name)
20
18
  Rhosync.bootstrap(get_testapp_path) do |rhosync|
@@ -28,6 +26,8 @@ describe "Server" do
28
26
  Rhosync::Server.use Rack::Static, :urls => ["/data"],
29
27
  :root => File.expand_path(File.join(File.dirname(__FILE__),'..','apps','rhotestapp'))
30
28
  end
29
+
30
+ it_should_behave_like "DBObjectsHelper"
31
31
 
32
32
  def app
33
33
  @app ||= Rhosync::Server.new
@@ -127,17 +127,7 @@ describe "Server" do
127
127
  @source_config = {
128
128
  "sources"=>
129
129
  {"FixedSchemaAdapter"=>
130
- {"schema"=>
131
- {"property"=>
132
- {"image_url_cropped"=>"blob,overwrite",
133
- "price"=>"string",
134
- "brand"=>"string",
135
- "name"=>"string",
136
- "image_url"=>"blob"},
137
- "unique_index"=>{"by_price"=>"price"},
138
- "version"=>"1.0",
139
- "index"=>{"by_name_brand"=>"name,brand"}},
140
- "poll_interval"=>300,
130
+ {"poll_interval"=>300,
141
131
  "sync_type"=>"incremental",
142
132
  "belongs_to"=>[{"brand"=>"SampleAdapter"}]},
143
133
  "SampleAdapter"=>{"poll_interval"=>300},
@@ -148,7 +138,7 @@ describe "Server" do
148
138
  it "should respond to clientcreate" do
149
139
  get "/application/clientcreate?device_type=blackberry"
150
140
  last_response.should be_ok
151
- last_response.content_type.should == 'application/json'
141
+ last_response.content_type.should =~ /application\/json/
152
142
  id = JSON.parse(last_response.body)['client']['client_id']
153
143
  id.length.should == 32
154
144
  JSON.parse(last_response.body).should ==
@@ -235,7 +225,7 @@ describe "Server" do
235
225
  set_test_data('test_db_storage',data)
236
226
  get "/application",:client_id => @c.id,:source_name => @s.name,:version => ClientSync::VERSION
237
227
  last_response.should be_ok
238
- last_response.content_type.should == 'application/json'
228
+ last_response.content_type.should =~ /application\/json/
239
229
  token = @c.get_value(:page_token)
240
230
  JSON.parse(last_response.body).should == [{"version"=>ClientSync::VERSION},{"token"=>token},
241
231
  {"count"=>2}, {"progress_count"=>0},{"total_count"=>2},{'insert'=>data}]
@@ -257,6 +247,12 @@ describe "Server" do
257
247
  {"count"=>0}, {"progress_count"=>2}, {"total_count"=>2},{}]
258
248
  end
259
249
 
250
+ it "should return error if source_name is unknown" do
251
+ get "/application",:client_id => @c.id,:source_name => 'Broken',:version => ClientSync::VERSION
252
+ last_response.status.should == 500
253
+ last_response.body.should == "ERROR: Source 'Broken' requested by client doesn't exist.\n"
254
+ end
255
+
260
256
  it "should get deletes json" do
261
257
  cs = ClientSync.new(@s,@c,1)
262
258
  data = {'1'=>@product1,'2'=>@product2}
@@ -286,7 +282,7 @@ describe "Server" do
286
282
  params = {:client_id => @c.id,:sources => sources,:search => {'name' => 'iPhone'},
287
283
  :version => ClientSync::VERSION}
288
284
  get "/application/search",params
289
- last_response.content_type.should == 'application/json'
285
+ last_response.content_type.should =~ /application\/json/
290
286
  token = @c.get_value(:search_token)
291
287
  JSON.parse(last_response.body).should == [[{'version'=>ClientSync::VERSION},{'token'=>token},
292
288
  {'source'=>sources[0][:name]},{'count'=>1},{'insert'=>{'1'=>@product1}}]]
@@ -72,6 +72,17 @@ describe "SourceSync" do
72
72
  end
73
73
  end
74
74
 
75
+ it "should process source adapter schema" do
76
+ mock_schema_method([SampleAdapter]) do
77
+ expected = {'1'=>@product1,'2'=>@product2}
78
+ set_state('test_db_storage' => expected)
79
+ @ss.process_query
80
+ verify_result(@s.docname(:md) => expected,
81
+ @s.docname(:schema) => "{\"property\":{\"brand\":\"string\",\"name\":\"string\"},\"version\":\"1.0\"}",
82
+ @s.docname(:schema_sha1) => "8c148c8c1a66c7baf685c07d58bea360da87981b")
83
+ end
84
+ end
85
+
75
86
  it "should process source adapter with stash" do
76
87
  expected = {'1'=>@product1,'2'=>@product2}
77
88
  set_state('test_db_storage' => expected)
@@ -94,6 +105,16 @@ describe "SourceSync" do
94
105
  end
95
106
  end
96
107
 
108
+ it "should process source adapter with pass_through set" do
109
+ expected = {'1'=>@product1,'2'=>@product2}
110
+ set_state('test_db_storage' => expected)
111
+ @s.pass_through = 'true'
112
+ @ss.process_query.should == expected
113
+ verify_result(@s.docname(:md) => {},
114
+ @s.docname(:md_size) => nil)
115
+ @s.pass_through = nil
116
+ end
117
+
97
118
  describe "create" do
98
119
  it "should do create where adapter.create returns nil" do
99
120
  set_state(@c.docname(:create) => {'2'=>@product2})
@@ -219,7 +240,7 @@ describe "SourceSync" do
219
240
  verify_result(@s.docname(:md) => expected,
220
241
  @s.docname(:errors) => {})
221
242
  else
222
- @ss.search(@c.id).should == true
243
+ @ss.search(@c.id).should == expected
223
244
  verify_result(@c.docname(:search) => expected,
224
245
  @c.docname(:search_errors) => {})
225
246
  end
@@ -230,11 +251,11 @@ describe "SourceSync" do
230
251
  @ss.should_receive(:log).with("SourceAdapter raised #{operation} exception: #{msg}")
231
252
  set_test_data('test_db_storage',{},msg,"#{operation} error")
232
253
  if operation == 'query'
233
- @ss.read.should == true
254
+ @ss.read.should be_nil
234
255
  verify_result(@s.docname(:md) => {},
235
256
  @s.docname(:errors) => {'query-error'=>{'message'=>msg}})
236
257
  else
237
- @ss.search(@c.id).should == true
258
+ @ss.search(@c.id).should be_nil
238
259
  verify_result(@c.docname(:search) => {},
239
260
  @c.docname(:search_errors) => {'search-error'=>{'message'=>msg}})
240
261
  end
data/spec/spec_helper.rb CHANGED
@@ -115,7 +115,7 @@ module TestHelpers
115
115
 
116
116
  def validate_db_by_name(db,s,data)
117
117
  db.execute("select source_id,name,sync_priority,partition,
118
- sync_type,source_attribs,metadata,blob_attribs,associations
118
+ sync_type,source_attribs,metadata,schema,blob_attribs,associations
119
119
  from sources where name='#{s.name}'").each do |row|
120
120
  return false if row[0].to_s != s.source_id.to_s
121
121
  return false if row[1] != s.name
@@ -124,8 +124,9 @@ module TestHelpers
124
124
  return false if row[4] != s.sync_type.to_s
125
125
  return false if row[5] != (s.schema ? "" : get_attrib_counter(data))
126
126
  return false if row[6] != s.get_value(:metadata)
127
- return false if row[7] != s.blob_attribs
128
- return false if row[8] != s.has_many
127
+ return false if row[7] != s.schema
128
+ return false if row[8] != s.blob_attribs
129
+ return false if row[9] != s.has_many
129
130
  end
130
131
 
131
132
  data = json_clone(data)
@@ -174,6 +175,24 @@ module TestHelpers
174
175
  end
175
176
  end
176
177
 
178
+ def mock_schema_method(adapters, &block)
179
+ adapters.each do |klass|
180
+ klass.class_eval 'def schema
181
+ {
182
+ "property" => {
183
+ "name" => "string",
184
+ "brand" => "string"
185
+ },
186
+ "version" => "1.0"
187
+ }.to_json
188
+ end'
189
+ end
190
+ yield
191
+ adapters.each do |klass|
192
+ klass.class_eval "def schema; end"
193
+ end
194
+ end
195
+
177
196
  def unzip_file(file,file_dir)
178
197
  Zip::ZipFile.open(file) do |zip_file|
179
198
  zip_file.each do |f|
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rhosync
3
3
  version: !ruby/object:Gem::Version
4
- hash: 62196465
4
+ hash: 62196471
5
5
  prerelease: true
6
6
  segments:
7
7
  - 2
8
8
  - 1
9
9
  - 0
10
10
  - beta
11
- - 1
12
- version: 2.1.0.beta.1
11
+ - 2
12
+ version: 2.1.0.beta.2
13
13
  platform: ruby
14
14
  authors:
15
15
  - Rhomobile
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2010-11-07 00:00:00 -07:00
20
+ date: 2010-12-07 00:00:00 -08:00
21
21
  default_executable: rhosync
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
@@ -156,11 +156,11 @@ dependencies:
156
156
  requirements:
157
157
  - - ~>
158
158
  - !ruby/object:Gem::Version
159
- hash: 15
159
+ hash: 13
160
160
  segments:
161
161
  - 1
162
- - 0
163
- version: "1.0"
162
+ - 1
163
+ version: "1.1"
164
164
  type: :runtime
165
165
  version_requirements: *id009
166
166
  - !ruby/object:Gem::Dependency
@@ -551,8 +551,8 @@ homepage: http://rhomobile.com/products/rhosync
551
551
  licenses: []
552
552
 
553
553
  post_install_message:
554
- rdoc_options:
555
- - --charset=UTF-8
554
+ rdoc_options: []
555
+
556
556
  require_paths:
557
557
  - lib
558
558
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -583,6 +583,9 @@ signing_key:
583
583
  specification_version: 3
584
584
  summary: RhoSync Synchronization Framework
585
585
  test_files:
586
+ - examples/simple/application.rb
587
+ - examples/simple/sources/sample_adapter.rb
588
+ - examples/simple/sources/simple_adapter.rb
586
589
  - spec/api/api_helper.rb
587
590
  - spec/api/create_client_spec.rb
588
591
  - spec/api/create_user_spec.rb
@@ -616,8 +619,8 @@ test_files:
616
619
  - spec/apps/rhotestapp/sources/sample_adapter.rb
617
620
  - spec/apps/rhotestapp/sources/simple_adapter.rb
618
621
  - spec/apps/rhotestapp/sources/sub_adapter.rb
619
- - spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem/mygem.rb
620
622
  - spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem.rb
623
+ - spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem/mygem.rb
621
624
  - spec/bulk_data/bulk_data_spec.rb
622
625
  - spec/client_spec.rb
623
626
  - spec/client_sync_spec.rb
@@ -649,6 +652,3 @@ test_files:
649
652
  - spec/sync_states_spec.rb
650
653
  - spec/test_methods_spec.rb
651
654
  - spec/user_spec.rb
652
- - examples/simple/application.rb
653
- - examples/simple/sources/sample_adapter.rb
654
- - examples/simple/sources/simple_adapter.rb