maestrano-connector-rails 0.4.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/README.md +1 -1
  4. data/VERSION +1 -1
  5. data/app/controllers/maestrano/connec_controller.rb +17 -19
  6. data/app/jobs/maestrano/connector/rails/all_synchronizations_job.rb +1 -1
  7. data/app/jobs/maestrano/connector/rails/push_to_connec_job.rb +11 -11
  8. data/app/jobs/maestrano/connector/rails/synchronization_job.rb +20 -11
  9. data/app/models/maestrano/connector/rails/concerns/complex_entity.rb +66 -74
  10. data/app/models/maestrano/connector/rails/concerns/connec_helper.rb +102 -0
  11. data/app/models/maestrano/connector/rails/concerns/entity.rb +233 -231
  12. data/app/models/maestrano/connector/rails/concerns/external.rb +7 -0
  13. data/app/models/maestrano/connector/rails/concerns/sub_entity_base.rb +14 -43
  14. data/app/models/maestrano/connector/rails/connec_helper.rb +5 -0
  15. data/app/models/maestrano/connector/rails/organization.rb +8 -2
  16. data/db/20160524112054_add_encryption_on_oauth_keys.rb +8 -0
  17. data/lib/generators/connector/install_generator.rb +1 -0
  18. data/lib/generators/connector/templates/complex_entity_example/contact.rb +1 -1
  19. data/lib/generators/connector/templates/complex_entity_example/contact_and_lead.rb +2 -2
  20. data/lib/generators/connector/templates/entity.rb +13 -19
  21. data/lib/generators/connector/templates/example_entity.rb +2 -2
  22. data/lib/generators/connector/templates/example_entity_spec.rb +73 -0
  23. data/lib/generators/connector/templates/external.rb +11 -0
  24. data/maestrano-connector-rails.gemspec +13 -8
  25. data/release_notes.md +81 -0
  26. data/spec/controllers/connec_controller_spec.rb +19 -6
  27. data/spec/dummy/app/models/maestrano/connector/rails/entity.rb +0 -7
  28. data/spec/dummy/app/models/maestrano/connector/rails/external.rb +7 -0
  29. data/spec/dummy/app/views/home/index.html.erb +1 -36
  30. data/spec/factories.rb +3 -0
  31. data/spec/integration/connec_to_external_spec.rb +188 -0
  32. data/spec/integration/external_to_connec_spec.rb +155 -0
  33. data/spec/integration/integration_complex_spec.rb +281 -0
  34. data/spec/integration/singleton_spec.rb +288 -0
  35. data/spec/jobs/all_synchronizations_job_spec.rb +5 -0
  36. data/spec/jobs/push_to_connec_job_spec.rb +3 -6
  37. data/spec/jobs/synchronization_job_spec.rb +29 -17
  38. data/spec/models/complex_entity_spec.rb +257 -412
  39. data/spec/models/connec_helper_spec.rb +143 -0
  40. data/spec/models/entity_spec.rb +420 -348
  41. data/spec/models/external_spec.rb +4 -0
  42. data/spec/models/organization_spec.rb +2 -1
  43. data/spec/models/sub_entity_base_spec.rb +28 -69
  44. data/template/factories.rb +3 -1
  45. data/template/maestrano-connector-template.rb +11 -13
  46. data/template/maestrano.rb +2 -1
  47. data/template/settings/development.yml +4 -2
  48. data/template/settings/production.yml +1 -11
  49. data/template/settings/settings.yml +8 -0
  50. data/template/settings/test.yml +2 -0
  51. data/template/settings/uat.yml +1 -9
  52. metadata +12 -7
  53. data/Gemfile.lock +0 -256
  54. data/realse_notes.md +0 -16
  55. data/spec/dummy/app/views/admin/index.html.erb +0 -51
  56. data/spec/dummy/db/development.sqlite3 +0 -0
  57. data/spec/dummy/db/test.sqlite3 +0 -0
@@ -7,6 +7,11 @@ describe Maestrano::Connector::Rails::AllSynchronizationsJob do
7
7
 
8
8
  subject { Maestrano::Connector::Rails::AllSynchronizationsJob.perform_now() }
9
9
 
10
+ # before{
11
+ # organization_not_active.update(encrypted_oauth_token: Maestrano::Connector::Rails::Organization.encrypt_oauth_token('123', key: 'This is a key that is 256 bits!!', iv: 'This iv is 12 bytes or longer'))
12
+ # organization_to_process.update(encrypted_oauth_token: Maestrano::Connector::Rails::Organization.encrypt_oauth_token('123', key: 'This is a key that is 256 bits!!', iv: 'This iv is 12 bytes or longer'))
13
+ # }
14
+
10
15
  describe 'perform' do
11
16
  it 'does not calls sync entity' do
12
17
  expect(Maestrano::Connector::Rails::SynchronizationJob).to_not receive(:perform_later).with(organization_not_linked, anything)
@@ -6,9 +6,6 @@ describe Maestrano::Connector::Rails::PushToConnecJob do
6
6
  let(:entity_name2) { 'entity2' }
7
7
  before {
8
8
  class Entities::Entity1 < Maestrano::Connector::Rails::Entity
9
- def map_to_connec(entity, organization)
10
- entity
11
- end
12
9
  end
13
10
  allow_any_instance_of(Entities::Entity1).to receive(:push_entities_to_connec)
14
11
  allow(Entities::Entity1).to receive(:external_entity_name).and_return('ext_entity1')
@@ -16,7 +13,7 @@ describe Maestrano::Connector::Rails::PushToConnecJob do
16
13
  end
17
14
  allow_any_instance_of(Entities::Entity2).to receive(:consolidate_and_map_data).and_return({})
18
15
  allow_any_instance_of(Entities::Entity2).to receive(:push_entities_to_connec)
19
- allow(Entities::Entity2).to receive(:connec_entities_names).and_return(%w())
16
+ allow(Entities::Entity2).to receive(:connec_entities_names).and_return(['Connec name'])
20
17
  allow(Entities::Entity2).to receive(:external_entities_names).and_return(%w(Subs ll))
21
18
  module Entities::SubEntities end;
22
19
  class Entities::SubEntities::Sub < Maestrano::Connector::Rails::SubEntityBase
@@ -66,7 +63,7 @@ describe Maestrano::Connector::Rails::PushToConnecJob do
66
63
  before { organization.update(synchronized_entities: {:"#{entity_name1}" => false, :"#{entity_name2}" => true})}
67
64
 
68
65
  it 'calls consolidate and map data on the complex entity with the right arguments' do
69
- expect_any_instance_of(Entities::Entity2).to receive(:consolidate_and_map_data).with({}, {"Subs"=>[entity21], "ll"=>[]}, organization, {})
66
+ expect_any_instance_of(Entities::Entity2).to receive(:consolidate_and_map_data).with({"Connec name" => []}, {"Subs"=>[entity21], "ll"=>[]})
70
67
  expect_any_instance_of(Entities::Entity2).to receive(:push_entities_to_connec)
71
68
  subject
72
69
  end
@@ -87,7 +84,7 @@ describe Maestrano::Connector::Rails::PushToConnecJob do
87
84
  before { organization.update(synchronized_entities: {:"#{entity_name1}" => true, :"#{entity_name2}" => false})}
88
85
 
89
86
  it 'calls consolidate_and_map_data on the non complex entity with the right arguments' do
90
- expect_any_instance_of(Entities::Entity1).to receive(:consolidate_and_map_data).with([], [entity11, entity12], organization, {}).and_return({})
87
+ expect_any_instance_of(Entities::Entity1).to receive(:consolidate_and_map_data).with([], [entity11, entity12]).and_return({})
91
88
  expect_any_instance_of(Entities::Entity1).to receive(:push_entities_to_connec)
92
89
  subject
93
90
  end
@@ -69,29 +69,41 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
69
69
 
70
70
  it { performes }
71
71
 
72
- it 'calls sync entity on all the organization synchronized entities set to true' do
73
- organization.synchronized_entities[organization.synchronized_entities.keys.first] = false
74
- expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).exactly(organization.synchronized_entities.count - 1).times
75
-
76
- subject
72
+ context 'first sync' do
73
+ 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
75
+ subject
76
+ end
77
77
  end
78
78
 
79
- context 'with options' do
80
- context 'with only_entities' do
81
- let(:opts) { {only_entities: %w(people price)} }
79
+ context 'subsequent sync' do
80
+ let!(:old_sync) { create(:synchronization, partial: false, status: 'SUCCESS', organization: organization) }
82
81
 
83
- it 'calls sync entity on the specified entities' do
84
- expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).twice
82
+ it 'calls sync entity on all the organization synchronized entities set to true' do
83
+ organization.synchronized_entities[organization.synchronized_entities.keys.first] = false
84
+ expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).exactly(organization.synchronized_entities.count - 1).times
85
85
 
86
- subject
87
- end
86
+ subject
87
+ end
88
+
89
+ context 'with options' do
90
+ context 'with only_entities' do
91
+ let(:opts) { {only_entities: %w(people price)} }
88
92
 
89
- it 'set the current syncrhonization as partial' do
90
- subject
91
- expect(Maestrano::Connector::Rails::Synchronization.last.partial).to be(true)
93
+ it 'calls sync entity on the specified entities' do
94
+ expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).twice
95
+
96
+ subject
97
+ end
98
+
99
+ it 'set the current syncrhonization as partial' do
100
+ subject
101
+ expect(Maestrano::Connector::Rails::Synchronization.last.partial).to be(true)
102
+ end
92
103
  end
93
104
  end
94
105
  end
106
+
95
107
  end
96
108
  end
97
109
 
@@ -107,7 +119,7 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
107
119
  it 'calls the seven methods' do
108
120
  expect_any_instance_of(Entities::Person).to receive(:before_sync)
109
121
  expect_any_instance_of(Entities::Person).to receive(:get_connec_entities)
110
- expect_any_instance_of(Entities::Person).to receive(:get_external_entities)
122
+ expect_any_instance_of(Entities::Person).to receive(:get_external_entities_wrapper)
111
123
  expect_any_instance_of(Entities::Person).to receive(:consolidate_and_map_data).and_return({})
112
124
  expect_any_instance_of(Entities::Person).to receive(:push_entities_to_external)
113
125
  expect_any_instance_of(Entities::Person).to receive(:push_entities_to_connec)
@@ -125,7 +137,7 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
125
137
  it 'calls the seven methods' do
126
138
  expect_any_instance_of(Entities::SomeStuff).to receive(:before_sync)
127
139
  expect_any_instance_of(Entities::SomeStuff).to receive(:get_connec_entities)
128
- expect_any_instance_of(Entities::SomeStuff).to receive(:get_external_entities)
140
+ expect_any_instance_of(Entities::SomeStuff).to receive(:get_external_entities_wrapper)
129
141
  expect_any_instance_of(Entities::SomeStuff).to receive(:consolidate_and_map_data).and_return({})
130
142
  expect_any_instance_of(Entities::SomeStuff).to receive(:push_entities_to_external)
131
143
  expect_any_instance_of(Entities::SomeStuff).to receive(:push_entities_to_connec)
@@ -2,496 +2,341 @@ require 'spec_helper'
2
2
 
3
3
  describe Maestrano::Connector::Rails::ComplexEntity do
4
4
 
5
- subject { Maestrano::Connector::Rails::ComplexEntity.new }
6
-
7
- #Complex specific methods
8
- describe 'complex specific methods' do
9
- describe 'connec_entities_names' do
10
- it { expect{ subject.class.connec_entities_names }.to raise_error('Not implemented') }
11
- end
12
- describe 'external_entities_names' do
13
- it { expect{ subject.class.external_entities_names }.to raise_error('Not implemented') }
14
- end
15
- describe 'connec_model_to_external_model' do
16
- it { expect{ subject.connec_model_to_external_model({}, nil) }.to raise_error('Not implemented') }
17
- end
18
- describe 'external_model_to_connec_model' do
19
- it { expect{ subject.external_model_to_connec_model({}, nil) }.to raise_error('Not implemented') }
20
- end
21
- end
22
-
23
- describe 'general methods' do
24
- let(:organization) { create(:organization) }
25
-
26
- describe 'map_to_external_with_idmap' do
27
- let(:id) { '322j-bbfg4' }
28
- let(:entity) { {'id' => id, 'name' => 'John', 'updated_at' => 2.day.ago} }
29
- let(:mapped_entity) { {'first_name' => 'John'} }
30
- let(:connec_name) { 'Connec_name' }
31
- let(:external_name) { 'External_name' }
32
- let(:sub_instance) { Maestrano::Connector::Rails::SubEntityBase.new }
33
- let(:human_name) { 'ET' }
34
- before {
35
- allow(sub_instance.class).to receive(:external?).and_return(false)
36
- allow(sub_instance.class).to receive(:entity_name).and_return(connec_name)
37
- allow(sub_instance).to receive(:map_to).and_return(mapped_entity)
38
- allow(sub_instance.class).to receive(:object_name_from_connec_entity_hash).and_return(human_name)
39
- }
40
-
41
- context 'when entity has no idmap' do
42
- it 'creates one' do
43
- expect {
44
- subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)
45
- }.to change{ Maestrano::Connector::Rails::IdMap.count }.by(1)
46
- end
5
+ describe 'class methods' do
6
+ subject { Maestrano::Connector::Rails::ComplexEntity }
7
+
8
+ describe 'connec_entities_names' do
9
+ it { expect{ subject.connec_entities_names }.to raise_error('Not implemented') }
47
10
  end
48
- it 'returns the mapped entity with its idmap' do
49
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to eql({entity: mapped_entity, idmap: Maestrano::Connector::Rails::IdMap.last})
11
+ describe 'external_entities_names' do
12
+ it { expect{ subject.external_entities_names }.to raise_error('Not implemented') }
50
13
  end
14
+ end
51
15
 
52
- context 'when entity has an idmap without last_push_to_external' do
53
- let!(:idmap) { create(:idmap, organization: organization, connec_id: id, connec_entity: connec_name.downcase, last_push_to_external: nil, external_entity: external_name.downcase) }
54
-
55
- it 'returns the mapped entity with its idmap' do
56
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to eql({entity: mapped_entity, idmap: idmap})
57
- end
58
- end
59
-
60
- context 'when entity has an idmap with an older last_push_to_external' do
61
- let!(:idmap) { create(:idmap, organization: organization, connec_id: id, connec_entity: connec_name.downcase, last_push_to_external: 1.year.ago, external_entity: external_name.downcase) }
62
-
63
- it 'returns the mapped entity with its idmap' do
64
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to eql({entity: mapped_entity, idmap: idmap})
65
- end
66
- end
67
-
68
- context 'when entity has an idmap with a more recent last_push_to_external' do
69
- let!(:idmap) { create(:idmap, organization: organization, connec_id: id, connec_entity: connec_name.downcase, last_push_to_external: 1.second.ago, external_entity: external_name.downcase) }
70
-
71
- it 'discards the entity' do
72
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to be_nil
73
- end
16
+ describe 'instance methods' do
17
+ let!(:organization) { create(:organization, uid: 'cld-123') }
18
+ let!(:connec_client) { Maestrano::Connec::Client[organization.tenant].new(organization.uid) }
19
+ let!(:external_client) { Object.new }
20
+ let(:opts) { {} }
21
+ subject { Maestrano::Connector::Rails::ComplexEntity.new(organization, connec_client, external_client, opts) }
22
+
23
+ #Complex specific methods
24
+ describe 'complex specific methods' do
25
+ describe 'connec_model_to_external_model' do
26
+ it { expect{ subject.connec_model_to_external_model({}) }.to raise_error('Not implemented') }
74
27
  end
75
-
76
- context 'when entity has an idmap with to_external set to false' do
77
- let!(:idmap) { create(:idmap, organization: organization, connec_id: id, connec_entity: connec_name.downcase, to_external: false, external_entity: external_name.downcase) }
78
-
79
- it 'discards the entity' do
80
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to be_nil
81
- end
82
- end
83
-
84
- context 'when entity has an idmap with external_inactive set to true' do
85
- let!(:idmap) { create(:idmap, organization: organization, connec_id: id, connec_entity: connec_name.downcase, external_inactive: true, external_entity: external_name.downcase) }
86
-
87
- it 'discards the entity' do
88
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to be_nil
89
- end
28
+ describe 'external_model_to_connec_model' do
29
+ it { expect{ subject.external_model_to_connec_model({}) }.to raise_error('Not implemented') }
90
30
  end
91
31
  end
92
32
 
93
33
  describe 'filter_connec_entities' do
94
- it { expect(subject.filter_connec_entities({'lead' => [{a: 2}]}, organization)).to eql({'lead' => [{a: 2}]}) }
95
- end
96
- end
97
-
98
- describe 'methods with sub complex entities' do
99
- before {
100
- module Entities::SubEntities
101
- end
102
- class Entities::SubEntities::ScE1 < Maestrano::Connector::Rails::SubEntityBase
103
- end
104
- class Entities::SubEntities::ScE2 < Maestrano::Connector::Rails::SubEntityBase
105
- end
106
- }
107
-
108
- describe 'get_connec_entities' do
109
- before {
110
- allow(subject.class).to receive(:connec_entities_names).and_return(%w(sc_e1 ScE2))
111
- }
112
-
113
- it 'calls get_connec_entities on each connec sub complex entities' do
114
- expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_connec_entities).with(nil, nil, nil, {opts: true})
115
- expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_connec_entities).with(nil, nil, nil, {opts: true})
116
- subject.get_connec_entities(nil, nil, nil, {opts: true})
117
- end
118
-
119
- let(:arr1) { [{'name' => 'Water'}, {'name' => 'Sugar'}] }
120
- let(:arr2) { [{'price' => 92}, {'price' => 300}] }
121
- it 'returns an hash of the connec_entities keyed by connec_entity_name' do
122
- allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_connec_entities).and_return(arr1)
123
- allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_connec_entities).and_return(arr2)
124
- expect(subject.get_connec_entities(nil, nil, nil, {opts: true})).to eql({'sc_e1' => arr1, 'ScE2' => arr2})
125
- end
34
+ it { expect(subject.filter_connec_entities({'lead' => [{a: 2}]})).to eql({'lead' => [{a: 2}]}) }
126
35
  end
127
36
 
128
- describe 'get_external_entities' do
37
+ describe 'methods with sub complex entities' do
129
38
  before {
130
- allow(subject.class).to receive(:external_entities_names).and_return(%w(sc_e1 ScE2))
39
+ module Entities::SubEntities
40
+ end
41
+ class Entities::SubEntities::ScE1 < Maestrano::Connector::Rails::SubEntityBase
42
+ end
43
+ class Entities::SubEntities::ScE2 < Maestrano::Connector::Rails::SubEntityBase
44
+ end
131
45
  }
132
46
 
133
- it 'calls get_external_entities on each connec sub complex entities' do
134
- expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_external_entities).with(nil, nil, nil, {opts: true})
135
- expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_external_entities).with(nil, nil, nil, {opts: true})
136
- subject.get_external_entities(nil, nil, nil, {opts: true})
137
- end
138
-
139
- let(:arr1) { [{'name' => 'Water'}, {'name' => 'Sugar'}] }
140
- let(:arr2) { [{'price' => 92}, {'price' => 300}] }
141
- it 'returns an hash of the external_entities keyed by external_entity_name' do
142
- allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_external_entities).and_return(arr1)
143
- allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_external_entities).and_return(arr2)
144
- expect(subject.get_external_entities(nil, nil, nil, {opts: true})).to eql({'sc_e1' => arr1, 'ScE2' => arr2})
145
- end
146
- end
147
-
148
-
149
- describe 'consolidate_and_map_data' do
150
- let(:opt) { {opt: true} }
151
- let(:organization) { create(:organization) }
47
+ describe 'get_connec_entities' do
48
+ before {
49
+ allow(subject.class).to receive(:connec_entities_names).and_return(%w(sc_e1 ScE2))
50
+ }
152
51
 
153
- it 'calls external_model_to_connec_model' do
154
- allow(subject).to receive(:connec_model_to_external_model).and_return({})
155
- expect(subject).to receive(:external_model_to_connec_model).with({a: {}}, organization).and_return({})
156
- subject.consolidate_and_map_data({}, {a: {}}, organization, opt)
157
- end
52
+ it 'calls get_connec_entities on each connec sub complex entities' do
53
+ expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_connec_entities).with(nil)
54
+ expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_connec_entities).with(nil)
55
+ subject.get_connec_entities(nil)
56
+ end
158
57
 
159
- it 'calls connec_model_to_external_model' do
160
- allow(subject).to receive(:external_model_to_connec_model).and_return({})
161
- expect(subject).to receive(:connec_model_to_external_model).with({a: {}}, organization).and_return({})
162
- subject.consolidate_and_map_data({a: {}}, {}, organization, opt)
58
+ let(:arr1) { [{'name' => 'Water'}, {'name' => 'Sugar'}] }
59
+ let(:arr2) { [{'price' => 92}, {'price' => 300}] }
60
+ it 'returns an hash of the connec_entities keyed by connec_entity_name' do
61
+ allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_connec_entities).and_return(arr1)
62
+ allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_connec_entities).and_return(arr2)
63
+ expect(subject.get_connec_entities(nil)).to eql({'sc_e1' => arr1, 'ScE2' => arr2})
64
+ end
163
65
  end
164
66
 
165
- describe 'connec_entities treatment' do
166
- #hash as it should be after connec_model_to_external_model
167
- let(:connec_hash) {
168
- {
169
- 'sc_e1' => {'ext1' => [{'name' => 'John'}, {'name' => 'Jane'}]},
170
- 'ScE2' => {'ext1' => [{'name' => 'Robert'}], 'ext2' => [{'price' => 45}]}
171
- }
172
- }
173
- before{
174
- allow(subject).to receive(:external_model_to_connec_model).and_return({})
175
- allow(subject).to receive(:connec_model_to_external_model).and_return(connec_hash)
67
+ describe 'get_external_entities' do
68
+ before {
69
+ allow(subject.class).to receive(:external_entities_names).and_return(%w(sc_e1 ScE2))
176
70
  }
177
71
 
178
- it 'calls map_to_external_with_idmap on each entity' do
179
- expect(subject).to receive(:map_to_external_with_idmap).exactly(4).times
180
- subject.consolidate_and_map_data({}, {}, organization, opt)
72
+ it 'calls get_external_entities on each connec sub complex entities' do
73
+ expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_external_entities_wrapper).with(nil)
74
+ expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_external_entities_wrapper).with(nil)
75
+ subject.get_external_entities_wrapper(nil)
181
76
  end
182
- end
183
77
 
184
- describe 'external_entities treatment' do
185
- #hash as it should be after external_model_to_connec_model
186
- let(:id1) { '5678ttd3' }
187
- let(:id2) { '5678taa3' }
188
- let(:entity1) { {'id' => id1, 'name' => 'Robert'} }
189
- let(:entity2) { {'id' => id2, 'price' => 45} }
190
- let(:mapped_entity1) { {'first_name' => 'Robert'} }
191
- let(:mapped_entity2) { {'net_price' => 45} }
192
- let(:external_hash) {
193
- {
194
- 'sc_e1' => {'Connec1' => [entity1]},
195
- 'ScE2' => {'Connec1' => [entity1], 'connec2' => [entity2]}
196
- }
197
- }
198
- let(:connec_hash) { {} }
199
- let(:human_name) { 'Jabba' }
200
- before{
201
- allow(subject).to receive(:external_model_to_connec_model).and_return(external_hash)
202
- allow(subject).to receive(:connec_model_to_external_model).and_return(connec_hash)
203
- allow(Entities::SubEntities::ScE1).to receive(:external?).and_return(true)
204
- allow(Entities::SubEntities::ScE1).to receive(:entity_name).and_return('sc_e1')
205
- allow(Entities::SubEntities::ScE1).to receive(:id_from_external_entity_hash).with(entity1).and_return(id1)
206
- allow(Entities::SubEntities::ScE1).to receive(:last_update_date_from_external_entity_hash).and_return(1.minute.ago)
207
- allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:map_to).with('Connec1', entity1, organization).and_return(mapped_entity1)
208
- allow(Entities::SubEntities::ScE2).to receive(:external?).and_return(true)
209
- allow(Entities::SubEntities::ScE2).to receive(:entity_name).and_return('Sce2')
210
- allow(Entities::SubEntities::ScE2).to receive(:id_from_external_entity_hash).with(entity1).and_return(id1)
211
- allow(Entities::SubEntities::ScE2).to receive(:id_from_external_entity_hash).with(entity2).and_return(id2)
212
- allow(Entities::SubEntities::ScE2).to receive(:last_update_date_from_external_entity_hash).and_return(1.minute.ago)
213
- allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:map_to).with('Connec1', entity1, organization).and_return(mapped_entity1)
214
- allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:map_to).with('connec2', entity2, organization).and_return(mapped_entity2)
215
- allow(Entities::SubEntities::ScE1).to receive(:object_name_from_external_entity_hash).and_return(human_name)
216
- allow(Entities::SubEntities::ScE2).to receive(:object_name_from_external_entity_hash).and_return(human_name)
217
- }
78
+ let(:arr1) { [{'name' => 'Water'}, {'name' => 'Sugar'}] }
79
+ let(:arr2) { [{'price' => 92}, {'price' => 300}] }
80
+ it 'returns an hash of the external_entities keyed by external_entity_name' do
81
+ allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_external_entities_wrapper).and_return(arr1)
82
+ allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_external_entities_wrapper).and_return(arr2)
83
+ expect(subject.get_external_entities_wrapper(nil)).to eql({'sc_e1' => arr1, 'ScE2' => arr2})
84
+ end
85
+ end
218
86
 
219
- context 'when entities have no idmaps' do
220
87
 
221
- it 'creates an idmap for each entity' do
222
- expect{
223
- subject.consolidate_and_map_data({}, {}, organization, opt)
224
- }.to change{ Maestrano::Connector::Rails::IdMap.count }.by(3)
88
+ describe 'consolidate and map methods' do
89
+ let(:human_name) { 'Jabba' }
90
+ let(:mapped_entity) { {mapped: 'entity'} }
91
+ let(:date) { 2.hour.ago }
92
+
93
+ describe 'consolidate_and_map_data' do
94
+ before{
95
+ allow(subject).to receive(:external_model_to_connec_model).and_return({})
96
+ allow(subject).to receive(:connec_model_to_external_model).and_return({})
97
+ }
98
+
99
+ it 'calls external_model_to_connec_model' do
100
+ expect(subject).to receive(:external_model_to_connec_model).with({a: {}}).and_return({})
101
+ subject.consolidate_and_map_data({}, {a: {}})
225
102
  end
226
103
 
227
- it 'returns the entity with their new idmaps' do
228
- mapped_entities = subject.consolidate_and_map_data({}, external_hash, organization, opt)
229
- expect(mapped_entities).to eql(external_entities: {
230
- 'sc_e1' => {'Connec1' => [{entity: mapped_entity1, idmap: Maestrano::Connector::Rails::IdMap.first}]},
231
- 'ScE2' => {
232
- 'Connec1' => [{entity: mapped_entity1, idmap: Maestrano::Connector::Rails::IdMap.second}],
233
- 'connec2' => [{entity: mapped_entity2, idmap: Maestrano::Connector::Rails::IdMap.last}],
234
- }
235
- },
236
- connec_entities: {})
104
+ it 'calls connec_model_to_external_model' do
105
+ expect(subject).to receive(:connec_model_to_external_model).with({a: {}}).and_return({})
106
+ subject.consolidate_and_map_data({a: {}}, {})
237
107
  end
238
- end
239
108
 
240
- context 'when entities have idmaps with to_connec set to false' do
241
- let!(:idmap1) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sc_e1', connec_entity: 'connec1', to_connec: false) }
242
- let!(:idmap21) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sce2', connec_entity: 'connec1', to_connec: false) }
243
- let!(:idmap22) { create(:idmap, organization: organization, external_id: id2, external_entity: 'sce2', connec_entity: 'connec2', to_connec: false) }
244
-
245
- it 'discards the entities' do
246
- mapped_entities = subject.consolidate_and_map_data({}, external_hash, organization, opt)
247
- expect(mapped_entities).to eql(external_entities: {
248
- 'sc_e1' => {'Connec1' => []},
249
- 'ScE2' => {
250
- 'Connec1' => [],
251
- 'connec2' => [],
252
- }
253
- },
254
- connec_entities: {})
109
+ it 'calls the consolidation on both connec and external and returns an hash with the results' do
110
+ expect(subject).to receive(:consolidate_and_map_connec_entities).with({}, {}).and_return({connec_result: 1})
111
+ expect(subject).to receive(:consolidate_and_map_external_entities).with({}).and_return({ext_result: 1})
112
+ expect(subject.consolidate_and_map_data({}, {})).to eql({connec_entities: {connec_result: 1}, external_entities: {ext_result: 1}})
255
113
  end
256
114
  end
257
115
 
258
- describe 'external_inactive flagging' do
116
+ describe 'consolidate_and_map_external_entities' do
117
+ let(:entity) { {'id' => id, 'name' => 'Jane'} }
118
+ let(:id) { 'id' }
119
+ let(:external_name) { 'sc_e1' }
120
+ let(:connec_name) { 'connec1' }
121
+ let(:modeled_external_entities) { {external_name => {connec_name => [entity]}} }
122
+ before {
123
+ allow(Entities::SubEntities::ScE1).to receive(:external?).and_return(true)
124
+ allow(Entities::SubEntities::ScE1).to receive(:entity_name).and_return(external_name)
125
+ allow(Entities::SubEntities::ScE1).to receive(:id_from_external_entity_hash).and_return(id)
126
+ allow(Entities::SubEntities::ScE1).to receive(:object_name_from_external_entity_hash).and_return(human_name)
127
+ allow(Entities::SubEntities::ScE1).to receive(:last_update_date_from_external_entity_hash).and_return(date)
128
+ allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:map_to).and_return(mapped_entity)
129
+ }
259
130
 
260
- context 'idmaps external_inactive set to true' do
261
- let!(:idmap1) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sc_e1', connec_entity: 'connec1', external_inactive: true) }
262
- let!(:idmap21) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sce2', connec_entity: 'connec1', external_inactive: true) }
263
- let!(:idmap22) { create(:idmap, organization: organization, external_id: id2, external_entity: 'sce2', connec_entity: 'connec2', external_inactive: true) }
131
+ context 'when idmap exists' do
132
+ let!(:idmap) { create(:idmap, organization: organization, connec_entity: connec_name.downcase, external_entity: external_name.downcase, external_id: id) }
264
133
 
265
- context 'entities inactive' do
266
- before {
267
- allow(Entities::SubEntities::ScE2).to receive(:inactive_from_external_entity_hash?).and_return(true)
268
- allow(Entities::SubEntities::ScE1).to receive(:inactive_from_external_entity_hash?).and_return(true)
269
- }
134
+ it 'does not create one' do
135
+ expect{
136
+ subject.consolidate_and_map_external_entities(modeled_external_entities)
137
+ }.to_not change{ Maestrano::Connector::Rails::IdMap.count }
138
+ end
270
139
 
271
- it 'discards the entities' do
272
- expect(subject.consolidate_and_map_data({}, external_hash, organization, opt)).to eql(external_entities: {
273
- 'sc_e1' => {'Connec1' => []},
274
- 'ScE2' => {
275
- 'Connec1' => [],
276
- 'connec2' => [],
277
- }
278
- },
279
- connec_entities: {})
140
+ it 'returns the mapped entity with the idmap' do
141
+ expect(subject.consolidate_and_map_external_entities(modeled_external_entities)).to eql({external_name => {connec_name => [{entity: mapped_entity, idmap: idmap}]}})
142
+ end
143
+
144
+ context 'when to_connec is false' do
145
+ before { idmap.update(to_connec: false) }
146
+
147
+ it 'discards the entity' do
148
+ expect(subject.consolidate_and_map_external_entities(modeled_external_entities)).to eql({external_name => {connec_name => []}})
280
149
  end
281
150
  end
282
151
 
283
- context 'entities active' do
152
+ context 'when entity is inactive' do
284
153
  before {
285
- allow(Entities::SubEntities::ScE2).to receive(:inactive_from_external_entity_hash?).and_return(false)
286
- allow(Entities::SubEntities::ScE1).to receive(:inactive_from_external_entity_hash?).and_return(false)
287
- [idmap1, idmap21, idmap22].each{|i| i.update(last_push_to_connec: 1.second.ago)} #Used only to simplify specing
154
+ allow(Entities::SubEntities::ScE1).to receive(:inactive_from_external_entity_hash?).and_return(true)
288
155
  }
289
156
 
157
+ it 'discards the entity' do
158
+ expect(subject.consolidate_and_map_external_entities(modeled_external_entities)).to eql({external_name => {connec_name => []}})
159
+ end
160
+
290
161
  it 'updates the idmaps' do
291
- subject.consolidate_and_map_data({}, external_hash, organization, opt)
292
- expect(idmap1.reload.external_inactive).to be false
293
- expect(idmap21.reload.external_inactive).to be false
294
- expect(idmap22.reload.external_inactive).to be false
295
- end
162
+ subject.consolidate_and_map_external_entities(modeled_external_entities)
163
+ expect(idmap.reload.external_inactive).to be true
164
+ end
296
165
  end
297
- end
298
166
 
299
- context 'idmaps external_inactive set to false' do
300
- let!(:idmap1) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sc_e1', connec_entity: 'connec1', external_inactive: false) }
301
- let!(:idmap21) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sce2', connec_entity: 'connec1', external_inactive: false) }
302
- let!(:idmap22) { create(:idmap, organization: organization, external_id: id2, external_entity: 'sce2', connec_entity: 'connec2', external_inactive: false) }
167
+ context 'when last_push_to_connec is recent' do
168
+ before { idmap.update(last_push_to_connec: 2.second.ago) }
303
169
 
304
- context 'entities inactive' do
305
- before {
306
- allow(Entities::SubEntities::ScE2).to receive(:inactive_from_external_entity_hash?).and_return(true)
307
- allow(Entities::SubEntities::ScE1).to receive(:inactive_from_external_entity_hash?).and_return(true)
308
- }
309
-
310
- it 'discards the entities and updates the idmaps' do
311
- expect(subject.consolidate_and_map_data({}, external_hash, organization, opt)).to eql(external_entities: {
312
- 'sc_e1' => {'Connec1' => []},
313
- 'ScE2' => {
314
- 'Connec1' => [],
315
- 'connec2' => [],
316
- }
317
- },
318
- connec_entities: {})
319
- expect(idmap1.reload.external_inactive).to be true
320
- expect(idmap21.reload.external_inactive).to be true
321
- expect(idmap22.reload.external_inactive).to be true
170
+ it 'discards the entity' do
171
+ expect(subject.consolidate_and_map_external_entities(modeled_external_entities)).to eql({external_name => {connec_name => []}})
322
172
  end
323
173
  end
324
- end
325
- end
326
174
 
327
- context 'when entities have idmaps with more recent last_push_to_connec' do
328
- let!(:idmap1) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sc_e1', connec_entity: 'connec1', last_push_to_connec: 1.second.ago) }
329
- let!(:idmap21) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sce2', connec_entity: 'connec1', last_push_to_connec: 1.second.ago) }
330
- let!(:idmap22) { create(:idmap, organization: organization, external_id: id2, external_entity: 'sce2', connec_entity: 'connec2', last_push_to_connec: 1.second.ago) }
331
-
332
- it 'discards the entities' do
333
- mapped_entities = subject.consolidate_and_map_data({}, external_hash, organization, opt)
334
- expect(mapped_entities).to eql(external_entities: {
335
- 'sc_e1' => {'Connec1' => []},
336
- 'ScE2' => {
337
- 'Connec1' => [],
338
- 'connec2' => [],
339
- }
340
- },
341
- connec_entities: {})
342
175
  end
343
176
  end
344
177
 
345
- context 'when entities have idmaps with older last_push_to_connec' do
178
+ describe 'consolidate_and_map_connec_entities' do
179
+ let(:id) { 'external-unfolded-id' }
180
+ let(:connec_id) { 'connec-id' }
181
+ let(:entity) { {'id' => id, 'name' => 'John', 'updated_at' => date} }
182
+ let(:modeled_connec_entities) { {connec_name => {external_name => [entity]}} }
183
+ let(:modeled_external_entities) { {} }
184
+ let(:connec_name) { 'sc_e1' }
185
+ let(:external_name) { 'ext1' }
346
186
  before{
347
- class Entities::SubEntities::Connec1 < Maestrano::Connector::Rails::SubEntityBase
348
- end
349
- class Entities::SubEntities::Connec2 < Maestrano::Connector::Rails::SubEntityBase
350
- end
351
- allow_any_instance_of(Entities::SubEntities::Connec1).to receive(:map_to).and_return({'name' => 'Jacob'})
352
- allow(Entities::SubEntities::Connec1).to receive(:external?).and_return(false)
353
- allow(Entities::SubEntities::Connec1).to receive(:entity_name).and_return('Connec1')
354
- allow(Entities::SubEntities::Connec1).to receive(:object_name_from_connec_entity_hash).and_return('human name')
187
+ allow(Entities::SubEntities::ScE1).to receive(:external?).and_return(false)
188
+ allow(Entities::SubEntities::ScE1).to receive(:entity_name).and_return(connec_name)
189
+ allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:map_to).with(external_name, entity).and_return(mapped_entity)
190
+ allow(Entities::SubEntities::ScE1).to receive(:object_name_from_connec_entity_hash).and_return(human_name)
191
+ allow(Maestrano::Connector::Rails::ConnecHelper).to receive(:unfold_references).and_return(entity.merge(__connec_id: connec_id))
355
192
  }
356
- let(:connec_id1) { '67ttf-5rr4d' }
357
- let!(:idmap1) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sc_e1', connec_entity: 'connec1', last_push_to_connec: 1.year.ago, connec_id: connec_id1) }
358
- let!(:idmap21) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sce2', connec_entity: 'connec1', last_push_to_connec: 1.year.ago) }
359
- let!(:idmap22) { create(:idmap, organization: organization, external_id: id2, external_entity: 'sce2', connec_entity: 'connec2', last_push_to_connec: 1.year.ago) }
360
- let(:connec_hash) { {'Connec1' => {'sc_e1' => [{'id' => connec_id1, 'first_name' => 'Jacob', 'updated_at' => 1.hour.ago}]}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}} }
361
-
362
- context 'without conflict' do
363
- it 'returns the entity with their idmaps' do
364
- subject.consolidate_and_map_data({'Connec1' => []}, {'sc_e1' => []}, organization, opt)
365
- expect(external_hash).to eql({
366
- 'sc_e1' => {'Connec1' => [{entity: mapped_entity1, idmap: idmap1}]},
367
- 'ScE2' => {
368
- 'Connec1' => [{entity: mapped_entity1, idmap: idmap21}],
369
- 'connec2' => [{entity: mapped_entity2, idmap: idmap22}],
370
- }
371
- })
193
+
194
+ context 'when idmaps do not exist' do
195
+ it 'creates the idmaps with a name and returns the mapped entities with their idmaps' do
196
+ expect{
197
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: Maestrano::Connector::Rails::IdMap.first}]}})
198
+ }.to change{ Maestrano::Connector::Rails::IdMap.count }.by(1)
199
+ expect(Maestrano::Connector::Rails::IdMap.last.name).to eql(human_name)
372
200
  end
373
201
  end
374
202
 
375
- context 'with conflict' do
376
- context 'with option connec_preemption' do
377
- context 'set to true' do
378
- let(:opt) { {connec_preemption: true} }
379
-
380
- it 'keeps the connec entities' do
381
- mapped_entities = subject.consolidate_and_map_data({'Connec1' => []}, {'sc_e1' => []}, organization, opt)
382
- expect(mapped_entities[:connec_entities]).to eq({'Connec1' => {'sc_e1' => [{entity: {'name' => 'Jacob'}, idmap: idmap1}]}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}})
383
- expect(mapped_entities[:external_entities]).to eql({
384
- 'sc_e1' => {'Connec1' => []},
385
- 'ScE2' => {
386
- 'Connec1' => [{entity: mapped_entity1, idmap: idmap21}],
387
- 'connec2' => [{entity: mapped_entity2, idmap: idmap22}],
388
- }
389
- })
390
- end
203
+ context 'when idmap exists' do
204
+ let!(:idmap1) { create(:idmap, organization: organization, connec_entity: connec_name.downcase, external_entity: external_name.downcase, external_id: id, connec_id: connec_id) }
205
+
206
+ it 'does not create an idmap' do
207
+ expect{
208
+ subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})
209
+ }.to_not change{ Maestrano::Connector::Rails::IdMap.count }
210
+ end
211
+
212
+ it 'returns the entity with its idmap' do
213
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: idmap1}]}})
214
+ end
215
+
216
+ context 'when external inactive' do
217
+ before { idmap1.update(external_inactive: true) }
218
+ it 'discards the entity' do
219
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})).to eql({connec_name => {external_name => []}})
391
220
  end
221
+ end
392
222
 
393
- context 'set to false' do
394
- let(:opt) { {connec_preemption: false} }
395
-
396
- it 'keeps the external entities' do
397
- mapped_entities = subject.consolidate_and_map_data({'Connec1' => []}, {'sc_e1' => []}, organization, opt)
398
- expect(mapped_entities[:connec_entities]).to eq({'Connec1' => {'sc_e1' => []}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}})
399
- expect(mapped_entities[:external_entities]).to eql({
400
- 'sc_e1' => {'Connec1' => [{entity: mapped_entity1, idmap: idmap1}]},
401
- 'ScE2' => {
402
- 'Connec1' => [{entity: mapped_entity1, idmap: idmap21}],
403
- 'connec2' => [{entity: mapped_entity2, idmap: idmap22}],
404
- }
405
- })
406
- end
223
+ context 'when to external flag is false' do
224
+ before { idmap1.update(to_external: false) }
225
+ it 'discards the entity' do
226
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})).to eql({connec_name => {external_name => []}})
407
227
  end
408
228
  end
409
229
 
410
- context 'without option' do
411
- context 'with a more recently updated external entity' do
412
- it 'keeps the external entity' do
413
- mapped_entities = subject.consolidate_and_map_data({'Connec1' => []}, {'sc_e1' => []}, organization, opt)
414
- expect(mapped_entities[:connec_entities]).to eq({'Connec1' => {'sc_e1' => []}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}})
415
- expect(mapped_entities[:external_entities]).to eql({
416
- 'sc_e1' => {'Connec1' => [{entity: mapped_entity1, idmap: idmap1}]},
417
- 'ScE2' => {
418
- 'Connec1' => [{entity: mapped_entity1, idmap: idmap21}],
419
- 'connec2' => [{entity: mapped_entity2, idmap: idmap22}],
420
- }
421
- })
230
+ context 'when last_push_to_external is recent' do
231
+ before { idmap1.update(last_push_to_external: 2.second.ago) }
232
+ it 'discards the entity' do
233
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})).to eql({connec_name => {external_name => []}})
234
+ end
235
+ end
236
+
237
+ context 'when conflict' do
238
+ let(:external_entity_1) { {'id' => id} }
239
+ let(:modeled_external_entities) { {external_name => {connec_name => [external_entity_1]}} }
240
+ before {
241
+ allow(Entities::SubEntities::ScE1).to receive(:id_from_external_entity_hash).and_return(id)
242
+ }
243
+
244
+ context 'with opts' do
245
+ context 'with connec preemption false' do
246
+ it 'discards the entity and keep the external one' do
247
+ subject.instance_variable_set(:@opts, {connec_preemption: false})
248
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, modeled_external_entities)).to eql({connec_name => {external_name => []}})
249
+ expect(modeled_external_entities[external_name][connec_name]).to_not be_empty
250
+ end
251
+ end
252
+
253
+ context 'with connec preemption true' do
254
+ it 'keeps the entity and discards the external one' do
255
+ subject.instance_variable_set(:@opts, {connec_preemption: true})
256
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, modeled_external_entities)).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: Maestrano::Connector::Rails::IdMap.first}]}})
257
+ expect(modeled_external_entities[external_name][connec_name]).to be_empty
258
+ end
422
259
  end
423
260
  end
424
261
 
425
- context 'with a more recently updated connec entity' do
426
- let(:connec_hash) { {'Connec1' => {'sc_e1' => [{'id' => connec_id1, 'first_name' => 'Jacob', 'updated_at' => 1.second.ago}]}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}} }
427
-
428
- it 'keeps the connec entities' do
429
- mapped_entities = subject.consolidate_and_map_data({'Connec1' => []}, {'sc_e1' => []}, organization, opt)
430
- expect(mapped_entities[:connec_entities]).to eq({'Connec1' => {'sc_e1' => [{entity: {'name' => 'Jacob'}, idmap: idmap1}]}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}})
431
- expect(mapped_entities[:external_entities]).to eql({
432
- 'sc_e1' => {'Connec1' => []},
433
- 'ScE2' => {
434
- 'Connec1' => [{entity: mapped_entity1, idmap: idmap21}],
435
- 'connec2' => [{entity: mapped_entity2, idmap: idmap22}],
436
- }
437
- })
262
+ context 'without opts' do
263
+ before {
264
+ allow(Entities::SubEntities::ScE1).to receive(:last_update_date_from_external_entity_hash).and_return(external_date)
265
+ }
266
+
267
+ context 'with connec one more recent' do
268
+ let(:external_date) { 1.year.ago }
269
+ let(:date) { 1.day.ago }
270
+
271
+ it 'keeps the entity and discards the external one' do
272
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, modeled_external_entities)).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: Maestrano::Connector::Rails::IdMap.first}]}})
273
+ expect(modeled_external_entities[external_name][connec_name]).to be_empty
274
+ end
275
+ end
276
+
277
+ context 'with external one more recent' do
278
+ let(:external_date) { 1.month.ago }
279
+ let(:date) { 1.year.ago }
280
+
281
+ it 'discards the entity and keep the external one' do
282
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, modeled_external_entities)).to eql({connec_name => {external_name => []}})
283
+ expect(modeled_external_entities[external_name][connec_name]).to_not be_empty
284
+ end
438
285
  end
439
286
  end
440
287
  end
441
288
  end
442
289
  end
443
290
  end
444
- end
445
291
 
446
- describe 'push_entities_to_connec' do
447
- let(:idmap) { nil }
448
- let(:mapped_entity_with_idmap) { {entity: {}, idmap: idmap} }
449
- let(:external_hash) {
450
- {
451
- 'sc_e1' => {'Connec1' => [mapped_entity_with_idmap]},
452
- 'ScE2' => {'Connec1' => [mapped_entity_with_idmap, mapped_entity_with_idmap], 'connec2' => [mapped_entity_with_idmap]}
292
+
293
+ describe 'push_entities_to_connec' do
294
+ let(:idmap) { nil }
295
+ let(:mapped_entity_with_idmap) { {entity: {}, idmap: idmap} }
296
+ let(:external_hash) {
297
+ {
298
+ 'sc_e1' => {'Connec1' => [mapped_entity_with_idmap]},
299
+ 'ScE2' => {'Connec1' => [mapped_entity_with_idmap, mapped_entity_with_idmap], 'connec2' => [mapped_entity_with_idmap]}
300
+ }
453
301
  }
454
- }
455
302
 
456
- it 'calls push_entities_to_connec on each sub complex entity' do
457
- expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:push_entities_to_connec_to).once.with(nil, [mapped_entity_with_idmap], 'Connec1', nil)
458
- expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:push_entities_to_connec_to).twice
459
- subject.push_entities_to_connec(nil, external_hash, nil)
460
- end
303
+ it 'calls push_entities_to_connec on each sub complex entity' do
304
+ expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:push_entities_to_connec_to).once.with([mapped_entity_with_idmap], 'Connec1')
305
+ expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:push_entities_to_connec_to).twice
306
+ subject.push_entities_to_connec(external_hash)
307
+ end
461
308
 
462
- describe 'full call' do
463
- let(:organization) { create(:organization) }
464
- let!(:client) { Maestrano::Connec::Client.new(organization.uid) }
465
- let(:idmap) { create(:idmap, organization: organization) }
466
- before {
467
- [Entities::SubEntities::ScE1, Entities::SubEntities::ScE2].each do |klass|
468
- allow(klass).to receive(:external?).and_return(true)
469
- allow(klass).to receive(:entity_name).and_return('n')
309
+ describe 'full call' do
310
+ let(:idmap) { create(:idmap, organization: organization) }
311
+ before {
312
+ [Entities::SubEntities::ScE1, Entities::SubEntities::ScE2].each do |klass|
313
+ allow(klass).to receive(:external?).and_return(true)
314
+ allow(klass).to receive(:entity_name).and_return('n')
315
+ end
316
+ allow(connec_client).to receive(:batch).and_return(ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {connec1s: {id: [{provider: 'connec', id: 'connec-id'}]}}}]}.to_json, {}), ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {connec1s: {id: [{provider: 'connec', id: 'connec-id'}]}}}]}.to_json, {}), ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {connec2s: {id: [{provider: 'connec', id: 'connec-id'}]}}}]}.to_json, {}))
317
+ }
318
+ it 'is successful' do
319
+ subject.push_entities_to_connec(external_hash)
320
+ idmap.reload
321
+ expect(idmap.message).to be nil
470
322
  end
471
- allow(client).to receive(:batch).and_return(ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {connec1s: {}}}]}.to_json, {}))
472
- }
473
- it 'is successful' do
474
- subject.push_entities_to_connec(client, external_hash, organization)
475
- idmap.reload
476
- expect(idmap.message).to be nil
477
323
  end
478
324
  end
479
- end
480
325
 
481
-
482
- describe 'push_entities_to_external' do
483
- let(:mapped_entity_with_idmap) { {entity: {}, idmap: nil} }
484
- let(:connec_hash) {
485
- {
486
- 'sc_e1' => {'ext1' => [mapped_entity_with_idmap]},
487
- 'ScE2' => {'ext1' => [mapped_entity_with_idmap, mapped_entity_with_idmap], 'ext2' => [mapped_entity_with_idmap]}
326
+ describe 'push_entities_to_external' do
327
+ let(:mapped_entity_with_idmap) { {entity: {}, idmap: nil} }
328
+ let(:connec_hash) {
329
+ {
330
+ 'sc_e1' => {'ext1' => [mapped_entity_with_idmap]},
331
+ 'ScE2' => {'ext1' => [mapped_entity_with_idmap, mapped_entity_with_idmap], 'ext2' => [mapped_entity_with_idmap]}
332
+ }
488
333
  }
489
- }
490
334
 
491
- it 'calls push_entities_to_connec on each sub complex entity' do
492
- expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:push_entities_to_external_to).once.with(nil, [mapped_entity_with_idmap], 'ext1', nil)
493
- expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:push_entities_to_external_to).twice
494
- subject.push_entities_to_external(nil, connec_hash, nil)
335
+ it 'calls push_entities_to_connec on each sub complex entity' do
336
+ expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:push_entities_to_external_to).once.with([mapped_entity_with_idmap], 'ext1')
337
+ expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:push_entities_to_external_to).twice
338
+ subject.push_entities_to_external(connec_hash)
339
+ end
495
340
  end
496
341
  end
497
342
  end