bell 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.
- data/.gitignore +5 -0
- data/.rvmrc +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +47 -0
- data/MIT-LICENSE +20 -0
- data/README.org +128 -0
- data/Rakefile +16 -0
- data/bell.gemspec +30 -0
- data/bin/bell +5 -0
- data/features/create_user.feature +16 -0
- data/features/full_report.feature +84 -0
- data/features/import_public_contacts.feature +20 -0
- data/features/import_user_contacts.feature +43 -0
- data/features/list_all_contacts.feature +19 -0
- data/features/list_user_contacts.feature +27 -0
- data/features/list_users.feature +22 -0
- data/features/remove_user.feature +21 -0
- data/features/rename_user.feature +25 -0
- data/features/step_definitions/cli_steps.rb +59 -0
- data/features/step_definitions/contact_steps.rb +104 -0
- data/features/step_definitions/database_steps.rb +3 -0
- data/features/step_definitions/report_steps.rb +17 -0
- data/features/step_definitions/user_steps.rb +71 -0
- data/features/support/env.rb +65 -0
- data/features/user_report.feature +67 -0
- data/lib/bell/cli.rb +12 -0
- data/lib/bell/commands/command.rb +58 -0
- data/lib/bell/commands/contact_command.rb +91 -0
- data/lib/bell/commands/implosion_command.rb +14 -0
- data/lib/bell/commands/report_command.rb +69 -0
- data/lib/bell/commands/user_command.rb +74 -0
- data/lib/bell/commands.rb +5 -0
- data/lib/bell/csv_parser.rb +52 -0
- data/lib/bell/dispatcher.rb +13 -0
- data/lib/bell/displayable.rb +13 -0
- data/lib/bell/full_report.rb +145 -0
- data/lib/bell/handlers/contacts_handler.rb +79 -0
- data/lib/bell/handlers/implosions_handler.rb +9 -0
- data/lib/bell/handlers/reports_handler.rb +41 -0
- data/lib/bell/handlers/users_handler.rb +50 -0
- data/lib/bell/handlers.rb +4 -0
- data/lib/bell/message.rb +115 -0
- data/lib/bell/public_contact.rb +17 -0
- data/lib/bell/user.rb +16 -0
- data/lib/bell/user_contact.rb +18 -0
- data/lib/bell/user_report.rb +88 -0
- data/lib/bell/util.rb +31 -0
- data/lib/bell.rb +157 -0
- data/spec/bell/cli_spec.rb +4 -0
- data/spec/bell/commands/command_spec.rb +59 -0
- data/spec/bell/commands/contact_command_spec.rb +112 -0
- data/spec/bell/commands/implosion_command_spec.rb +31 -0
- data/spec/bell/commands/report_command_spec.rb +71 -0
- data/spec/bell/commands/user_command_spec.rb +128 -0
- data/spec/bell/csv_parser_spec.rb +167 -0
- data/spec/bell/dispatcher_spec.rb +4 -0
- data/spec/bell/full_report_spec.rb +4 -0
- data/spec/bell/handlers/contacts_handler_spec.rb +160 -0
- data/spec/bell/handlers/implosions_handler_spec.rb +11 -0
- data/spec/bell/handlers/reports_handler_spec.rb +183 -0
- data/spec/bell/handlers/users_handler_spec.rb +94 -0
- data/spec/bell/public_contact_spec.rb +4 -0
- data/spec/bell/user_contact_spec.rb +4 -0
- data/spec/bell/user_report_spec.rb +4 -0
- data/spec/bell/user_spec.rb +4 -0
- data/spec/spec_helper.rb +21 -0
- metadata +230 -0
@@ -0,0 +1,167 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) << '/../spec_helper')
|
2
|
+
|
3
|
+
describe Bell::CSVParser do
|
4
|
+
describe ".parse_contacts" do
|
5
|
+
let(:options) { { :path => '/path/to/contacts.csv',
|
6
|
+
:user => { :name => 'foo' } } }
|
7
|
+
let(:described_module) { Bell::CSVParser }
|
8
|
+
|
9
|
+
context "when given a path to a non-existing file or directory" do
|
10
|
+
let(:no_such_file_or_directory_message) do
|
11
|
+
Bell::Message.no_such_file_or_directory(options[:path])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "shows the 'no such file or directory' message" do
|
15
|
+
Bell::CSV.stub!(:read).and_raise(Errno::ENOENT)
|
16
|
+
described_module.
|
17
|
+
should_receive(:display).
|
18
|
+
with(no_such_file_or_directory_message)
|
19
|
+
described_module.parse_contacts(options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when given a path to a directory" do
|
24
|
+
let(:path_is_a_directory_message) do
|
25
|
+
Bell::Message.path_is_a_directory(options[:path])
|
26
|
+
end
|
27
|
+
|
28
|
+
it "shows the 'path is a directory' message" do
|
29
|
+
Bell::CSV.stub!(:read).and_raise(Errno::EISDIR)
|
30
|
+
described_module.
|
31
|
+
should_receive(:display).
|
32
|
+
with(path_is_a_directory_message)
|
33
|
+
described_module.parse_contacts(options)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when given a path to a malformed csv file" do
|
38
|
+
let(:invalid_contacts_file_message) do
|
39
|
+
Bell::Message.invalid_contacts_file(options[:path])
|
40
|
+
end
|
41
|
+
|
42
|
+
it "shows the 'invalid contacts file' message" do
|
43
|
+
Bell::CSV.stub!(:read).and_raise(Bell::CSV::MalformedCSVError)
|
44
|
+
described_module.
|
45
|
+
should_receive(:display).
|
46
|
+
with(invalid_contacts_file_message)
|
47
|
+
described_module.parse_contacts(options)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when given a csv file with invalid rows" do
|
52
|
+
let(:user) { mock(Bell::User, :null_object => true) }
|
53
|
+
|
54
|
+
before do
|
55
|
+
described_module.stub!(:raise).with(Bell::InvalidContacts)
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when there's a row with less than two columns" do
|
59
|
+
let(:first_row) { ['bob', '9876987698'] }
|
60
|
+
let(:second_row) { ['kennedy'] }
|
61
|
+
let(:row_with_few_columns_message) do
|
62
|
+
Bell::Message.row_with_few_columns(second_row, 2)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "shows the 'row with few columns' message" do
|
66
|
+
Bell::CSV.stub!(:read).and_return([first_row, second_row])
|
67
|
+
Bell::User.stub!(:find).and_return(user)
|
68
|
+
described_module.
|
69
|
+
should_receive(:display).
|
70
|
+
with(row_with_few_columns_message)
|
71
|
+
described_module.parse_contacts(options)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when there's a row with more than two columns" do
|
76
|
+
let(:first_row) { ["1234123412", "john", "kennedy"] }
|
77
|
+
let(:second_row) { ["bob", "9876987698"] }
|
78
|
+
let(:row_with_extra_columns_message) do
|
79
|
+
Bell::Message.row_with_extra_columns(first_row, 1)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "shows the 'row with extra columns' message" do
|
83
|
+
Bell::CSV.stub!(:read).and_return([first_row, second_row])
|
84
|
+
Bell::User.stub!(:find).and_return(user)
|
85
|
+
described_module.
|
86
|
+
should_receive(:display).
|
87
|
+
with(row_with_extra_columns_message)
|
88
|
+
described_module.parse_contacts(options)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when given a valid csv file" do
|
94
|
+
let(:user) { mock(Bell::User, :null_object => true) }
|
95
|
+
|
96
|
+
before do
|
97
|
+
described_module.stub!(:raise).with(Bell::InvalidContacts)
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when there's a row with a short contact number" do
|
101
|
+
let(:first_row) { ["john", "1234123412"] }
|
102
|
+
let(:second_row) { ["bob", "987698769"] }
|
103
|
+
let(:contact) { Bell::UserContact.new(:name => second_row.first,
|
104
|
+
:number => second_row.last,
|
105
|
+
:user_id => user.id) }
|
106
|
+
let(:formatted_contact_errors_message) do
|
107
|
+
Bell::Message.formatted_contact_errors(contact, :line_number => 2)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "shows the contact's errors" do
|
111
|
+
Bell::CSV.stub!(:read).and_return([first_row, second_row])
|
112
|
+
Bell::User.stub!(:find).and_return(user)
|
113
|
+
contact.valid?
|
114
|
+
described_module.
|
115
|
+
should_receive(:display).
|
116
|
+
with(formatted_contact_errors_message)
|
117
|
+
described_module.parse_contacts(options)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when there's a row with a long contact number" do
|
122
|
+
let(:first_row) { ["bob", "98769876989"] }
|
123
|
+
let(:second_row) { ["john", "1234123412"] }
|
124
|
+
let(:contact) { Bell::UserContact.new(:name => first_row.first,
|
125
|
+
:number => first_row.last,
|
126
|
+
:user_id => user.id) }
|
127
|
+
let(:formatted_contact_errors_message) do
|
128
|
+
Bell::Message.formatted_contact_errors(contact, :line_number => 1)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "shows the contact's errors" do
|
132
|
+
Bell::CSV.stub!(:read).and_return([first_row, second_row])
|
133
|
+
Bell::User.stub!(:find).and_return(user)
|
134
|
+
contact.valid?
|
135
|
+
described_module.
|
136
|
+
should_receive(:display).
|
137
|
+
with(formatted_contact_errors_message)
|
138
|
+
described_module.parse_contacts(options)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "with empty rows" do
|
143
|
+
it "returns nil" do
|
144
|
+
Bell::CSV.stub!(:read).and_return([])
|
145
|
+
described_module.parse_contacts(options).should be_nil
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "with valid rows" do
|
150
|
+
let(:first_row) { ["john", "1234123412"] }
|
151
|
+
let(:second_row) { ["bob", "9876987698"] }
|
152
|
+
let(:first_contact) { Bell::UserContact.new(:name => first_row.first,
|
153
|
+
:number => first_row.last,
|
154
|
+
:user_id => user.id) }
|
155
|
+
let(:second_contact) { Bell::UserContact.new(:name => second_row.first,
|
156
|
+
:number => second_row.last,
|
157
|
+
:user_id => user.id) }
|
158
|
+
it "returns an array with the contact instances" do
|
159
|
+
Bell::CSV.stub!(:read).and_return([first_row, second_row])
|
160
|
+
Bell::User.stub!(:find).and_return(user)
|
161
|
+
described_module.parse_contacts(options).
|
162
|
+
should == [first_contact, second_contact]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) << '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Bell::Handlers::ContactsHandler do
|
4
|
+
let(:params) { mock("params").as_null_object }
|
5
|
+
let(:formatted_contact_list) { mock("formatted_contact_list") }
|
6
|
+
let(:user) do
|
7
|
+
mock(Bell::User, :id => 1,
|
8
|
+
:null_object => true,
|
9
|
+
:contacts => mock("contacts"))
|
10
|
+
end
|
11
|
+
let(:contact) { mock(Bell::UserContact).as_null_object }
|
12
|
+
let(:contacts_handler) { described_class }
|
13
|
+
let(:no_contacts_created_message) { Bell::Message.no_contacts_created }
|
14
|
+
|
15
|
+
describe ".list" do
|
16
|
+
context "called without extra arguments" do
|
17
|
+
context "there are no contacts created" do
|
18
|
+
|
19
|
+
it "shows the 'no contacts created' message" do
|
20
|
+
params.stub!(:empty?).and_return(true)
|
21
|
+
Bell::UserContact.stub!(:empty?).and_return(true)
|
22
|
+
contacts_handler.should_receive(:display).with(no_contacts_created_message)
|
23
|
+
contacts_handler.list
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "there are contacts created" do
|
28
|
+
it "shows a list with all contacts" do
|
29
|
+
params.stub!(:empty?).and_return(true)
|
30
|
+
Bell::UserContact.stub!(:empty?).and_return(false)
|
31
|
+
contacts_handler.should_receive(:formatted_contact_list).
|
32
|
+
and_return(formatted_contact_list)
|
33
|
+
contacts_handler.should_receive(:display).with(formatted_contact_list)
|
34
|
+
contacts_handler.list
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "called with a user name" do
|
40
|
+
context "when a user with the given doesn't exist" do
|
41
|
+
let(:user_does_not_exist_message) do
|
42
|
+
Bell::Message.user_does_not_exist(params[:user][:name])
|
43
|
+
end
|
44
|
+
|
45
|
+
it "shows the 'user does not exist' message" do
|
46
|
+
params.stub!(:empty?).and_return(false)
|
47
|
+
Bell::User.stub!(:find).and_return(false)
|
48
|
+
contacts_handler.should_receive(:display).with(user_does_not_exist_message)
|
49
|
+
contacts_handler.list(params)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when the given user exists" do
|
54
|
+
before do
|
55
|
+
params.stub!(:empty?).and_return(false)
|
56
|
+
Bell::User.stub!(:find).and_return(user)
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when doesn't have contacts" do
|
60
|
+
let(:contact_list_empty_message) do
|
61
|
+
Bell::Message.contact_list_empty(user.name)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "shows the 'contact list empty' message" do
|
65
|
+
user.stub_chain(:contacts, :empty?).and_return(true)
|
66
|
+
contacts_handler.should_receive(:display).with(contact_list_empty_message)
|
67
|
+
contacts_handler.list(params)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when it has contacts" do
|
72
|
+
it "shows a list with all the users' contacts" do
|
73
|
+
user.stub_chain(:contacts, :empty?).and_return(false)
|
74
|
+
contacts_handler.should_receive(:formatted_contact_list).
|
75
|
+
and_return(formatted_contact_list)
|
76
|
+
contacts_handler.should_receive(:display).with(formatted_contact_list)
|
77
|
+
contacts_handler.list(params)
|
78
|
+
end
|
79
|
+
|
80
|
+
context "when asked for the CSV format" do
|
81
|
+
let(:contacts) { mock("contacts", :empty? => false) }
|
82
|
+
let(:user) { mock(Bell::User, :name => 'bob', :contacts => contacts) }
|
83
|
+
let(:params) { { :user => { :name => user.name }, :csv => true } }
|
84
|
+
|
85
|
+
it "shows a list with all the users' contacts" do
|
86
|
+
contacts_handler.should_receive(:formatted_contact_list).
|
87
|
+
with(user.contacts, :user_contacts => true, :csv => true).
|
88
|
+
and_return(formatted_contact_list)
|
89
|
+
contacts_handler.should_receive(:display).
|
90
|
+
with(formatted_contact_list)
|
91
|
+
contacts_handler.list(params)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe ".import" do
|
100
|
+
context "when requesting a user contact import" do
|
101
|
+
let(:params) { { :user => { :name => 'foo' } } }
|
102
|
+
|
103
|
+
context "when the given user exists" do
|
104
|
+
let(:contacts) { [mock(Bell::User), mock(Bell::User) ]}
|
105
|
+
|
106
|
+
context "when the CSVParser returns contacts" do
|
107
|
+
it "saves them" do
|
108
|
+
Bell::User.stub!(:find).and_return(user)
|
109
|
+
Bell::CSVParser.stub!(:parse_contacts).and_return(contacts)
|
110
|
+
contacts.each { |contact| contact.should_receive(:save) }
|
111
|
+
described_class.import(params)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when CSVParser raises InvalidContacts" do
|
116
|
+
it "shows the 'no contacts created' message" do
|
117
|
+
Bell::User.stub!(:find).and_return(user)
|
118
|
+
Bell::CSVParser.stub!(:parse_contacts).and_raise(Bell::InvalidContacts)
|
119
|
+
described_class.should_receive(:display).with(no_contacts_created_message)
|
120
|
+
described_class.import(params)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "when the given user doesn't exist" do
|
126
|
+
let(:user_does_not_exist_message) { mock('user_does_not_exist_message') }
|
127
|
+
|
128
|
+
it "shows the 'user does not exist' message" do
|
129
|
+
Bell::User.stub!(:find).and_return(nil)
|
130
|
+
Bell::Message.
|
131
|
+
should_receive(:user_does_not_exist).
|
132
|
+
and_return(user_does_not_exist_message)
|
133
|
+
described_class.import(params)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "when requesting a public contact import" do
|
139
|
+
let(:params) { { :path => '/path/to/public_contacts.csv',
|
140
|
+
:public => true } }
|
141
|
+
let(:contacts) { [mock(Bell::User), mock(Bell::User) ]}
|
142
|
+
|
143
|
+
context "when the CSVParser returns contacts" do
|
144
|
+
it "saves them" do
|
145
|
+
Bell::CSVParser.stub!(:parse_contacts).and_return(contacts)
|
146
|
+
contacts.each { |contact| contact.should_receive(:save) }
|
147
|
+
described_class.import(params)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "when CSVParser returns raises InvalidContacts" do
|
152
|
+
it "shows the 'no contacts created' message" do
|
153
|
+
Bell::CSVParser.stub!(:parse_contacts).and_raise(Bell::InvalidContacts)
|
154
|
+
described_class.should_receive(:display).with(no_contacts_created_message)
|
155
|
+
described_class.import(params)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) << '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Bell::Handlers::ImplosionsHandler do
|
4
|
+
let(:params) { mock("params").as_null_object }
|
5
|
+
let(:implosions_handler) { described_class }
|
6
|
+
|
7
|
+
it "implodes the current bell databases" do
|
8
|
+
Bell.should_receive(:implode!)
|
9
|
+
implosions_handler.implode(params)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) << '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Bell::Handlers::ReportsHandler do
|
4
|
+
let(:no_such_file_or_directory_message) { mock("no_such_file_or_directory_message") }
|
5
|
+
let(:path_is_a_directory_message) { mock("path_is_a_directory_message") }
|
6
|
+
let(:non_csv_file_message) { mock("non_csv_file_message") }
|
7
|
+
let(:malformed_csv_message) { mock("malformed_csv_message") }
|
8
|
+
let(:invalid_rows_message) { mock("invalid_rows_message") }
|
9
|
+
let(:invalid_rows_exception_message) { 'Erro nas linhas 3, 4' }
|
10
|
+
let(:invalid_rows_exception) { Embratel::InvalidRowsError.new(invalid_rows_exception_message) }
|
11
|
+
let(:phone_bill) { mock(Embratel::PhoneBill) }
|
12
|
+
|
13
|
+
describe ".full_report" do
|
14
|
+
let(:params) { { :path => 'fatura.csv' } }
|
15
|
+
|
16
|
+
context "when given a path to a non-existing file or directory" do
|
17
|
+
it "shows the 'no such file or directory' message" do
|
18
|
+
Embratel::PhoneBill.stub!(:new).and_raise(Errno::ENOENT)
|
19
|
+
Bell::Message.should_receive(:no_such_file_or_directory).
|
20
|
+
with(params[:path]).
|
21
|
+
and_return(no_such_file_or_directory_message)
|
22
|
+
described_class.should_receive(:display).
|
23
|
+
with(no_such_file_or_directory_message)
|
24
|
+
described_class.full_report(params)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when given a path to a directory" do
|
29
|
+
it "shows the 'path is a directory' message" do
|
30
|
+
Embratel::PhoneBill.stub!(:new).and_raise(Errno::EISDIR)
|
31
|
+
Bell::Message.should_receive(:path_is_a_directory).
|
32
|
+
with(params[:path]).
|
33
|
+
and_return(path_is_a_directory_message)
|
34
|
+
described_class.should_receive(:display).
|
35
|
+
with(path_is_a_directory_message)
|
36
|
+
described_class.full_report(params)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when given a path to a malformed CSV file" do
|
41
|
+
it "shows the 'invalid phone bill file' message" do
|
42
|
+
Embratel::PhoneBill.stub!(:new).and_raise(Bell::CSV::MalformedCSVError)
|
43
|
+
Bell::Message.should_receive(:malformed_csv_file).
|
44
|
+
with(params[:path]).
|
45
|
+
and_return(malformed_csv_message)
|
46
|
+
described_class.should_receive(:display).
|
47
|
+
with(malformed_csv_message)
|
48
|
+
described_class.full_report(params)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when given a path to a non CSV file" do
|
53
|
+
it "shows the 'non csv file' message" do
|
54
|
+
Embratel::PhoneBill.stub!(:new).and_raise(Embratel::NonCSVFileError)
|
55
|
+
Bell::Message.should_receive(:non_csv_file).
|
56
|
+
with(params[:path]).
|
57
|
+
and_return(non_csv_file_message)
|
58
|
+
described_class.should_receive(:display).with(non_csv_file_message)
|
59
|
+
described_class.full_report(params)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when given a path to a phone bill file with invalid rows" do
|
64
|
+
it "shows the 'invalid rows' message" do
|
65
|
+
Embratel::PhoneBill.stub!(:new).and_raise(invalid_rows_exception)
|
66
|
+
Bell::Message.should_receive(:invalid_rows).
|
67
|
+
with(params[:path], invalid_rows_exception_message).
|
68
|
+
and_return(invalid_rows_message)
|
69
|
+
described_class.should_receive(:display).with(invalid_rows_message)
|
70
|
+
described_class.user_report(params)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when given a path to a valid phone bill file" do
|
75
|
+
let(:report) { mock(Bell::FullReport, :to_s => mock("string")) }
|
76
|
+
|
77
|
+
it "shows the report" do
|
78
|
+
Embratel::PhoneBill.stub!(:new).and_return(phone_bill)
|
79
|
+
Bell::FullReport.should_receive(:new).with(phone_bill).and_return(report)
|
80
|
+
described_class.should_receive(:display).with(report.to_s)
|
81
|
+
described_class.full_report(params)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe ".user_report" do
|
87
|
+
let(:params) { { :path => 'fatura.csv', :user => { :name => 'bob' } } }
|
88
|
+
|
89
|
+
context "when given a path to a non-existing file or directory" do
|
90
|
+
it "shows the 'no such file or directory' message" do
|
91
|
+
Embratel::PhoneBill.stub!(:new).and_raise(Errno::ENOENT)
|
92
|
+
Bell::Message.should_receive(:no_such_file_or_directory).
|
93
|
+
with(params[:path]).
|
94
|
+
and_return(no_such_file_or_directory_message)
|
95
|
+
described_class.should_receive(:display).
|
96
|
+
with(no_such_file_or_directory_message)
|
97
|
+
described_class.user_report(params)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when given a path to a directory" do
|
102
|
+
it "shows the 'path is a directory' message" do
|
103
|
+
Embratel::PhoneBill.stub!(:new).and_raise(Errno::EISDIR)
|
104
|
+
Bell::Message.should_receive(:path_is_a_directory).
|
105
|
+
with(params[:path]).
|
106
|
+
and_return(path_is_a_directory_message)
|
107
|
+
described_class.should_receive(:display).
|
108
|
+
with(path_is_a_directory_message)
|
109
|
+
described_class.user_report(params)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when given a path to a malformed CSV file" do
|
114
|
+
it "shows the 'malformed csv file' message" do
|
115
|
+
Embratel::PhoneBill.stub!(:new).and_raise(Bell::CSV::MalformedCSVError)
|
116
|
+
Bell::Message.should_receive(:malformed_csv_file).
|
117
|
+
with(params[:path]).
|
118
|
+
and_return(malformed_csv_message)
|
119
|
+
described_class.should_receive(:display).
|
120
|
+
with(malformed_csv_message)
|
121
|
+
described_class.user_report(params)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "when given a path to a non CSV file" do
|
126
|
+
it "shows the 'non csv file' message" do
|
127
|
+
Embratel::PhoneBill.stub!(:new).and_raise(Embratel::NonCSVFileError)
|
128
|
+
Bell::Message.should_receive(:non_csv_file).
|
129
|
+
with(params[:path]).
|
130
|
+
and_return(non_csv_file_message)
|
131
|
+
described_class.should_receive(:display).with(non_csv_file_message)
|
132
|
+
described_class.user_report(params)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "when given a path to a phone bill file with invalid rows" do
|
137
|
+
it "shows the 'invalid rows' message" do
|
138
|
+
Embratel::PhoneBill.stub!(:new).and_raise(invalid_rows_exception)
|
139
|
+
Bell::Message.should_receive(:invalid_rows).
|
140
|
+
with(params[:path], invalid_rows_exception_message).
|
141
|
+
and_return(invalid_rows_message)
|
142
|
+
described_class.should_receive(:display).with(invalid_rows_message)
|
143
|
+
described_class.user_report(params)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "when given a path to a valid phone bill file" do
|
148
|
+
context "when given user exists" do
|
149
|
+
let(:user) { mock(Bell::User) }
|
150
|
+
let(:user_report) { mock(Bell::UserReport, :to_s => mock("string")) }
|
151
|
+
|
152
|
+
it "shows the report" do
|
153
|
+
Embratel::PhoneBill.stub!(:new).and_return(phone_bill)
|
154
|
+
Bell::User.stub!(:find).
|
155
|
+
with(:name => params[:user][:name]).
|
156
|
+
and_return(user)
|
157
|
+
Bell::UserReport.should_receive(:new).
|
158
|
+
with(phone_bill, params[:user][:name]).
|
159
|
+
and_return(user_report)
|
160
|
+
described_class.should_receive(:display).with(user_report.to_s)
|
161
|
+
described_class.user_report(params)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context "when given user doesn't exist" do
|
166
|
+
let(:user_does_not_exist_message) { mock("user_does_not_exist_message") }
|
167
|
+
|
168
|
+
it "shows the 'user does not exist' message" do
|
169
|
+
Embratel::PhoneBill.stub!(:new).and_return(phone_bill)
|
170
|
+
Bell::User.stub!(:find).
|
171
|
+
with(:name => params[:user][:name]).
|
172
|
+
and_return(nil)
|
173
|
+
Bell::Message.should_receive(:user_does_not_exist).
|
174
|
+
with(params[:user][:name]).
|
175
|
+
and_return(user_does_not_exist_message)
|
176
|
+
described_class.should_receive(:display).
|
177
|
+
with(user_does_not_exist_message)
|
178
|
+
described_class.user_report(params)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) << '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Bell::Handlers::UsersHandler do
|
4
|
+
let(:users_handler) { described_class }
|
5
|
+
let(:user_created_message) { Bell::Message.user_created(params[:user][:name]) }
|
6
|
+
let(:no_created_users_message) { Bell::Message.no_created_users }
|
7
|
+
let(:user_already_exists_message) do
|
8
|
+
Bell::Message.user_already_exists(params[:user][:name])
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".create" do
|
12
|
+
let(:params) { { :user => { :name => 'bob' } } }
|
13
|
+
|
14
|
+
context "when there is already a user with the given name" do
|
15
|
+
it "shows the 'user already exists' message" do
|
16
|
+
Bell::User.stub!(:find).with(:name => params[:user][:name]).and_return(true)
|
17
|
+
users_handler.should_receive(:display).with(user_already_exists_message)
|
18
|
+
users_handler.create(params)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when there are no users with the given name" do
|
23
|
+
it "creates the user" do
|
24
|
+
Bell::User.stub!(:find).and_return(false)
|
25
|
+
Bell::User.should_receive(:create).with(:name => params[:user][:name])
|
26
|
+
users_handler.create(params)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "shows the 'user created' message" do
|
30
|
+
users_handler.should_receive(:display).with(user_created_message)
|
31
|
+
users_handler.create(params)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ".list" do
|
37
|
+
let(:params) { {} }
|
38
|
+
|
39
|
+
context "when there are no created users" do
|
40
|
+
it "shows the 'no created users' message" do
|
41
|
+
Bell::User.stub!(:empty?).and_return(true)
|
42
|
+
users_handler.should_receive(:display).with(no_created_users_message)
|
43
|
+
users_handler.list(params)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when there are created users" do
|
48
|
+
let(:bob) { Bell::User.new(:name => 'bob') }
|
49
|
+
let(:john) { Bell::User.new(:name => 'john') }
|
50
|
+
|
51
|
+
it "shows the users' names" do
|
52
|
+
Bell::User.stub!(:empty?).and_return(false)
|
53
|
+
Bell::User.stub!(:all).and_return([bob, john])
|
54
|
+
users_handler.should_receive(:display).with("bob\njohn")
|
55
|
+
users_handler.list(params)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe ".remove" do
|
61
|
+
let(:params) { { :user => { :name => 'bob' } } }
|
62
|
+
|
63
|
+
context "when there are no users with the given name" do
|
64
|
+
let(:user_does_not_exist_message) do
|
65
|
+
Bell::Message.user_does_not_exist(params[:user][:name])
|
66
|
+
end
|
67
|
+
|
68
|
+
it "shows the 'user does not exist' message" do
|
69
|
+
Bell::User.stub!(:find).with(:name => params[:user][:name]).and_return(false)
|
70
|
+
users_handler.should_receive(:display).with(user_does_not_exist_message)
|
71
|
+
users_handler.remove(params)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when there is a user with the given name" do
|
76
|
+
let(:user) { mock(Bell::User, :name => 'bob').as_null_object }
|
77
|
+
let(:user_removed_message) { Bell::Message.user_removed(user.name) }
|
78
|
+
|
79
|
+
before do
|
80
|
+
Bell::User.stub!(:find).and_return(user)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "removes the user" do
|
84
|
+
user.should_receive(:destroy)
|
85
|
+
users_handler.remove(params)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "shows the 'user removed' message" do
|
89
|
+
users_handler.should_receive(:display).with(user_removed_message)
|
90
|
+
users_handler.remove(params)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
require 'bell'
|
3
|
+
require 'spec'
|
4
|
+
|
5
|
+
unless defined?(FIXTURES_PATH)
|
6
|
+
FIXTURES_PATH = File.join(File.dirname(__FILE__), 'fixtures')
|
7
|
+
end
|
8
|
+
|
9
|
+
Spec::Runner.configure do |config|
|
10
|
+
config.suppress_deprecation_warnings!
|
11
|
+
end
|
12
|
+
|
13
|
+
class Spec::Example::ExampleGroup
|
14
|
+
def execute(*args, &block)
|
15
|
+
DB.transaction do
|
16
|
+
super(*args, &block)
|
17
|
+
raise Sequel::Error::Rollback
|
18
|
+
end
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|