openc_bot 0.0.11

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 (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