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.
Files changed (67) hide show
  1. data/.gitignore +5 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +47 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.org +128 -0
  7. data/Rakefile +16 -0
  8. data/bell.gemspec +30 -0
  9. data/bin/bell +5 -0
  10. data/features/create_user.feature +16 -0
  11. data/features/full_report.feature +84 -0
  12. data/features/import_public_contacts.feature +20 -0
  13. data/features/import_user_contacts.feature +43 -0
  14. data/features/list_all_contacts.feature +19 -0
  15. data/features/list_user_contacts.feature +27 -0
  16. data/features/list_users.feature +22 -0
  17. data/features/remove_user.feature +21 -0
  18. data/features/rename_user.feature +25 -0
  19. data/features/step_definitions/cli_steps.rb +59 -0
  20. data/features/step_definitions/contact_steps.rb +104 -0
  21. data/features/step_definitions/database_steps.rb +3 -0
  22. data/features/step_definitions/report_steps.rb +17 -0
  23. data/features/step_definitions/user_steps.rb +71 -0
  24. data/features/support/env.rb +65 -0
  25. data/features/user_report.feature +67 -0
  26. data/lib/bell/cli.rb +12 -0
  27. data/lib/bell/commands/command.rb +58 -0
  28. data/lib/bell/commands/contact_command.rb +91 -0
  29. data/lib/bell/commands/implosion_command.rb +14 -0
  30. data/lib/bell/commands/report_command.rb +69 -0
  31. data/lib/bell/commands/user_command.rb +74 -0
  32. data/lib/bell/commands.rb +5 -0
  33. data/lib/bell/csv_parser.rb +52 -0
  34. data/lib/bell/dispatcher.rb +13 -0
  35. data/lib/bell/displayable.rb +13 -0
  36. data/lib/bell/full_report.rb +145 -0
  37. data/lib/bell/handlers/contacts_handler.rb +79 -0
  38. data/lib/bell/handlers/implosions_handler.rb +9 -0
  39. data/lib/bell/handlers/reports_handler.rb +41 -0
  40. data/lib/bell/handlers/users_handler.rb +50 -0
  41. data/lib/bell/handlers.rb +4 -0
  42. data/lib/bell/message.rb +115 -0
  43. data/lib/bell/public_contact.rb +17 -0
  44. data/lib/bell/user.rb +16 -0
  45. data/lib/bell/user_contact.rb +18 -0
  46. data/lib/bell/user_report.rb +88 -0
  47. data/lib/bell/util.rb +31 -0
  48. data/lib/bell.rb +157 -0
  49. data/spec/bell/cli_spec.rb +4 -0
  50. data/spec/bell/commands/command_spec.rb +59 -0
  51. data/spec/bell/commands/contact_command_spec.rb +112 -0
  52. data/spec/bell/commands/implosion_command_spec.rb +31 -0
  53. data/spec/bell/commands/report_command_spec.rb +71 -0
  54. data/spec/bell/commands/user_command_spec.rb +128 -0
  55. data/spec/bell/csv_parser_spec.rb +167 -0
  56. data/spec/bell/dispatcher_spec.rb +4 -0
  57. data/spec/bell/full_report_spec.rb +4 -0
  58. data/spec/bell/handlers/contacts_handler_spec.rb +160 -0
  59. data/spec/bell/handlers/implosions_handler_spec.rb +11 -0
  60. data/spec/bell/handlers/reports_handler_spec.rb +183 -0
  61. data/spec/bell/handlers/users_handler_spec.rb +94 -0
  62. data/spec/bell/public_contact_spec.rb +4 -0
  63. data/spec/bell/user_contact_spec.rb +4 -0
  64. data/spec/bell/user_report_spec.rb +4 -0
  65. data/spec/bell/user_spec.rb +4 -0
  66. data/spec/spec_helper.rb +21 -0
  67. 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,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) << '/../spec_helper')
2
+
3
+ describe Bell::Dispatcher do
4
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) << '/../spec_helper')
2
+
3
+ describe Bell::FullReport do
4
+ 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
@@ -0,0 +1,4 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe Bell::PublicContact do
4
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) << '/../spec_helper')
2
+
3
+ describe Bell::UserContact do
4
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) << '/../spec_helper')
2
+
3
+ describe Bell::UserReport do
4
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.dirname(__FILE__) << '/../spec_helper')
2
+
3
+ describe Bell::User do
4
+ end
@@ -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