maestrano-connector-rails 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/app/controllers/maestrano/dependancies_controller.rb +5 -0
  4. data/app/controllers/maestrano/synchronizations_controller.rb +46 -0
  5. data/app/jobs/maestrano/connector/rails/synchronization_job.rb +49 -12
  6. data/app/models/maestrano/connector/rails/complex_entity.rb +1 -1
  7. data/app/models/maestrano/connector/rails/concerns/complex_entity.rb +4 -25
  8. data/app/models/maestrano/connector/rails/concerns/connec_helper.rb +17 -0
  9. data/app/models/maestrano/connector/rails/concerns/entity.rb +33 -34
  10. data/app/models/maestrano/connector/rails/concerns/entity_base.rb +34 -0
  11. data/app/models/maestrano/connector/rails/entity.rb +2 -2
  12. data/app/models/maestrano/connector/rails/entity_base.rb +5 -0
  13. data/config/routes.rb +7 -0
  14. data/lib/generators/connector/templates/entity.rb +2 -1
  15. data/maestrano-connector-rails.gemspec +11 -6
  16. data/spec/controllers/dependancies_controller_spec.rb +31 -0
  17. data/spec/controllers/synchronizations_controller_spec.rb +179 -0
  18. data/spec/dummy/app/models/entities/.keep +0 -0
  19. data/spec/jobs/synchronization_job_spec.rb +84 -32
  20. data/spec/models/complex_entity_spec.rb +11 -0
  21. data/spec/models/connec_helper_spec.rb +22 -0
  22. data/spec/models/entity_base_spec.rb +20 -0
  23. data/spec/models/entity_spec.rb +21 -2
  24. data/spec/models/external_spec.rb +9 -5
  25. data/spec/models/sub_entity_base_spec.rb +0 -1
  26. data/spec/spec_helper.rb +7 -1
  27. metadata +10 -5
  28. data/spec/dummy/app/models/entities/example_entitiy.rb +0 -26
  29. data/spec/dummy/app/models/maestrano/connector/rails/entity.rb +0 -3
  30. data/spec/dummy/app/models/maestrano/connector/rails/external.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 252ed0e53f7dcb7b820c329f3cfac7f1a6523633
4
- data.tar.gz: e3fc619f7c65568d1b4db83e918ffd17b1b26556
3
+ metadata.gz: 48d5cff94c3992312d69f4ae46493d883e9c752f
4
+ data.tar.gz: c9fb97913e6f032198ec72fc69bb2351aa220546
5
5
  SHA512:
6
- metadata.gz: 0ebed3f59cbe4a425b82c2a532244b4f2e7fd3b3feba3b46135b6fc39e40fce131a7ac0837132dbae7abec21c9446e47ce1c0878bbe9cf625e9bd3f3c946f213
7
- data.tar.gz: ad5443f7a03bd2c41e12945ed65d7655dffba7e4f6b2602b864cf49c24f0045d73a4f7cc46b157b76a6c79d63a11b12d80d2bda6a75e11560b0c46b5769116fe
6
+ metadata.gz: 9635d73732f2d8e40e545049ddf45d752b2c725d2660fc03bbbda23fc158fbab0d4445b0721736a96f4596970e9f740fd98b7f3be2efb0bc4296f3a9c68bc40b
7
+ data.tar.gz: 94486ead1d56581183097dfb52f08498bf0fe093b5b220bfe91b83803007baf6a01a0b80d5d18b71cb5be9ccb075a916681e3f396be09f5adf1494be6e5117b0
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.2
1
+ 1.2.0
@@ -0,0 +1,5 @@
1
+ class Maestrano::DependanciesController < Maestrano::Rails::WebHookController
2
+ def index
3
+ render json: Maestrano::Connector::Rails::ConnecHelper.dependancies
4
+ end
5
+ end
@@ -0,0 +1,46 @@
1
+ class Maestrano::SynchronizationsController < Maestrano::Rails::WebHookController
2
+ def show
3
+ uid = params[:id]
4
+ organization = Maestrano::Connector::Rails::Organization.find_by_uid(uid)
5
+ return render json: { errors: {message: "Organization not found", code: 404} }, status: :not_found unless organization
6
+
7
+ h = {
8
+ group_id: organization.uid,
9
+ sync_enabled: organization.sync_enabled
10
+ }
11
+
12
+ last_sync = organization.synchronizations.last
13
+ if last_sync
14
+ h.merge!(
15
+ {
16
+ status: last_sync.status,
17
+ message: last_sync.message,
18
+ updated_at: last_sync.updated_at
19
+ }
20
+ )
21
+ end
22
+
23
+ render json: h
24
+ end
25
+
26
+ def create
27
+ uid = params[:group_id]
28
+ opts = params[:opts] || {}
29
+ organization = Maestrano::Connector::Rails::Organization.find_by_uid(uid)
30
+ return render json: { errors: {message: "Organization not found", code: 404} }, status: :not_found unless organization
31
+
32
+ Maestrano::Connector::Rails::SynchronizationJob.perform_later(organization, opts.with_indifferent_access)
33
+ head :created
34
+ end
35
+
36
+ def toggle_sync
37
+ uid = params[:group_id]
38
+ organization = Maestrano::Connector::Rails::Organization.find_by_uid(uid)
39
+ return render json: { errors: {message: "Organization not found", code: 404} }, status: :not_found unless organization
40
+
41
+ organization.toggle(:sync_enabled)
42
+ organization.save
43
+
44
+ render json: {sync_enabled: organization.sync_enabled}
45
+ end
46
+ end
@@ -35,12 +35,14 @@ module Maestrano::Connector::Rails
35
35
 
36
36
  # First synchronization should be from external to Connec! only to let the smart merging works
37
37
  # We do a doube sync: only from external, then only from connec!
38
+ # We also do batched sync as the first one can be quite huge
38
39
  if last_synchronization.nil?
39
40
  ConnectorLogger.log('info', organization, "First synchronization ever. Doing two half syncs to allow smart merging to work its magic.")
40
- [{skip_connec: true}, {skip_external: true}].each do |opt|
41
- organization.synchronized_entities.select{|k, v| v}.keys.each do |entity|
42
- sync_entity(entity.to_s, organization, connec_client, external_client, last_synchronization_date, opts.merge(opt))
43
- end
41
+ organization.synchronized_entities.select{|k, v| v}.keys.each do |entity|
42
+ ConnectorLogger.log('info', organization, "First synchronization ever. Doing half sync from external for #{entity}.")
43
+ first_sync_entity(entity.to_s, organization, connec_client, external_client, last_synchronization_date, opts, true)
44
+ ConnectorLogger.log('info', organization, "First synchronization ever. Doing half sync from Connec! for #{entity}.")
45
+ first_sync_entity(entity.to_s, organization, connec_client, external_client, last_synchronization_date, opts, false)
44
46
  end
45
47
  elsif opts[:only_entities]
46
48
  ConnectorLogger.log('info', organization, "Synchronization is partial and will synchronize only #{opts[:only_entities].join(' ')}")
@@ -64,15 +66,50 @@ module Maestrano::Connector::Rails
64
66
  end
65
67
 
66
68
  def sync_entity(entity_name, organization, connec_client, external_client, last_synchronization_date, opts)
67
- entity_instance = "Entities::#{entity_name.titleize.split.join}".constantize.new(organization, connec_client, external_client, opts.dup)
69
+ entity_instance = instanciate_entity(entity_name, organization, connec_client, external_client, opts)
70
+
71
+ perform_sync(entity_instance, last_synchronization_date)
72
+ end
73
+
74
+ # Does a batched sync on either external or connec!
75
+ def first_sync_entity(entity_name, organization, connec_client, external_client, last_synchronization_date, opts, external = true)
76
+ limit = Settings.first_sync_batch_size || 50
77
+ skip = 0
78
+ entities_count = limit
79
+
80
+ h = {__limit: limit}
81
+ external ? h.merge!(__skip_connec: true) : h.merge!(__skip_external: true)
82
+ entity_instance = instanciate_entity(entity_name, organization, connec_client, external_client, opts.merge(h))
68
83
 
69
- entity_instance.before_sync(last_synchronization_date)
70
- external_entities = entity_instance.get_external_entities_wrapper(last_synchronization_date)
71
- connec_entities = entity_instance.get_connec_entities(last_synchronization_date)
72
- mapped_entities = entity_instance.consolidate_and_map_data(connec_entities, external_entities)
73
- entity_instance.push_entities_to_external(mapped_entities[:connec_entities])
74
- entity_instance.push_entities_to_connec(mapped_entities[:external_entities])
75
- entity_instance.after_sync(last_synchronization_date)
84
+ # IF entities_count > limit
85
+ # This first sync feature is probably not implemented in the connector
86
+ # because it fetched more than the expected number of entities
87
+ # No need to fetch it a second Time
88
+ # ELSIF entities_count < limit
89
+ # No more entities to fetch
90
+ while entities_count == limit do
91
+ entity_instance.opts_merge!(__skip: skip)
92
+ entities_count = perform_sync(entity_instance, last_synchronization_date, external)
93
+ skip += limit
94
+ end
76
95
  end
96
+
97
+ private
98
+ def instanciate_entity(entity_name, organization, connec_client, external_client, opts)
99
+ "Entities::#{entity_name.titleize.split.join}".constantize.new(organization, connec_client, external_client, opts.dup)
100
+ end
101
+
102
+ # Perform the sync and return the entities_count for either external or connec
103
+ def perform_sync(entity_instance, last_synchronization_date, external = true)
104
+ entity_instance.before_sync(last_synchronization_date)
105
+ external_entities = entity_instance.get_external_entities_wrapper(last_synchronization_date)
106
+ connec_entities = entity_instance.get_connec_entities(last_synchronization_date)
107
+ mapped_entities = entity_instance.consolidate_and_map_data(connec_entities, external_entities)
108
+ entity_instance.push_entities_to_external(mapped_entities[:connec_entities])
109
+ entity_instance.push_entities_to_connec(mapped_entities[:external_entities])
110
+ entity_instance.after_sync(last_synchronization_date)
111
+
112
+ external ? entity_instance.class.count_entities(external_entities) : entity_instance.class.count_entities(connec_entities)
113
+ end
77
114
  end
78
115
  end
@@ -1,5 +1,5 @@
1
1
  module Maestrano::Connector::Rails
2
- class ComplexEntity
2
+ class ComplexEntity < EntityBase
3
3
  include Maestrano::Connector::Rails::Concerns::ComplexEntity
4
4
  end
5
5
  end
@@ -1,13 +1,6 @@
1
1
  module Maestrano::Connector::Rails::Concerns::ComplexEntity
2
2
  extend ActiveSupport::Concern
3
3
 
4
- def initialize(organization, connec_client, external_client, opts={})
5
- @organization = organization
6
- @connec_client = connec_client
7
- @external_client = external_client
8
- @opts = opts
9
- end
10
-
11
4
  # -------------------------------------------------------------
12
5
  # Complex specific methods
13
6
  # Those methods needs to be implemented in each complex entity
@@ -20,6 +13,10 @@ module Maestrano::Connector::Rails::Concerns::ComplexEntity
20
13
  def external_entities_names
21
14
  raise "Not implemented"
22
15
  end
16
+
17
+ def count_entities(entities)
18
+ entities.values.map(&:size).max
19
+ end
23
20
  end
24
21
 
25
22
  # input : {
@@ -141,24 +138,6 @@ module Maestrano::Connector::Rails::Concerns::ComplexEntity
141
138
  end
142
139
  end
143
140
 
144
- def before_sync(last_synchronization_date)
145
- # Does nothing by default
146
- end
147
-
148
- def after_sync(last_synchronization_date)
149
- # Does nothing by default
150
- end
151
-
152
- # This method is called during the webhook workflow only. It should return the hash of arrays of filtered entities
153
- # The aim is to have the same filtering as with the Connec! filters on API calls in the webhooks
154
- # input : {
155
- # external_entities_names[0]: [unmapped_external_entity1}, unmapped_external_entity2],
156
- # external_entities_names[1]: [unmapped_external_entity3}, unmapped_external_entity4]
157
- # }
158
- def filter_connec_entities(entities)
159
- entities
160
- end
161
-
162
141
  def instantiate_sub_entity_instance(entity_name)
163
142
  "Entities::SubEntities::#{entity_name.titleize.split.join}".constantize.new(@organization, @connec_client, @external_client, @opts)
164
143
  end
@@ -2,12 +2,29 @@ module Maestrano::Connector::Rails::Concerns::ConnecHelper
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  module ClassMethods
5
+ def dependancies
6
+ # Meant to be overloaded if needed
7
+ {
8
+ connec: '1.0',
9
+ impac: '1.0',
10
+ maestrano_hub: '1.0'
11
+ }
12
+ end
5
13
 
6
14
  def get_client(organization)
7
15
  client = Maestrano::Connec::Client[organization.tenant].new(organization.uid)
8
16
  client.class.headers('CONNEC-EXTERNAL-IDS' => 'true')
9
17
  client
10
18
  end
19
+
20
+ def connec_version(organization)
21
+ @@connec_version = Rails.cache.fetch('connec_version', namespace: 'maestrano', expires_in: 1.day) do
22
+ response = get_client(organization).class.get("#{Maestrano[organization.tenant].param('connec.host')}/version")
23
+ response = JSON.parse(response.body)
24
+ @@connec_version = response['ci_branch']
25
+ end
26
+ @@connec_version
27
+ end
11
28
 
12
29
  # Replace the ids arrays by the external id
13
30
  # If a reference has no id for this oauth_provider and oauth_uid but has one for connec returns nil
@@ -1,13 +1,6 @@
1
1
  module Maestrano::Connector::Rails::Concerns::Entity
2
2
  extend ActiveSupport::Concern
3
3
 
4
- def initialize(organization, connec_client, external_client, opts={})
5
- @organization = organization
6
- @connec_client = connec_client
7
- @external_client = external_client
8
- @opts = opts
9
- end
10
-
11
4
  module ClassMethods
12
5
  # ----------------------------------------------
13
6
  # IdMap methods
@@ -131,8 +124,21 @@ module Maestrano::Connector::Rails::Concerns::Entity
131
124
  def can_update_external?
132
125
  true
133
126
  end
127
+
128
+ # ----------------------------------------------
129
+ # Helper methods
130
+ # ----------------------------------------------
131
+ def count_entities(entities)
132
+ entities.size
133
+ end
134
134
  end
135
135
 
136
+ # ==============================================
137
+ # ==============================================
138
+ # Instance methods
139
+ # ==============================================
140
+ # ==============================================
141
+
136
142
  # ----------------------------------------------
137
143
  # Mapper methods
138
144
  # ----------------------------------------------
@@ -159,7 +165,7 @@ module Maestrano::Connector::Rails::Concerns::Entity
159
165
  # * $filter (see Connec! documentation)
160
166
  # * $orderby (see Connec! documentation)
161
167
  def get_connec_entities(last_synchronization_date=nil)
162
- return [] if @opts[:skip_connec] || !self.class.can_read_connec?
168
+ return [] if @opts[:__skip_connec] || !self.class.can_read_connec?
163
169
 
164
170
  Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Fetching Connec! #{self.class.connec_entity_name}")
165
171
 
@@ -169,6 +175,13 @@ module Maestrano::Connector::Rails::Concerns::Entity
169
175
 
170
176
  # Fetch first page
171
177
  page_number = 0
178
+
179
+ batched_fetch = @opts[:__limit] && @opts[:__skip]
180
+ if batched_fetch
181
+ query_params[:$top] = @opts[:__limit]
182
+ query_params[:$skip] = @opts[:__skip]
183
+ end
184
+
172
185
  if last_synchronization_date.blank? || @opts[:full_sync]
173
186
  query_params[:$filter] = @opts[:$filter] if @opts[:$filter]
174
187
  else
@@ -181,14 +194,17 @@ module Maestrano::Connector::Rails::Concerns::Entity
181
194
  entities = response_hash["#{self.class.normalized_connec_entity_name}"]
182
195
  entities = [entities] if self.class.singleton?
183
196
 
184
- # Fetch subsequent pages
185
- while response_hash['pagination'] && response_hash['pagination']['next']
186
- page_number += 1
187
- # ugly way to convert https://api-connec/api/v2/group_id/organizations?next_page_params to /organizations?next_page_params
188
- next_page = response_hash['pagination']['next'].gsub(/^(.*)\/#{self.class.normalized_connec_entity_name}/, self.class.normalized_connec_entity_name)
197
+ # Only the first page if batched_fetch
198
+ unless batched_fetch
199
+ # Fetch subsequent pages
200
+ while response_hash['pagination'] && response_hash['pagination']['next']
201
+ page_number += 1
202
+ # ugly way to convert https://api-connec/api/v2/group_id/organizations?next_page_params to /organizations?next_page_params
203
+ next_page = response_hash['pagination']['next'].gsub(/^(.*)\/#{self.class.normalized_connec_entity_name}/, self.class.normalized_connec_entity_name)
189
204
 
190
- response_hash = fetch_connec(next_page, page_number)
191
- entities << response_hash["#{self.class.normalized_connec_entity_name}"]
205
+ response_hash = fetch_connec(next_page, page_number)
206
+ entities << response_hash["#{self.class.normalized_connec_entity_name}"]
207
+ end
192
208
  end
193
209
 
194
210
  entities.flatten!
@@ -224,7 +240,7 @@ module Maestrano::Connector::Rails::Concerns::Entity
224
240
  # External methods
225
241
  # ----------------------------------------------
226
242
  def get_external_entities_wrapper(last_synchronization_date=nil)
227
- return [] if @opts[:skip_external] || !self.class.can_read_external?
243
+ return [] if @opts[:__skip_external] || !self.class.can_read_external?
228
244
  get_external_entities(last_synchronization_date)
229
245
  end
230
246
 
@@ -299,12 +315,6 @@ module Maestrano::Connector::Rails::Concerns::Entity
299
315
  raise "Not implemented"
300
316
  end
301
317
 
302
- # This method is called during the webhook workflow only. It should return the array of filtered entities
303
- # The aim is to have the same filtering as with the Connec! filters on API calls in the webhooks
304
- def filter_connec_entities(entities)
305
- entities
306
- end
307
-
308
318
  # ----------------------------------------------
309
319
  # General methods
310
320
  # ----------------------------------------------
@@ -313,6 +323,7 @@ module Maestrano::Connector::Rails::Concerns::Entity
313
323
  # * Maps not discarded entities and associates them with their idmap, or create one if there isn't any
314
324
  # * Returns a hash {connec_entities: [], external_entities: []}
315
325
  def consolidate_and_map_data(connec_entities, external_entities)
326
+ Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Consolidating and mapping #{self.class.external_entity_name}/#{self.class.connec_entity_name}")
316
327
  return consolidate_and_map_singleton(connec_entities, external_entities) if self.class.singleton?
317
328
 
318
329
  mapped_connec_entities = consolidate_and_map_connec_entities(connec_entities, external_entities, self.class.references, self.class.external_entity_name)
@@ -395,18 +406,6 @@ module Maestrano::Connector::Rails::Concerns::Entity
395
406
  end
396
407
  end
397
408
 
398
- # ----------------------------------------------
399
- # After and before sync
400
- # ----------------------------------------------
401
- def before_sync(last_synchronization_date)
402
- # Does nothing by default
403
- end
404
-
405
- def after_sync(last_synchronization_date)
406
- # Does nothing by default
407
- end
408
-
409
-
410
409
  # ----------------------------------------------
411
410
  # Internal helper methods
412
411
  # ----------------------------------------------
@@ -0,0 +1,34 @@
1
+ module Maestrano::Connector::Rails::Concerns::EntityBase
2
+ extend ActiveSupport::Concern
3
+
4
+ def initialize(organization, connec_client, external_client, opts={})
5
+ @organization = organization
6
+ @connec_client = connec_client
7
+ @external_client = external_client
8
+ @opts = opts
9
+ end
10
+
11
+ def opts_merge!(opts)
12
+ @opts.merge!(opts)
13
+ end
14
+
15
+ def before_sync(last_synchronization_date)
16
+ # Does nothing by default
17
+ end
18
+
19
+ def after_sync(last_synchronization_date)
20
+ # Does nothing by default
21
+ end
22
+
23
+ # This method is called during the webhook workflow only. It should return the hash of arrays of filtered entities
24
+ # The aim is to have the same filtering as with the Connec! filters on API calls in the webhooks
25
+ # input :
26
+ # For non complex entities [unmapped_external_entity1, unmapped_external_entity2]
27
+ # For complex entities {
28
+ # external_entities_names[0]: [unmapped_external_entity1, unmapped_external_entity2],
29
+ # external_entities_names[1]: [unmapped_external_entity3, unmapped_external_entity4]
30
+ # }
31
+ def filter_connec_entities(entities)
32
+ entities
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  module Maestrano::Connector::Rails
2
- class Entity
2
+ class Entity < EntityBase
3
3
  include Maestrano::Connector::Rails::Concerns::Entity
4
4
  end
5
- end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Maestrano::Connector::Rails
2
+ class EntityBase
3
+ include Maestrano::Connector::Rails::Concerns::EntityBase
4
+ end
5
+ end
data/config/routes.rb CHANGED
@@ -4,5 +4,12 @@ Maestrano::Connector::Rails::Engine.routes.draw do
4
4
  namespace :maestrano do
5
5
  match 'signout', to: 'sessions#destroy', as: 'signout', via: [:get, :post]
6
6
  post 'connec/notifications/:tenant' => 'connec#notifications'
7
+
8
+ resources :synchronizations, only: [:show, :create] do
9
+ collection do
10
+ put :toggle_sync
11
+ end
12
+ end
13
+ resources :dependancies, only: [:index]
7
14
  end
8
15
  end
@@ -1,4 +1,4 @@
1
- class Maestrano::Connector::Rails::Entity
1
+ class Maestrano::Connector::Rails::Entity < Maestrano::Connector::Rails::EntityBase
2
2
  include Maestrano::Connector::Rails::Concerns::Entity
3
3
 
4
4
  # In this class and in all entities which inherit from it, the following instance variables are available:
@@ -13,6 +13,7 @@ class Maestrano::Connector::Rails::Entity
13
13
  # TODO
14
14
  # This method should return only entities that have been updated since the last_synchronization_date
15
15
  # It should also implements an option to do a full synchronization when @opts[:full_sync] == true or when there is no last_synchronization_date
16
+ # It should also support [:__limit] and [:__skip] opts, meaning that if they are present, it should return only @[:__limit] entities while skipping the @opts[:__skip] firsts
16
17
  # Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Received data: Source=#{Maestrano::Connector::Rails::External.external_name}, Entity=#{self.class.external_entity_name}, Response=#{entities}")
17
18
  end
18
19
 
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: maestrano-connector-rails 1.1.2 ruby lib
5
+ # stub: maestrano-connector-rails 1.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "maestrano-connector-rails"
9
- s.version = "1.1.2"
9
+ s.version = "1.2.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Pierre Berard"]
14
- s.date = "2016-06-22"
14
+ s.date = "2016-07-01"
15
15
  s.description = "Maestrano is the next generation marketplace for SME applications. See https://maestrano.com for details."
16
16
  s.email = "pierre.berard@maestrano.com"
17
17
  s.executables = ["rails"]
@@ -32,7 +32,9 @@ Gem::Specification.new do |s|
32
32
  "app/controllers/maestrano/application_controller.rb",
33
33
  "app/controllers/maestrano/auth/saml_controller.rb",
34
34
  "app/controllers/maestrano/connec_controller.rb",
35
+ "app/controllers/maestrano/dependancies_controller.rb",
35
36
  "app/controllers/maestrano/sessions_controller.rb",
37
+ "app/controllers/maestrano/synchronizations_controller.rb",
36
38
  "app/helpers/maestrano/connector/rails/session_helper.rb",
37
39
  "app/jobs/maestrano/connector/rails/all_synchronizations_job.rb",
38
40
  "app/jobs/maestrano/connector/rails/push_to_connec_job.rb",
@@ -42,11 +44,13 @@ Gem::Specification.new do |s|
42
44
  "app/models/maestrano/connector/rails/concerns/connec_helper.rb",
43
45
  "app/models/maestrano/connector/rails/concerns/connector_logger.rb",
44
46
  "app/models/maestrano/connector/rails/concerns/entity.rb",
47
+ "app/models/maestrano/connector/rails/concerns/entity_base.rb",
45
48
  "app/models/maestrano/connector/rails/concerns/external.rb",
46
49
  "app/models/maestrano/connector/rails/concerns/sub_entity_base.rb",
47
50
  "app/models/maestrano/connector/rails/connec_helper.rb",
48
51
  "app/models/maestrano/connector/rails/connector_logger.rb",
49
52
  "app/models/maestrano/connector/rails/entity.rb",
53
+ "app/models/maestrano/connector/rails/entity_base.rb",
50
54
  "app/models/maestrano/connector/rails/external.rb",
51
55
  "app/models/maestrano/connector/rails/id_map.rb",
52
56
  "app/models/maestrano/connector/rails/organization.rb",
@@ -102,8 +106,10 @@ Gem::Specification.new do |s|
102
106
  "maestrano.png",
103
107
  "release_notes.md",
104
108
  "spec/controllers/connec_controller_spec.rb",
109
+ "spec/controllers/dependancies_controller_spec.rb",
105
110
  "spec/controllers/group_users_controller_spec.rb",
106
111
  "spec/controllers/groups_controller_spec.rb",
112
+ "spec/controllers/synchronizations_controller_spec.rb",
107
113
  "spec/dummy/README.md",
108
114
  "spec/dummy/Rakefile",
109
115
  "spec/dummy/app/assets/images/.keep",
@@ -118,9 +124,7 @@ Gem::Specification.new do |s|
118
124
  "spec/dummy/app/mailers/.keep",
119
125
  "spec/dummy/app/models/.keep",
120
126
  "spec/dummy/app/models/concerns/.keep",
121
- "spec/dummy/app/models/entities/example_entitiy.rb",
122
- "spec/dummy/app/models/maestrano/connector/rails/entity.rb",
123
- "spec/dummy/app/models/maestrano/connector/rails/external.rb",
127
+ "spec/dummy/app/models/entities/.keep",
124
128
  "spec/dummy/app/views/home/index.html.erb",
125
129
  "spec/dummy/app/views/layouts/application.html.erb",
126
130
  "spec/dummy/bin/bundle",
@@ -170,6 +174,7 @@ Gem::Specification.new do |s|
170
174
  "spec/models/complex_entity_spec.rb",
171
175
  "spec/models/connec_helper_spec.rb",
172
176
  "spec/models/connector_logger_spec.rb",
177
+ "spec/models/entity_base_spec.rb",
173
178
  "spec/models/entity_spec.rb",
174
179
  "spec/models/external_spec.rb",
175
180
  "spec/models/id_map_spec.rb",
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Maestrano::DependanciesController, type: :controller do
4
+ routes { Maestrano::Connector::Rails::Engine.routes }
5
+
6
+ describe 'index' do
7
+ subject { get :index }
8
+
9
+ context 'without authentication' do
10
+ before {
11
+ controller.class.before_filter :authenticate_maestrano!
12
+ }
13
+
14
+ it 'respond with unauthorized' do
15
+ subject
16
+ expect(response.status).to eq(401)
17
+ end
18
+ end
19
+
20
+ context 'with authentication' do
21
+ before {
22
+ controller.class.skip_before_filter :authenticate_maestrano!
23
+ }
24
+
25
+ it 'renders the dependancies hash' do
26
+ subject
27
+ expect(response.body).to eql(Maestrano::Connector::Rails::ConnecHelper.dependancies.to_json)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,179 @@
1
+ require 'spec_helper'
2
+
3
+ describe Maestrano::SynchronizationsController, type: :controller do
4
+ routes { Maestrano::Connector::Rails::Engine.routes }
5
+
6
+ let(:uid) { 'cld-aaaa' }
7
+
8
+ describe 'show' do
9
+ subject { get :show, id: uid }
10
+
11
+
12
+ context 'without authentication' do
13
+ before {
14
+ controller.class.before_filter :authenticate_maestrano!
15
+ }
16
+
17
+ it 'respond with unauthorized' do
18
+ subject
19
+ expect(response.status).to eq(401)
20
+ end
21
+ end
22
+
23
+ context 'with authentication' do
24
+ before {
25
+ controller.class.skip_before_filter :authenticate_maestrano!
26
+ }
27
+
28
+ context 'when organization is not found' do
29
+ let!(:organization) { create(:organization, uid: 'cld-bbbb') }
30
+
31
+ it 'is a 404' do
32
+ subject
33
+ expect(response.status).to eq(404)
34
+ end
35
+ end
36
+
37
+ context 'when organization is found' do
38
+ let!(:organization) { create(:organization, uid: uid) }
39
+
40
+ it 'is a success' do
41
+ subject
42
+ expect(response.status).to eq(200)
43
+ end
44
+
45
+ context 'with no last sync' do
46
+ it 'renders a partial json' do
47
+ subject
48
+ expect(JSON.parse(response.body)).to eql(
49
+ JSON.parse({
50
+ group_id: organization.uid,
51
+ sync_enabled: organization.sync_enabled,
52
+ }.to_json)
53
+ )
54
+ end
55
+ end
56
+
57
+ context 'with a last sync' do
58
+ let!(:sync1) { create(:synchronization, organization: organization) }
59
+ let!(:sync2) { create(:synchronization, organization: organization, message: 'msg') }
60
+
61
+ it 'renders a full json' do
62
+ subject
63
+ expect(JSON.parse(response.body)).to eql(
64
+ JSON.parse({
65
+ group_id: organization.uid,
66
+ sync_enabled: organization.sync_enabled,
67
+ status: sync2.status,
68
+ message: sync2.message,
69
+ updated_at: sync2.updated_at
70
+ }.to_json)
71
+ )
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ describe 'create' do
79
+ let(:opts) { {'only_entities' => ['customer']} }
80
+ subject { post :create, group_id: uid, opts: opts }
81
+
82
+
83
+ context 'without authentication' do
84
+ before {
85
+ controller.class.before_filter :authenticate_maestrano!
86
+ }
87
+
88
+ it 'respond with unauthorized' do
89
+ subject
90
+ expect(response.status).to eq(401)
91
+ end
92
+ end
93
+
94
+ context 'with authentication' do
95
+ before {
96
+ controller.class.skip_before_filter :authenticate_maestrano!
97
+ }
98
+
99
+ context 'when organization is not found' do
100
+ let!(:organization) { create(:organization, uid: 'cld-bbbb') }
101
+
102
+ it 'is a 404' do
103
+ subject
104
+ expect(response.status).to eq(404)
105
+ end
106
+ end
107
+
108
+ context 'when organization is found' do
109
+ let!(:organization) { create(:organization, uid: uid) }
110
+
111
+ it 'is a success' do
112
+ subject
113
+ expect(response.status).to eq(201)
114
+ end
115
+
116
+ it 'queues a sync' do
117
+ expect(Maestrano::Connector::Rails::SynchronizationJob).to receive(:perform_later).with(organization, opts)
118
+ subject
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ describe 'toggle_sync' do
125
+ subject { put :toggle_sync, group_id: uid }
126
+
127
+
128
+ context 'without authentication' do
129
+ before {
130
+ controller.class.before_filter :authenticate_maestrano!
131
+ }
132
+
133
+ it 'respond with unauthorized' do
134
+ subject
135
+ expect(response.status).to eq(401)
136
+ end
137
+ end
138
+
139
+ context 'with authentication' do
140
+ before {
141
+ controller.class.skip_before_filter :authenticate_maestrano!
142
+ }
143
+
144
+ context 'when organization is not found' do
145
+ let!(:organization) { create(:organization, uid: 'cld-bbbb') }
146
+
147
+ it 'is a 404' do
148
+ subject
149
+ expect(response.status).to eq(404)
150
+ end
151
+ end
152
+
153
+ context 'when organization is found' do
154
+ let!(:organization) { create(:organization, uid: uid) }
155
+
156
+ it 'is a success' do
157
+ subject
158
+ expect(response.status).to eq(200)
159
+ end
160
+
161
+ context 'when sync_enabled is true' do
162
+ before { organization.update(sync_enabled: true) }
163
+ it 'disables the organizatio syncs' do
164
+ subject
165
+ expect(organization.reload.sync_enabled).to be false
166
+ end
167
+ end
168
+
169
+ context 'when sync_enabled is false' do
170
+ before { organization.update(sync_enabled: false) }
171
+ it 'enables the organizatio syncs' do
172
+ subject
173
+ expect(organization.reload.sync_enabled).to be true
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
File without changes
@@ -20,7 +20,7 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
20
20
  end
21
21
 
22
22
  context 'with sync_enabled set to true' do
23
- before {organization.update(sync_enabled: true)}
23
+ before { organization.update(sync_enabled: true)}
24
24
 
25
25
  context 'with a sync still running for less than 30 minutes' do
26
26
  let!(:running_sync) { create(:synchronization, organization: organization, status: 'RUNNING', created_at: 29.minutes.ago) }
@@ -67,17 +67,18 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
67
67
  end
68
68
  end
69
69
 
70
- it { performes }
71
70
 
72
71
  context 'first sync' do
73
72
  it 'does two half syncs' do
74
- expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).exactly(2 * organization.synchronized_entities.count).times
73
+ expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:first_sync_entity).exactly(2 * organization.synchronized_entities.count).times
75
74
  subject
76
75
  end
77
76
  end
78
77
 
79
78
  context 'subsequent sync' do
80
79
  let!(:old_sync) { create(:synchronization, partial: false, status: 'SUCCESS', organization: organization) }
80
+
81
+ it { performes }
81
82
 
82
83
  it 'calls sync entity on all the organization synchronized entities set to true' do
83
84
  organization.synchronized_entities[organization.synchronized_entities.keys.first] = false
@@ -107,42 +108,93 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
107
108
  end
108
109
  end
109
110
 
110
- describe 'sync_entity' do
111
+ describe 'other methods' do
111
112
  subject { Maestrano::Connector::Rails::SynchronizationJob.new }
112
113
 
113
- context 'non complex entity' do
114
- before {
115
- class Entities::Person < Maestrano::Connector::Rails::Entity
114
+ describe 'sync_entity' do
115
+
116
+ context 'non complex entity' do
117
+ before {
118
+ class Entities::Person < Maestrano::Connector::Rails::Entity
119
+ end
120
+ }
121
+
122
+ it 'calls the seven methods' do
123
+ expect_any_instance_of(Entities::Person).to receive(:before_sync)
124
+ expect_any_instance_of(Entities::Person).to receive(:get_connec_entities).and_return([])
125
+ expect_any_instance_of(Entities::Person).to receive(:get_external_entities_wrapper).and_return([])
126
+ expect_any_instance_of(Entities::Person).to receive(:consolidate_and_map_data).and_return({})
127
+ expect_any_instance_of(Entities::Person).to receive(:push_entities_to_external)
128
+ expect_any_instance_of(Entities::Person).to receive(:push_entities_to_connec)
129
+ expect_any_instance_of(Entities::Person).to receive(:after_sync)
130
+ subject.sync_entity('person', organization, nil, nil, nil, {})
131
+ end
132
+ end
133
+
134
+ context 'complex entity' do
135
+ before {
136
+ class Entities::SomeStuff < Maestrano::Connector::Rails::ComplexEntity
137
+ end
138
+ }
139
+
140
+ it 'calls the seven methods' do
141
+ expect_any_instance_of(Entities::SomeStuff).to receive(:before_sync)
142
+ expect_any_instance_of(Entities::SomeStuff).to receive(:get_connec_entities).and_return({})
143
+ expect_any_instance_of(Entities::SomeStuff).to receive(:get_external_entities_wrapper).and_return({})
144
+ expect_any_instance_of(Entities::SomeStuff).to receive(:consolidate_and_map_data).and_return({})
145
+ expect_any_instance_of(Entities::SomeStuff).to receive(:push_entities_to_external)
146
+ expect_any_instance_of(Entities::SomeStuff).to receive(:push_entities_to_connec)
147
+ expect_any_instance_of(Entities::SomeStuff).to receive(:after_sync)
148
+ subject.sync_entity('some stuff', organization, nil, nil, nil, {})
116
149
  end
117
- }
118
-
119
- it 'calls the seven methods' do
120
- expect_any_instance_of(Entities::Person).to receive(:before_sync)
121
- expect_any_instance_of(Entities::Person).to receive(:get_connec_entities)
122
- expect_any_instance_of(Entities::Person).to receive(:get_external_entities_wrapper)
123
- expect_any_instance_of(Entities::Person).to receive(:consolidate_and_map_data).and_return({})
124
- expect_any_instance_of(Entities::Person).to receive(:push_entities_to_external)
125
- expect_any_instance_of(Entities::Person).to receive(:push_entities_to_connec)
126
- expect_any_instance_of(Entities::Person).to receive(:after_sync)
127
- subject.sync_entity('person', organization, nil, nil, nil, {})
128
150
  end
129
151
  end
130
152
 
131
- context 'complex entity' do
132
- before {
133
- class Entities::SomeStuff < Maestrano::Connector::Rails::ComplexEntity
153
+ describe 'first_sync_entity' do
154
+ let(:batch_limit) { 50 }
155
+
156
+ context 'non complex entity' do
157
+ before {
158
+ class Entities::Person < Maestrano::Connector::Rails::Entity
159
+ end
160
+ allow_any_instance_of(Entities::Person).to receive(:get_connec_entities).and_return([])
161
+ allow_any_instance_of(Entities::Person).to receive(:get_external_entities_wrapper).and_return([])
162
+ allow_any_instance_of(Entities::Person).to receive(:consolidate_and_map_data).and_return({})
163
+ allow_any_instance_of(Entities::Person).to receive(:push_entities_to_external)
164
+ allow_any_instance_of(Entities::Person).to receive(:push_entities_to_connec)
165
+ }
166
+
167
+ context 'with pagination' do
168
+ context 'with more than 50 entities' do
169
+ it 'calls perform_sync several time' do
170
+ allow(subject).to receive(:perform_sync).and_return(batch_limit, 0)
171
+ expect_any_instance_of(Entities::Person).to receive(:opts_merge!).twice
172
+ expect(subject).to receive(:perform_sync).twice
173
+
174
+ subject.first_sync_entity('person', organization, nil, nil, nil, {}, true)
175
+ end
176
+ end
177
+
178
+ context 'with less than 50 entities' do
179
+ it 'calls perform_sync once' do
180
+ allow(subject).to receive(:perform_sync).and_return(batch_limit - 10)
181
+ expect_any_instance_of(Entities::Person).to receive(:opts_merge!).once.with({__skip: 0})
182
+ expect(subject).to receive(:perform_sync).once
183
+
184
+ subject.first_sync_entity('person', organization, nil, nil, nil, {}, true)
185
+ end
186
+ end
187
+ end
188
+
189
+ context 'without pagination' do
190
+ it 'calls perform_sync once' do
191
+ allow(subject).to receive(:perform_sync).and_return(batch_limit + 10)
192
+ expect_any_instance_of(Entities::Person).to receive(:opts_merge!).once.with({__skip: 0})
193
+ expect(subject).to receive(:perform_sync).once
194
+
195
+ subject.first_sync_entity('person', organization, nil, nil, nil, {}, true)
196
+ end
134
197
  end
135
- }
136
-
137
- it 'calls the seven methods' do
138
- expect_any_instance_of(Entities::SomeStuff).to receive(:before_sync)
139
- expect_any_instance_of(Entities::SomeStuff).to receive(:get_connec_entities)
140
- expect_any_instance_of(Entities::SomeStuff).to receive(:get_external_entities_wrapper)
141
- expect_any_instance_of(Entities::SomeStuff).to receive(:consolidate_and_map_data).and_return({})
142
- expect_any_instance_of(Entities::SomeStuff).to receive(:push_entities_to_external)
143
- expect_any_instance_of(Entities::SomeStuff).to receive(:push_entities_to_connec)
144
- expect_any_instance_of(Entities::SomeStuff).to receive(:after_sync)
145
- subject.sync_entity('some stuff', organization, nil, nil, nil, {})
146
198
  end
147
199
  end
148
200
  end
@@ -11,6 +11,17 @@ describe Maestrano::Connector::Rails::ComplexEntity do
11
11
  describe 'external_entities_names' do
12
12
  it { expect{ subject.external_entities_names }.to raise_error('Not implemented') }
13
13
  end
14
+
15
+ describe 'count_entities' do
16
+ it 'returns the biggest array size' do
17
+ entities = {
18
+ 'people' => [*1..27],
19
+ 'organizations' => [*1..39],
20
+ 'items' => []
21
+ }
22
+ expect(subject.count_entities(entities)).to eql(39)
23
+ end
24
+ end
14
25
  end
15
26
 
16
27
  describe 'instance methods' do
@@ -5,6 +5,28 @@ describe Maestrano::Connector::Rails::ConnecHelper do
5
5
 
6
6
  let!(:organization) { create(:organization) }
7
7
 
8
+ describe 'dependancies' do
9
+ it 'returns a default hash' do
10
+ expect(subject.dependancies).to eql({
11
+ connec: '1.0',
12
+ impac: '1.0',
13
+ maestrano_hub: '1.0'
14
+ })
15
+ end
16
+ end
17
+
18
+ describe 'connec_version' do
19
+ let!(:organization) { create(:organization, tenant: 'default') }
20
+ before {
21
+ allow(Maestrano::Connec::Client[organization.tenant]).to receive(:get).and_return(ActionDispatch::Response.new(200, {}, {ci_build_number: '111', ci_branch: '1.1', ci_commit: '111'}.to_json, {}))
22
+ }
23
+
24
+ it 'returns the connec_version' do
25
+ expect(subject.connec_version(organization)).to eql('1.1')
26
+ end
27
+
28
+ end
29
+
8
30
  describe 'unfold_references' do
9
31
  let(:connec_hash) {
10
32
  {
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Maestrano::Connector::Rails::EntityBase do
4
+ describe 'instance methods' do
5
+ let!(:organization) { create(:organization, uid: 'cld-123') }
6
+ let!(:connec_client) { Maestrano::Connec::Client[organization.tenant].new(organization.uid) }
7
+ let!(:external_client) { Object.new }
8
+ let(:opts) { {} }
9
+ subject { Maestrano::Connector::Rails::EntityBase.new(organization, connec_client, external_client, opts) }
10
+
11
+ describe 'opts_merge!' do
12
+ let(:opts) { {a: 1, opts: 2} }
13
+
14
+ it 'merges options with the instance variable' do
15
+ subject.opts_merge!(opts: 3, test: 'test')
16
+ expect(subject.instance_variable_get(:@opts)).to eql(a: 1, opts: 3, test: 'test')
17
+ end
18
+ end
19
+ end
20
+ end
@@ -110,6 +110,12 @@ describe Maestrano::Connector::Rails::Entity do
110
110
  describe 'connec_matching_fields' do
111
111
  it { expect(subject.connec_matching_fields).to be_nil }
112
112
  end
113
+
114
+ describe 'count_entities' do
115
+ it 'returns the array size' do
116
+ expect(subject.count_entities([*1..27])).to eql(27)
117
+ end
118
+ end
113
119
  end
114
120
 
115
121
  describe 'instance methods' do
@@ -189,7 +195,7 @@ describe Maestrano::Connector::Rails::Entity do
189
195
  end
190
196
 
191
197
  describe 'when skip_connec' do
192
- let(:opts) { {skip_connec: true} }
198
+ let(:opts) { {__skip_connec: true} }
193
199
  it { expect(subject.get_connec_entities(nil)).to eql([]) }
194
200
  end
195
201
 
@@ -211,6 +217,19 @@ describe Maestrano::Connector::Rails::Entity do
211
217
  allow(connec_client).to receive(:get).and_return(ActionDispatch::Response.new(200, {}, {people: []}.to_json, {}))
212
218
  }
213
219
 
220
+ context 'with limit and skip opts' do
221
+ let(:opts) { {__skip: 100, __limit: 50} }
222
+ before {
223
+ allow(connec_client).to receive(:get).and_return(ActionDispatch::Response.new(200, {}, {people: [], pagination: {next: "https://api-connec.maestrano.com/api/v2/cld-dkg601/people?%24skip=10&%24top=10"}}.to_json, {}), ActionDispatch::Response.new(200, {}, {people: []}.to_json, {}))
224
+ }
225
+
226
+ it 'performs a size limited date and do not paginate' do
227
+ uri_param = {"$filter" => "updated_at gt '#{sync.updated_at.iso8601}'", "$skip" => 100, "$top" => 50}.to_query
228
+ expect(connec_client).to receive(:get).once.with("#{connec_name.downcase.pluralize}?#{uri_param}")
229
+ subject.get_connec_entities(sync.updated_at)
230
+ end
231
+ end
232
+
214
233
  context 'when opts[:full_sync] is true' do
215
234
  let(:opts) { {full_sync: true} }
216
235
  it 'performs a full get' do
@@ -474,7 +493,7 @@ describe Maestrano::Connector::Rails::Entity do
474
493
  end
475
494
 
476
495
  context 'when skip external' do
477
- let(:opts) { {skip_external: true} }
496
+ let(:opts) { {__skip_external: true} }
478
497
 
479
498
  it 'returns an empty array and does not call get_external_entities' do
480
499
  expect(subject).to_not receive(:get_connec_entities)
@@ -3,17 +3,21 @@ require 'spec_helper'
3
3
  describe Maestrano::Connector::Rails::External do
4
4
  subject { Maestrano::Connector::Rails::External }
5
5
 
6
+ before {
7
+ allow(Maestrano::Connector::Rails::External).to receive(:external_name).and_call_original
8
+ allow(Maestrano::Connector::Rails::External).to receive(:get_client).and_call_original
9
+ allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_call_original
10
+ }
11
+
6
12
  describe 'external_name' do
7
- it { expect(subject.external_name).to eql('Dummy app') }
13
+ it { expect{ subject.external_name }.to raise_error(RuntimeError) }
8
14
  end
9
15
 
10
16
  describe 'get_client' do
11
- let(:organization) { create(:organization) }
12
-
13
- it { expect(subject.get_client(organization)).to eql(nil) }
17
+ it { expect{ subject.get_client(nil) }.to raise_error(RuntimeError) }
14
18
  end
15
19
 
16
20
  describe 'entities_list' do
17
- it { expect(subject.entities_list).to eql(%w(entity1 entity2))}
21
+ it { expect{ subject.entities_list }.to raise_error(RuntimeError) }
18
22
  end
19
23
  end
@@ -76,7 +76,6 @@ describe Maestrano::Connector::Rails::SubEntityBase do
76
76
  let!(:connec_client) { Maestrano::Connec::Client[organization.tenant].new(organization.uid) }
77
77
  let!(:external_client) { Object.new }
78
78
  let(:opts) { {} }
79
- subject { Maestrano::Connector::Rails::Entity.new(organization, connec_client, external_client, opts) }
80
79
  subject { Maestrano::Connector::Rails::SubEntityBase.new(organization, connec_client, external_client, opts) }
81
80
 
82
81
  describe 'map_to' do
data/spec/spec_helper.rb CHANGED
@@ -20,4 +20,10 @@ RSpec.configure do |config|
20
20
  config.order = "random"
21
21
  config.include FactoryGirl::Syntax::Methods
22
22
  config.include Maestrano::Connector::Rails::Engine.routes.url_helpers
23
- end
23
+
24
+ config.before(:each) do
25
+ allow(Maestrano::Connector::Rails::External).to receive(:external_name).and_return('External app')
26
+ allow(Maestrano::Connector::Rails::External).to receive(:get_client).and_return(Object.new)
27
+ allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return(%w(entity1 entity2))
28
+ end
29
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maestrano-connector-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pierre Berard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-22 00:00:00.000000000 Z
11
+ date: 2016-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: maestrano-rails
@@ -284,7 +284,9 @@ files:
284
284
  - app/controllers/maestrano/application_controller.rb
285
285
  - app/controllers/maestrano/auth/saml_controller.rb
286
286
  - app/controllers/maestrano/connec_controller.rb
287
+ - app/controllers/maestrano/dependancies_controller.rb
287
288
  - app/controllers/maestrano/sessions_controller.rb
289
+ - app/controllers/maestrano/synchronizations_controller.rb
288
290
  - app/helpers/maestrano/connector/rails/session_helper.rb
289
291
  - app/jobs/maestrano/connector/rails/all_synchronizations_job.rb
290
292
  - app/jobs/maestrano/connector/rails/push_to_connec_job.rb
@@ -294,11 +296,13 @@ files:
294
296
  - app/models/maestrano/connector/rails/concerns/connec_helper.rb
295
297
  - app/models/maestrano/connector/rails/concerns/connector_logger.rb
296
298
  - app/models/maestrano/connector/rails/concerns/entity.rb
299
+ - app/models/maestrano/connector/rails/concerns/entity_base.rb
297
300
  - app/models/maestrano/connector/rails/concerns/external.rb
298
301
  - app/models/maestrano/connector/rails/concerns/sub_entity_base.rb
299
302
  - app/models/maestrano/connector/rails/connec_helper.rb
300
303
  - app/models/maestrano/connector/rails/connector_logger.rb
301
304
  - app/models/maestrano/connector/rails/entity.rb
305
+ - app/models/maestrano/connector/rails/entity_base.rb
302
306
  - app/models/maestrano/connector/rails/external.rb
303
307
  - app/models/maestrano/connector/rails/id_map.rb
304
308
  - app/models/maestrano/connector/rails/organization.rb
@@ -354,8 +358,10 @@ files:
354
358
  - maestrano.png
355
359
  - release_notes.md
356
360
  - spec/controllers/connec_controller_spec.rb
361
+ - spec/controllers/dependancies_controller_spec.rb
357
362
  - spec/controllers/group_users_controller_spec.rb
358
363
  - spec/controllers/groups_controller_spec.rb
364
+ - spec/controllers/synchronizations_controller_spec.rb
359
365
  - spec/dummy/README.md
360
366
  - spec/dummy/Rakefile
361
367
  - spec/dummy/app/assets/images/.keep
@@ -370,9 +376,7 @@ files:
370
376
  - spec/dummy/app/mailers/.keep
371
377
  - spec/dummy/app/models/.keep
372
378
  - spec/dummy/app/models/concerns/.keep
373
- - spec/dummy/app/models/entities/example_entitiy.rb
374
- - spec/dummy/app/models/maestrano/connector/rails/entity.rb
375
- - spec/dummy/app/models/maestrano/connector/rails/external.rb
379
+ - spec/dummy/app/models/entities/.keep
376
380
  - spec/dummy/app/views/home/index.html.erb
377
381
  - spec/dummy/app/views/layouts/application.html.erb
378
382
  - spec/dummy/bin/bundle
@@ -422,6 +426,7 @@ files:
422
426
  - spec/models/complex_entity_spec.rb
423
427
  - spec/models/connec_helper_spec.rb
424
428
  - spec/models/connector_logger_spec.rb
429
+ - spec/models/entity_base_spec.rb
425
430
  - spec/models/entity_spec.rb
426
431
  - spec/models/external_spec.rb
427
432
  - spec/models/id_map_spec.rb
@@ -1,26 +0,0 @@
1
- # TODO
2
- # This file is provided as an example and should be removed
3
- # One such file needs to be created for each synchronizable entity,
4
- # with its associated mapper
5
-
6
- # class Entities::ExampleEntity < Maestrano::Connector::Rails::Entity
7
- # def connec_entity_name
8
- # 'ExampleEntity'
9
- # end
10
-
11
- # def external_entity_name
12
- # 'Contact'
13
- # end
14
-
15
- # def mapper_class
16
- # ExampleEntityMapper
17
- # end
18
- # end
19
-
20
- # class ExampleEntityMapper < Maestrano::Connector::Rails::GenericMapper
21
- # extend HashMapper
22
-
23
- # map from('/title'), to('/Salutation')
24
- # map from('/first_name'), to('/FirstName')
25
- # map from('address_work/billing2/city'), to('City')
26
- # end
@@ -1,3 +0,0 @@
1
- class Maestrano::Connector::Rails::Entity
2
- include Maestrano::Connector::Rails::Concerns::Entity
3
- end
@@ -1,18 +0,0 @@
1
- class Maestrano::Connector::Rails::External
2
- include Maestrano::Connector::Rails::Concerns::External
3
-
4
- def self.external_name
5
- 'Dummy app'
6
- end
7
-
8
- def self.get_client(organization)
9
- nil
10
- end
11
-
12
- # Return an array of all the entities that the connector can synchronize
13
- # If you add new entities, you need to generate
14
- # a migration to add them to existing organizations
15
- def self.entities_list
16
- %w(entity1 entity2)
17
- end
18
- end