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
@@ -0,0 +1,281 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'complex entities workflow' do
4
+ class Entities::CustomerAndSupplier < Maestrano::Connector::Rails::ComplexEntity
5
+ def self.connec_entities_names
6
+ %w(CompOrganization)
7
+ end
8
+ def self.external_entities_names
9
+ %w(CompCustomer CompSupplier)
10
+ end
11
+ def connec_model_to_external_model(connec_hash_of_entities)
12
+ organizations = connec_hash_of_entities['CompOrganization']
13
+ modeled_connec_entities = {'CompOrganization' => { 'CompSupplier' => [], 'CompCustomer' => [] }}
14
+
15
+ organizations.each do |organization|
16
+ if organization['is_supplier']
17
+ modeled_connec_entities['CompOrganization']['CompSupplier'] << organization
18
+ else
19
+ modeled_connec_entities['CompOrganization']['CompCustomer'] << organization
20
+ end
21
+ end
22
+ return modeled_connec_entities
23
+ end
24
+ def external_model_to_connec_model(external_hash_of_entities)
25
+ return {'CompCustomer' => {'CompOrganization' => external_hash_of_entities['CompCustomer']}, 'CompSupplier' => {'CompOrganization' => external_hash_of_entities['CompSupplier']}}
26
+ end
27
+ end
28
+
29
+ module Entities::SubEntities
30
+ end
31
+ class Entities::SubEntities::CompOrganization < Maestrano::Connector::Rails::SubEntityBase
32
+ def self.external?
33
+ false
34
+ end
35
+ def self.entity_name
36
+ 'CompOrganization'
37
+ end
38
+ def self.mapper_classes
39
+ {
40
+ 'CompCustomer' => ::CompMapper,
41
+ 'CompSupplier' => ::CompMapper
42
+ }
43
+ end
44
+ def self.object_name_from_connec_entity_hash(entity)
45
+ entity['name']
46
+ end
47
+ def self.references
48
+ {'CompCustomer' => ['ref_id'], 'CompSupplier' => ['ref_id']}
49
+ end
50
+ def self.id_from_external_entity_hash(entity)
51
+ entity['id']
52
+ end
53
+ end
54
+
55
+ class Entities::SubEntities::CompCustomer < Maestrano::Connector::Rails::SubEntityBase
56
+ def self.external?
57
+ true
58
+ end
59
+ def self.entity_name
60
+ 'CompCustomer'
61
+ end
62
+ def self.mapper_classes
63
+ {'CompOrganization' => ::CompMapper}
64
+ end
65
+ def self.id_from_external_entity_hash(entity)
66
+ entity['id']
67
+ end
68
+ def self.object_name_from_external_entity_hash(entity)
69
+ entity['name']
70
+ end
71
+ def self.references
72
+ {'CompOrganization' => ['ref_id']}
73
+ end
74
+ def map_to(name, entity)
75
+ super.merge(is_supplier: false)
76
+ end
77
+ end
78
+ class Entities::SubEntities::CompSupplier < Maestrano::Connector::Rails::SubEntityBase
79
+ def self.external?
80
+ true
81
+ end
82
+ def self.entity_name
83
+ 'CompSupplier'
84
+ end
85
+ def self.mapper_classes
86
+ {'CompOrganization' => ::CompMapper}
87
+ end
88
+ def self.id_from_external_entity_hash(entity)
89
+ entity['id']
90
+ end
91
+ def self.object_name_from_external_entity_hash(entity)
92
+ entity['name']
93
+ end
94
+ def self.references
95
+ {'CompOrganization' => ['ref_id']}
96
+ end
97
+ def map_to(name, entity)
98
+ super.merge(is_supplier: true)
99
+ end
100
+ end
101
+
102
+ class CompMapper
103
+ extend HashMapper
104
+ map from('id'), to('id')
105
+ map from('ref_id'), to('ref_id')
106
+ map from('name'), to('name')
107
+ end
108
+
109
+ let(:provider) { 'provider' }
110
+ let(:oauth_uid) { 'oauth uid' }
111
+ let!(:organization) { create(:organization, oauth_provider: provider, oauth_uid: oauth_uid, uid: 'uid') }
112
+ let(:connec_client) { Maestrano::Connec::Client[organization.tenant].new(organization.uid) }
113
+ let(:external_client) { Object.new }
114
+
115
+
116
+ let(:connec_org1_id) { 'connec_org1_id' }
117
+ let(:connec_org2_id) { 'connec_org2_id' }
118
+ let(:connec_org1_ext_id) { 'connec_org1_ext_id' }
119
+ let(:connec_org2_ext_id) { 'connec_org2_ext_id' }
120
+ let(:connec_org1_name) { 'connec_org1_name' }
121
+ let(:connec_org2_name) { 'connec_org2_name' }
122
+ let(:connec_org1_ext_ref_id) { 'connec_org1_ext_ref_id' }
123
+ let(:connec_org2_ext_ref_id) { 'connec_org2_ext_ref_id' }
124
+ let(:connec_org1) {
125
+ {
126
+ 'id' => [{'provider' => 'connec', 'id' => connec_org1_id, 'realm' => organization.uid}],
127
+ 'name' => connec_org1_name,
128
+ 'is_supplier' => true,
129
+ 'ref_id' => [{'provider' => provider, 'id' => connec_org1_ext_ref_id, 'realm' => oauth_uid}]
130
+ }
131
+ }
132
+ let(:mapped_connec_org1) {
133
+ {
134
+ ref_id: connec_org1_ext_ref_id,
135
+ name: connec_org1_name,
136
+ }
137
+ }
138
+ let(:connec_org2) {
139
+ {
140
+ 'id' => [{'provider' => provider, 'id' => connec_org2_ext_id, 'realm' => oauth_uid}, {'id' => connec_org2_id, 'provider' => 'connec', 'realm' => organization.uid}],
141
+ 'name' => connec_org2_name,
142
+ 'is_supplier' => false,
143
+ 'ref_id' => [{'provider' => provider, 'id' => connec_org2_ext_ref_id, 'realm' => oauth_uid}]
144
+ }
145
+ }
146
+ let(:mapped_connec_org2) {
147
+ {
148
+ ref_id: connec_org2_ext_ref_id,
149
+ name: connec_org2_name,
150
+ id: connec_org2_ext_id
151
+ }
152
+ }
153
+ let(:connec_orgs) { [connec_org1, connec_org2] }
154
+
155
+ let(:ext_customer_id) { 'ext_customer_id' }
156
+ let(:ext_supplier_id) { 'ext_supplier_id' }
157
+ let(:ext_customer_name) { 'ext_customer_name' }
158
+ let(:ext_supplier_name) { 'ext_supplier_name' }
159
+ let(:ext_ref_id) { 'ext_ref_id' }
160
+ let(:ext_customer) {
161
+ {
162
+ 'id' => ext_customer_id,
163
+ 'name' => ext_customer_name,
164
+ 'ref_id' => ext_ref_id
165
+ }
166
+ }
167
+ let(:mapped_ext_customer) {
168
+ {
169
+ :id => [
170
+ {
171
+ :id => ext_customer_id,
172
+ :provider => provider,
173
+ :realm => oauth_uid
174
+ }
175
+ ],
176
+ :ref_id => [
177
+ {
178
+ :id => ext_ref_id,
179
+ :provider => provider,
180
+ :realm => oauth_uid
181
+ }
182
+ ],
183
+ :name => ext_customer_name,
184
+ :is_supplier => false
185
+ }
186
+ }
187
+ let(:ext_supplier) {
188
+ {
189
+ 'id' => ext_supplier_id,
190
+ 'name' => ext_supplier_name,
191
+ 'ref_id' => ext_ref_id
192
+ }
193
+ }
194
+ let(:mapped_ext_supplier) {
195
+ {
196
+ :id => [
197
+ {
198
+ :id => ext_supplier_id,
199
+ :provider => provider,
200
+ :realm => oauth_uid
201
+ }
202
+ ],
203
+ :ref_id => [
204
+ {
205
+ :id => ext_ref_id,
206
+ :provider => provider,
207
+ :realm => oauth_uid
208
+ }
209
+ ],
210
+ :name => ext_supplier_name,
211
+ :is_supplier => true
212
+ }
213
+ }
214
+ let!(:supplier_idmap) { Entities::SubEntities::CompSupplier.create_idmap(organization_id: organization.id, external_id: ext_supplier_id, connec_entity: 'comporganization') }
215
+
216
+ before {
217
+ allow(connec_client).to receive(:get).and_return(ActionDispatch::Response.new(200, {}, {comporganizations: connec_orgs}.to_json, {}))
218
+ allow_any_instance_of(Entities::SubEntities::CompCustomer).to receive(:get_external_entities).and_return([ext_customer])
219
+ allow_any_instance_of(Entities::SubEntities::CompSupplier).to receive(:get_external_entities).and_return([ext_supplier])
220
+ }
221
+
222
+ subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity('customer_and_supplier', organization, connec_client, external_client, nil, {}) }
223
+
224
+ it 'handles the fetching correctly' do
225
+ 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: []})
226
+ subject
227
+ end
228
+
229
+ it 'handles the idmap correctly' do
230
+ allow(connec_client).to receive(:batch).and_return(ActionDispatch::Response.new(201, {}, {results: []}.to_json, {}))
231
+ allow_any_instance_of(Entities::SubEntities::CompOrganization).to receive(:create_external_entity).and_return(connec_org1_ext_id)
232
+ allow_any_instance_of(Entities::SubEntities::CompOrganization).to receive(:update_external_entity).and_return(nil)
233
+ expect{
234
+ subject
235
+ }.to change{ Maestrano::Connector::Rails::IdMap.count }.by(3)
236
+
237
+ expect(supplier_idmap.reload.name).to eql(ext_supplier_name)
238
+ expect(supplier_idmap.reload.connec_entity).to eql('comporganization')
239
+ expect(supplier_idmap.reload.external_entity).to eql('compsupplier')
240
+ expect(supplier_idmap.reload.message).to be_nil
241
+ expect(supplier_idmap.reload.external_id).to eql(ext_supplier_id)
242
+
243
+ customer_idmap = Entities::SubEntities::CompCustomer.find_idmap({external_id: ext_customer_id})
244
+ expect(customer_idmap).to_not be_nil
245
+ expect(customer_idmap.name).to eql(ext_customer_name)
246
+ expect(customer_idmap.connec_entity).to eql('comporganization')
247
+ expect(customer_idmap.external_entity).to eql('compcustomer')
248
+ expect(customer_idmap.message).to be_nil
249
+
250
+ org1_idmap = Entities::SubEntities::CompOrganization.find_idmap({external_id: connec_org1_ext_id})
251
+ expect(org1_idmap).to_not be_nil
252
+ expect(org1_idmap.name).to eql(connec_org1_name)
253
+ expect(org1_idmap.connec_entity).to eql('comporganization')
254
+ expect(org1_idmap.external_entity).to eql('compsupplier')
255
+ expect(org1_idmap.message).to be_nil
256
+
257
+ org2_idmap = Entities::SubEntities::CompOrganization.find_idmap({external_id: connec_org2_ext_id})
258
+ expect(org2_idmap).to_not be_nil
259
+ expect(org2_idmap.name).to eql(connec_org2_name)
260
+ expect(org2_idmap.connec_entity).to eql('comporganization')
261
+ expect(org2_idmap.external_entity).to eql('compcustomer')
262
+ expect(org2_idmap.message).to be_nil
263
+ end
264
+
265
+ it 'handles the mapping correctly' do
266
+ cust_idmap = Entities::SubEntities::CompCustomer.create_idmap(organization_id: organization.id, external_id: ext_customer_id, connec_entity: 'comporganization')
267
+ org1_idmap = Entities::SubEntities::CompOrganization.create_idmap(organization_id: organization.id, external_id: connec_org1_ext_id, external_entity: 'compsupplier')
268
+ org2_idmap = Entities::SubEntities::CompOrganization.create_idmap(organization_id: organization.id, external_id: connec_org2_ext_id, external_entity: 'compcustomer')
269
+ allow(Maestrano::Connector::Rails::IdMap).to receive(:create).and_return(org1_idmap, org2_idmap, cust_idmap)
270
+ expect_any_instance_of(Entities::CustomerAndSupplier).to receive(:push_entities_to_external).with({'CompOrganization' => {'CompSupplier' => [{entity: mapped_connec_org1, idmap: org1_idmap}], 'CompCustomer' => [{entity: mapped_connec_org2, idmap: org2_idmap}]}})
271
+ expect_any_instance_of(Entities::CustomerAndSupplier).to receive(:push_entities_to_connec).with({'CompCustomer' => {'CompOrganization' => [{entity: mapped_ext_customer, idmap: cust_idmap}]}, 'CompSupplier' => {'CompOrganization' => [{entity: mapped_ext_supplier, idmap: supplier_idmap}]}})
272
+ subject
273
+ end
274
+
275
+ it 'sends two objects to connec, two objects to external and send back one id to connec' do
276
+ expect_any_instance_of(Entities::SubEntities::CompOrganization).to receive(:create_external_entity).once
277
+ expect_any_instance_of(Entities::SubEntities::CompOrganization).to receive(:update_external_entity).once
278
+ expect(connec_client).to receive(:batch).exactly(3).times.and_return(ActionDispatch::Response.new(201, {}, {results: []}.to_json, {}), ActionDispatch::Response.new(200, {}, {results: []}.to_json, {}))
279
+ subject
280
+ end
281
+ end
@@ -0,0 +1,288 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'singleton workflow' do
4
+
5
+ class Entities::SingletonIntegration < Maestrano::Connector::Rails::Entity
6
+ def self.external_entity_name
7
+ 'Company'
8
+ end
9
+
10
+ def self.connec_entity_name
11
+ 'Company'
12
+ end
13
+
14
+ def self.mapper_class
15
+ CompanyMapper
16
+ end
17
+
18
+ def self.object_name_from_connec_entity_hash(entity)
19
+ entity['name']
20
+ end
21
+
22
+ def self.object_name_from_external_entity_hash(entity)
23
+ entity['name']
24
+ end
25
+
26
+ def self.id_from_external_entity_hash(entity)
27
+ entity['id']
28
+ end
29
+
30
+ def self.last_update_date_from_external_entity_hash(entity)
31
+ entity['updated_at']
32
+ end
33
+
34
+ def self.singleton?
35
+ true
36
+ end
37
+
38
+ class CompanyMapper
39
+ extend HashMapper
40
+ map from('id'), to('id')
41
+ map from('name'), to('name')
42
+ end
43
+ end
44
+
45
+ let(:provider) { 'provider' }
46
+ let(:oauth_uid) { 'oauth uid' }
47
+ let!(:organization) { create(:organization, oauth_provider: provider, oauth_uid: oauth_uid) }
48
+ let(:connec_client) { Maestrano::Connec::Client[organization.tenant].new(organization.uid) }
49
+ let(:external_client) { Object.new }
50
+ let(:ext_comp_id) { 'ext comp id' }
51
+ let(:connec_updated) { 1.hour.ago }
52
+ let(:ext_updated) { 1.hour.ago }
53
+ let(:company_base) {
54
+ {
55
+ "name" => "My awesome company",
56
+ "updated_at" => connec_updated
57
+ }
58
+ }
59
+
60
+ let(:ext_company_base) {
61
+ {
62
+ 'id' => ext_comp_id,
63
+ 'name' => 'My not so awesome store',
64
+ 'updated_at' => ext_updated
65
+ }
66
+ }
67
+
68
+ let(:mapped_connec_entity) {
69
+ {
70
+ id: ext_comp_id,
71
+ name: "My awesome company"
72
+ }
73
+ }
74
+
75
+ let(:mapped_external_entity) {
76
+ {
77
+ id: [
78
+ {
79
+ :id=>ext_comp_id,
80
+ :provider=>provider,
81
+ :realm=>oauth_uid
82
+ }
83
+ ],
84
+ name: 'My not so awesome store'
85
+ }
86
+ }
87
+
88
+
89
+ before {
90
+ allow(connec_client).to receive(:get).and_return(ActionDispatch::Response.new(200, {}, {company: company}.to_json, {}))
91
+ allow_any_instance_of(Entities::SingletonIntegration).to receive(:get_external_entities).and_return(ext_company)
92
+ allow_any_instance_of(Entities::SingletonIntegration).to receive(:update_external_entity).and_return(nil)
93
+ 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, {}))
94
+ }
95
+
96
+ subject { Maestrano::Connector::Rails::SynchronizationJob.new.sync_entity('singleton_integration', organization, connec_client, external_client, nil, {}) }
97
+
98
+
99
+ describe 'when no idmap' do
100
+
101
+ describe 'when received both' do
102
+ let(:company) { [company_base.merge('id' => [{'id' => 'some connec id', 'provider' => 'connec', 'realm' => organization.uid}])] }
103
+ let(:ext_company) { [ext_company_base] }
104
+
105
+ context 'when connec most recent' do
106
+ let(:connec_updated) { 1.second.ago }
107
+ let(:batch_params) {
108
+ {
109
+ :sequential => true,
110
+ :ops => [
111
+ {
112
+ :method => "put",
113
+ :url => "/api/v2/#{organization.uid}/company/some connec id",
114
+ :params => {
115
+ :company => {
116
+ id: [
117
+ {
118
+ :id => "ext comp id",
119
+ :provider => "provider",
120
+ :realm => "oauth uid"
121
+ }
122
+ ]
123
+ }
124
+ }
125
+ }
126
+ ]
127
+ }
128
+ }
129
+
130
+ it 'handles the idmap correctly' do
131
+ expect{
132
+ subject
133
+ }.to change{ Maestrano::Connector::Rails::IdMap.count }.by(1)
134
+ idmap = Maestrano::Connector::Rails::IdMap.last
135
+ expect(idmap.name).to eql('My awesome company')
136
+ expect(idmap.connec_entity).to eql('company')
137
+ expect(idmap.external_entity).to eql('company')
138
+ expect(idmap.message).to be_nil
139
+ expect(idmap.external_id).to eql(ext_comp_id)
140
+ expect(idmap.connec_id).to eql('some connec id')
141
+ end
142
+
143
+ it 'does the mapping correctly' do
144
+ idmap = Entities::SingletonIntegration.create_idmap(organization_id: organization.id, external_id: ext_comp_id, connec_id: 'some connec id')
145
+ allow(Entities::SingletonIntegration).to receive(:create_idmap).and_return(idmap)
146
+ expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_external).with([{entity: {name: 'My awesome company'}, idmap: idmap}])
147
+ subject
148
+ end
149
+
150
+ it 'send the external id to connec' do
151
+ expect(connec_client).to receive(:batch).with(batch_params)
152
+ subject
153
+ end
154
+ end
155
+
156
+ context 'when external most recent' do
157
+ let(:external_updated) { 1.second.ago }
158
+
159
+ it 'handles the idmap correctly' do
160
+ expect{
161
+ subject
162
+ }.to change{ Maestrano::Connector::Rails::IdMap.count }.by(1)
163
+ idmap = Maestrano::Connector::Rails::IdMap.last
164
+ expect(idmap.name).to eql('My not so awesome store')
165
+ expect(idmap.connec_entity).to eql('company')
166
+ expect(idmap.external_entity).to eql('company')
167
+ expect(idmap.message).to be_nil
168
+ expect(idmap.external_id).to eql(ext_comp_id)
169
+ end
170
+
171
+ it 'does the mapping correctly' do
172
+ idmap = Entities::SingletonIntegration.create_idmap(organization_id: organization.id, external_id: ext_comp_id)
173
+ allow(Entities::SingletonIntegration).to receive(:create_idmap).and_return(idmap)
174
+ expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_connec).with([{entity: mapped_external_entity, idmap: idmap}])
175
+ subject
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+
182
+
183
+ describe 'when idmap exists' do
184
+ describe 'when received both' do
185
+ let(:company) { [company_base.merge('id' => [{'id' => ext_comp_id, 'provider' => provider, 'realm' => oauth_uid}, {'id' => 'connec-id', 'provider' => 'connec', 'realm' => 'some-realm'}])] }
186
+ let(:ext_company) { [ext_company_base] }
187
+ let!(:idmap) { Entities::SingletonIntegration.create_idmap(organization_id: organization.id, external_id: ext_comp_id) }
188
+
189
+ context 'when connec most recent' do
190
+ let(:connec_updated) { 1.second.ago }
191
+
192
+ it 'handles the idmap correctly' do
193
+ expect{
194
+ subject
195
+ }.to_not change{ Maestrano::Connector::Rails::IdMap.count }
196
+ idmap = Maestrano::Connector::Rails::IdMap.last
197
+ expect(idmap.name).to eql('My awesome company')
198
+ expect(idmap.connec_entity).to eql('company')
199
+ expect(idmap.external_entity).to eql('company')
200
+ expect(idmap.message).to be_nil
201
+ expect(idmap.external_id).to eql(ext_comp_id)
202
+ end
203
+
204
+ it 'does the mapping correctly' do
205
+ expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_external).with([{entity: mapped_connec_entity, idmap: idmap}])
206
+ subject
207
+ end
208
+
209
+ it 'does not map the external one' do
210
+ expect_any_instance_of(Entities::SingletonIntegration).to_not receive(:map_to_connec)
211
+ subject
212
+ end
213
+ end
214
+
215
+ context 'when external most recent' do
216
+ let(:external_updated) { 1.second.ago }
217
+
218
+ it 'handles the idmap correctly' do
219
+ expect{
220
+ subject
221
+ }.to_not change{ Maestrano::Connector::Rails::IdMap.count }
222
+ idmap = Maestrano::Connector::Rails::IdMap.last
223
+ expect(idmap.name).to eql('My not so awesome store')
224
+ expect(idmap.connec_entity).to eql('company')
225
+ expect(idmap.external_entity).to eql('company')
226
+ expect(idmap.message).to be_nil
227
+ expect(idmap.external_id).to eql(ext_comp_id)
228
+ end
229
+
230
+ it 'does the mapping correctly' do
231
+ expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_connec).with([{entity: mapped_external_entity, idmap: idmap}])
232
+ subject
233
+ end
234
+
235
+ it 'does not map the external one' do
236
+ expect_any_instance_of(Entities::SingletonIntegration).to_not receive(:map_to_external)
237
+ subject
238
+ end
239
+ end
240
+ end
241
+ end
242
+
243
+ describe 'when received only connec one' do
244
+ let(:company) { [company_base.merge('id' => [{'id' => ext_comp_id, 'provider' => provider, 'realm' => oauth_uid}, {'id' => 'connec-id', 'provider' => 'connec', 'realm' => 'some-realm'}])] }
245
+ let(:ext_company) { [] }
246
+ let!(:idmap) { Entities::SingletonIntegration.create_idmap(organization_id: organization.id, external_id: ext_comp_id) }
247
+
248
+ it 'handles the idmap correctly' do
249
+ expect{
250
+ subject
251
+ }.to_not change{ Maestrano::Connector::Rails::IdMap.count }
252
+ idmap = Maestrano::Connector::Rails::IdMap.last
253
+ expect(idmap.name).to eql('My awesome company')
254
+ expect(idmap.connec_entity).to eql('company')
255
+ expect(idmap.external_entity).to eql('company')
256
+ expect(idmap.message).to be_nil
257
+ expect(idmap.external_id).to eql(ext_comp_id)
258
+ end
259
+
260
+ it 'does the mapping correctly' do
261
+ expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_external).with([{entity: mapped_connec_entity, idmap: idmap}])
262
+ subject
263
+ end
264
+ end
265
+
266
+ describe 'when receive only external one' do
267
+ let(:company) { [] }
268
+ let(:ext_company) { [ext_company_base] }
269
+ let!(:idmap) { Entities::SingletonIntegration.create_idmap(organization_id: organization.id, external_id: ext_comp_id) }
270
+
271
+ it 'handles the idmap correctly' do
272
+ expect{
273
+ subject
274
+ }.to_not change{ Maestrano::Connector::Rails::IdMap.count }
275
+ idmap = Maestrano::Connector::Rails::IdMap.last
276
+ expect(idmap.name).to eql('My not so awesome store')
277
+ expect(idmap.connec_entity).to eql('company')
278
+ expect(idmap.external_entity).to eql('company')
279
+ expect(idmap.message).to be_nil
280
+ expect(idmap.external_id).to eql(ext_comp_id)
281
+ end
282
+
283
+ it 'does the mapping correctly' do
284
+ expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_connec).with([{entity: mapped_external_entity, idmap: idmap}])
285
+ subject
286
+ end
287
+ end
288
+ end