maestrano-connector-rails 2.0.1 → 2.0.2.pre.RC1

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/connec_controller.rb +4 -3
  4. data/app/controllers/maestrano/synchronizations_controller.rb +11 -0
  5. data/app/helpers/maestrano/connector/rails/entity_helper.rb +22 -0
  6. data/app/jobs/maestrano/connector/rails/push_to_connec_job.rb +1 -1
  7. data/app/jobs/maestrano/connector/rails/synchronization_job.rb +4 -2
  8. data/app/models/maestrano/connector/rails/concerns/entity.rb +2 -2
  9. data/app/models/maestrano/connector/rails/organization.rb +32 -5
  10. data/config/routes.rb +1 -0
  11. data/db/migrate/20170202033323_update_organization_metadata.rb +15 -0
  12. data/lib/generators/connector/templates/home.js +1 -1
  13. data/lib/generators/connector/templates/home_controller.rb +9 -6
  14. data/lib/generators/connector/templates/home_index.haml +17 -9
  15. data/lib/generators/connector/templates/stylesheets/layout.sass +7 -0
  16. data/maestrano-connector-rails.gemspec +6 -4
  17. data/spec/controllers/connec_controller_spec.rb +17 -4
  18. data/spec/dummy/db/schema.rb +3 -1
  19. data/spec/integration/complex_id_references_spec.rb +1 -0
  20. data/spec/integration/complex_naming_spec.rb +1 -0
  21. data/spec/integration/complex_spec.rb +4 -1
  22. data/spec/integration/connec_to_external_spec.rb +8 -2
  23. data/spec/integration/external_to_connec_spec.rb +5 -1
  24. data/spec/integration/id_references_spec.rb +4 -1
  25. data/spec/integration/singleton_spec.rb +5 -1
  26. data/spec/jobs/push_to_connec_job_spec.rb +6 -2
  27. data/spec/jobs/synchronization_job_spec.rb +0 -8
  28. data/spec/models/entity_spec.rb +2 -0
  29. data/spec/models/organization_spec.rb +19 -4
  30. metadata +6 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f98ffd30f0c9e18fb5ad95d5a52849bba5e437d0
4
- data.tar.gz: 9864988bffd82f6ce6d66aec534f5822b59c36db
3
+ metadata.gz: 74dbb8e9c430a2e596fdd639adffb4c5ffe72b00
4
+ data.tar.gz: 2d7d7e742c74765d315728913e846bc31268bb2b
5
5
  SHA512:
6
- metadata.gz: 303ce74c7bd93ad0874971fd5faec32ffd2e65db3581a255725fde10a7db198471ef2f76ac6c340a14c8c08bc1276e59c640c86ca1385b3f5cccd492ec4dea8c
7
- data.tar.gz: 9f369354a387999193b660096617465b41549acd6123e58ec4590cda4ade4ad7a10c74a552e061862bd5467fd92347c27fa84071d367ef8441b508de9bc06225
6
+ metadata.gz: fc6c45a3e8b39444508ec0430fe001907135ff52591d44c4914a74aeb763e8a3ff3f905eb4438063a3d1bd5201e90c6962b82d570e045698514d394c71006b80
7
+ data.tar.gz: 72cfe2b906911c29480de3420934921e66a07495db4d89e5195883ecd8c6e33de95b50cbfdbe8a683961d51ab1b45fb133a1e08ac6a730d14b85b8269262e71f
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.1
1
+ 2.0.2.pre.RC1
@@ -49,7 +49,7 @@ class Maestrano::ConnecController < Maestrano::Rails::WebHookController
49
49
  return false
50
50
  end
51
51
 
52
- unless organization.sync_enabled && organization.synchronized_entities[entity_class_hash[:name].to_sym]
52
+ unless organization.sync_enabled && organization.synchronized_entities[entity_class_hash[:name].to_sym][:can_push_to_external]
53
53
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Skipping notification from Connec! webhook, entity_name=\"#{entity_name}\"")
54
54
  return false
55
55
  end
@@ -58,12 +58,13 @@ class Maestrano::ConnecController < Maestrano::Rails::WebHookController
58
58
  end
59
59
 
60
60
  def find_entity_class(entity_name)
61
+ parametrised_entity_name = entity_name.parameterize('_').pluralize
61
62
  Maestrano::Connector::Rails::External.entities_list.each do |entity_name_from_list|
62
63
  clazz = "Entities::#{entity_name_from_list.singularize.titleize.split.join}".constantize
63
64
  if clazz.methods.include?('connec_entities_names'.to_sym)
64
65
  formatted_entities_names = clazz.connec_entities_names.map { |n| n.parameterize('_').pluralize }
65
- return {class: clazz, is_complex: true, name: entity_name_from_list} if formatted_entities_names.include?(entity_name)
66
- elsif clazz.methods.include?('connec_entity_name'.to_sym) && clazz.normalized_connec_entity_name == entity_name
66
+ return {class: clazz, is_complex: true, name: entity_name_from_list} if formatted_entities_names.include?(parametrised_entity_name)
67
+ elsif clazz.methods.include?('connec_entity_name'.to_sym) && clazz.normalized_connec_entity_name == parametrised_entity_name
67
68
  return {class: clazz, is_complex: false, name: entity_name_from_list}
68
69
  end
69
70
  end
@@ -27,6 +27,17 @@ class Maestrano::SynchronizationsController < Maestrano::Rails::WebHookControlle
27
27
  render_organization_sync(organization, status, 201)
28
28
  end
29
29
 
30
+ def update_metadata
31
+ tenant = params[:tenant]
32
+ uid = params[:group_id]
33
+ organization = Maestrano::Connector::Rails::Organization.find_by(uid: uid, tenant: tenant)
34
+ return render json: {errors: [{message: 'Organization not found', code: 404}]}, status: :not_found unless organization
35
+
36
+ organization.set_instance_metadata
37
+ organization.reset_synchronized_entities
38
+ render_organization_sync(organization, status, 200)
39
+ end
40
+
30
41
  def toggle_sync
31
42
  tenant = params[:tenant]
32
43
  uid = params[:group_id]
@@ -0,0 +1,22 @@
1
+ module Maestrano::Connector::Rails
2
+ module EntityHelper
3
+ def self.snake_name(entity)
4
+ class_name = entity.class.name.underscore.split('/').last
5
+ if entity.is_a?(Maestrano::Connector::Rails::SubEntityBase)
6
+ name = ''
7
+ Entities.constants&.each do |c|
8
+ klass = Entities.const_get(c)
9
+ next unless klass.respond_to?(:formatted_external_entities_names)
10
+ if klass.formatted_external_entities_names.values.include?(class_name.camelize) ||
11
+ klass.formatted_connec_entities_names.values.include?(class_name.camelize)
12
+ name = c
13
+ break
14
+ end
15
+ end
16
+ name.to_s.underscore.to_sym
17
+ else
18
+ class_name.to_sym
19
+ end
20
+ end
21
+ end
22
+ end
@@ -12,7 +12,7 @@ module Maestrano::Connector::Rails
12
12
 
13
13
  entities_hash.each do |external_entity_name, entities|
14
14
  if entity_instance_hash = find_entity_instance(external_entity_name, organization, connec_client, external_client, opts)
15
- next unless organization.synchronized_entities[entity_instance_hash[:name].to_sym]
15
+ next unless organization.synchronized_entities[entity_instance_hash[:name].to_sym][:can_push_to_connec]
16
16
 
17
17
  entity_instance = entity_instance_hash[:instance]
18
18
 
@@ -38,7 +38,8 @@ module Maestrano::Connector::Rails
38
38
  # We also do batched sync as the first one can be quite huge
39
39
  if last_synchronization.nil?
40
40
  ConnectorLogger.log('info', organization, 'First synchronization ever. Doing two half syncs to allow smart merging to work its magic.')
41
- organization.synchronized_entities.select { |k, v| v }.keys.each do |entity|
41
+ organization.synchronized_entities.each do |entity, settings|
42
+ next unless settings[:can_push_to_connec] || settings[:can_push_to_external]
42
43
  ConnectorLogger.log('info', organization, "First synchronization ever. Doing half sync from external for #{entity}.")
43
44
  first_sync_entity(entity.to_s, organization, connec_client, external_client, last_synchronization_date, opts, true)
44
45
  ConnectorLogger.log('info', organization, "First synchronization ever. Doing half sync from Connec! for #{entity}.")
@@ -52,7 +53,8 @@ module Maestrano::Connector::Rails
52
53
  sync_entity(entity, organization, connec_client, external_client, last_synchronization_date, opts)
53
54
  end
54
55
  else
55
- organization.synchronized_entities.select { |_k, v| v }.keys.each do |entity|
56
+ organization.synchronized_entities.each do |entity, settings|
57
+ next unless settings[:can_push_to_connec] || settings[:can_push_to_external]
56
58
  sync_entity(entity.to_s, organization, connec_client, external_client, last_synchronization_date, opts)
57
59
  end
58
60
  end
@@ -253,7 +253,7 @@ module Maestrano::Connector::Rails::Concerns::Entity
253
253
  # * connec_id and push timestamp
254
254
  # * error message
255
255
  def push_entities_to_connec_to(mapped_external_entities_with_idmaps, connec_entity_name)
256
- return unless self.class.can_write_connec?
256
+ return unless @organization.push_to_connec_enabled?(self)
257
257
 
258
258
  Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Sending #{Maestrano::Connector::Rails::External.external_name} #{self.class.external_entity_name.pluralize} to Connec! #{connec_entity_name.pluralize}")
259
259
 
@@ -304,7 +304,7 @@ module Maestrano::Connector::Rails::Concerns::Entity
304
304
  # Pushes connec entities to the external application
305
305
  # Sends new external ids to Connec! (either only the id, or the id + the id references)
306
306
  def push_entities_to_external_to(mapped_connec_entities_with_idmaps, external_entity_name)
307
- return unless self.class.can_write_external?
307
+ return unless @organization.push_to_external_enabled?(self)
308
308
 
309
309
  Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Sending Connec! #{self.class.connec_entity_name.pluralize} to #{Maestrano::Connector::Rails::External.external_name} #{external_entity_name.pluralize}")
310
310
 
@@ -15,7 +15,7 @@ module Maestrano::Connector::Rails
15
15
  super
16
16
  self.synchronized_entities = {}
17
17
  External.entities_list.each do |entity|
18
- self.synchronized_entities[entity.to_sym] = true
18
+ self.synchronized_entities[entity.to_sym] = {can_push_to_connec: true, can_push_to_external: true}
19
19
  end
20
20
  end
21
21
 
@@ -49,13 +49,13 @@ module Maestrano::Connector::Rails
49
49
 
50
50
  def displayable_synchronized_entities
51
51
  result = {}
52
- synchronized_entities.each do |entity, boolean|
52
+ synchronized_entities.each do |entity, hash|
53
53
  begin
54
54
  clazz = "Entities::#{entity.to_s.titleize.split.join}".constantize
55
55
  rescue
56
56
  next
57
57
  end
58
- result[entity] = {value: boolean, connec_name: clazz.public_connec_entity_name, external_name: clazz.public_external_entity_name}
58
+ result[entity] = {connec_name: clazz.public_connec_entity_name, external_name: clazz.public_external_entity_name}.merge(hash)
59
59
  end
60
60
  result
61
61
  end
@@ -115,10 +115,37 @@ module Maestrano::Connector::Rails
115
115
  last_successful_synchronization&.updated_at || date_filtering_limit
116
116
  end
117
117
 
118
- def reset_synchronized_entities
118
+ def reset_synchronized_entities(default = false)
119
119
  synchronized_entities.slice!(*External.entities_list.map(&:to_sym))
120
- External.entities_list.each { |entity| synchronized_entities[entity.to_sym] ||= false }
120
+ External.entities_list.each do |entity|
121
+ if synchronized_entities[entity.to_sym].is_a?(Hash)
122
+ can_push_to_external = synchronized_entities[entity.to_sym][:can_push_to_external]
123
+ can_push_to_connec = synchronized_entities[entity.to_sym][:can_push_to_connec]
124
+ else
125
+ can_push_to_external = synchronized_entities[entity.to_sym]
126
+ can_push_to_connec = synchronized_entities[entity.to_sym]
127
+ end
128
+ synchronized_entities[entity.to_sym] = {can_push_to_connec: (can_push_to_connec || default) && !pull_disabled, can_push_to_external: (can_push_to_external || default) && !push_disabled}
129
+ end
121
130
  save
122
131
  end
132
+
133
+ def push_to_connec_enabled?(entity)
134
+ synchronized_entities.dig(EntityHelper.snake_name(entity), :can_push_to_connec) && entity&.class.can_write_connec?
135
+ end
136
+
137
+ def push_to_external_enabled?(entity)
138
+ synchronized_entities.dig(EntityHelper.snake_name(entity), :can_push_to_external) && entity&.class.can_write_external?
139
+ end
140
+
141
+ def set_instance_metadata
142
+ auth = {:username => Maestrano[tenant].param('api.id'), :password => Maestrano[tenant].param('api.key')}
143
+ res = HTTParty.get("#{ENV['HUB_HOST']}/api/v1/account/groups/#{uid}", :basic_auth => auth)
144
+
145
+ self.push_disabled = res.dig('data', 'metadata', 'push_disabled')
146
+ self.pull_disabled = res.dig('data', 'metadata', 'pull_disabled')
147
+
148
+ self.save
149
+ end
123
150
  end
124
151
  end
data/config/routes.rb CHANGED
@@ -13,6 +13,7 @@ Maestrano::Connector::Rails::Engine.routes.draw do
13
13
  resources :synchronizations, only: [:show, :create] do
14
14
  collection do
15
15
  put :toggle_sync
16
+ put :update_metadata
16
17
  end
17
18
  end
18
19
  end
@@ -0,0 +1,15 @@
1
+ class UpdateOrganizationMetadata < ActiveRecord::Migration
2
+ def change
3
+ add_column :organizations, :push_disabled, :boolean
4
+ add_column :organizations, :pull_disabled, :boolean
5
+ # Migration to update the way we handle synchronized_entities for data sharing.
6
+ # Before : synchronized_entities = {company: true}
7
+ # After: synchronized_entities = {company: {can_push_to_connec: true, can_push_to_external: true}}
8
+
9
+ #We also add metadata from MnoHub
10
+ Maestrano::Connector::Rails::Organization.all.each do |o|
11
+ o.set_instance_metadata
12
+ o.reset_synchronized_entities
13
+ end
14
+ end
15
+ end
@@ -12,4 +12,4 @@ function historicalDataDisplay()
12
12
 
13
13
  $(function () {
14
14
  $('[data-toggle="tooltip"]').tooltip()
15
- })
15
+ })
@@ -5,15 +5,18 @@ class HomeController < ApplicationController
5
5
 
6
6
  # Update list of entities to synchronize
7
7
  current_organization.synchronized_entities.keys.each do |entity|
8
- current_organization.synchronized_entities[entity] = params[entity.to_s].present?
8
+ current_organization.synchronized_entities[entity][:can_push_to_connec] = params[entity.to_s]["to_connec"] == "1"
9
+ current_organization.synchronized_entities[entity][:can_push_to_external] = params[entity.to_s]["to_external"] == "1"
9
10
  end
11
+ full_sync = params['historical-data'].present? && !current_organization.historical_data
12
+ opts = {full_sync: full_sync}
10
13
  current_organization.sync_enabled = current_organization.synchronized_entities.values.any?
11
14
  current_organization.enable_historical_data(params['historical-data'].present?)
12
- trigger_sync = current_organization.sync_enabled && current_organization.sync_enabled_changed?
15
+ trigger_sync = current_organization.sync_enabled
13
16
  current_organization.save
14
17
 
15
18
  # Trigger sync only if the sync has been enabled
16
- start_synchronization if trigger_sync
19
+ start_synchronization(opts) if trigger_sync
17
20
 
18
21
  redirect_to(:back)
19
22
  end
@@ -32,8 +35,8 @@ class HomeController < ApplicationController
32
35
 
33
36
  private
34
37
 
35
- def start_synchronization
36
- Maestrano::Connector::Rails::SynchronizationJob.perform_later(current_organization.id, {})
37
- flash[:info] = 'Congrats, you\'re all set up! Your data are now being synced'
38
+ def start_synchronization(opts)
39
+ Maestrano::Connector::Rails::SynchronizationJob.perform_later(current_organization.id, opts)
40
+ flash[:info] = 'Congrats, you\'re all set up! Your data are now being synced' if current_organization.sync_enabled_changed?
38
41
  end
39
42
  end
@@ -4,7 +4,7 @@
4
4
  .banners
5
5
  .row
6
6
  .col-md-10.col-md-offset-2
7
- %h2 ApplicationName Connector
7
+ %h1 ApplicationName Connector
8
8
  %p
9
9
  -if current_organization
10
10
  Link your company <strong>#{current_organization.name} (#{current_organization.uid})</strong> to ApplicationName to get your business in synch. Check the status of your connection on this screen.
@@ -23,7 +23,7 @@
23
23
  %span.badge.link-step-badge
24
24
  1
25
25
  .col-md-6.link-step-description
26
- %h
26
+ %p
27
27
  - if current_organization.oauth_uid
28
28
  Your ApplicationName account <strong>#{current_organization.oauth_name} (#{current_organization.oauth_uid})</strong> is currently linked
29
29
  - else
@@ -44,22 +44,30 @@
44
44
  .col-md-1.text-center.link-step-number
45
45
  %span.badge.link-step-badge 2
46
46
  .col-md-9.link-step-description
47
- %h You can customize which entities are synchronized by the connector:
47
+ %p You can customize which entities are synchronized by the connector:
48
+ %p (#{image_tag "logos/to_connec.png", class: "small-image"} : from ApplicationName to Connec! and #{image_tag "logos/to_external.png", class: "small-image"} : from Connec! to ApplicationName)
48
49
  .spacer1
49
50
  .row
50
51
  .col-md-11.col-md-offset-1.center
51
- .col-md-4.col-md-offset-1
52
- ApplicationName wording
53
- .col-md-4
54
- Universal wording
52
+ .row
53
+ .col-md-1
54
+ =image_tag "logos/to_connec.png", class: "image"
55
+ .col-md-1
56
+ =image_tag "logos/to_external.png", class: "image"
57
+ .col-md-4
58
+ Vend wording
59
+ .col-md-3
60
+ Universal wording
55
61
  .spacer1
56
62
  .row
57
63
  .col-md-11.col-md-offset-1
58
64
  - current_organization.displayable_synchronized_entities.each do |k, v|
59
65
  .row.sync-entity
60
66
  .col-md-1.link-step-action
61
- %input{type: "checkbox", id: "#{k}", name: "#{k}", checked: v[:value]}
62
- %label.col-md-8{:for => "#{k}", style: 'padding-top: 5px;'}
67
+ #{check_box("#{k}", "to_connec", {checked: (v[:can_push_to_connec] || v[:can_push_to_external]) && !current_organization.pull_disabled, onclick: "return !#{k}_to_external.checked;", disabled: current_organization.pull_disabled})}
68
+ .col-md-1.link-step-action
69
+ #{check_box("#{k}", "to_external", {checked: v[:can_push_to_external] && !current_organization.push_disabled, onchange: "#{k}_to_connec.checked = #{!current_organization.pull_disabled};", disabled: current_organization.push_disabled})}
70
+ %label.col-md-7{:for => "#{k}", style: 'padding-top: 5px;'}
63
71
  .col-md-6
64
72
  #{v[:external_name]}
65
73
  .col-md-6
@@ -69,6 +69,13 @@ html, body
69
69
  .logo
70
70
  height: 51px
71
71
 
72
+ .image
73
+ height: 30px
74
+ margin-left: -25px
75
+
76
+ .small-image
77
+ height: 20px
78
+
72
79
  .center
73
80
  text-align: center
74
81
 
@@ -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 2.0.1 ruby lib
5
+ # stub: maestrano-connector-rails 2.0.2.pre.RC1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "maestrano-connector-rails".freeze
9
- s.version = "2.0.1"
9
+ s.version = "2.0.2.pre.RC1"
10
10
 
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
11
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Maestrano".freeze]
14
- s.date = "2017-01-04"
14
+ s.date = "2017-02-02"
15
15
  s.description = "Maestrano is the next generation marketplace for SME applications. See https://sme.maestrano.com for details.".freeze
16
16
  s.email = "developers@maestrano.com".freeze
17
17
  s.executables = ["rails".freeze, "rake".freeze]
@@ -41,6 +41,7 @@ Gem::Specification.new do |s|
41
41
  "app/controllers/maestrano/sessions_controller.rb",
42
42
  "app/controllers/maestrano/synchronizations_controller.rb",
43
43
  "app/controllers/version_controller.rb",
44
+ "app/helpers/maestrano/connector/rails/entity_helper.rb",
44
45
  "app/helpers/maestrano/connector/rails/session_helper.rb",
45
46
  "app/jobs/maestrano/connector/rails/all_synchronizations_job.rb",
46
47
  "app/jobs/maestrano/connector/rails/push_to_connec_job.rb",
@@ -82,6 +83,7 @@ Gem::Specification.new do |s|
82
83
  "db/migrate/20160614160654_add_encryption_on_oauth_keys.rb",
83
84
  "db/migrate/20161011005751_add_unique_index_on_organization_oauth_uid.rb",
84
85
  "db/migrate/20161018155513_add_org_uid_to_organization.rb",
86
+ "db/migrate/20170202033323_update_organization_metadata.rb",
85
87
  "lib/generators/connector/USAGE",
86
88
  "lib/generators/connector/complex_entity_generator.rb",
87
89
  "lib/generators/connector/install_generator.rb",
@@ -76,7 +76,7 @@ describe Maestrano::ConnecController, type: :controller do
76
76
  before {
77
77
  allow(Entities::ContactAndLead).to receive(:external_entities_names).and_return(%w())
78
78
  }
79
- let!(:organization) { create(:organization, uid: group_id, oauth_uid: 'lala', sync_enabled: true, synchronized_entities: {contact_and_lead: true}) }
79
+ let!(:organization) { create(:organization, uid: group_id, oauth_uid: 'lala', sync_enabled: true) }
80
80
 
81
81
  it 'process the data and push them' do
82
82
  expect_any_instance_of(Entities::ContactAndLead).to receive(:before_sync)
@@ -130,7 +130,7 @@ describe Maestrano::ConnecController, type: :controller do
130
130
 
131
131
  context 'with a valid organization' do
132
132
  context 'with sync disabled' do
133
- let!(:organization) { create(:organization, uid: group_id, oauth_uid: 'lala', sync_enabled: false, synchronized_entities: {person: true}) }
133
+ let!(:organization) { create(:organization, uid: group_id, oauth_uid: 'lala', sync_enabled: false) }
134
134
 
135
135
  it 'does nothing' do
136
136
  expect(Maestrano::Connector::Rails::External).to_not receive(:get_client).with(organization)
@@ -139,7 +139,7 @@ describe Maestrano::ConnecController, type: :controller do
139
139
  end
140
140
 
141
141
  context 'with sync disabled for this entity' do
142
- let!(:organization) { create(:organization, uid: group_id, oauth_uid: 'lala', sync_enabled: true, synchronized_entities: {person: false}) }
142
+ let!(:organization) { create(:organization, uid: group_id, oauth_uid: 'lala', sync_enabled: true, synchronized_entities: {person: {can_push_to_connec: false}}) }
143
143
 
144
144
  it 'does nothing' do
145
145
  expect(Maestrano::Connector::Rails::External).to_not receive(:get_client).with(organization)
@@ -148,7 +148,7 @@ describe Maestrano::ConnecController, type: :controller do
148
148
  end
149
149
 
150
150
  context "when syncing" do
151
- let!(:organization) { create(:organization, uid: group_id, oauth_uid: 'lala', sync_enabled: true, synchronized_entities: {person: true}) }
151
+ let!(:organization) { create(:organization, uid: group_id, oauth_uid: 'lala', sync_enabled: true) }
152
152
 
153
153
  it 'process the data and push them' do
154
154
  expect_any_instance_of(Entities::Person).to receive(:before_sync)
@@ -158,6 +158,19 @@ describe Maestrano::ConnecController, type: :controller do
158
158
  expect_any_instance_of(Entities::Person).to receive(:after_sync)
159
159
  subject
160
160
  end
161
+
162
+ context 'with different entity name case and singular' do
163
+ let(:notifications) { {'Person' => [entity]} }
164
+
165
+ it 'process the data and push them' do
166
+ expect_any_instance_of(Entities::Person).to receive(:before_sync)
167
+ expect_any_instance_of(Entities::Person).to receive(:filter_connec_entities).and_return([entity])
168
+ expect_any_instance_of(Entities::Person).to receive(:consolidate_and_map_data).with([entity], []).and_return({})
169
+ expect_any_instance_of(Entities::Person).to receive(:push_entities_to_external)
170
+ expect_any_instance_of(Entities::Person).to receive(:after_sync)
171
+ subject
172
+ end
173
+ end
161
174
  end
162
175
  end
163
176
  end
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20161018155513) do
14
+ ActiveRecord::Schema.define(version: 20170202033323) do
15
15
 
16
16
  create_table "id_maps", force: :cascade do |t|
17
17
  t.string "connec_id"
@@ -56,6 +56,8 @@ ActiveRecord::Schema.define(version: 20161018155513) do
56
56
  t.string "encrypted_refresh_token_iv"
57
57
  t.string "encrypted_refresh_token_salt"
58
58
  t.string "org_uid"
59
+ t.boolean "push_disabled"
60
+ t.boolean "pull_disabled"
59
61
  end
60
62
 
61
63
  add_index "organizations", ["oauth_uid"], name: "index_organizations_on_oauth_uid", unique: true
@@ -90,6 +90,7 @@ describe 'complex id references' do
90
90
 
91
91
  before {
92
92
  allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return(%w(id_payment))
93
+ organization.reset_synchronized_entities(true)
93
94
 
94
95
  allow(connec_client).to receive(:get).and_return(ActionDispatch::Response.new(200, {}, {idpayments: [connec_payment]}.to_json, {}))
95
96
  allow(connec_client).to receive(:batch).and_return(ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {payments: {}}}]}.to_json, {}))
@@ -87,6 +87,7 @@ describe 'complex entity subentities naming conflict' do
87
87
 
88
88
  before {
89
89
  allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return(%w(name_payment))
90
+ organization.reset_synchronized_entities(true)
90
91
  }
91
92
 
92
93
  subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity('name_payment', organization, connec_client, external_client, organization.last_synchronization_date, {}) }
@@ -212,14 +212,17 @@ describe 'complex entities workflow' do
212
212
  }
213
213
  }
214
214
  let!(:supplier_idmap) { Entities::SubEntities::CompSupplier.create_idmap(organization_id: organization.id, external_id: ext_supplier_id, connec_entity: 'comporganization') }
215
+ let(:entity_name) { 'customer_and_supplier' }
215
216
 
216
217
  before do
217
218
  allow(connec_client).to receive(:get).and_return(ActionDispatch::Response.new(200, {}, {comporganizations: connec_orgs}.to_json, {}))
218
219
  allow_any_instance_of(Entities::SubEntities::CompCustomer).to receive(:get_external_entities).and_return([ext_customer])
219
220
  allow_any_instance_of(Entities::SubEntities::CompSupplier).to receive(:get_external_entities).and_return([ext_supplier])
221
+ allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return([entity_name])
222
+ organization.reset_synchronized_entities(true)
220
223
  end
221
224
 
222
- subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity('customer_and_supplier', organization, connec_client, external_client, nil, {}) }
225
+ subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity(entity_name, organization, connec_client, external_client, nil, {}) }
223
226
 
224
227
  it 'handles the fetching correctly' do
225
228
  expect_any_instance_of(Entities::CustomerAndSupplier).to receive(:consolidate_and_map_data).with({'CompOrganization' => connec_orgs}, {'CompCustomer' => [ext_customer], 'CompSupplier' => [ext_supplier]}).and_return({connec_entities: [], external_entities: []})
@@ -88,15 +88,18 @@ describe 'connec to the external application' do
88
88
  }
89
89
  }
90
90
  let(:person) { person1 }
91
+ let(:entity_name) { 'connec_to_external' }
91
92
 
92
93
  before do
93
94
  allow(connec_client).to receive(:get).and_return(ActionDispatch::Response.new(200, {}, {people: [person]}.to_json, {}))
94
95
  allow(connec_client).to receive(:batch).and_return(ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {people: {}}}]}.to_json, {}))
95
96
 
96
97
  allow_any_instance_of(Entities::ConnecToExternal).to receive(:get_external_entities).and_return([])
98
+ allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return([entity_name])
99
+ organization.reset_synchronized_entities(true)
97
100
  end
98
101
 
99
- subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity('connec_to_external', organization, connec_client, external_client, organization.last_synchronization_date, {}) }
102
+ subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity(entity_name, organization, connec_client, external_client, organization.last_synchronization_date, {}) }
100
103
 
101
104
  describe 'a new record created in connec with all references known' do
102
105
  before {
@@ -228,11 +231,14 @@ describe 'connec to the external application' do
228
231
 
229
232
  describe 'a creation from connec where the creation_only_mapper has to be used' do
230
233
  #idmap.last_push_to_external is nil
234
+ let(:entity_name) { 'connec_to_external_missing_field' }
231
235
  before do
232
236
  allow_any_instance_of(Entities::ConnecToExternalMissingField).to receive(:get_external_entities).and_return([])
237
+ allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return([entity_name])
238
+ organization.reset_synchronized_entities(true)
233
239
  end
234
240
 
235
- subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity('connec_to_external_missing_field', organization, connec_client, external_client, organization.last_synchronization_date, {}) }
241
+ subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity(entity_name, organization, connec_client, external_client, organization.last_synchronization_date, {}) }
236
242
 
237
243
  class Entities::ConnecToExternalMissingField < Entities::ConnecToExternal
238
244
 
@@ -88,12 +88,16 @@ describe 'external application to connec' do
88
88
  }
89
89
  }
90
90
 
91
+ let(:entity_name) { 'external_to_connec' }
92
+
91
93
  before {
92
94
  allow_any_instance_of(Entities::ExternalToConnec).to receive(:get_connec_entities).and_return([])
93
95
  allow_any_instance_of(Entities::ExternalToConnec).to receive(:get_external_entities).and_return([contact])
96
+ allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return([entity_name])
97
+ organization.reset_synchronized_entities(true)
94
98
  }
95
99
 
96
- subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity('external_to_connec', organization, connec_client, external_client, nil, {}) }
100
+ subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity(entity_name, organization, connec_client, external_client, nil, {}) }
97
101
 
98
102
  describe 'creating an record in connec' do
99
103
  before {
@@ -58,6 +58,7 @@ describe 'id references' do
58
58
  let(:ext_line_id2) { 'ext line id2' }
59
59
 
60
60
  let(:payment_title) { 'This is a payment' }
61
+ let(:entity_name) { 'id_reference' }
61
62
 
62
63
 
63
64
  before {
@@ -65,9 +66,11 @@ describe 'id references' do
65
66
  allow(connec_client).to receive(:batch).and_return(ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {payments: {}}}]}.to_json, {}))
66
67
 
67
68
  allow_any_instance_of(Entities::IdReference).to receive(:get_external_entities).and_return([])
69
+ allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return([entity_name])
70
+ organization.reset_synchronized_entities(true)
68
71
  }
69
72
 
70
- subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity('id_reference', organization, connec_client, external_client, organization.last_synchronization_date, {}) }
73
+ subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity(entity_name, organization, connec_client, external_client, organization.last_synchronization_date, {}) }
71
74
 
72
75
  describe 'a creation from connec' do
73
76
  before {
@@ -85,15 +85,19 @@ describe 'singleton workflow' do
85
85
  }
86
86
  }
87
87
 
88
+ let(:synchronized_entity) { "singleton_integration" }
89
+
88
90
 
89
91
  before {
90
92
  allow(connec_client).to receive(:get).and_return(ActionDispatch::Response.new(200, {}, {company: company}.to_json, {}))
91
93
  allow_any_instance_of(Entities::SingletonIntegration).to receive(:get_external_entities).and_return(ext_company)
92
94
  allow_any_instance_of(Entities::SingletonIntegration).to receive(:update_external_entity).and_return(nil)
93
95
  allow(connec_client).to receive(:batch).and_return(ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {company: {id: [{provider: 'connec', id: 'some connec id'}]}}}]}.to_json, {}))
96
+ allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return([synchronized_entity])
97
+ organization.reset_synchronized_entities(true)
94
98
  }
95
99
 
96
- subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity('singleton_integration', organization, connec_client, external_client, nil, {}) }
100
+ subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity(synchronized_entity, organization, connec_client, external_client, nil, {}) }
97
101
 
98
102
 
99
103
  describe 'when no idmap' do
@@ -60,7 +60,9 @@ describe Maestrano::Connector::Rails::PushToConnecJob do
60
60
  describe 'with entities in synchronized entities' do
61
61
 
62
62
  describe 'complex entity' do
63
- before { organization.update(synchronized_entities: {:"#{entity_name1}" => false, :"#{entity_name2}" => true})}
63
+ let(:hash1) { {can_push_to_connec: false, can_push_to_external: false} }
64
+ let(:hash2) { {can_push_to_connec: true, can_push_to_external: true} }
65
+ before { organization.update(synchronized_entities: {:"#{entity_name1}" => hash1, :"#{entity_name2}" => hash2})}
64
66
 
65
67
  it 'calls consolidate and map data on the complex entity with the right arguments' do
66
68
  expect_any_instance_of(Entities::Entity2).to receive(:consolidate_and_map_data).with({"Connec name" => []}, {"Subs"=>[entity21], "ll"=>[]})
@@ -81,7 +83,9 @@ describe Maestrano::Connector::Rails::PushToConnecJob do
81
83
  end
82
84
 
83
85
  describe 'non complex entity' do
84
- before { organization.update(synchronized_entities: {:"#{entity_name1}" => true, :"#{entity_name2}" => false})}
86
+ let(:hash1) { {can_push_to_connec: true, can_push_to_external: true} }
87
+ let(:hash2) { {can_push_to_connec: false, can_push_to_external: false} }
88
+ before { organization.update(synchronized_entities: {:"#{entity_name1}" => hash1, :"#{entity_name2}" => hash2})}
85
89
 
86
90
  it 'calls consolidate_and_map_data on the non complex entity with the right arguments' do
87
91
  expect_any_instance_of(Entities::Entity1).to receive(:consolidate_and_map_data).with([], [entity11, entity12]).and_return({})
@@ -80,14 +80,6 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
80
80
 
81
81
  it { performes }
82
82
 
83
- it 'calls sync entity on all the organization synchronized entities set to true' do
84
- organization.synchronized_entities[organization.synchronized_entities.keys.first] = false
85
- organization.save
86
- expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).exactly(organization.synchronized_entities.count - 1).times
87
-
88
- subject
89
- end
90
-
91
83
  context 'with options' do
92
84
  context 'with only_entities' do
93
85
  let(:opts) { {only_entities: %w(people price)} }
@@ -154,6 +154,8 @@ describe Maestrano::Connector::Rails::Entity do
154
154
  before do
155
155
  allow(subject.class).to receive(:connec_entity_name).and_return(connec_name)
156
156
  allow(subject.class).to receive(:external_entity_name).and_return(external_name)
157
+ allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return(%w(entity))
158
+ organization.reset_synchronized_entities(true)
157
159
  end
158
160
 
159
161
  describe 'Mapper methods' do
@@ -209,19 +209,34 @@ describe Maestrano::Connector::Rails::Organization do
209
209
  end
210
210
 
211
211
  describe '#reset_synchronized_entities' do
212
- let(:organization) { create(:organization, synchronized_entities: {entity1: true, entity2: false, tomatoes: true}) }
212
+ let(:hash1) { {can_push_to_connec: true, can_push_to_external: true} }
213
+ let(:hash2) { {can_push_to_connec: false, can_push_to_external: false} }
214
+ let(:organization) { create(:organization, synchronized_entities: {entity1: true, entity2: true, tomatoes: false}) }
213
215
  subject { organization.reset_synchronized_entities }
214
216
 
215
217
  it 'keeps only the known entities' do
216
218
  subject
217
- expect(organization.synchronized_entities).to eql(entity1: true, entity2: false)
219
+ expect(organization.synchronized_entities).to eql(entity1: hash1, entity2: hash1)
218
220
  end
219
221
 
220
222
  it 'adds missing entities' do
221
- organization.update_attributes(synchronized_entities: {entity1: true, tomatoes: true})
223
+ organization.update_attributes(synchronized_entities: {entity1: true, tomatoes: false})
222
224
 
223
225
  subject
224
- expect(organization.synchronized_entities).to eql(entity1: true, entity2: false)
226
+ expect(organization.synchronized_entities).to eql(entity1: hash1, entity2: hash2)
227
+ end
228
+
229
+ context 'with metadata from mnohub' do
230
+ before {
231
+ organization.push_disabled = true
232
+ organization.pull_disabled = true
233
+ }
234
+
235
+
236
+ it 'takes into account the metadata' do
237
+ subject
238
+ expect(organization.synchronized_entities).to eql(entity1: hash2, entity2: hash2)
239
+ end
225
240
  end
226
241
  end
227
242
  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: 2.0.1
4
+ version: 2.0.2.pre.RC1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maestrano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-04 00:00:00.000000000 Z
11
+ date: 2017-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -420,6 +420,7 @@ files:
420
420
  - app/controllers/maestrano/sessions_controller.rb
421
421
  - app/controllers/maestrano/synchronizations_controller.rb
422
422
  - app/controllers/version_controller.rb
423
+ - app/helpers/maestrano/connector/rails/entity_helper.rb
423
424
  - app/helpers/maestrano/connector/rails/session_helper.rb
424
425
  - app/jobs/maestrano/connector/rails/all_synchronizations_job.rb
425
426
  - app/jobs/maestrano/connector/rails/push_to_connec_job.rb
@@ -461,6 +462,7 @@ files:
461
462
  - db/migrate/20160614160654_add_encryption_on_oauth_keys.rb
462
463
  - db/migrate/20161011005751_add_unique_index_on_organization_oauth_uid.rb
463
464
  - db/migrate/20161018155513_add_org_uid_to_organization.rb
465
+ - db/migrate/20170202033323_update_organization_metadata.rb
464
466
  - lib/generators/connector/USAGE
465
467
  - lib/generators/connector/complex_entity_generator.rb
466
468
  - lib/generators/connector/install_generator.rb
@@ -610,9 +612,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
610
612
  version: '0'
611
613
  required_rubygems_version: !ruby/object:Gem::Requirement
612
614
  requirements:
613
- - - ">="
615
+ - - ">"
614
616
  - !ruby/object:Gem::Version
615
- version: '0'
617
+ version: 1.3.1
616
618
  requirements: []
617
619
  rubyforge_project:
618
620
  rubygems_version: 2.6.8