mas-rad_core 0.0.1

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 (126) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +3 -0
  4. data/Rakefile +14 -0
  5. data/app/models/accreditation.rb +5 -0
  6. data/app/models/adviser.rb +61 -0
  7. data/app/models/allowed_payment_method.rb +7 -0
  8. data/app/models/authentication.rb +19 -0
  9. data/app/models/firm.rb +143 -0
  10. data/app/models/in_person_advice_method.rb +7 -0
  11. data/app/models/initial_advice_fee_structure.rb +7 -0
  12. data/app/models/initial_meeting_duration.rb +7 -0
  13. data/app/models/investment_size.rb +7 -0
  14. data/app/models/lookup/adviser.rb +10 -0
  15. data/app/models/lookup/firm.rb +17 -0
  16. data/app/models/lookup/subsidiary.rb +11 -0
  17. data/app/models/ongoing_advice_fee_structure.rb +7 -0
  18. data/app/models/other_advice_method.rb +7 -0
  19. data/app/models/principal.rb +94 -0
  20. data/app/models/professional_body.rb +3 -0
  21. data/app/models/professional_standing.rb +3 -0
  22. data/app/models/qualification.rb +5 -0
  23. data/app/models/travel_distance.rb +15 -0
  24. data/config/routes.rb +2 -0
  25. data/db/migrate/20141211110031_create_lookup_firms.rb +11 -0
  26. data/db/migrate/20141221140208_create_principals.rb +23 -0
  27. data/db/migrate/20141222150416_add_last_sign_in_at_to_principal.rb +5 -0
  28. data/db/migrate/20141230112136_create_lookup_subsidiaries.rb +10 -0
  29. data/db/migrate/20150106115732_remove_last_sign_in_at_from_principals.rb +5 -0
  30. data/db/migrate/20150114144343_create_lookup_advisers.rb +10 -0
  31. data/db/migrate/20150114151447_create_firms.rb +13 -0
  32. data/db/migrate/20150115130949_add_address_to_firm.rb +9 -0
  33. data/db/migrate/20150119102735_create_in_person_advice_methods.rb +15 -0
  34. data/db/migrate/20150119111754_create_other_advice_methods.rb +15 -0
  35. data/db/migrate/20150119114218_add_free_initial_meeting_to_firm.rb +5 -0
  36. data/db/migrate/20150119125208_create_initial_meeting_durations.rb +11 -0
  37. data/db/migrate/20150119152325_create_initial_advice_fee_structures.rb +15 -0
  38. data/db/migrate/20150119152336_create_ongoing_advice_fee_structures.rb +15 -0
  39. data/db/migrate/20150120133717_create_allowed_payment_methods.rb +15 -0
  40. data/db/migrate/20150120141928_add_minimum_fixed_fee_to_firm.rb +5 -0
  41. data/db/migrate/20150120150738_create_investment_sizes.rb +15 -0
  42. data/db/migrate/20150121110757_create_advisers.rb +11 -0
  43. data/db/migrate/20150121123437_add_business_income_breakdown_fields_to_firm.rb +11 -0
  44. data/db/migrate/20150121134845_create_qualifications.rb +15 -0
  45. data/db/migrate/20150121154458_create_accreditations.rb +15 -0
  46. data/db/migrate/20150121173015_create_professional_standings.rb +15 -0
  47. data/db/migrate/20150121181341_create_professional_bodies.rb +15 -0
  48. data/db/migrate/20150121183728_add_confirmed_disclaimer_to_advisers.rb +5 -0
  49. data/db/migrate/20150124124350_add_geographical_fields_to_adviser.rb +7 -0
  50. data/db/migrate/20150125145457_add_parent_id_to_firms.rb +5 -0
  51. data/db/migrate/20150125164156_remove_unique_constraint_from_firms_fca_number.rb +5 -0
  52. data/db/migrate/20150127084858_add_ordering_on_reference_data.rb +31 -0
  53. data/db/migrate/20150209144836_remove_covers_whole_of_uk_from_advisers.rb +17 -0
  54. data/lib/mas/rad_core.rb +4 -0
  55. data/lib/mas/rad_core/engine.rb +21 -0
  56. data/lib/mas/rad_core/version.rb +5 -0
  57. data/lib/mas/stats.rb +19 -0
  58. data/lib/mas/tasks/rad_core_tasks.rake +4 -0
  59. data/spec/dummy/Rakefile +6 -0
  60. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  61. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  62. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  63. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  64. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  65. data/spec/dummy/bin/bundle +3 -0
  66. data/spec/dummy/bin/rails +4 -0
  67. data/spec/dummy/bin/rake +4 -0
  68. data/spec/dummy/bin/setup +29 -0
  69. data/spec/dummy/config.ru +4 -0
  70. data/spec/dummy/config/application.rb +26 -0
  71. data/spec/dummy/config/boot.rb +5 -0
  72. data/spec/dummy/config/database.example.yml +14 -0
  73. data/spec/dummy/config/database.yml +13 -0
  74. data/spec/dummy/config/environment.rb +5 -0
  75. data/spec/dummy/config/environments/development.rb +41 -0
  76. data/spec/dummy/config/environments/production.rb +79 -0
  77. data/spec/dummy/config/environments/test.rb +42 -0
  78. data/spec/dummy/config/initializers/assets.rb +11 -0
  79. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  80. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  81. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  82. data/spec/dummy/config/initializers/inflections.rb +16 -0
  83. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  84. data/spec/dummy/config/initializers/session_store.rb +3 -0
  85. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  86. data/spec/dummy/config/locales/en.yml +23 -0
  87. data/spec/dummy/config/routes.rb +3 -0
  88. data/spec/dummy/config/secrets.yml +22 -0
  89. data/spec/dummy/db/schema.rb +246 -0
  90. data/spec/dummy/log/test.log +13097 -0
  91. data/spec/dummy/public/404.html +67 -0
  92. data/spec/dummy/public/422.html +67 -0
  93. data/spec/dummy/public/500.html +66 -0
  94. data/spec/dummy/public/favicon.ico +0 -0
  95. data/spec/factories/accreditation.rb +5 -0
  96. data/spec/factories/adviser.rb +21 -0
  97. data/spec/factories/allowed_payment_method.rb +5 -0
  98. data/spec/factories/firm.rb +34 -0
  99. data/spec/factories/in_person_advice_method.rb +5 -0
  100. data/spec/factories/initial_advice_fee_structure.rb +5 -0
  101. data/spec/factories/initial_meeting_duration.rb +5 -0
  102. data/spec/factories/investment_size.rb +5 -0
  103. data/spec/factories/lookup_firm.rb +6 -0
  104. data/spec/factories/ongoing_advice_fee_structure.rb +5 -0
  105. data/spec/factories/other_advice_method.rb +5 -0
  106. data/spec/factories/principal.rb +15 -0
  107. data/spec/factories/professional_body.rb +5 -0
  108. data/spec/factories/professional_standing.rb +5 -0
  109. data/spec/factories/qualification.rb +5 -0
  110. data/spec/models/accreditation_spec.rb +3 -0
  111. data/spec/models/adviser_spec.rb +93 -0
  112. data/spec/models/allowed_payment_method_spec.rb +3 -0
  113. data/spec/models/firm_spec.rb +188 -0
  114. data/spec/models/in_person_advice_method_spec.rb +3 -0
  115. data/spec/models/initial_advice_fee_structure_spec.rb +3 -0
  116. data/spec/models/initial_meeting_duration_spec.rb +3 -0
  117. data/spec/models/investment_size_spec.rb +3 -0
  118. data/spec/models/lookup/adviser_spec.rb +21 -0
  119. data/spec/models/lookup/firm_spec.rb +19 -0
  120. data/spec/models/ongoing_advice_fee_structure_spec.rb +3 -0
  121. data/spec/models/other_advice_method_spec.rb +3 -0
  122. data/spec/models/principal_spec.rb +185 -0
  123. data/spec/models/qualification_spec.rb +3 -0
  124. data/spec/spec_helper.rb +24 -0
  125. data/spec/support/shared_examples/reference_data.rb +14 -0
  126. metadata +361 -0
@@ -0,0 +1,3 @@
1
+ RSpec.describe AllowedPaymentMethod do
2
+ it_behaves_like 'reference data'
3
+ end
@@ -0,0 +1,188 @@
1
+ RSpec.describe Firm do
2
+ subject(:firm) { build(:firm) }
3
+
4
+ describe '#in_person_advice?' do
5
+ context 'when the firm offers in person advice' do
6
+ it 'is true' do
7
+ expect(firm).to be_in_person_advice
8
+ end
9
+ end
10
+
11
+ context 'when the firm does not offer in person advice' do
12
+ it 'is false' do
13
+ firm.in_person_advice_methods.clear
14
+
15
+ expect(firm).to_not be_in_person_advice
16
+ end
17
+ end
18
+ end
19
+
20
+ describe 'subsidaries' do
21
+ context 'when the firm has a parent' do
22
+ it 'is classed as a subsidiary' do
23
+ expect(build(:subsidiary)).to be_subsidiary
24
+ end
25
+ end
26
+
27
+ describe '#subsidiaries' do
28
+ it 'exposes subsidiaries' do
29
+ subsidiary = create(:subsidiary)
30
+ expect(subsidiary.parent.subsidiaries).to contain_exactly(subsidiary)
31
+ end
32
+ end
33
+ end
34
+
35
+ describe 'validation' do
36
+ it 'is valid with valid attributes' do
37
+ expect(firm).to be_valid
38
+ end
39
+
40
+ it 'orders fields correctly for dough' do
41
+ expect(firm.field_order).not_to be_empty
42
+ end
43
+
44
+ describe 'email address' do
45
+ context 'when not present' do
46
+ before { firm.email_address = nil }
47
+
48
+ it { is_expected.to_not be_valid }
49
+ end
50
+
51
+ context 'when badly formatted' do
52
+ before { firm.email_address = 'not-valid' }
53
+
54
+ it { is_expected.to_not be_valid }
55
+ end
56
+ end
57
+
58
+ describe 'telephone number' do
59
+ context 'when not present' do
60
+ before { firm.telephone_number = nil }
61
+
62
+ it { is_expected.to_not be_valid }
63
+ end
64
+
65
+ context 'when badly formatted' do
66
+ before { firm.telephone_number = 'not-valid' }
67
+
68
+ it { is_expected.to_not be_valid }
69
+ end
70
+ end
71
+
72
+ describe 'address line 1' do
73
+ context 'when missing' do
74
+ before { firm.address_line_one = nil }
75
+
76
+ it { is_expected.not_to be_valid }
77
+ end
78
+ end
79
+
80
+ describe 'address town' do
81
+ context 'when missing' do
82
+ before { firm.address_town = nil }
83
+
84
+ it { is_expected.not_to be_valid }
85
+ end
86
+ end
87
+
88
+ describe 'address county' do
89
+ context 'when missing' do
90
+ before { firm.address_county = nil }
91
+
92
+ it { is_expected.not_to be_valid }
93
+ end
94
+ end
95
+
96
+ describe 'address postcode' do
97
+ context 'when missing' do
98
+ before { firm.address_postcode = nil }
99
+
100
+ it { is_expected.not_to be_valid }
101
+ end
102
+
103
+ context 'when invalid' do
104
+ before { firm.address_postcode = nil }
105
+
106
+ it { is_expected.not_to be_valid }
107
+ end
108
+ end
109
+
110
+ describe 'in person advice methods' do
111
+ context 'when none assigned' do
112
+ before { firm.in_person_advice_methods = [] }
113
+
114
+ it { is_expected.to be_valid }
115
+ end
116
+ end
117
+
118
+ describe 'free initial meeting' do
119
+ context 'when missing' do
120
+ before { firm.free_initial_meeting = nil }
121
+
122
+ it { is_expected.not_to be_valid }
123
+ end
124
+
125
+ context 'when set to true' do
126
+ before { firm.free_initial_meeting = true }
127
+
128
+ describe 'initial meeting duration' do
129
+ before { firm.initial_meeting_duration = nil }
130
+
131
+ context 'when missing' do
132
+ it { is_expected.not_to be_valid }
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ describe 'initial advice fee structures' do
139
+ context 'when none assigned' do
140
+ before { firm.initial_advice_fee_structures = [] }
141
+
142
+ it { is_expected.not_to be_valid }
143
+ end
144
+ end
145
+
146
+ describe 'ongoing advice fee structures' do
147
+ context 'when none assigned' do
148
+ before { firm.ongoing_advice_fee_structures = [] }
149
+
150
+ it { is_expected.not_to be_valid }
151
+ end
152
+ end
153
+
154
+ describe 'allowed payment methods' do
155
+ context 'when none assigned' do
156
+ before { firm.allowed_payment_methods = [] }
157
+
158
+ it { is_expected.not_to be_valid }
159
+ end
160
+ end
161
+
162
+ describe 'minimum fixed fee' do
163
+ context 'when not numeric' do
164
+ before { firm.minimum_fixed_fee = 'not-numeric' }
165
+
166
+ it { is_expected.not_to be_valid }
167
+ end
168
+ end
169
+
170
+ describe 'business income breakdown' do
171
+ context 'when sum not equal to 100' do
172
+ before do
173
+ firm.retirement_income_products_percent = 5
174
+ end
175
+
176
+ it { is_expected.not_to be_valid }
177
+ end
178
+ end
179
+
180
+ describe 'investment size' do
181
+ context 'when none assigned' do
182
+ before { firm.investment_sizes = [] }
183
+
184
+ it { is_expected.not_to be_valid }
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.describe InPersonAdviceMethod do
2
+ it_behaves_like 'reference data'
3
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.describe InitialAdviceFeeStructure do
2
+ it_behaves_like 'reference data'
3
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.describe InitialMeetingDuration do
2
+ it_behaves_like 'reference data'
3
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.describe InvestmentSize do
2
+ it_behaves_like 'reference data'
3
+ end
@@ -0,0 +1,21 @@
1
+ RSpec.describe Lookup::Adviser do
2
+ describe 'validation' do
3
+ it 'is valid with valid attributes' do
4
+ expect(
5
+ described_class.new(reference_number: 'AAA00001', name: 'Ben Lovell')
6
+ ).to be_valid
7
+ end
8
+
9
+ describe 'Reference number rules' do
10
+ it 'must be 8 characters' do
11
+ expect(described_class.new(reference_number: '123A45')).to_not be_valid
12
+ end
13
+ end
14
+
15
+ describe 'Name rules' do
16
+ it 'must be provided' do
17
+ expect(described_class.new(reference_number: 'AAA00001')).to_not be_valid
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ RSpec.describe Lookup::Firm do
2
+ describe 'validation' do
3
+ it 'is valid with valid attributes' do
4
+ expect(
5
+ described_class.new(fca_number: 123456, registered_name: 'Ben Lovell Ltd')
6
+ ).to be_valid
7
+ end
8
+
9
+ describe 'FCA Number rules' do
10
+ it 'accepts numeric' do
11
+ expect(described_class.new(fca_number: '123A45')).to_not be_valid
12
+ end
13
+
14
+ it 'accepts only 6 digits' do
15
+ expect(described_class.new(fca_number: 1234567)).to_not be_valid
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.describe OngoingAdviceFeeStructure do
2
+ it_behaves_like 'reference data'
3
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.describe OtherAdviceMethod do
2
+ it_behaves_like 'reference data'
3
+ end
@@ -0,0 +1,185 @@
1
+ RSpec.describe Principal do
2
+ let(:principal) { create(:principal) }
3
+
4
+ describe '#lookup_firm' do
5
+ it 'returns my associated lookup firm' do
6
+ expect(principal.lookup_firm).to be
7
+ end
8
+ end
9
+
10
+ describe '#subsidiaries?' do
11
+ context 'when my firm has subsidiaries' do
12
+ before { principal.lookup_firm.subsidiaries.create! }
13
+
14
+ it 'is truthy' do
15
+ expect(principal.subsidiaries?).to be_truthy
16
+ end
17
+ end
18
+
19
+ context 'when my firm has no subsidiaries' do
20
+ it 'is falsey' do
21
+ expect(principal.subsidiaries?).to be_falsey
22
+ end
23
+ end
24
+ end
25
+
26
+ it 'uses the token for ID purposes' do
27
+ expect(principal.id).to eq(principal.token)
28
+ expect(Principal.find(principal.token)).to eq(principal)
29
+ end
30
+
31
+ context 'upon creation' do
32
+ it 'generates an 8 character, 4 byte token' do
33
+ expect(principal.token.length).to eq(8)
34
+ end
35
+
36
+ it 'creates the associated Firm' do
37
+ expect(principal.firm.fca_number).to eq(principal.lookup_firm.fca_number)
38
+ end
39
+ end
40
+
41
+ describe 'validation' do
42
+ it 'is valid with valid attributes' do
43
+ expect(principal).to be_valid
44
+ end
45
+
46
+ it 'must confirm accuracy' do
47
+ expect(build(:principal, confirmed_disclaimer: false)).to_not be_valid
48
+ end
49
+
50
+ describe 'FCA number' do
51
+ it 'must be a present' do
52
+ build(:principal).tap do |p|
53
+ p.fca_number = nil
54
+ expect(p).to_not be_valid
55
+ end
56
+ end
57
+
58
+ it 'must be a 6 digit number' do
59
+ build(:principal).tap do |p|
60
+ p.fca_number = 12345
61
+ expect(p).to_not be_valid
62
+ end
63
+ end
64
+
65
+ it 'must match a `Lookup::Firm`' do
66
+ Lookup::Firm.find_by(fca_number: principal.fca_number).destroy
67
+
68
+ expect(principal).to_not be_valid
69
+ end
70
+
71
+ it 'must be unique' do
72
+ build(:principal).tap do |p|
73
+ p.fca_number = principal.fca_number
74
+ expect(p).to_not be_valid
75
+ end
76
+ end
77
+ end
78
+
79
+ describe 'Email address' do
80
+ it 'must be present' do
81
+ expect(build(:principal, email_address: '')).to_not be_valid
82
+ end
83
+
84
+ it 'must be unique' do
85
+ dupe = build(:principal, email_address: principal.email_address)
86
+ expect(dupe).to_not be_valid
87
+ end
88
+
89
+ it 'must be a reasonably valid format' do
90
+ %w(zzz abc@abc a@a.).each do |bad|
91
+ principal.email_address = bad
92
+ expect(principal).to_not be_valid
93
+ end
94
+ end
95
+
96
+ it 'must not exceed 50 characters' do
97
+ long_email = "a@#{'a' * 50}.com"
98
+ expect(build(:principal, email_address: long_email)).to_not be_valid
99
+ end
100
+ end
101
+
102
+ describe 'First name' do
103
+ it 'must be present' do
104
+ expect(build(:principal, first_name: '')).to_not be_valid
105
+ end
106
+
107
+ it 'must be at least 2 characters' do
108
+ expect(build(:principal, first_name: 'A')).to_not be_valid
109
+ end
110
+
111
+ it 'must not exceed 80 characters' do
112
+ expect(build(:principal, first_name: 'A' * 81)).to_not be_valid
113
+ end
114
+ end
115
+
116
+ describe 'Last name' do
117
+ it 'must be present' do
118
+ expect(build(:principal, last_name: '')).to_not be_valid
119
+ end
120
+
121
+ it 'must be at least 2 characters' do
122
+ expect(build(:principal, last_name: 'A')).to_not be_valid
123
+ end
124
+
125
+ it 'must not exceed 80 characters' do
126
+ expect(build(:principal, last_name: 'A' * 81)).to_not be_valid
127
+ end
128
+ end
129
+
130
+ describe 'Job title' do
131
+ it 'must be present' do
132
+ expect(build(:principal, job_title: '')).to_not be_valid
133
+ end
134
+
135
+ it 'must be at least 2 characters' do
136
+ expect(build(:principal, job_title: 'A')).to_not be_valid
137
+ end
138
+
139
+ it 'must not exceed 80 characters' do
140
+ expect(build(:principal, job_title: 'A' * 81)).to_not be_valid
141
+ end
142
+ end
143
+
144
+ describe 'Telephone number' do
145
+ it 'must be present' do
146
+ expect(build(:principal, telephone_number: '')).to_not be_valid
147
+ end
148
+
149
+ it 'must not exceed 50 characters' do
150
+ expect(build(:principal, telephone_number: '1' * 51)).to_not be_valid
151
+ end
152
+
153
+ it 'must contain only digits and spaces' do
154
+ expect(build(:principal, telephone_number: '1 abcd')).to_not be_valid
155
+ end
156
+ end
157
+
158
+ describe 'Website address' do
159
+ context 'when provided' do
160
+ it 'must not exceed 100 characters' do
161
+ expect(build(:principal, website_address: "#{'a' * 100}.com")).not_to be_valid
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ describe 'dough #field_order' do
168
+ let(:fields) do
169
+ [
170
+ :fca_number,
171
+ :website_address,
172
+ :first_name,
173
+ :last_name,
174
+ :job_title,
175
+ :email_address,
176
+ :telephone_number,
177
+ :confirmed_disclaimer
178
+ ]
179
+ end
180
+
181
+ it 'orders fields per the identification form' do
182
+ expect(principal.field_order).to contain_exactly(*fields)
183
+ end
184
+ end
185
+ end