openc_bot 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.travis.yml +8 -0
  4. data/CHANGELOG.md +2 -0
  5. data/Gemfile +8 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +253 -0
  8. data/Rakefile +14 -0
  9. data/bin/openc_bot +13 -0
  10. data/create_bot.sh +30 -0
  11. data/create_company_bot.sh +16 -0
  12. data/create_simple_licence_bot.sh +31 -0
  13. data/db/.gitkeep +0 -0
  14. data/examples/basic/.gitignore +3 -0
  15. data/examples/basic/Gemfile +7 -0
  16. data/examples/basic/config.yml +21 -0
  17. data/examples/basic/lib/basic.rb +88 -0
  18. data/examples/basic_with_proxy/Gemfile +7 -0
  19. data/examples/basic_with_proxy/config.yml +21 -0
  20. data/examples/basic_with_proxy/lib/basic_with_proxy.rb +103 -0
  21. data/examples/bot_with_simple_iterator/Gemfile +6 -0
  22. data/examples/bot_with_simple_iterator/config.yml +21 -0
  23. data/examples/bot_with_simple_iterator/lib/bot_with_simple_iterator.rb +112 -0
  24. data/examples/company_fetchers/basic.rb +49 -0
  25. data/lib/monkey_patches/mechanize.rb +53 -0
  26. data/lib/openc_bot.rb +89 -0
  27. data/lib/openc_bot/bot_data_validator.rb +18 -0
  28. data/lib/openc_bot/company_fetcher_bot.rb +40 -0
  29. data/lib/openc_bot/exceptions.rb +17 -0
  30. data/lib/openc_bot/helpers/_csv.rb +10 -0
  31. data/lib/openc_bot/helpers/alpha_search.rb +73 -0
  32. data/lib/openc_bot/helpers/dates.rb +33 -0
  33. data/lib/openc_bot/helpers/html.rb +8 -0
  34. data/lib/openc_bot/helpers/incremental_search.rb +106 -0
  35. data/lib/openc_bot/helpers/register_methods.rb +205 -0
  36. data/lib/openc_bot/helpers/text.rb +18 -0
  37. data/lib/openc_bot/incrementers.rb +2 -0
  38. data/lib/openc_bot/incrementers/base.rb +214 -0
  39. data/lib/openc_bot/incrementers/common.rb +47 -0
  40. data/lib/openc_bot/tasks.rb +385 -0
  41. data/lib/openc_bot/templates/README.md +35 -0
  42. data/lib/openc_bot/templates/bin/export_data +28 -0
  43. data/lib/openc_bot/templates/bin/fetch_data +23 -0
  44. data/lib/openc_bot/templates/bin/verify_data +1 -0
  45. data/lib/openc_bot/templates/config.yml +21 -0
  46. data/lib/openc_bot/templates/lib/bot.rb +43 -0
  47. data/lib/openc_bot/templates/lib/company_fetcher_bot.rb +95 -0
  48. data/lib/openc_bot/templates/lib/simple_bot.rb +67 -0
  49. data/lib/openc_bot/templates/spec/bot_spec.rb +11 -0
  50. data/lib/openc_bot/templates/spec/simple_bot_spec.rb +11 -0
  51. data/lib/openc_bot/templates/spec/spec_helper.rb +13 -0
  52. data/lib/openc_bot/version.rb +3 -0
  53. data/lib/simple_openc_bot.rb +289 -0
  54. data/openc_bot.gemspec +35 -0
  55. data/schemas/company-schema.json +112 -0
  56. data/schemas/includes/address.json +23 -0
  57. data/schemas/includes/base-statement.json +27 -0
  58. data/schemas/includes/company.json +14 -0
  59. data/schemas/includes/filing.json +20 -0
  60. data/schemas/includes/license-data.json +27 -0
  61. data/schemas/includes/officer.json +14 -0
  62. data/schemas/includes/previous_name.json +11 -0
  63. data/schemas/includes/share-parcel-data.json +67 -0
  64. data/schemas/includes/share-parcel.json +60 -0
  65. data/schemas/includes/subsidiary-relationship-data.json +52 -0
  66. data/schemas/includes/total-shares.json +10 -0
  67. data/schemas/licence-schema.json +21 -0
  68. data/schemas/share-parcel-schema.json +21 -0
  69. data/schemas/subsidiary-relationship-schema.json +19 -0
  70. data/spec/dummy_classes/foo_bot.rb +4 -0
  71. data/spec/lib/bot_data_validator_spec.rb +69 -0
  72. data/spec/lib/company_fetcher_bot_spec.rb +93 -0
  73. data/spec/lib/exceptions_spec.rb +25 -0
  74. data/spec/lib/helpers/alpha_search_spec.rb +173 -0
  75. data/spec/lib/helpers/dates_spec.rb +65 -0
  76. data/spec/lib/helpers/incremental_search_spec.rb +471 -0
  77. data/spec/lib/helpers/register_methods_spec.rb +558 -0
  78. data/spec/lib/helpers/text_spec.rb +50 -0
  79. data/spec/lib/openc_bot/db/.gitkeep +0 -0
  80. data/spec/lib/openc_bot/incrementers/common_spec.rb +83 -0
  81. data/spec/lib/openc_bot_spec.rb +116 -0
  82. data/spec/schemas/company-schema_spec.rb +676 -0
  83. data/spec/simple_openc_bot_spec.rb +302 -0
  84. data/spec/spec_helper.rb +19 -0
  85. metadata +300 -0
@@ -0,0 +1,50 @@
1
+ # encoding: UTF-8
2
+ require_relative '../../spec_helper'
3
+ require 'openc_bot/helpers/text'
4
+
5
+ describe OpencBot::Helpers::Text do
6
+ describe "#normalise_utf8_spaces" do
7
+ it "should convert UTF-8 spaces to normal spaces" do
8
+ raw_and_normalised_text = {
9
+ "Hello World" => "Hello World",
10
+ '' => '',
11
+ nil => nil,
12
+ " \xC2\xA0\xC2\xA0 Mr Fred Flintstone \xC2\xA0" => ' Mr Fred Flintstone ',
13
+ "AVTOPREVOZNIŠTVO - PREVOZ BLAGA ROBERT FLORJANČIČ S.P." => "AVTOPREVOZNIŠTVO - PREVOZ BLAGA ROBERT FLORJANČIČ S.P."
14
+ }
15
+ raw_and_normalised_text.each do |raw_text, normalised_text|
16
+ OpencBot::Helpers::Text.normalise_utf8_spaces(raw_text).should == normalised_text
17
+ end
18
+ end
19
+ end
20
+
21
+ describe "#strip_all_spaces" do
22
+ it "should strip all spaces from text" do
23
+ OpencBot::Helpers::Text.strip_all_spaces(" \n \xC2\xA0\xC2\xA0 Mr Fred Flintstone\n ").should == 'Mr Fred Flintstone'
24
+ end
25
+
26
+ it "should not strip UTF8 chars that aren't spaces" do
27
+ OpencBot::Helpers::Text.strip_all_spaces(" \xC3\x8Dan Flintstone\n ").should == 'Ían Flintstone'
28
+ end
29
+
30
+ it "should replace UTF8 space with normal space" do
31
+ OpencBot::Helpers::Text.strip_all_spaces(" Mr\xC2\xA0Fred Flintstone\n ").should == 'Mr Fred Flintstone'
32
+ end
33
+
34
+ it "should not mess with other UTF8 characters" do
35
+ utf8_name = "AVTOPREVOZNIŠTVO - PREVOZ BLAGA ROBERT FLORJANČIČ S.P."
36
+ OpencBot::Helpers::Text.strip_all_spaces(utf8_name).should == utf8_name
37
+ end
38
+
39
+ it "should return nil when nil given" do
40
+ OpencBot::Helpers::Text.strip_all_spaces(nil).should be_nil
41
+ end
42
+
43
+ it "should replace multiple spaces with single space" do
44
+ OpencBot::Helpers::Text.strip_all_spaces(" Mr\xC2\xA0Fred Percy Flintstone\n ").should == 'Mr Fred Percy Flintstone'
45
+ end
46
+
47
+ end
48
+
49
+
50
+ end
File without changes
@@ -0,0 +1,83 @@
1
+ # encoding: UTF-8
2
+ require_relative '../../../spec_helper'
3
+ require 'openc_bot'
4
+ require 'openc_bot/incrementers'
5
+
6
+ describe OpencBot::ManualIncrementer do
7
+ before do
8
+ @app_path = File.expand_path(File.join(File.dirname(__FILE__), "../../.."))
9
+ @incrementer = OpencBot::ManualIncrementer.new(:manual_incrementer, :fields => [:url], :app_path => @app_path, :show_progress => false)
10
+ @incrementer.sqlite_magic_connection.execute("DELETE FROM items")
11
+ @incrementer.reset_current
12
+ end
13
+
14
+ after do
15
+ @incrementer.sqlite_magic_connection.execute("DROP TABLE items")
16
+ end
17
+
18
+ it "should return same stuff as saved, plus an id" do
19
+ hashes = [
20
+ {"name" => "tony", "address" => "number 0", "url" => "http://example.com/tony"},
21
+ {"name" => "jude", "address" => "number 1", "url" => "http://example.com/jude"},
22
+ {"name" => "brig", "address" => "number 2", "url" => "http://example.com/brig"}
23
+ ]
24
+ hashes.each do |h|
25
+ @incrementer.add_row(h)
26
+ end
27
+ @incrementer.enum.each.with_index(1) do |row, i|
28
+ # id assignment in sqlite is 1 indexed, not 0
29
+ row.should == hashes[i - 1].merge("_id" => i)
30
+ end
31
+ end
32
+
33
+ it "should resume from where left off" do
34
+ hashes = [
35
+ {"name" => "tony", "address" => "number 1", "url" => "http://example.com/tony"},
36
+ {"name" => "jude", "address" => "number 2", "url" => "http://example.com/jude"},
37
+ {"name" => "brig", "address" => "number 3", "url" => "http://example.com/brig"}
38
+ ]
39
+ hashes.each do |h|
40
+ @incrementer.add_row(h)
41
+ end
42
+ counter = @incrementer.enum
43
+ counter.next.should == hashes[0].merge("_id" => 1)
44
+ counter.next.should == hashes[1].merge("_id" => 2)
45
+
46
+ @new_incrementer = OpencBot::ManualIncrementer.new(:manual_incrementer, :app_path => @app_path, :fields => [:url])
47
+ # TODO: effectively performs id >= current_row['_id'] which results
48
+ # in the same row being run twice across the two separate runs.
49
+ # Is this desired behaviour?
50
+ @new_incrementer.resumable.next.should == hashes[1].merge("_id" => 2)
51
+ end
52
+
53
+ it "should be relatively fast to save" do
54
+ hashes = []
55
+ (0...2000).each do |n|
56
+ hashes << {'number' => n}
57
+ end
58
+ hashes.each do |h|
59
+ @incrementer.add_row(h)
60
+ end
61
+ end
62
+
63
+ it "should be relatively fast to skip" do
64
+ hashes = []
65
+ (0...2000).each do |n|
66
+ hashes << {'number' => n}
67
+ end
68
+ hashes.each do |h|
69
+ @incrementer.add_row(h)
70
+ end
71
+ counter = @incrementer.enum
72
+ start_time = Time.now
73
+ 1000.times do
74
+ counter.next
75
+ end
76
+ end_time = Time.now
77
+ @new_incrementer = OpencBot::ManualIncrementer.new(:manual_incrementer, :app_path => @app_path, :fields => [:url])
78
+ # TODO: effectively performs id >= current_row['_id'] which results
79
+ # in the same row being run twice across the two separate runs.
80
+ # Is this desired behaviour?
81
+ @new_incrementer.resumable.next["number"].should == 999
82
+ end
83
+ end
@@ -0,0 +1,116 @@
1
+ # encoding: UTF-8
2
+ require_relative '../spec_helper'
3
+ require 'openc_bot'
4
+ require_relative '../dummy_classes/foo_bot'
5
+
6
+ describe "A module that extends OpencBot" do
7
+
8
+ before do
9
+ @dummy_connection = double('database_connection')
10
+ FooBot.stub(:sqlite_magic_connection).and_return(@dummy_connection)
11
+ end
12
+
13
+ it "should include ScraperWiki methods" do
14
+ FooBot.should respond_to(:save_sqlite)
15
+ end
16
+
17
+ it "should define OpencBotError exception as subclass of StandardError" do
18
+ OpencBot::OpencBotError.superclass.should be StandardError
19
+ end
20
+
21
+ it "should define DatabaseError exception as subclass of OpencBotError" do
22
+ OpencBot::DatabaseError.superclass.should be OpencBot::OpencBotError
23
+ end
24
+
25
+ it "should define InvalidDataError exception as subclass of OpencBotError" do
26
+ OpencBot::InvalidDataError.superclass.should be OpencBot::OpencBotError
27
+ end
28
+
29
+ describe '#insert_or_update' do
30
+ before do
31
+ @datum = {:foo => 'bar', :foo2 => 'bar2', :foo3 => 'bar3', :foo4 => 'bar4'}
32
+ @unique_keys = [:foo2,:foo3]
33
+ @expected_query = "INSERT INTO foo_table (foo,foo2,foo3,foo4) VALUES (:foo,:foo2,:foo3,:foo4)"
34
+ end
35
+
36
+ it "should delegate to connection" do
37
+ @dummy_connection.should_receive(:insert_or_update).with(@unique_keys, @datum, 'foo_table')
38
+ FooBot.insert_or_update(@unique_keys, @datum, 'foo_table')
39
+ end
40
+
41
+ it "should use ocdata table by default" do
42
+ @dummy_connection.should_receive(:insert_or_update).with(@unique_keys, @datum, 'ocdata')
43
+ FooBot.insert_or_update(@unique_keys, @datum)
44
+ end
45
+ end
46
+
47
+ describe '#unlock_database' do
48
+ it "should start and end transaction on database" do
49
+ @dummy_connection.should_receive(:execute).with('BEGIN TRANSACTION; END;')
50
+ FooBot.unlock_database
51
+ end
52
+ end
53
+
54
+ describe '#verbose?' do
55
+ it 'should return false if ENV["VERBOSE"] not set' do
56
+ FooBot.verbose?.should be_false
57
+ end
58
+
59
+ it 'should return false if ENV["VERBOSE"] set' do
60
+ ENV["VERBOSE"] = 'true'
61
+ FooBot.verbose?.should be_true
62
+ ENV["VERBOSE"] = nil # reset
63
+ end
64
+ end
65
+
66
+ describe '#save_run_report' do
67
+
68
+ it 'should save_data in ocrunreports table' do
69
+ FooBot.should_receive(:save_data).with(anything, anything, :ocrunreports)
70
+ FooBot.save_run_report(:foo => 'bar')
71
+ end
72
+
73
+ it 'should convert run data into JSON' do
74
+ dummy_time = Time.now
75
+ Time.stub(:now).and_return(dummy_time)
76
+ expected_run_report = ({ :foo => 'bar' }).to_json
77
+ FooBot.should_receive(:save_data).with(anything, { :report => expected_run_report, :run_at => dummy_time.to_s }, anything)
78
+ FooBot.save_run_report(:foo => 'bar')
79
+ end
80
+
81
+ it 'should use timestamp as unique key' do
82
+ FooBot.should_receive(:save_data).with([:run_at], anything, anything)
83
+ FooBot.save_run_report(:foo => 'bar')
84
+ end
85
+ end
86
+
87
+ describe "normalise_utf8_spaces private method" do
88
+ it "should convert UTF-8 spaces to normal spaces" do
89
+ raw_and_normalised_text = {
90
+ "Hello World" => "Hello World",
91
+ '' => '',
92
+ nil => nil,
93
+ " \xC2\xA0\xC2\xA0 Mr Fred Flintstone \xC2\xA0" => ' Mr Fred Flintstone ',
94
+ }
95
+ raw_and_normalised_text.each do |raw_text, normalised_text|
96
+ FooBot.send(:normalise_utf8_spaces, raw_text).should == normalised_text
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "#sqlite_magic_connection" do
102
+ it "should override default ScraperWiki#sqlite_magic_connection to use module name and adjacent db directory" do
103
+ FooBot.unstub(:sqlite_magic_connection)
104
+ expected_db_loc = File.expand_path(File.join(File.dirname(__FILE__),'..','db','foobot.db'))
105
+ SqliteMagic::Connection.should_receive(:new).with(expected_db_loc).and_return(@dummy_sqlite_magic_connection)
106
+ FooBot.sqlite_magic_connection
107
+ end
108
+ end
109
+
110
+ describe "#root_directory" do
111
+ it "should return directory one up from that containing module" do
112
+ FooBot.root_directory.should == File.expand_path(File.join(File.dirname(__FILE__), '..'))
113
+ end
114
+ end
115
+
116
+ end
@@ -0,0 +1,676 @@
1
+ # encoding: UTF-8
2
+ require 'json-schema'
3
+ require 'active_support/core_ext'
4
+ require 'debugger'
5
+
6
+ describe 'company-schema' do
7
+ before do
8
+ @schema = File.join(File.dirname(__FILE__),'..','..','schemas','company-schema.json')
9
+ end
10
+
11
+ it "should validate simple company" do
12
+ valid_company_params =
13
+ [
14
+ { :name => 'Foo Inc',
15
+ :company_number => '12345',
16
+ :jurisdiction_code => 'ie'
17
+ },
18
+ { :name => 'Foo Inc',
19
+ :company_number => '12345',
20
+ :jurisdiction_code => 'us_de',
21
+ :registered_address => '32 Foo St, Footown,'
22
+ }
23
+ ]
24
+ valid_company_params.each do |valid_params|
25
+ errors = validate_datum_and_return_errors(valid_params)
26
+ errors.should be_empty, "Valid params were not valid: #{valid_params}"
27
+ end
28
+ end
29
+
30
+ it "should validate complex company" do
31
+ valid_company_params =
32
+ { :name => 'Foo Inc',
33
+ :company_number => '12345',
34
+ :jurisdiction_code => 'us_de',
35
+ :incorporation_date => '2010-10-20',
36
+ :dissolution_date => '2012-01-12'
37
+ }
38
+ errors = validate_datum_and_return_errors(valid_company_params)
39
+ errors.should be_empty
40
+ end
41
+
42
+ it "should not validate invalid company" do
43
+ invalid_company_params =
44
+ [
45
+ { :name => 'Foo Inc',
46
+ :jurisdiction_code => 'ie'
47
+ },
48
+ { :name => 'Foo Inc',
49
+ :jurisdiction_code => 'usa_de',
50
+ :company_number => '12345'
51
+ },
52
+ { :name => 'Bar',
53
+ :jurisdiction_code => 'us_de',
54
+ :company_number => ''
55
+ },
56
+ { :name => 'Foo Inc',
57
+ :jurisdiction_code => 'a',
58
+ :company_number => '12345'
59
+ },
60
+ { :name => '',
61
+ :jurisdiction_code => 'us_de',
62
+ :company_number => '12345'
63
+ },
64
+ { :name => 'Foo Inc',
65
+ :jurisdiction_code => 'us_de',
66
+ :company_number => '12345',
67
+ :foo => 'bar'
68
+ }
69
+ ]
70
+ invalid_company_params.each do |invalid_params|
71
+ errors = validate_datum_and_return_errors(invalid_params)
72
+ errors.should_not be_empty, "Invalid params were not invalid: #{invalid_params}"
73
+ end
74
+ end
75
+
76
+ context "and company has registered_address" do
77
+ it "should be valid if it is a string" do
78
+ valid_company_params =
79
+ { :name => 'Foo Inc',
80
+ :company_number => '12345',
81
+ :jurisdiction_code => 'us_de',
82
+ :registered_address => '32 Foo St, Footown,'
83
+ }
84
+ errors = validate_datum_and_return_errors(valid_company_params)
85
+ errors.should be_empty
86
+ end
87
+
88
+ it "should be valid if it is nil" do
89
+ valid_company_params =
90
+ { :name => 'Foo Inc',
91
+ :company_number => '12345',
92
+ :jurisdiction_code => 'us_de',
93
+ :registered_address => nil
94
+ }
95
+ errors = validate_datum_and_return_errors(valid_company_params)
96
+ errors.should be_empty
97
+ end
98
+
99
+ it "should be valid if it is a valid address object" do
100
+ valid_company_params =
101
+ [
102
+ { :name => 'Foo Inc',
103
+ :company_number => '12345',
104
+ :jurisdiction_code => 'us_de',
105
+ :registered_address => { :street_address => '32 Foo St', :locality => 'Footown', :region => 'Fooshire', :postal_code => 'FO1 2BA' }
106
+ },
107
+ { :name => 'Foo Inc',
108
+ :company_number => '12345',
109
+ :jurisdiction_code => 'us_de',
110
+ :registered_address => { :street_address => '32 Foo St' }
111
+ },
112
+ { :name => 'Foo Inc',
113
+ :company_number => '12345',
114
+ :jurisdiction_code => 'us_de',
115
+ :registered_address => { :postal_code => 'FO1 2BA' }
116
+ }
117
+ ]
118
+ valid_company_params.each do |valid_params|
119
+ errors = validate_datum_and_return_errors(valid_params)
120
+ errors.should be_empty, "Valid params were not valid: #{valid_params}.Errors = #{errors}"
121
+ end
122
+ end
123
+
124
+ it "should not be valid if it is not a valid address object" do
125
+ invalid_company_params =
126
+ [
127
+ { :name => 'Foo Inc',
128
+ :company_number => '12345',
129
+ :jurisdiction_code => 'ie',
130
+ :registered_address => []
131
+ },
132
+ { :name => 'Foo Inc',
133
+ :company_number => '12345',
134
+ :jurisdiction_code => 'ie',
135
+ :registered_address => ''
136
+ },
137
+ { :name => 'Foo Inc',
138
+ :company_number => '12345',
139
+ :jurisdiction_code => 'ie',
140
+ :registered_address => {:country => 'Germany'}
141
+ },
142
+ # { :name => 'Foo Inc',
143
+ # :company_number => '12345',
144
+ # :jurisdiction_code => 'us_de',
145
+ # :registered_address => {:country => 'Germany'}
146
+ # }
147
+ ]
148
+ invalid_company_params.each do |invalid_params|
149
+ errors = validate_datum_and_return_errors(invalid_params)
150
+ errors.should_not be_empty, "Invalid params were not invalid: #{invalid_params}"
151
+ end
152
+ end
153
+ end
154
+
155
+ context "and company has previous names" do
156
+ it "should validate valid previous names data" do
157
+ valid_company_params =
158
+ [
159
+ { :name => 'Foo Inc',
160
+ :company_number => '12345',
161
+ :jurisdiction_code => 'ie',
162
+ :previous_names => [{:company_name => 'FooBar Inc'},
163
+ {:company_name => 'FooBaz', :con_date => '2012-07-22'},
164
+ {:company_name => 'FooBaz', :con_date => '2012-07-22', :start_date => '2008-01-08'}]
165
+ },
166
+ { :name => 'Foo Inc',
167
+ :company_number => '12345',
168
+ :jurisdiction_code => 'ie',
169
+ # allow empty arrays
170
+ :previous_names => []
171
+ }
172
+ ]
173
+ valid_company_params.each do |valid_params|
174
+ errors = validate_datum_and_return_errors(valid_params)
175
+ errors.should be_empty, "Valid params were not valid: #{valid_params}"
176
+ end
177
+ end
178
+
179
+ it "should not validated invalid previous names data" do
180
+ invalid_company_params =
181
+ [
182
+ { :name => 'Foo Inc',
183
+ :company_number => '12345',
184
+ :jurisdiction_code => 'ie',
185
+ :previous_names => 'some name'
186
+ },
187
+ { :name => 'Foo Inc',
188
+ :company_number => '12345',
189
+ :jurisdiction_code => 'ie',
190
+ :previous_names => ['some name']
191
+ },
192
+ { :name => 'Foo Inc',
193
+ :company_number => '12345',
194
+ :jurisdiction_code => 'ie',
195
+ :previous_names => [{:name => 'Baz Inc'}]
196
+ },
197
+ { :name => 'Foo Inc',
198
+ :company_number => '12345',
199
+ :jurisdiction_code => 'ie',
200
+ :previous_names => [{:company_name => ''}]
201
+ }
202
+ ]
203
+
204
+ invalid_company_params.each do |invalid_params|
205
+ errors = validate_datum_and_return_errors(invalid_params)
206
+ errors.should_not be_empty, "Invalid params were not invalid: #{invalid_params}"
207
+ end
208
+
209
+ end
210
+ end
211
+
212
+ context "and company has branch flag" do
213
+ it "should be valid if it is F or L or nil" do
214
+ valid_company_params =
215
+ [
216
+ { :name => 'Foo Inc',
217
+ :company_number => '12345',
218
+ :jurisdiction_code => 'ie',
219
+ :branch => 'F'
220
+ },
221
+ { :name => 'Foo Inc',
222
+ :company_number => '12345',
223
+ :jurisdiction_code => 'us_de',
224
+ :branch => 'L'
225
+ },
226
+ { :name => 'Foo Inc',
227
+ :company_number => '12345',
228
+ :jurisdiction_code => 'us_de',
229
+ :branch => nil
230
+ }
231
+ ]
232
+ valid_company_params.each do |valid_params|
233
+ errors = validate_datum_and_return_errors(valid_params)
234
+ errors.should be_empty, "Valid params were not valid: #{valid_params}.Errors = #{errors}"
235
+ end
236
+
237
+ end
238
+
239
+ it "should not be valid if it is not F or L" do
240
+ invalid_company_params =
241
+ [
242
+ { :name => 'Foo Inc',
243
+ :company_number => '12345',
244
+ :jurisdiction_code => 'ie',
245
+ :branch => 'X'
246
+ },
247
+ { :name => 'Foo Inc',
248
+ :company_number => '12345',
249
+ :jurisdiction_code => 'ie',
250
+ :branch => 'FOO'
251
+ },
252
+ { :name => 'Foo Inc',
253
+ :company_number => '12345',
254
+ :jurisdiction_code => 'us_de',
255
+ :branch => ''
256
+ }
257
+ ]
258
+ invalid_company_params.each do |invalid_params|
259
+ errors = validate_datum_and_return_errors(invalid_params)
260
+ errors.should_not be_empty, "Invalid params were not invalid: #{invalid_params}"
261
+ end
262
+
263
+ end
264
+ end
265
+
266
+ context "and company has all_attributes" do
267
+ it "should allow arbitrary elements to all_attributes hash" do
268
+ valid_company_params =
269
+ [
270
+ { :name => 'Foo Inc',
271
+ :company_number => '12345',
272
+ :jurisdiction_code => 'ie',
273
+ :all_attributes => {:foo => 'bar', :some_number => 42, :an_array => [1,2,3]}
274
+ },
275
+ { :name => 'Foo Inc',
276
+ :company_number => '12345',
277
+ :jurisdiction_code => 'us_de',
278
+ :all_attributes => {}
279
+ }
280
+ ]
281
+ valid_company_params.each do |valid_params|
282
+ errors = validate_datum_and_return_errors(valid_params)
283
+ errors.should be_empty, "Valid params were not valid: #{valid_params}.Errors = #{errors}"
284
+ end
285
+ end
286
+
287
+ it "should require jurisdiction_of_origin to be a non-empty string or null" do
288
+ valid_params_1 =
289
+ { :name => 'Foo Inc',
290
+ :company_number => '12345',
291
+ :jurisdiction_code => 'ie',
292
+ :all_attributes => {:jurisdiction_of_origin => 'Some Country'}
293
+ }
294
+ valid_params_2 =
295
+ { :name => 'Foo Inc',
296
+ :company_number => '12345',
297
+ :jurisdiction_code => 'ie',
298
+ :all_attributes => {:jurisdiction_of_origin => nil}
299
+ }
300
+ invalid_params_1 =
301
+ { :name => 'Foo Inc',
302
+ :company_number => '12345',
303
+ :jurisdiction_code => 'ie',
304
+ :all_attributes => {:jurisdiction_of_origin => ''}
305
+ }
306
+ invalid_params_2 =
307
+ { :name => 'Foo Inc',
308
+ :company_number => '12345',
309
+ :jurisdiction_code => 'ie',
310
+ :all_attributes => {:jurisdiction_of_origin => 43}
311
+ }
312
+ validate_datum_and_return_errors(valid_params_1).should be_empty
313
+ validate_datum_and_return_errors(valid_params_2).should be_empty
314
+ validate_datum_and_return_errors(invalid_params_1).should_not be_empty
315
+ validate_datum_and_return_errors(invalid_params_2).should_not be_empty
316
+ end
317
+
318
+ it "should require home_company_number to be a non-empty string or null" do
319
+ require_all_attributes_attribute_to_be_string_or_nil(:home_company_number)
320
+ end
321
+
322
+ it "should require home_legal_name to be a non-empty string or null" do
323
+ require_all_attributes_attribute_to_be_string_or_nil(:home_legal_name)
324
+ end
325
+
326
+ it "should require registered_agent_name to be a string or nil" do
327
+ require_all_attributes_attribute_to_be_string_or_nil(:registered_agent_name)
328
+ end
329
+
330
+ it "should require registered_agent_address to be a string or nil" do
331
+ require_all_attributes_attribute_to_be_string_or_nil(:registered_agent_address)
332
+ end
333
+
334
+ it "should require number_of_employees to be an positive" do
335
+ valid_params =
336
+ { :name => 'Foo Inc',
337
+ :company_number => '12345',
338
+ :jurisdiction_code => 'ie',
339
+ :all_attributes => {:number_of_employees => 42}
340
+ }
341
+ invalid_params_1 =
342
+ { :name => 'Foo Inc',
343
+ :company_number => '12345',
344
+ :jurisdiction_code => 'ie',
345
+ :all_attributes => {:number_of_employees => ''}
346
+ }
347
+ invalid_params_2 =
348
+ { :name => 'Foo Inc',
349
+ :company_number => '12345',
350
+ :jurisdiction_code => 'ie',
351
+ :all_attributes => {:number_of_employees => 'foo'}
352
+ }
353
+ invalid_params_3 =
354
+ { :name => 'Foo Inc',
355
+ :company_number => '12345',
356
+ :jurisdiction_code => 'ie',
357
+ :all_attributes => {:number_of_employees => -1}
358
+ }
359
+ validate_datum_and_return_errors(valid_params).should be_empty
360
+ validate_datum_and_return_errors(invalid_params_1).should_not be_empty
361
+ validate_datum_and_return_errors(invalid_params_2).should_not be_empty
362
+ validate_datum_and_return_errors(invalid_params_3).should_not be_empty
363
+ end
364
+ end
365
+
366
+ context "and company has officers" do
367
+ it "should validate if officers are valid" do
368
+ valid_company_params =
369
+ [
370
+ { :name => 'Foo Inc',
371
+ :company_number => '12345',
372
+ :jurisdiction_code => 'ie',
373
+ :officers => [{:name => 'Fred Flintstone'},
374
+ {:name => 'Barney Rubble', :position => 'Director'},
375
+ {:name => 'Barney Rubble', :other_attributes => {:foo => 'bar'}},
376
+ {:name => 'Pebbles', :start_date => '2010-12-22', :end_date => '2011-01-03'}]
377
+ },
378
+ { :name => 'Foo Inc',
379
+ :company_number => '12345',
380
+ :jurisdiction_code => 'ie',
381
+ # allow empty arrays
382
+ :officers => []
383
+ }
384
+ ]
385
+ valid_company_params.each do |valid_params|
386
+ errors = validate_datum_and_return_errors(valid_params)
387
+ errors.should be_empty, "Valid params were not valid: #{valid_params}"
388
+ end
389
+ end
390
+
391
+ it "should not validate if officers are not valid" do
392
+ invalid_company_params =
393
+ [
394
+ { :name => 'Foo Inc',
395
+ :company_number => '12345',
396
+ :jurisdiction_code => 'ie',
397
+ :officers => [{:name => ''}]
398
+ },
399
+ { :name => 'Foo Inc',
400
+ :company_number => '12345',
401
+ :jurisdiction_code => 'ie',
402
+ :officers => [{:position => 'Director'}]
403
+ },
404
+ { :name => 'Foo Inc',
405
+ :company_number => '12345',
406
+ :jurisdiction_code => 'ie',
407
+ :officers => 'some body'
408
+ },
409
+ { :name => 'Foo Inc',
410
+ :company_number => '12345',
411
+ :jurisdiction_code => 'ie',
412
+ :officers => [{:name => 'Fred', :other_attributes => 'non object'}]
413
+ },
414
+ { :name => 'Foo Inc',
415
+ :company_number => '12345',
416
+ :jurisdiction_code => 'ie',
417
+ :officers => ['some body']
418
+ }
419
+ ]
420
+ invalid_company_params.each do |invalid_params|
421
+ errors = validate_datum_and_return_errors(invalid_params)
422
+ errors.should_not be_empty, "Invalid params were not invalid: #{invalid_params}"
423
+ end
424
+ end
425
+ end
426
+
427
+ context "and company has filings" do
428
+ it "should validate if filings are valid" do
429
+ valid_company_params =
430
+ [
431
+ { :name => 'Foo Inc',
432
+ :company_number => '12345',
433
+ :jurisdiction_code => 'ie',
434
+ :filings => [ {:title => 'Annual Report', :date => '2010-11-22'},
435
+ {:description => 'Another type of filing', :date => '2010-11-22'},
436
+ {:title => 'Annual Report', :description => 'Another type of filing', :uid => '12345A321', :date => '2010-11-22'},
437
+ {:filing_type_name => 'Some type', :date => '2010-11-22'}]
438
+ },
439
+ { :name => 'Foo Inc',
440
+ :company_number => '12345',
441
+ :jurisdiction_code => 'ie',
442
+ :filings => [ {:title => 'Annual Report', :date => '2010-11-22', :other_attributes => {:foo => 'bar'}},
443
+ {:filing_type_name => 'Some type', :filing_type_code => '10-K', :date => '2010-11-22'}]
444
+ },
445
+ { :name => 'Foo Inc',
446
+ :company_number => '12345',
447
+ :jurisdiction_code => 'ie',
448
+ # allow empty arrays
449
+ :filings => []
450
+ }
451
+ ]
452
+ valid_company_params.each do |valid_params|
453
+ errors = validate_datum_and_return_errors(valid_params)
454
+ errors.should be_empty, "Valid params were not valid: #{valid_params}.Errors = #{errors}"
455
+ end
456
+ end
457
+
458
+ it "should not validate if filings are not valid" do
459
+ invalid_company_params =
460
+ [
461
+ { :name => 'Foo Inc',
462
+ :company_number => '12345',
463
+ :jurisdiction_code => 'ie',
464
+ :filings => [ {:filing_type_name => 'Some type'}]
465
+ },
466
+ { :name => 'Foo Inc',
467
+ :company_number => '12345',
468
+ :jurisdiction_code => 'ie',
469
+ :filings => 'foo filing'
470
+ },
471
+ { :name => 'Foo Inc',
472
+ :company_number => '12345',
473
+ :jurisdiction_code => 'ie',
474
+ :filings => ['foo filing']
475
+ }
476
+ ]
477
+ invalid_company_params.each do |invalid_params|
478
+ errors = validate_datum_and_return_errors(invalid_params)
479
+ errors.should_not be_empty, "Invalid params were not invalid: #{invalid_params}"
480
+ end
481
+ end
482
+
483
+ it "should require either title or description or filing_type_name to be present" do
484
+ valid_company_params =
485
+ [
486
+ { :name => 'Foo Inc',
487
+ :company_number => '12345',
488
+ :jurisdiction_code => 'ie',
489
+ :filings => [ {:filing_type_name => 'Some type', :date => '2010-11-22'}]
490
+ },
491
+ { :name => 'Foo Inc',
492
+ :company_number => '12345',
493
+ :jurisdiction_code => 'ie',
494
+ :filings => [ {:description => 'Some type', :date => '2010-11-22'}]
495
+ },
496
+ { :name => 'Foo Inc',
497
+ :company_number => '12345',
498
+ :jurisdiction_code => 'ie',
499
+ :filings => [ {:title => 'Some type', :date => '2010-11-22'}]
500
+ }
501
+ ]
502
+ invalid_params =
503
+ { :name => 'Foo Inc',
504
+ :company_number => '12345',
505
+ :jurisdiction_code => 'ie',
506
+ :filings => [ {:uid => '12345', :date => '2010-11-22'}]
507
+ }
508
+ valid_company_params.each do |valid_params|
509
+ errors = validate_datum_and_return_errors(valid_params)
510
+ errors.should be_empty, "Valid params were not valid: #{valid_params}.Errors = #{errors}"
511
+ end
512
+
513
+ validate_datum_and_return_errors(invalid_params).should_not be_empty
514
+ end
515
+ end
516
+
517
+ context "and company has share_parcels" do
518
+ it "should validate if share_parcels are valid" do
519
+ valid_company_params =
520
+ [
521
+ { :name => 'Foo Inc',
522
+ :company_number => '12345',
523
+ :jurisdiction_code => 'ie',
524
+ :share_parcels =>
525
+ [ { :number_of_shares => 1234,
526
+ :shareholders => [ {:name => 'Fred Flintstone'} ],
527
+ :confidence => 42
528
+ },
529
+ { :percentage_of_shares => 23.5,
530
+ :shareholders => [ {:name => 'Barney Rubble'},
531
+ {:name => 'Wilma Flintstone'} ]
532
+ },
533
+ ]
534
+ },
535
+ { :name => 'Foo Inc',
536
+ :company_number => '12345',
537
+ :jurisdiction_code => 'ie',
538
+ # allow empty arrays
539
+ :share_parcels => []
540
+ }
541
+ ]
542
+ valid_company_params.each do |valid_params|
543
+ errors = validate_datum_and_return_errors(valid_params)
544
+ errors.should be_empty, "Valid params were not valid: #{valid_params}.Errors = #{errors}"
545
+ end
546
+ end
547
+
548
+ it "should not validate if share_parcels are not valid" do
549
+ invalid_company_params =
550
+ [
551
+ { :name => 'Foo Inc',
552
+ :company_number => '12345',
553
+ :jurisdiction_code => 'ie',
554
+ :share_parcels =>
555
+ [{ :percentage_of_shares => '23.5',
556
+ :shareholders => [ {:name => ''} ]}]
557
+ },
558
+ { :name => 'Foo Inc',
559
+ :company_number => '12345',
560
+ :jurisdiction_code => 'ie',
561
+ :share_parcels =>
562
+ [{ :percentage_of_shares => '23.5',
563
+ :shareholders => []}]
564
+ },
565
+ { :name => 'Foo Inc',
566
+ :company_number => '12345',
567
+ :jurisdiction_code => 'ie',
568
+ :share_parcels =>
569
+ [{ :percentage_of_shares => '23.5'}]
570
+ },
571
+ { :name => 'Foo Inc',
572
+ :company_number => '12345',
573
+ :jurisdiction_code => 'ie',
574
+ :share_parcels => 'foo filing'
575
+ },
576
+ { :name => 'Foo Inc',
577
+ :company_number => '12345',
578
+ :jurisdiction_code => 'ie',
579
+ :share_parcels => ['foo filing']
580
+ }
581
+ ]
582
+ invalid_company_params.each do |invalid_params|
583
+ errors = validate_datum_and_return_errors(invalid_params)
584
+ errors.should_not be_empty, "Invalid params were not invalid: #{invalid_params}"
585
+ end
586
+ end
587
+ end
588
+
589
+ context "and company has total_shares" do
590
+ it "should validate if total_shares are valid" do
591
+ valid_company_params =
592
+ [
593
+ { :name => 'Foo Inc',
594
+ :company_number => '12345',
595
+ :jurisdiction_code => 'ie',
596
+ :total_shares =>
597
+ { :number => 123,
598
+ :share_class => 'Ordinary' }
599
+ },
600
+ { :name => 'Foo Inc',
601
+ :company_number => '12345',
602
+ :jurisdiction_code => 'ie',
603
+ :total_shares =>
604
+ { :number => 123 }
605
+ }
606
+ ]
607
+ valid_company_params.each do |valid_params|
608
+ errors = validate_datum_and_return_errors(valid_params)
609
+ errors.should be_empty, "Valid params were not valid: #{valid_params}.Errors = #{errors}"
610
+ end
611
+ end
612
+
613
+ it "should not validate if share_parcels are not valid" do
614
+ invalid_company_params =
615
+ [
616
+ { :name => 'Foo Inc',
617
+ :company_number => '12345',
618
+ :jurisdiction_code => 'ie',
619
+ :total_shares =>
620
+ { :share_class => 'Ordinary' }
621
+ },
622
+ { :name => 'Foo Inc',
623
+ :company_number => '12345',
624
+ :jurisdiction_code => 'ie',
625
+ :total_shares =>
626
+ { :number => 123,
627
+ :share_class => '' }
628
+ },
629
+ { :name => 'Foo Inc',
630
+ :company_number => '12345',
631
+ :jurisdiction_code => 'ie',
632
+ :total_shares => 'foo filing'
633
+ },
634
+ { :name => 'Foo Inc',
635
+ :company_number => '12345',
636
+ :jurisdiction_code => 'ie',
637
+ :total_shares => ['foo filing']
638
+ }
639
+ ]
640
+ invalid_company_params.each do |invalid_params|
641
+ errors = validate_datum_and_return_errors(invalid_params)
642
+ errors.should_not be_empty, "Invalid params were not invalid: #{invalid_params}"
643
+ end
644
+ end
645
+ end
646
+
647
+ def validate_datum_and_return_errors(record)
648
+ errors = JSON::Validator.fully_validate(
649
+ @schema,
650
+ record.to_json,
651
+ {:errors_as_objects => true})
652
+ end
653
+
654
+ def require_all_attributes_attribute_to_be_string_or_nil(attribute_name)
655
+ ['Some String', nil].each do |val|
656
+ valid_params =
657
+ { :name => 'Foo Inc',
658
+ :company_number => '12345',
659
+ :jurisdiction_code => 'ie',
660
+ :all_attributes => {attribute_name => val}
661
+ }
662
+ validate_datum_and_return_errors(valid_params).should be_empty, "Valid params were not validated: #{valid_params}"
663
+ end
664
+
665
+ ['', 43].each do |val|
666
+ invalid_params =
667
+ { :name => 'Foo Inc',
668
+ :company_number => '12345',
669
+ :jurisdiction_code => 'ie',
670
+ :all_attributes => {attribute_name => val}
671
+ }
672
+ validate_datum_and_return_errors(invalid_params).should_not be_empty, "Invalid params were validated: #{invalid_params}"
673
+ end
674
+ end
675
+
676
+ end