maestrano-connector-rails 0.4.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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