maestrano-connector-rails 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e56b9e6724bd01d1877cdccbafc5e741c70161bf
4
- data.tar.gz: c0dd848069ca945053bdfb31b84df0cb4d2a5414
3
+ metadata.gz: a944dc14eab6daaf5ba9596a36958f2e363aba3d
4
+ data.tar.gz: 800b7d60536b0c229da755641a9e9d43089894a3
5
5
  SHA512:
6
- metadata.gz: e6a23959d393239d71a5759f4ee589c916ca8b0f55ec410d50161952b29f516006e342285cd94ae0d32f83c7dc3da8fa59b1cea4f86dd0d4633ac344eca70d05
7
- data.tar.gz: 0502316314c93a0d78993339d0caed4f0a3086bd8c20a6acacd53464a18674ce680cd228790aed70e0ebef7adb9be36e9043735a5f775f021fb9d034e77e75d6
6
+ metadata.gz: 989bd5a085084e768190d3b8af8302de4f8a397ea6e129da2d8834d776bf12f33ec7b0362798bfa20803f7065ce28c8f09679dfac31bdf161cc3e62597bd962a
7
+ data.tar.gz: 54e7614a33ff5c3cf1552f77874cd9c17880f01a4e5fb820d9d6fa2acd1ef620a2a24c6df9ed96f5545f57acabbe647b6a38fad130ce970ca1e6f20036d34b8f
data/.rubocop.yml CHANGED
@@ -20,6 +20,9 @@ Style/CollectionMethods:
20
20
  Metrics/LineLength:
21
21
  Max: 320
22
22
 
23
+ Metrics/MethodLength:
24
+ Max: 50
25
+
23
26
  Style/IndentationConsistency:
24
27
  EnforcedStyle: rails
25
28
 
data/.rubocop_todo.yml CHANGED
@@ -102,14 +102,6 @@ Style/EmptyLinesAroundModuleBody:
102
102
  Style/FrozenStringLiteralComment:
103
103
  Enabled: false
104
104
 
105
- # Offense count: 1
106
- # Cop supports --auto-correct.
107
- # Configuration parameters: EnforcedStyle, SupportedStyles.
108
- # SupportedStyles: predicate, comparison
109
- Style/NumericPredicate:
110
- Exclude:
111
- - 'app/models/maestrano/connector/rails/organization.rb'
112
-
113
105
  # Offense count: 3
114
106
  # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
115
107
  # NamePrefix: is_, has_, have_
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ source 'http://rubygems.org'
3
3
  # Add dependencies required to use your gem here.
4
4
  gem 'rails', '~> 4.2'
5
5
  gem 'maestrano-rails'
6
+
6
7
  gem 'hash_mapper', '>= 0.2.2'
7
8
  gem 'haml-rails'
8
9
  gem 'bootstrap-sass'
@@ -14,7 +15,7 @@ gem 'figaro'
14
15
  gem 'sidekiq'
15
16
  # The missing unique jobs for sidekiq
16
17
  gem 'sidekiq-unique-jobs'
17
- gem 'sinatra', require: nil
18
+ gem 'sinatra', require: false
18
19
  gem 'sidekiq-cron'
19
20
  gem 'slim'
20
21
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.5.0
@@ -24,7 +24,7 @@ class Maestrano::Auth::SamlController < Maestrano::Rails::SamlBaseController
24
24
  if session[:settings]
25
25
  session.delete(:settings)
26
26
  redirect_to main_app.root_path
27
- elsif current_organization && current_organization.oauth_uid && current_organization.sync_enabled
27
+ elsif current_organization&.oauth_uid && current_organization&.sync_enabled
28
28
  redirect_to main_app.home_redirect_to_external_path
29
29
  else
30
30
  redirect_to main_app.root_path
@@ -9,7 +9,7 @@ class Maestrano::ConnecController < Maestrano::Rails::WebHookController
9
9
 
10
10
  entities.each do |entity|
11
11
  organization = Maestrano::Connector::Rails::Organization.find_by_uid_and_tenant(entity[:group_id], params[:tenant])
12
- next Rails.logger.warn "Received notification from Connec! for unknown group or group without oauth: #{entity['group_id']} (tenant: #{params[:tenant]})" unless organization && organization.oauth_uid
12
+ next Rails.logger.warn "Received notification from Connec! for unknown group or group without oauth: #{entity['group_id']} (tenant: #{params[:tenant]})" unless organization&.oauth_uid
13
13
  next unless organization.sync_enabled && organization.synchronized_entities[entity_class_hash[:name].to_sym]
14
14
 
15
15
  Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Received entity from Connec! webhook: Entity=#{entity_name}, Data=#{entity}")
@@ -3,23 +3,11 @@ class Maestrano::SynchronizationsController < Maestrano::Rails::WebHookControlle
3
3
  tenant = params[:tenant]
4
4
  uid = params[:id]
5
5
  organization = Maestrano::Connector::Rails::Organization.find_by_uid_and_tenant(uid, tenant)
6
- return render json: {errors: [{message: "Organization not found", code: 404}]}, status: :not_found unless organization
7
-
8
- h = {
9
- group_id: organization.uid,
10
- sync_enabled: organization.sync_enabled
11
- }
12
-
13
- last_sync = organization.synchronizations.last
14
- if last_sync
15
- h.merge!(
16
- status: last_sync.status,
17
- message: last_sync.message,
18
- updated_at: last_sync.updated_at
19
- )
20
- end
6
+ return render json: {errors: [{message: 'Organization not found', code: 404}]}, status: :not_found unless organization
7
+
8
+ status = organization_status organization
21
9
 
22
- render json: h
10
+ render_organization_sync(organization, status, 200)
23
11
  end
24
12
 
25
13
  def create
@@ -27,21 +15,55 @@ class Maestrano::SynchronizationsController < Maestrano::Rails::WebHookControlle
27
15
  uid = params[:group_id]
28
16
  opts = params[:opts] || {}
29
17
  organization = Maestrano::Connector::Rails::Organization.find_by_uid_and_tenant(uid, tenant)
30
- return render json: {errors: [{message: "Organization not found", code: 404}]}, status: :not_found unless organization
18
+ return render json: {errors: [{message: 'Organization not found', code: 404}]}, status: :not_found unless organization
19
+
20
+ status = organization_status(organization)
31
21
 
32
- Maestrano::Connector::Rails::SynchronizationJob.perform_later(organization, opts.with_indifferent_access)
33
- head :created
22
+ unless status == 'RUNNING' || status == 'ENQUEUED'
23
+ Maestrano::Connector::Rails::SynchronizationJob.perform_later(organization.id, opts.with_indifferent_access)
24
+ status = 'ENQUEUED'
25
+ end
26
+
27
+ render_organization_sync(organization, status, 201)
34
28
  end
35
29
 
36
30
  def toggle_sync
37
31
  tenant = params[:tenant]
38
32
  uid = params[:group_id]
39
33
  organization = Maestrano::Connector::Rails::Organization.find_by_uid_and_tenant(uid, tenant)
40
- return render json: {errors: [{message: "Organization not found", code: 404}]}, status: :not_found unless organization
34
+ return render json: {errors: [{message: 'Organization not found', code: 404}]}, status: :not_found unless organization
41
35
 
42
36
  organization.toggle(:sync_enabled)
43
37
  organization.save
44
-
45
- render json: {sync_enabled: organization.sync_enabled}
38
+ status = organization_status organization
39
+ render_organization_sync(organization, status, 200)
46
40
  end
41
+
42
+ private
43
+
44
+ def render_organization_sync(organization, status, code)
45
+ h = {
46
+ group_id: organization.uid,
47
+ sync_enabled: organization.sync_enabled,
48
+ status: status
49
+ }
50
+ last_sync = organization.synchronizations.last
51
+ if last_sync
52
+ h[:message] = last_sync.message
53
+ h[:updated_at] = last_sync.updated_at
54
+ end
55
+
56
+ render json: h, status: code
57
+ end
58
+
59
+ def organization_status(organization)
60
+ last_sync = organization.synchronizations.last
61
+ if Maestrano::Connector::Rails::SynchronizationJob.find_running_job(organization.id)
62
+ 'RUNNING'
63
+ elsif Maestrano::Connector::Rails::SynchronizationJob.find_job(organization.id)
64
+ 'ENQUEUED'
65
+ else
66
+ last_sync&.status || 'DISABLED'
67
+ end
68
+ end
47
69
  end
@@ -6,7 +6,7 @@ module Maestrano::Connector::Rails
6
6
  def perform(name = nil, count = nil)
7
7
  Maestrano::Connector::Rails::Organization.where.not(oauth_provider: nil, encrypted_oauth_token: nil).each do |o|
8
8
  next unless [true, 1].include?(o.sync_enabled)
9
- Maestrano::Connector::Rails::SynchronizationJob.perform_later(o, {})
9
+ Maestrano::Connector::Rails::SynchronizationJob.perform_later(o.id, {})
10
10
  end
11
11
  end
12
12
  end
@@ -7,9 +7,9 @@ module Maestrano::Connector::Rails
7
7
  # * :only_entities => [person, tasks_list]
8
8
  # * :full_sync => true synchronization is performed without date filtering
9
9
  # * :connec_preemption => true|false : preemption is always|never given to connec in case of conflict (if not set, the most recently updated entity is kept)
10
- def perform(organization, opts = {})
11
- return unless organization.sync_enabled
12
-
10
+ def perform(organization_id, opts = {})
11
+ organization = Maestrano::Connector::Rails::Organization.find(organization_id)
12
+ return unless organization&.sync_enabled
13
13
  # Check if previous synchronization is still running
14
14
  if Synchronization.where(organization_id: organization.id, status: 'RUNNING').where(created_at: (30.minutes.ago..Time.now)).exists?
15
15
  ConnectorLogger.log('info', organization, 'Synchronization skipped: Previous synchronization is still running')
@@ -105,6 +105,25 @@ module Maestrano::Connector::Rails
105
105
  end
106
106
  end
107
107
 
108
+ def self.enqueued?(organization_id)
109
+ SynchronizationJob.find_job(organization_id).present? || SynchronizationJob.find_running_job(organization_id).present?
110
+ end
111
+
112
+ def self.find_job(organization_id)
113
+ queue = Sidekiq::Queue.new(:default)
114
+ queue.find do |job|
115
+ organization_id == job.item['args'][0]['arguments'].first
116
+ end
117
+ end
118
+
119
+ def self.find_running_job(organization_id)
120
+ Sidekiq::Workers.new.find do |_, _, work|
121
+ work['queue'] == 'default' && work['payload']['args'][0]['arguments'].first == organization_id
122
+ end
123
+ rescue
124
+ nil
125
+ end
126
+
108
127
  private
109
128
 
110
129
  def instanciate_entity(entity_name, organization, connec_client, external_client, opts)
@@ -120,7 +139,7 @@ module Maestrano::Connector::Rails
120
139
  entity_instance.push_entities_to_external(mapped_entities[:connec_entities])
121
140
  entity_instance.push_entities_to_connec(mapped_entities[:external_entities])
122
141
  entity_instance.after_sync(last_synchronization_date)
123
-
142
+
124
143
  entity_instance.class.count_and_first(external ? external_entities : connec_entities)
125
144
  end
126
145
  end
@@ -312,7 +312,7 @@ module Maestrano::Connector::Rails::Concerns::Entity
312
312
 
313
313
  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}")
314
314
 
315
- entities_to_send_to_connec = mapped_connec_entities_with_idmaps.map{ |mapped_connec_entity_with_idmap|
315
+ entities_to_send_to_connec = mapped_connec_entities_with_idmaps.map { |mapped_connec_entity_with_idmap|
316
316
  push_entity_to_external(mapped_connec_entity_with_idmap, external_entity_name)
317
317
  }.compact
318
318
 
@@ -324,7 +324,7 @@ module Maestrano::Connector::Rails::Concerns::Entity
324
324
  # with either only the id, or the id + id references
325
325
  proc = lambda do |entity|
326
326
  id = {id: [Maestrano::Connector::Rails::ConnecHelper.id_hash(entity[:idmap].external_id, @organization)]}
327
- body = entity[:completed_hash] ? entity[:completed_hash].merge(id) : id
327
+ body = entity[:completed_hash]&.merge(id) || id
328
328
  batch_op('put', body, entity[:idmap].connec_id, self.class.normalized_connec_entity_name)
329
329
  end
330
330
  batch_calls(entities_to_send_to_connec, proc, self.class.connec_entity_name, true)
@@ -62,7 +62,7 @@ module Maestrano::Connector::Rails
62
62
  end
63
63
 
64
64
  def member?(user)
65
- user_organization_rels.where(user_id: user.id).count > 0
65
+ user_organization_rels.where(user_id: user.id).count.positive?
66
66
  end
67
67
 
68
68
  def remove_member(user)
@@ -108,7 +108,7 @@ module Maestrano::Connector::Rails
108
108
  end
109
109
 
110
110
  def last_synchronization_date
111
- (last_successful_synchronization && last_successful_synchronization.updated_at) || date_filtering_limit
111
+ last_successful_synchronization&.updated_at || date_filtering_limit
112
112
  end
113
113
  end
114
114
  end
@@ -23,7 +23,7 @@ class HomeController < ApplicationController
23
23
 
24
24
  def synchronize
25
25
  return redirect_to(:back) unless is_admin
26
- Maestrano::Connector::Rails::SynchronizationJob.perform_later(current_organization, (params['opts'] || {}).merge(forced: true))
26
+ Maestrano::Connector::Rails::SynchronizationJob.perform_later(current_organization.id, (params['opts'] || {}).merge(forced: true))
27
27
  flash[:info] = 'Synchronization requested'
28
28
  redirect_to(:back)
29
29
  end
@@ -35,7 +35,7 @@ class HomeController < ApplicationController
35
35
  private
36
36
 
37
37
  def start_synchronization(old_sync_state, organization)
38
- Maestrano::Connector::Rails::SynchronizationJob.perform_later(organization, {})
38
+ Maestrano::Connector::Rails::SynchronizationJob.perform_later(organization.id, {})
39
39
  flash[:info] = 'Congrats, you\'re all set up! Your data are now being synced'
40
40
  end
41
41
  end
@@ -87,7 +87,7 @@ describe HomeController, type: :controller do
87
87
  subject { post :synchronize, opts: {'opts' => 'some_opts'} }
88
88
 
89
89
  it 'calls perform_later with opts' do
90
- expect(Maestrano::Connector::Rails::SynchronizationJob).to receive(:perform_later).with(organization, 'opts' => 'some_opts', forced: true)
90
+ expect(Maestrano::Connector::Rails::SynchronizationJob).to receive(:perform_later).with(organization.id, 'opts' => 'some_opts', forced: true)
91
91
  subject
92
92
  end
93
93
  end
@@ -96,7 +96,7 @@ describe HomeController, type: :controller do
96
96
  subject { post :synchronize }
97
97
 
98
98
  it 'calls perform_later with empty opts hash' do
99
- expect(Maestrano::Connector::Rails::SynchronizationJob).to receive(:perform_later).with(organization, forced: true)
99
+ expect(Maestrano::Connector::Rails::SynchronizationJob).to receive(:perform_later).with(organization.id, forced: true)
100
100
  subject
101
101
  end
102
102
  end
@@ -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.4.0 ruby lib
5
+ # stub: maestrano-connector-rails 1.5.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "maestrano-connector-rails"
9
- s.version = "1.4.0"
9
+ s.version = "1.5.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 = ["Maestrano", "Pierre Berard", "Marco Bagnasco"]
14
- s.date = "2016-08-24"
14
+ s.date = "2016-09-30"
15
15
  s.description = "Maestrano is the next generation marketplace for SME applications. See https://maestrano.com for details."
16
16
  s.email = "developers@maestrano.com"
17
17
  s.executables = ["rails"]
@@ -61,6 +61,7 @@ describe Maestrano::SynchronizationsController, type: :controller do
61
61
  JSON.parse({
62
62
  group_id: organization.uid,
63
63
  sync_enabled: organization.sync_enabled,
64
+ status: 'DISABLED'
64
65
  }.to_json)
65
66
  )
66
67
  end
@@ -78,7 +79,7 @@ describe Maestrano::SynchronizationsController, type: :controller do
78
79
  sync_enabled: organization.sync_enabled,
79
80
  status: sync2.status,
80
81
  message: sync2.message,
81
- updated_at: sync2.updated_at
82
+ updated_at: sync2.updated_at
82
83
  }.to_json)
83
84
  )
84
85
  end
@@ -135,7 +136,7 @@ describe Maestrano::SynchronizationsController, type: :controller do
135
136
  end
136
137
 
137
138
  it 'queues a sync' do
138
- expect(Maestrano::Connector::Rails::SynchronizationJob).to receive(:perform_later).with(organization, opts)
139
+ expect(Maestrano::Connector::Rails::SynchronizationJob).to receive(:perform_later).with(organization.id, opts)
139
140
  subject
140
141
  end
141
142
  end
@@ -14,9 +14,9 @@ describe Maestrano::Connector::Rails::AllSynchronizationsJob do
14
14
 
15
15
  describe 'perform' do
16
16
  it 'does not calls sync entity' do
17
- expect(Maestrano::Connector::Rails::SynchronizationJob).to_not receive(:perform_later).with(organization_not_linked, anything)
18
- expect(Maestrano::Connector::Rails::SynchronizationJob).to_not receive(:perform_later).with(organization_not_active, anything)
19
- expect(Maestrano::Connector::Rails::SynchronizationJob).to receive(:perform_later).with(organization_to_process, anything)
17
+ expect(Maestrano::Connector::Rails::SynchronizationJob).to_not receive(:perform_later).with(organization_not_linked.id, anything)
18
+ expect(Maestrano::Connector::Rails::SynchronizationJob).to_not receive(:perform_later).with(organization_not_active.id, anything)
19
+ expect(Maestrano::Connector::Rails::SynchronizationJob).to receive(:perform_later).with(organization_to_process.id, anything)
20
20
 
21
21
  subject
22
22
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Maestrano::Connector::Rails::SynchronizationJob do
4
4
  let(:organization) { create(:organization) }
5
5
  let(:opts) { {} }
6
- subject { Maestrano::Connector::Rails::SynchronizationJob.perform_now(organization, opts) }
6
+ subject { Maestrano::Connector::Rails::SynchronizationJob.perform_now(organization.id, opts) }
7
7
 
8
8
  def does_not_perform
9
9
  expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to_not receive(:sync_entity)
@@ -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) }
@@ -77,11 +77,12 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
77
77
 
78
78
  context 'subsequent sync' do
79
79
  let!(:old_sync) { create(:synchronization, partial: false, status: 'SUCCESS', organization: organization) }
80
-
80
+
81
81
  it { performes }
82
82
 
83
83
  it 'calls sync entity on all the organization synchronized entities set to true' do
84
84
  organization.synchronized_entities[organization.synchronized_entities.keys.first] = false
85
+ organization.save
85
86
  expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).exactly(organization.synchronized_entities.count - 1).times
86
87
 
87
88
  subject
@@ -172,11 +173,11 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
172
173
  context 'with more than 50 entities' do
173
174
  let(:external_entities1) { [*1..50] }
174
175
  let(:external_entities2) { [*51..60] }
175
-
176
+
176
177
  it 'calls perform_sync several time' do
177
178
  expect_any_instance_of(Entities::Person).to receive(:opts_merge!).twice
178
179
  expect(subject).to receive(:perform_sync).twice.and_call_original
179
-
180
+
180
181
  subject.first_sync_entity('person', organization, nil, nil, nil, {}, true)
181
182
  end
182
183
  end
@@ -187,7 +188,7 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
187
188
  it 'calls perform_sync once' do
188
189
  expect_any_instance_of(Entities::Person).to receive(:opts_merge!).once.with({__skip: 0})
189
190
  expect(subject).to receive(:perform_sync).once.and_call_original
190
-
191
+
191
192
  subject.first_sync_entity('person', organization, nil, nil, nil, {}, true)
192
193
  end
193
194
  end
@@ -200,7 +201,7 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
200
201
  it 'calls perform_sync once' do
201
202
  expect_any_instance_of(Entities::Person).to receive(:opts_merge!).once.with({__skip: 0})
202
203
  expect(subject).to receive(:perform_sync).once.and_call_original
203
-
204
+
204
205
  subject.first_sync_entity('person', organization, nil, nil, nil, {}, true)
205
206
  end
206
207
  end
@@ -220,4 +221,4 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
220
221
  end
221
222
  end
222
223
  end
223
- end
224
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maestrano-connector-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maestrano
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-08-24 00:00:00.000000000 Z
13
+ date: 2016-09-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails