global-registry-bindings 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +79 -35
  3. data/lib/global_registry_bindings/entity/entity_type_methods.rb +35 -33
  4. data/lib/global_registry_bindings/entity/mdm_methods.rb +9 -19
  5. data/lib/global_registry_bindings/entity/push_entity_methods.rb +31 -38
  6. data/lib/global_registry_bindings/entity/push_relationship_methods.rb +61 -47
  7. data/lib/global_registry_bindings/entity/relationship_type_methods.rb +48 -37
  8. data/lib/global_registry_bindings/exceptions.rb +1 -0
  9. data/lib/global_registry_bindings/global_registry_bindings.rb +129 -46
  10. data/lib/global_registry_bindings/{entity/delete_entity_methods.rb → model/delete_entity.rb} +5 -5
  11. data/lib/global_registry_bindings/model/entity.rb +64 -0
  12. data/lib/global_registry_bindings/model/pull_mdm.rb +23 -0
  13. data/lib/global_registry_bindings/model/push_entity.rb +21 -0
  14. data/lib/global_registry_bindings/model/push_relationship.rb +79 -0
  15. data/lib/global_registry_bindings/model/relationship.rb +68 -0
  16. data/lib/global_registry_bindings/options.rb +26 -59
  17. data/lib/global_registry_bindings/options/entity_class_options.rb +34 -0
  18. data/lib/global_registry_bindings/options/entity_instance_options.rb +90 -0
  19. data/lib/global_registry_bindings/options/entity_options_parser.rb +76 -0
  20. data/lib/global_registry_bindings/options/relationship_class_options.rb +37 -0
  21. data/lib/global_registry_bindings/options/relationship_instance_options.rb +131 -0
  22. data/lib/global_registry_bindings/options/relationship_options_parser.rb +98 -0
  23. data/lib/global_registry_bindings/railtie.rb +2 -1
  24. data/lib/global_registry_bindings/version.rb +1 -1
  25. data/lib/global_registry_bindings/worker.rb +25 -0
  26. data/lib/global_registry_bindings/workers/{delete_gr_entity_worker.rb → delete_entity_worker.rb} +1 -6
  27. data/lib/global_registry_bindings/workers/pull_mdm_id_worker.rb +12 -13
  28. data/lib/global_registry_bindings/workers/push_entity_worker.rb +24 -0
  29. data/lib/global_registry_bindings/workers/push_relationship_worker.rb +17 -7
  30. data/spec/acceptance/global_registry_bindings_spec.rb +50 -40
  31. data/spec/factories/factories.rb +24 -0
  32. data/spec/fixtures/get_entity_types_area.json +44 -0
  33. data/spec/fixtures/post_entities_community.json +8 -0
  34. data/spec/fixtures/post_relationship_types_fancy_org_area.json +16 -0
  35. data/spec/fixtures/put_entities_community_relationship.json +16 -0
  36. data/spec/fixtures/put_entities_fancy_org_area_relationship.json +8 -0
  37. data/spec/fixtures/put_entities_fancy_org_relationship.json +17 -0
  38. data/spec/fixtures/put_entities_person_country_relationship.json +23 -0
  39. data/spec/fixtures/put_entities_relationship_400.json +3 -0
  40. data/spec/fixtures/put_relationship_types_fields_fancy_org_area.json +25 -0
  41. data/spec/helpers/sidekiq_helpers.rb +14 -0
  42. data/spec/internal/app/models/address.rb +7 -2
  43. data/spec/internal/app/models/area.rb +7 -0
  44. data/spec/internal/app/models/assignment.rb +5 -4
  45. data/spec/internal/app/models/community.rb +19 -0
  46. data/spec/internal/app/models/country.rb +8 -0
  47. data/spec/internal/app/models/namespaced/person.rb +48 -2
  48. data/spec/internal/app/models/organization.rb +26 -3
  49. data/spec/internal/db/schema.rb +28 -0
  50. data/spec/internal/log/test.log +71023 -0
  51. data/spec/models/address_spec.rb +6 -204
  52. data/spec/models/assignment_spec.rb +40 -186
  53. data/spec/models/organization_spec.rb +106 -92
  54. data/spec/models/person_spec.rb +158 -214
  55. data/spec/models/user_edited_person_spec.rb +2 -2
  56. data/spec/spec_helper.rb +5 -6
  57. data/spec/workers/delete_gr_entity_worker_spec.rb +4 -4
  58. data/spec/workers/pull_mdm_id_worker_spec.rb +94 -32
  59. data/spec/workers/push_entity_worker_spec.rb +476 -0
  60. data/spec/workers/push_relationship_worker_spec.rb +344 -15
  61. metadata +45 -10
  62. data/lib/global_registry_bindings/entity/entity_methods.rb +0 -62
  63. data/lib/global_registry_bindings/options/class_options.rb +0 -62
  64. data/lib/global_registry_bindings/options/instance_options.rb +0 -63
  65. data/lib/global_registry_bindings/workers/push_gr_entity_worker.rb +0 -22
  66. data/spec/workers/push_gr_entity_worker_spec.rb +0 -27
@@ -2,8 +2,8 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe 'Namespaced::Person::UserEdited' do
6
- describe ':pull_mdm_id_from_global_registry_async' do
5
+ RSpec.describe Namespaced::Person::UserEdited do
6
+ describe '#pull_mdm_id_from_global_registry_async' do
7
7
  it 'should enqueue sidekiq job' do
8
8
  user_edited = build(:user_edited)
9
9
  expect do
data/spec/spec_helper.rb CHANGED
@@ -26,6 +26,8 @@ MOCK_REDIS = MockRedis.new
26
26
 
27
27
  ActionController::Base.cache_store = :memory_store
28
28
 
29
+ require 'helpers/sidekiq_helpers'
30
+
29
31
  RSpec.configure do |config|
30
32
  config.use_transactional_fixtures = true
31
33
  config.file_fixture_path = 'spec/fixtures'
@@ -33,23 +35,20 @@ RSpec.configure do |config|
33
35
  config.run_all_when_everything_filtered = true
34
36
  config.include ActiveSupport::Testing::TimeHelpers
35
37
  config.include FactoryGirl::Syntax::Methods
38
+ config.include SidekiqHelpers
36
39
 
37
40
  config.before(:suite) do
38
41
  FactoryGirl.find_definitions
39
42
  end
40
43
 
41
44
  config.before(:each) do
42
- MOCK_REDIS.keys.each do |key|
43
- MOCK_REDIS.del(key)
44
- end
45
-
46
45
  SidekiqUniqueJobs.configure do |c|
47
46
  c.redis_test_mode = :mock
48
47
  end
49
48
  allow(Sidekiq).to receive(:redis).and_yield(MOCK_REDIS)
50
49
 
51
- Sidekiq::Queues.clear_all
52
- Sidekiq::Worker.clear_all
50
+ clear_sidekiq_jobs_and_locks
51
+
53
52
  Rails.cache.clear
54
53
  end
55
54
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe 'GlobalRegistry::Bindings::Workers' do
6
- describe 'DeleteGrEntityWorker' do
5
+ RSpec.describe GlobalRegistry::Bindings::Workers::DeleteEntityWorker do
6
+ context 'entity 22527d88-3cba-11e7-b876-129bd0521531' do
7
7
  context 'valid global_registry_id' do
8
8
  let!(:request) do
9
9
  stub_request(:delete, 'https://backend.global-registry.org/entities/22527d88-3cba-11e7-b876-129bd0521531')
@@ -11,7 +11,7 @@ RSpec.describe 'GlobalRegistry::Bindings::Workers' do
11
11
  end
12
12
 
13
13
  it 'should delete the entity' do
14
- worker = GlobalRegistry::Bindings::Workers::DeleteGrEntityWorker.new
14
+ worker = GlobalRegistry::Bindings::Workers::DeleteEntityWorker.new
15
15
  worker.perform('22527d88-3cba-11e7-b876-129bd0521531')
16
16
  expect(request).to have_been_requested.once
17
17
  end
@@ -24,7 +24,7 @@ RSpec.describe 'GlobalRegistry::Bindings::Workers' do
24
24
  end
25
25
 
26
26
  it 'should delete the entity' do
27
- worker = GlobalRegistry::Bindings::Workers::DeleteGrEntityWorker.new
27
+ worker = GlobalRegistry::Bindings::Workers::DeleteEntityWorker.new
28
28
  worker.perform('22527d88-3cba-11e7-b876-129bd0521531')
29
29
  expect(request).to have_been_requested.once
30
30
  end
@@ -2,48 +2,110 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe 'GlobalRegistry::Bindings::Workers' do
6
- describe 'PullMdmIdWorker' do
7
- let(:user) { create(:person) }
8
-
9
- it 'sends :pull_mdm_id_from_global_registry to the model instance' do
10
- allow(Namespaced::Person).to receive(:pull_mdm_id_from_global_registry)
11
- expect(Namespaced::Person).to receive(:find).with(user.id).and_return(user)
12
- expect(user).to receive(:pull_mdm_id_from_global_registry)
13
-
14
- worker_name = "GlobalRegistry::Bindings::Workers::#{Namespaced::Person.global_registry.mdm_worker_class_name}"
15
- worker = worker_name.constantize.new
16
- worker.perform(Namespaced::Person, user.id)
5
+ RSpec.describe GlobalRegistry::Bindings::Workers::PullMdmIdWorker do
6
+ context Namespaced::Person do
7
+ let(:person) { create(:person) }
8
+
9
+ context 'with valid id' do
10
+ it 'should call #pull_mdm_id_from_global_registry' do
11
+ expect(Namespaced::Person).to receive(:find).with(person.id).and_return(person)
12
+
13
+ worker_name =
14
+ "GlobalRegistry::Bindings::Workers::#{Namespaced::Person.global_registry_entity.mdm_worker_class_name}"
15
+ worker = worker_name.constantize.new
16
+ expect(worker).to receive(:pull_mdm_id_from_global_registry)
17
+ worker.perform('Namespaced::Person', person.id)
18
+ expect(worker.model).to be person
19
+ end
20
+ end
21
+
22
+ context ActiveRecord::RecordNotFound do
23
+ it 'should fail silently' do
24
+ expect(Namespaced::Person).to receive(:find).with(person.id).and_raise(ActiveRecord::RecordNotFound)
25
+ expect(GlobalRegistry::Bindings::Workers::PullMdmIdWorker).not_to receive(:pull_mdm_id_from_global_registry)
26
+
27
+ worker_name =
28
+ "GlobalRegistry::Bindings::Workers::#{Namespaced::Person.global_registry_entity.mdm_worker_class_name}"
29
+ worker = worker_name.constantize.new
30
+ worker.perform(Namespaced::Person, person.id)
31
+ expect(worker.model).to be nil
32
+ end
17
33
  end
18
34
 
19
- it 'fails silently on ActiveRecord::RecordNotFound' do
20
- allow(Namespaced::Person).to receive(:pull_mdm_id_from_global_registry)
21
- expect(Namespaced::Person).to receive(:find).with(user.id).and_raise(ActiveRecord::RecordNotFound)
22
- expect(user).not_to receive(:pull_mdm_id_from_global_registry)
35
+ context RestClient::ResourceNotFound do
36
+ it 'should log a message' do
37
+ expect(Namespaced::Person).to receive(:find).with(person.id).and_raise(RestClient::ResourceNotFound)
38
+ expect(GlobalRegistry::Bindings::Workers::PullMdmIdWorker).not_to receive(:pull_mdm_id_from_global_registry)
39
+ expect(Rails.logger).to receive(:info).with('GR entity for GlobalRegistry::Bindings::Workers::PullNamespaced' \
40
+ 'PersonMdmIdWorker 1 does not exist; will _not_ retry')
23
41
 
24
- worker_name = "GlobalRegistry::Bindings::Workers::#{Namespaced::Person.global_registry.mdm_worker_class_name}"
25
- worker = worker_name.constantize.new
26
- worker.perform(Namespaced::Person, user.id)
42
+ worker_name =
43
+ "GlobalRegistry::Bindings::Workers::#{Namespaced::Person.global_registry_entity.mdm_worker_class_name}"
44
+ worker = worker_name.constantize.new
45
+ worker.perform(Namespaced::Person, person.id)
46
+ expect(worker.model).to be nil
47
+ end
27
48
  end
49
+ end
28
50
 
29
- it 'logs a message on RestClient::ResourceNotFound' do
30
- allow(Namespaced::Person).to receive(:pull_mdm_id_from_global_registry)
31
- expect(Namespaced::Person).to receive(:find).with(user.id).and_raise(RestClient::ResourceNotFound)
32
- expect(user).not_to receive(:pull_mdm_id_from_global_registry)
33
- expect(Rails.logger).to receive(:info).with('GR entity for GlobalRegistry::Bindings::Workers::PullNamespaced' \
34
- 'PersonMdmIdWorker 1 does not exist; will _not_ retry')
51
+ describe '#pull_mdm_id_from_global_registry' do
52
+ context Namespaced::Person do
53
+ let(:worker) { GlobalRegistry::Bindings::Workers::PullNamespacedPersonMdmIdWorker.new }
54
+ before do
55
+ worker.model = person
56
+ end
57
+
58
+ context 'model missing global_registry_id' do
59
+ let(:person) { create(:person) }
35
60
 
36
- worker_name = "GlobalRegistry::Bindings::Workers::#{Namespaced::Person.global_registry.mdm_worker_class_name}"
37
- worker = worker_name.constantize.new
38
- worker.perform('Namespaced::Person', user.id)
61
+ it 'should raise an exception' do
62
+ expect do
63
+ worker.pull_mdm_id_from_global_registry
64
+ end.to raise_error GlobalRegistry::Bindings::RecordMissingGlobalRegistryId,
65
+ "Namespaced::Person(#{person.id}) has no global_registry_id; will retry"
66
+ end
67
+ end
68
+
69
+ context 'entity missing mdm id' do
70
+ let(:person) { create(:person, global_registry_id: '22527d88-3cba-11e7-b876-129bd0521531') }
71
+ let!(:request) do
72
+ stub_request(:get, 'https://backend.global-registry.org/entities/22527d88-3cba-11e7-b876-129bd0521531')
73
+ .with(query: { 'filters[owned_by]' => 'mdm' })
74
+ .to_return(body: file_fixture('get_entities_person.json'), status: 200)
75
+ end
76
+
77
+ it 'should raise an exception' do
78
+ expect do
79
+ worker.pull_mdm_id_from_global_registry
80
+ end.to raise_error GlobalRegistry::Bindings::EntityMissingMdmId,
81
+ "GR entity #{person.global_registry_id} for Namespaced::Person(#{person.id}) has " \
82
+ 'no mdm id; will retry'
83
+ end
84
+ end
85
+
86
+ context 'entity missing mdm id' do
87
+ let(:person) { create(:person, global_registry_id: '22527d88-3cba-11e7-b876-129bd0521531') }
88
+ let!(:request) do
89
+ stub_request(:get, 'https://backend.global-registry.org/entities/22527d88-3cba-11e7-b876-129bd0521531')
90
+ .with(query: { 'filters[owned_by]' => 'mdm' })
91
+ .to_return(body: file_fixture('get_entities_person_mdm.json'), status: 200)
92
+ end
93
+
94
+ it 'should raise an exception' do
95
+ expect do
96
+ worker.pull_mdm_id_from_global_registry
97
+ expect(person.global_registry_mdm_id).to eq 'c81340b2-7e57-4978-b6b9-396f21bb0bb2'
98
+ end.not_to raise_error
99
+ end
100
+ end
39
101
  end
40
102
  end
41
103
 
42
- describe 'mdm_worker_class' do
104
+ describe '#mdm_worker_class' do
43
105
  before do
44
106
  module MdmTest
45
107
  class Klass
46
- def self.global_registry
108
+ def self.global_registry_entity
47
109
  @gr ||= Object.new
48
110
  end
49
111
  end
@@ -55,10 +117,10 @@ RSpec.describe 'GlobalRegistry::Bindings::Workers' do
55
117
  end
56
118
 
57
119
  it 'generates worker class with mdm timeout set' do
58
- expect(MdmTest::Klass.global_registry).to(
120
+ expect(MdmTest::Klass.global_registry_entity).to(
59
121
  receive(:mdm_worker_class_name).and_return('PullMdmTestKlassMdmIdWorker')
60
122
  )
61
- expect(MdmTest::Klass.global_registry).to(
123
+ expect(MdmTest::Klass.global_registry_entity).to(
62
124
  receive(:mdm_timeout).and_return(33.minutes)
63
125
  )
64
126
 
@@ -0,0 +1,476 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe GlobalRegistry::Bindings::Workers::PushEntityWorker do
6
+ around { |example| travel_to Time.utc(2001, 2, 3), &example }
7
+ describe '#perform(model_class, id)' do
8
+ context Namespaced::Person do
9
+ let(:person) { create(:person) }
10
+ context 'with valid id' do
11
+ it 'should call #push_entity_to_global_registry' do
12
+ expect(Namespaced::Person).to receive(:find).with(person.id).and_return(person)
13
+
14
+ worker = GlobalRegistry::Bindings::Workers::PushEntityWorker.new
15
+ expect(worker).to receive(:push_entity_to_global_registry)
16
+ worker.perform('Namespaced::Person', person.id)
17
+ expect(worker.model).to be person
18
+ end
19
+ end
20
+
21
+ context 'with invalid id' do
22
+ it 'should fail silently' do
23
+ expect(Namespaced::Person).to receive(:find).with(person.id).and_raise(ActiveRecord::RecordNotFound)
24
+ expect(GlobalRegistry::Bindings::Workers::PushEntityWorker).not_to receive(:push_entity_to_global_registry)
25
+
26
+ worker = GlobalRegistry::Bindings::Workers::PushEntityWorker.new
27
+ worker.perform(Namespaced::Person, person.id)
28
+ expect(worker.model).to be nil
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ describe '#push_entity_to_global_registry' do
35
+ describe Organization do
36
+ let(:worker) { GlobalRegistry::Bindings::Workers::PushEntityWorker.new organization }
37
+ context 'and unknown \'fancy_org\' entity_type' do
38
+ let!(:requests) do
39
+ [stub_request(:get, 'https://backend.global-registry.org/entity_types')
40
+ .with(query: { 'filters[name]' => 'fancy_org', 'filters[parent_id]' => nil })
41
+ .to_return(body: file_fixture('get_entity_types.json'), status: 200),
42
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
43
+ .with(body: { entity_type: { name: 'fancy_org', parent_id: nil, field_type: 'entity' } })
44
+ .to_return(body: file_fixture('post_entity_types_fancy_org.json'), status: 200),
45
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
46
+ .with(body: { entity_type: { name: 'name', parent_id: '025a1128-3f33-11e7-b876-129bd0521531',
47
+ field_type: 'string' } })
48
+ .to_return(status: 200),
49
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
50
+ .with(body: { entity_type: { name: 'description', parent_id: '025a1128-3f33-11e7-b876-129bd0521531',
51
+ field_type: 'string' } })
52
+ .to_return(status: 200),
53
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
54
+ .with(body: { entity_type: { name: 'start_date', parent_id: '025a1128-3f33-11e7-b876-129bd0521531',
55
+ field_type: 'date' } })
56
+ .to_return(status: 200)]
57
+ end
58
+
59
+ context 'with root level organization' do
60
+ let(:organization) { create(:organization) }
61
+ let!(:sub_requests) do
62
+ [stub_request(:post, 'https://backend.global-registry.org/entities')
63
+ .with(body: { entity: { fancy_org: { name: 'Organization', description: 'Fancy Organization',
64
+ start_date: '2001-02-03', parent_id: nil,
65
+ client_integration_id: organization.id,
66
+ client_updated_at: '2001-02-03 00:00:00' } } })
67
+ .to_return(body: file_fixture('post_entities_fancy_org.json'), status: 200)]
68
+ end
69
+
70
+ it 'should create \'fancy_org\' entity_type and push entity to Global Registry' do
71
+ worker.push_entity_to_global_registry
72
+ (requests + sub_requests).each { |r| expect(r).to have_been_requested.once }
73
+ expect(organization.gr_id).to eq 'aebb4170-3f34-11e7-bba6-129bd0521531'
74
+ end
75
+ end
76
+
77
+ context 'with organization with parent missing global_registry_id' do
78
+ let(:parent) { create(:organization, name: 'Parent', description: 'Parent Fancy Organization') }
79
+ let(:organization) { create(:organization, parent: parent) }
80
+
81
+ it 'should create \'fancy_org\' entity_type raise an exception' do
82
+ expect do
83
+ worker.push_entity_to_global_registry
84
+ requests.each { |r| expect(r).to have_been_requested.once }
85
+ end.to raise_error GlobalRegistry::Bindings::ParentEntityMissingGlobalRegistryId,
86
+ "Organization(#{organization.id}) has parent entity Organization(#{parent.id}) " \
87
+ 'missing global_registry_id; will retry.'
88
+ end
89
+ end
90
+
91
+ context 'organization with an existing parent' do
92
+ let(:parent) do
93
+ create :organization, name: 'Parent', description: 'Parent Fancy Organization',
94
+ gr_id: 'cd5da38a-c336-46a7-b818-dcdd51c4acde'
95
+ end
96
+ let(:organization) { create(:organization, parent: parent) }
97
+ let!(:sub_requests) do
98
+ [stub_request(:post, 'https://backend.global-registry.org/entities')
99
+ .with(body: { entity: { fancy_org: { name: 'Organization', description: 'Fancy Organization',
100
+ start_date: '2001-02-03',
101
+ parent_id: 'cd5da38a-c336-46a7-b818-dcdd51c4acde',
102
+ client_integration_id: organization.id,
103
+ client_updated_at: '2001-02-03 00:00:00' } } })
104
+ .to_return(body: file_fixture('post_entities_fancy_org.json'), status: 200)]
105
+ end
106
+
107
+ it 'should create \'fancy_org\' entity_type and push both entities' do
108
+ worker.push_entity_to_global_registry
109
+ (requests + sub_requests).each { |r| expect(r).to have_been_requested.once }
110
+ expect(parent.gr_id).to eq 'cd5da38a-c336-46a7-b818-dcdd51c4acde'
111
+ expect(organization.gr_id).to eq 'aebb4170-3f34-11e7-bba6-129bd0521531'
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ describe Namespaced::Person do
118
+ let(:worker) { GlobalRegistry::Bindings::Workers::PushEntityWorker.new person }
119
+ context 'as create' do
120
+ let(:person) { create(:person) }
121
+
122
+ context '\'person\' entity_type does not exist' do
123
+ let!(:requests) do
124
+ [stub_request(:get, 'https://backend.global-registry.org/entity_types')
125
+ .with(query: { 'filters[name]' => 'person', 'filters[parent_id]' => nil })
126
+ .to_return(body: file_fixture('get_entity_types.json'), status: 200),
127
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
128
+ .with(body: { entity_type: { name: 'person', parent_id: nil, field_type: 'entity' } })
129
+ .to_return(body: file_fixture('post_entity_types_person.json'), status: 200),
130
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
131
+ .with(body: { entity_type: { name: 'first_name', parent_id: 'ee13a693-3ce7-4c19-b59a-30c8f137acd8',
132
+ field_type: 'string' } })
133
+ .to_return(status: 200),
134
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
135
+ .with(body: { entity_type: { name: 'last_name', parent_id: 'ee13a693-3ce7-4c19-b59a-30c8f137acd8',
136
+ field_type: 'string' } })
137
+ .to_return(status: 200),
138
+ stub_request(:post, 'https://backend.global-registry.org/entities')
139
+ .with(body: { entity: { person: { first_name: 'Tony', last_name: 'Stark',
140
+ client_integration_id: person.id,
141
+ client_updated_at: '2001-02-03 00:00:00',
142
+ authentication: {
143
+ key_guid: '98711710-acb5-4a41-ba51-e0fc56644b53'
144
+ } } } })
145
+ .to_return(body: file_fixture('post_entities_person.json'), status: 200)]
146
+ end
147
+
148
+ it 'should create \'person\' entity_type and push entity' do
149
+ worker.push_entity_to_global_registry
150
+ requests.each { |r| expect(r).to have_been_requested.once }
151
+ expect(person.global_registry_id).to eq '22527d88-3cba-11e7-b876-129bd0521531'
152
+ end
153
+ end
154
+
155
+ context '\'person\' entity_type exists' do
156
+ let!(:requests) do
157
+ [stub_request(:get, 'https://backend.global-registry.org/entity_types')
158
+ .with(query: { 'filters[name]' => 'person', 'filters[parent_id]' => nil })
159
+ .to_return(body: file_fixture('get_entity_types_person.json'), status: 200),
160
+ stub_request(:post, 'https://backend.global-registry.org/entities')
161
+ .with(body: { entity: { person: { first_name: 'Tony', last_name: 'Stark',
162
+ client_integration_id: person.id,
163
+ client_updated_at: '2001-02-03 00:00:00',
164
+ authentication: {
165
+ key_guid: '98711710-acb5-4a41-ba51-e0fc56644b53'
166
+ } } } })
167
+ .to_return(body: file_fixture('post_entities_person.json'), status: 200)]
168
+ end
169
+
170
+ it 'should skip creating entity_type and push the entity' do
171
+ worker.push_entity_to_global_registry
172
+ requests.each { |r| expect(r).to have_been_requested.once }
173
+ expect(person.global_registry_id).to eq '22527d88-3cba-11e7-b876-129bd0521531'
174
+ end
175
+ end
176
+
177
+ context 'partial \'person\' entity_type exists' do
178
+ let!(:requests) do
179
+ [stub_request(:get, 'https://backend.global-registry.org/entity_types')
180
+ .with(query: { 'filters[name]' => 'person', 'filters[parent_id]' => nil })
181
+ .to_return(body: file_fixture('get_entity_types_person_partial.json'), status: 200),
182
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
183
+ .with(body: { entity_type: { name: 'first_name', parent_id: 'ee13a693-3ce7-4c19-b59a-30c8f137acd8',
184
+ field_type: 'string' } })
185
+ .to_return(status: 200),
186
+ stub_request(:post, 'https://backend.global-registry.org/entities')
187
+ .with(body: { entity: { person: { first_name: 'Tony', last_name: 'Stark',
188
+ client_integration_id: person.id,
189
+ client_updated_at: '2001-02-03 00:00:00',
190
+ authentication: {
191
+ key_guid: '98711710-acb5-4a41-ba51-e0fc56644b53'
192
+ } } } })
193
+ .to_return(body: file_fixture('post_entities_person.json'), status: 200)]
194
+ end
195
+
196
+ it 'should skip creating entity_type and push the entity' do
197
+ worker.push_entity_to_global_registry
198
+ requests.each { |r| expect(r).to have_been_requested.once }
199
+ expect(person.global_registry_id).to eq '22527d88-3cba-11e7-b876-129bd0521531'
200
+ end
201
+ end
202
+
203
+ context '\'person\' entity_type is cached' do
204
+ before :each do
205
+ person_entity_types = JSON.parse(file_fixture('get_entity_types_person.json').read)
206
+ Rails.cache.write('GlobalRegistry::Bindings::EntityType::person', person_entity_types['entity_types'].first)
207
+ end
208
+
209
+ it 'should skip creating entity_type and push the entity' do
210
+ request = stub_request(:post, 'https://backend.global-registry.org/entities')
211
+ .with(body: { entity: { person: { first_name: 'Tony', last_name: 'Stark',
212
+ client_integration_id: person.id,
213
+ client_updated_at: '2001-02-03 00:00:00',
214
+ authentication: {
215
+ key_guid: '98711710-acb5-4a41-ba51-e0fc56644b53'
216
+ } } } })
217
+ .to_return(body: file_fixture('post_entities_person.json'), status: 200)
218
+ worker.push_entity_to_global_registry
219
+ expect(request).to have_been_requested.once
220
+ expect(person.global_registry_id).to eq '22527d88-3cba-11e7-b876-129bd0521531'
221
+ end
222
+ end
223
+ end
224
+
225
+ context 'as an update' do
226
+ let(:person) { create(:person, global_registry_id: 'f8d20318-2ff2-4a98-a5eb-e9d840508bf1') }
227
+ context '\'person\' entity_type is cached' do
228
+ before :each do
229
+ person_entity_types = JSON.parse(file_fixture('get_entity_types_person.json').read)
230
+ Rails.cache.write('GlobalRegistry::Bindings::EntityType::person', person_entity_types['entity_types'].first)
231
+ end
232
+
233
+ it 'should skip creating entity_type and update the entity' do
234
+ request = stub_request(:put,
235
+ 'https://backend.global-registry.org/entities/f8d20318-2ff2-4a98-a5eb-e9d840508bf1')
236
+ .with(body: { entity: { person: { first_name: 'Tony', last_name: 'Stark',
237
+ client_integration_id: person.id,
238
+ client_updated_at: '2001-02-03 00:00:00',
239
+ authentication: {
240
+ key_guid: '98711710-acb5-4a41-ba51-e0fc56644b53'
241
+ } } } })
242
+ .to_return(body: file_fixture('post_entities_person.json'), status: 200)
243
+ worker.push_entity_to_global_registry
244
+ expect(request).to have_been_requested.once
245
+ end
246
+
247
+ context 'invalid entity id' do
248
+ let!(:requests) do
249
+ [stub_request(:put,
250
+ 'https://backend.global-registry.org/entities/f8d20318-2ff2-4a98-a5eb-e9d840508bf1')
251
+ .with(body: { entity: { person: { first_name: 'Tony', last_name: 'Stark',
252
+ client_integration_id: person.id,
253
+ client_updated_at: '2001-02-03 00:00:00',
254
+ authentication: {
255
+ key_guid: '98711710-acb5-4a41-ba51-e0fc56644b53'
256
+ } } } })
257
+ .to_return(status: 404),
258
+ stub_request(:post, 'https://backend.global-registry.org/entities')
259
+ .with(body: { entity: { person: { first_name: 'Tony', last_name: 'Stark',
260
+ client_integration_id: person.id,
261
+ client_updated_at: '2001-02-03 00:00:00',
262
+ authentication: {
263
+ key_guid: '98711710-acb5-4a41-ba51-e0fc56644b53'
264
+ } } } })
265
+ .to_return(body: file_fixture('post_entities_person.json'), status: 200)]
266
+ end
267
+
268
+ it 'should push entity as create' do
269
+ worker.push_entity_to_global_registry
270
+ requests.each { |r| expect(r).to have_been_requested.once }
271
+ expect(person.global_registry_id).to eq '22527d88-3cba-11e7-b876-129bd0521531'
272
+ end
273
+ end
274
+ end
275
+ end
276
+ end
277
+
278
+ describe Address do
279
+ let(:worker) { GlobalRegistry::Bindings::Workers::PushEntityWorker.new address }
280
+ context 'as create' do
281
+ context '\'address\' record does not belong to a person' do
282
+ let(:address) { create(:address) }
283
+
284
+ it 'should not create \'address\' entity_type and skip push of entity' do
285
+ worker.push_entity_to_global_registry
286
+ end
287
+ end
288
+
289
+ context '\'address\' entity_type does not exist' do
290
+ let!(:requests) do
291
+ [stub_request(:get, 'https://backend.global-registry.org/entity_types')
292
+ .with(query: { 'filters[name]' => 'person', 'filters[parent_id]' => nil })
293
+ .to_return(body: file_fixture('get_entity_types_person.json'), status: 200),
294
+ stub_request(:get, 'https://backend.global-registry.org/entity_types')
295
+ .with(query: { 'filters[name]' => 'address',
296
+ 'filters[parent_id]' => 'ee13a693-3ce7-4c19-b59a-30c8f137acd8' })
297
+ .to_return(body: file_fixture('get_entity_types.json'), status: 200),
298
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
299
+ .with(body: { entity_type: { name: 'address', parent_id: 'ee13a693-3ce7-4c19-b59a-30c8f137acd8',
300
+ field_type: 'entity' } })
301
+ .to_return(body: file_fixture('post_entity_types_address.json'), status: 200),
302
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
303
+ .with(body: { entity_type: { name: 'zip', parent_id: 'f5331684-3ca8-11e7-b937-129bd0521531',
304
+ field_type: 'string' } })
305
+ .to_return(status: 200),
306
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
307
+ .with(body: { entity_type: { name: 'line1', parent_id: 'f5331684-3ca8-11e7-b937-129bd0521531',
308
+ field_type: 'string' } })
309
+ .to_return(status: 200),
310
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
311
+ .with(body: { entity_type: { name: 'line2', parent_id: 'f5331684-3ca8-11e7-b937-129bd0521531',
312
+ field_type: 'string' } })
313
+ .to_return(status: 200),
314
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
315
+ .with(body: { entity_type: { name: 'primary', parent_id: 'f5331684-3ca8-11e7-b937-129bd0521531',
316
+ field_type: 'boolean' } })
317
+ .to_return(status: 200),
318
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
319
+ .with(body: { entity_type: { name: 'postal_code', parent_id: 'f5331684-3ca8-11e7-b937-129bd0521531',
320
+ field_type: 'string' } })
321
+ .to_return(status: 200)]
322
+ end
323
+
324
+ context '\'address\' record belongs to a person without global registry id' do
325
+ let(:person) { create(:person) }
326
+ let(:address) { create(:address, person: person) }
327
+
328
+ it 'should create \'address\' entity_type and raise an error' do
329
+ expect do
330
+ worker.push_entity_to_global_registry
331
+ end.to raise_error GlobalRegistry::Bindings::ParentEntityMissingGlobalRegistryId,
332
+ "Address(#{address.id}) has parent entity Namespaced::Person(#{person.id}) " \
333
+ 'missing global_registry_id; will retry.'
334
+ requests.each { |r| expect(r).to have_been_requested.once }
335
+ expect(person.global_registry_id).to be nil
336
+ expect(address.global_registry_id).to be nil
337
+ end
338
+ end
339
+
340
+ context '\'address\' record belongs to an existing person entity' do
341
+ let(:person) { create(:person, global_registry_id: '22527d88-3cba-11e7-b876-129bd0521531') }
342
+ let(:address) { create(:address, person: person) }
343
+ let!(:sub_requests) do
344
+ [stub_request(:put,
345
+ 'https://backend.global-registry.org/entities/22527d88-3cba-11e7-b876-129bd0521531')
346
+ .with(body: { entity: { person: { client_integration_id: person.id,
347
+ address: {
348
+ zip: '90265', primary: 'true',
349
+ line1: '10880 Malibu Point', postal_code: '90265',
350
+ client_integration_id: address.id,
351
+ client_updated_at: '2001-02-03 00:00:00'
352
+ } } } })
353
+ .to_return(body: file_fixture('put_entities_address.json'), status: 200)]
354
+ end
355
+
356
+ it 'should create \'address\' entity_type and push address entity' do
357
+ worker.push_entity_to_global_registry
358
+ (requests + sub_requests).each { |r| expect(r).to have_been_requested.once }
359
+ expect(address.global_registry_id).to eq '0a594356-3f1c-11e7-bba6-129bd0521531'
360
+ end
361
+ end
362
+ end
363
+
364
+ context '\'address\' and \'person\' entity_types exist' do
365
+ let(:person) { create(:person, global_registry_id: '22527d88-3cba-11e7-b876-129bd0521531') }
366
+ let(:address) { create(:address, person: person) }
367
+ let!(:requests) do
368
+ [stub_request(:get, 'https://backend.global-registry.org/entity_types')
369
+ .with(query: { 'filters[name]' => 'person', 'filters[parent_id]' => nil })
370
+ .to_return(body: file_fixture('get_entity_types_person.json'), status: 200),
371
+ stub_request(:put,
372
+ 'https://backend.global-registry.org/entities/22527d88-3cba-11e7-b876-129bd0521531')
373
+ .with(body: { entity: { person: { client_integration_id: person.id,
374
+ address: {
375
+ zip: '90265', primary: 'true',
376
+ line1: '10880 Malibu Point', postal_code: '90265',
377
+ client_integration_id: address.id,
378
+ client_updated_at: '2001-02-03 00:00:00'
379
+ } } } })
380
+ .to_return(body: file_fixture('put_entities_address.json'), status: 200)]
381
+ end
382
+
383
+ context '\'address\' entity_type has partial fields' do
384
+ let!(:sub_requests) do
385
+ [stub_request(:get, 'https://backend.global-registry.org/entity_types')
386
+ .with(query: { 'filters[name]' => 'address',
387
+ 'filters[parent_id]' => 'ee13a693-3ce7-4c19-b59a-30c8f137acd8' })
388
+ .to_return(body: file_fixture('get_entity_types_address_partial.json'), status: 200),
389
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
390
+ .with(body: { entity_type: { name: 'line2', parent_id: 'f5331684-3ca8-11e7-b937-129bd0521531',
391
+ field_type: 'string' } })
392
+ .to_return(status: 200),
393
+ stub_request(:post, 'https://backend.global-registry.org/entity_types')
394
+ .with(body: { entity_type: { name: 'primary', parent_id: 'f5331684-3ca8-11e7-b937-129bd0521531',
395
+ field_type: 'boolean' } })
396
+ .to_return(status: 200)]
397
+ end
398
+
399
+ it 'should add missing fields and push address entity' do
400
+ worker.push_entity_to_global_registry
401
+ (requests + sub_requests).each { |r| expect(r).to have_been_requested.once }
402
+ expect(address.global_registry_id).to eq '0a594356-3f1c-11e7-bba6-129bd0521531'
403
+ end
404
+ end
405
+
406
+ context '\'address\' entity_type has all fields' do
407
+ let!(:sub_requests) do
408
+ [stub_request(:get, 'https://backend.global-registry.org/entity_types')
409
+ .with(query: { 'filters[name]' => 'address',
410
+ 'filters[parent_id]' => 'ee13a693-3ce7-4c19-b59a-30c8f137acd8' })
411
+ .to_return(body: file_fixture('get_entity_types_address.json'), status: 200)]
412
+ end
413
+
414
+ it 'should push address entity' do
415
+ worker.push_entity_to_global_registry
416
+ (requests + sub_requests).each { |r| expect(r).to have_been_requested.once }
417
+ expect(address.global_registry_id).to eq '0a594356-3f1c-11e7-bba6-129bd0521531'
418
+ end
419
+ end
420
+ end
421
+ end
422
+
423
+ context 'as an update' do
424
+ before :each do
425
+ person_entity_types = JSON.parse(file_fixture('get_entity_types_person.json').read)
426
+ Rails.cache.write('GlobalRegistry::Bindings::EntityType::person', person_entity_types['entity_types'].first)
427
+ address_entity_types = JSON.parse(file_fixture('get_entity_types_address.json').read)
428
+ Rails.cache.write('GlobalRegistry::Bindings::EntityType::address',
429
+ address_entity_types['entity_types'].first)
430
+ end
431
+ let(:person) { create(:person, global_registry_id: '22527d88-3cba-11e7-b876-129bd0521531') }
432
+ let(:address) do
433
+ create(:address, person: person, global_registry_id: '0a594356-3f1c-11e7-bba6-129bd0521531')
434
+ end
435
+ let!(:request) do
436
+ stub_request(:put,
437
+ 'https://backend.global-registry.org/entities/22527d88-3cba-11e7-b876-129bd0521531')
438
+ .with(body: { entity: { person: { client_integration_id: person.id,
439
+ address: {
440
+ zip: '90265', primary: 'false',
441
+ line1: '100 Sesame Street', postal_code: '90265',
442
+ client_integration_id: address.id,
443
+ client_updated_at: '2001-02-03 00:00:00'
444
+ } } } })
445
+ .to_return(body: file_fixture('put_entities_address.json'), status: 200)
446
+ end
447
+
448
+ it 'should push address entity' do
449
+ address.address1 = '100 Sesame Street'
450
+ address.primary = false
451
+ expect do
452
+ worker.push_entity_to_global_registry
453
+ end.to_not(change { address.global_registry_id })
454
+ expect(request).to have_been_requested.once
455
+ end
456
+ end
457
+ end
458
+
459
+ describe Community do
460
+ let(:worker) { GlobalRegistry::Bindings::Workers::PushEntityWorker.new community }
461
+ let(:community) { create(:community, infobase_id: 234) }
462
+ let!(:request) do
463
+ stub_request(:post, 'https://backend.global-registry.org/entities')
464
+ .with(body: { entity: { community: { name: 'Community', client_integration_id: community.id,
465
+ client_updated_at: '2001-02-03 00:00:00' } } })
466
+ .to_return(body: file_fixture('post_entities_community.json'), status: 200)
467
+ end
468
+
469
+ it 'should push community entity' do
470
+ worker.push_entity_to_global_registry
471
+ expect(request).to have_been_requested.once
472
+ expect(community.global_registry_id).to eq '6133f6fe-c63a-425a-bb46-68917c689723'
473
+ end
474
+ end
475
+ end
476
+ end