maestrano-connector-rails 1.1.2 → 1.2.0

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.
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