voicemail 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +26 -0
- data/.rspec +3 -0
- data/Gemfile +3 -0
- data/Guardfile +5 -0
- data/LICENSE +20 -0
- data/README.md +62 -0
- data/Rakefile +11 -0
- data/lib/voicemail/application_controller.rb +27 -0
- data/lib/voicemail/mailbox_controller.rb +56 -0
- data/lib/voicemail/mailbox_main_menu_controller.rb +41 -0
- data/lib/voicemail/mailbox_messages_controller.rb +55 -0
- data/lib/voicemail/mailbox_play_message_controller.rb +69 -0
- data/lib/voicemail/mailbox_set_greeting_controller.rb +75 -0
- data/lib/voicemail/mailbox_set_pin_controller.rb +45 -0
- data/lib/voicemail/plugin.rb +86 -0
- data/lib/voicemail/storage.rb +7 -0
- data/lib/voicemail/storage_pstore.rb +93 -0
- data/lib/voicemail/version.rb +3 -0
- data/lib/voicemail/voicemail_controller.rb +32 -0
- data/lib/voicemail.rb +14 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/voicemail_controller_spec_helper.rb +39 -0
- data/spec/voicemail/mailbox_controller_spec.rb +79 -0
- data/spec/voicemail/mailbox_main_menu_controller_spec.rb +35 -0
- data/spec/voicemail/mailbox_messages_controller_spec.rb +71 -0
- data/spec/voicemail/mailbox_play_message_controller_spec.rb +70 -0
- data/spec/voicemail/mailbox_set_greeting_controller_spec.rb +61 -0
- data/spec/voicemail/mailbox_set_pin_controller_spec.rb +53 -0
- data/spec/voicemail/storage_pstore_spec.rb +45 -0
- data/spec/voicemail/storage_spec.rb +13 -0
- data/spec/voicemail/voicemail_controller_spec.rb +65 -0
- data/tmp/.gitignore +2 -0
- data/voicemail.gemspec +29 -0
- metadata +200 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'pstore'
|
2
|
+
|
3
|
+
module Voicemail
|
4
|
+
class StoragePstore
|
5
|
+
attr_accessor :store
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@store = PStore.new config.storage.pstore_location
|
9
|
+
setup_schema
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_mailbox(mailbox_id)
|
13
|
+
store.transaction true do
|
14
|
+
store[:mailboxes][mailbox_id]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def count_new_messages(mailbox_id)
|
19
|
+
store.transaction true do
|
20
|
+
store[:recordings][mailbox_id].size
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def next_new_message(mailbox_id)
|
25
|
+
store.transaction true do
|
26
|
+
store[:recordings][mailbox_id].first
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def archive_message(mailbox_id, message_id)
|
31
|
+
store.transaction do
|
32
|
+
item = store[:recordings][mailbox_id].select { |i| i[:id] == message_id }
|
33
|
+
rec = item.first
|
34
|
+
if rec
|
35
|
+
store[:archived][mailbox_id] << rec
|
36
|
+
store[:recordings][mailbox_id].delete(rec)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete_message(mailbox_id, message_id)
|
42
|
+
File.unlink(rec[:uri]) if File.exists?(rec[:uri])
|
43
|
+
store[:recordings][mailbox_id].delete(rec)
|
44
|
+
end
|
45
|
+
|
46
|
+
def save_greeting_for_mailbox(mailbox_id, recording_uri)
|
47
|
+
store.transaction do
|
48
|
+
store[:mailboxes][mailbox_id][:greeting_message] = recording_uri
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def change_pin_for_mailbox(mailbox_id, new_pin)
|
53
|
+
store.transaction do
|
54
|
+
store[:mailboxes][mailbox_id][:pin] = new_pin
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def save_recording(mailbox_id, from, recording_uri)
|
59
|
+
store.transaction do
|
60
|
+
recording = {
|
61
|
+
id: SecureRandom.uuid,
|
62
|
+
from: from,
|
63
|
+
received: Time.now,
|
64
|
+
uri: recording_uri.gsub(/file:\/\//, '')
|
65
|
+
}
|
66
|
+
logger.fatal "store[:recordings][#{mailbox_id}] << recording"
|
67
|
+
store[:recordings][mailbox_id] << recording
|
68
|
+
logger.info "Saving recording: #{recording.inspect}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_mailbox
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def setup_schema
|
78
|
+
store.transaction do
|
79
|
+
store[:mailboxes] ||= {}
|
80
|
+
store[:recordings] ||= {}
|
81
|
+
store[:archived] ||= {}
|
82
|
+
|
83
|
+
store[:mailboxes][1] = {greeting_message: "Hello.", id: 1, pin: '1234'}
|
84
|
+
store[:recordings][1] ||= []
|
85
|
+
store[:archived][1] ||= []
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def config
|
90
|
+
Voicemail::Plugin.config
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Voicemail
|
2
|
+
class VoicemailController < ApplicationController
|
3
|
+
def run
|
4
|
+
answer
|
5
|
+
if mailbox
|
6
|
+
play_greeting
|
7
|
+
handle_recording
|
8
|
+
else
|
9
|
+
mailbox_not_found
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def play_greeting
|
14
|
+
play mailbox[:greeting_message] || config.default_greeting
|
15
|
+
end
|
16
|
+
|
17
|
+
def handle_recording
|
18
|
+
@from = call.from
|
19
|
+
record_comp = record config.recording.to_hash.merge(interruptible: true, max_duration: 30_000, direction: :recv)
|
20
|
+
save_recording record_comp.complete_event.recording.uri
|
21
|
+
end
|
22
|
+
|
23
|
+
def mailbox_not_found
|
24
|
+
play config.mailbox_not_found
|
25
|
+
hangup
|
26
|
+
end
|
27
|
+
|
28
|
+
def save_recording(uri)
|
29
|
+
storage.save_recording mailbox[:id], @from, uri
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/voicemail.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Voicemail; end
|
2
|
+
require "voicemail/version"
|
3
|
+
require "voicemail/storage_pstore"
|
4
|
+
require "voicemail/storage"
|
5
|
+
require "voicemail/application_controller"
|
6
|
+
require "voicemail/voicemail_controller"
|
7
|
+
require "voicemail/mailbox_controller"
|
8
|
+
require "voicemail/mailbox_main_menu_controller"
|
9
|
+
require "voicemail/mailbox_messages_controller"
|
10
|
+
require "voicemail/mailbox_play_message_controller"
|
11
|
+
require "voicemail/mailbox_set_greeting_controller"
|
12
|
+
require "voicemail/mailbox_set_pin_controller"
|
13
|
+
|
14
|
+
require "voicemail/plugin"
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'adhearsion'
|
2
|
+
require 'flexmock'
|
3
|
+
require 'voicemail'
|
4
|
+
|
5
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each { |f| require f }
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.color_enabled = true
|
9
|
+
config.tty = true
|
10
|
+
|
11
|
+
config.mock_framework = :flexmock
|
12
|
+
config.filter_run :focus => true
|
13
|
+
config.run_all_when_everything_filtered = true
|
14
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module VoicemailControllerSpecHelper
|
2
|
+
def self.included(test_case)
|
3
|
+
test_case.let(:from) { "sip:user@server.com" }
|
4
|
+
test_case.let(:call) { flexmock 'Call', from: from }
|
5
|
+
test_case.let(:config) { Voicemail::Plugin.config }
|
6
|
+
test_case.let(:greeting_message) { nil }
|
7
|
+
test_case.let(:mailbox) do
|
8
|
+
{
|
9
|
+
id: 100,
|
10
|
+
pin: 1234,
|
11
|
+
greeting_message: greeting_message,
|
12
|
+
send_email: true,
|
13
|
+
email_address: 'lpradovera@mojolingo.com'
|
14
|
+
}
|
15
|
+
end
|
16
|
+
test_case.let(:storage_instance) { flexmock 'StorageInstance' }
|
17
|
+
test_case.let(:metadata) do
|
18
|
+
{ :mailbox => '100', :storage => storage_instance }
|
19
|
+
end
|
20
|
+
|
21
|
+
test_case.subject(:controller) { flexmock test_case.described_class.new(call, metadata) }
|
22
|
+
|
23
|
+
test_case.before(:each) do
|
24
|
+
storage_instance.should_receive(:get_mailbox).with(metadata[:mailbox]).and_return(mailbox)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def should_play(*args)
|
29
|
+
subject.should_receive(:play).once.tap { |exp| exp.with(*args) if args.count > 0 }
|
30
|
+
end
|
31
|
+
|
32
|
+
def should_ask(*args)
|
33
|
+
subject.should_receive(:ask).with(*args).once
|
34
|
+
end
|
35
|
+
|
36
|
+
def should_invoke(*args)
|
37
|
+
subject.should_receive(:invoke).once.with(*args)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Voicemail::MailboxController do
|
4
|
+
include VoicemailControllerSpecHelper
|
5
|
+
|
6
|
+
describe "#run" do
|
7
|
+
context "with a missing mailbox parameter in metadata" do
|
8
|
+
let(:metadata) { Hash.new }
|
9
|
+
|
10
|
+
it "should raise an error if there is no mailbox in the metadata" do
|
11
|
+
expect { controller.run }.to raise_error ArgumentError
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "with a present mailbox parameter in metadata" do
|
16
|
+
context "with an invalid mailbox" do
|
17
|
+
let(:mailbox) { nil }
|
18
|
+
|
19
|
+
it "plays the mailbox not found message and hangs up" do
|
20
|
+
should_play config.mailbox_not_found
|
21
|
+
subject.should_receive(:hangup).once
|
22
|
+
controller.run
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with an existing mailbox" do
|
27
|
+
it "plays the mailbox greeting message" do
|
28
|
+
should_play config.mailbox.greeting_message
|
29
|
+
subject.should_receive(:authenticate).and_return(true)
|
30
|
+
subject.should_receive(:play_number_of_messages).and_return(true)
|
31
|
+
subject.should_receive(:main_menu).and_return(true)
|
32
|
+
controller.run
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#authenticate" do
|
38
|
+
it "authenticates an user that enters the correct pin" do
|
39
|
+
should_ask(config.mailbox.please_enter_pin, terminator: "#", timeout: config.prompt_timeout).once.and_return(1234)
|
40
|
+
controller.authenticate.should == true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "tell a user his pin is wrong and retries" do
|
44
|
+
subject.should_receive(:ask).times(2).and_return(1111, 1234)
|
45
|
+
should_play config.mailbox.pin_wrong
|
46
|
+
controller.authenticate.should == true
|
47
|
+
end
|
48
|
+
|
49
|
+
it "fails with a message if the user enters a wrong PIN the set number of times" do
|
50
|
+
subject.should_receive(:ask).times(3).and_return(1111, 2222, 3333)
|
51
|
+
subject.should_receive(:play).with(config.mailbox.pin_wrong).times(3)
|
52
|
+
controller.authenticate.should == false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#play_number_of_messages" do
|
57
|
+
it "plays the number of new messages if there is at least one" do
|
58
|
+
storage_instance.should_receive(:count_new_messages).once.with(mailbox[:id]).and_return(3)
|
59
|
+
should_play(config.mailbox.number_before).ordered
|
60
|
+
subject.should_receive(:play_numeric).ordered.with(3)
|
61
|
+
should_play(config.mailbox.number_after).ordered
|
62
|
+
controller.play_number_of_messages
|
63
|
+
end
|
64
|
+
|
65
|
+
it "does play the no messages audio if there are none" do
|
66
|
+
storage_instance.should_receive(:count_new_messages).once.with(mailbox[:id]).and_return(0)
|
67
|
+
should_play(config.messages.no_new_messages).ordered
|
68
|
+
controller.play_number_of_messages
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#main_menu" do
|
73
|
+
it "passes to MainMenuController" do
|
74
|
+
subject.should_receive(:pass).once.with(Voicemail::MailboxMainMenuController, mailbox: mailbox[:id])
|
75
|
+
controller.main_menu
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Voicemail::MailboxMainMenuController do
|
4
|
+
include VoicemailControllerSpecHelper
|
5
|
+
|
6
|
+
describe "#main_menu" do
|
7
|
+
it "calls #menu with the proper parameters" do
|
8
|
+
subject.should_receive(:menu).once.with(config.mailbox.menu_greeting,
|
9
|
+
{ timeout: config.menu_timeout,
|
10
|
+
tries: config.menu_tries }, Proc)
|
11
|
+
controller.main_menu
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#set_greeting" do
|
16
|
+
it "invokes MailboxSetGreetingController" do
|
17
|
+
should_invoke Voicemail::MailboxSetGreetingController, mailbox: mailbox[:id]
|
18
|
+
controller.set_greeting
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#set_pin" do
|
23
|
+
it "invokes MailboxSetGreetingController" do
|
24
|
+
should_invoke Voicemail::MailboxSetPinController, mailbox: mailbox[:id]
|
25
|
+
controller.set_pin
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#listen_to_messages" do
|
30
|
+
it "invokes MailboxMessagesController" do
|
31
|
+
should_invoke Voicemail::MailboxMessagesController, mailbox: mailbox[:id]
|
32
|
+
controller.listen_to_messages
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Voicemail
|
4
|
+
describe MailboxMessagesController do
|
5
|
+
include VoicemailControllerSpecHelper
|
6
|
+
|
7
|
+
let(:call) { flexmock('Call') }
|
8
|
+
let(:config) { Voicemail::Plugin.config }
|
9
|
+
let(:metadata) do
|
10
|
+
{ :mailbox => '100' }
|
11
|
+
end
|
12
|
+
let(:mailbox) do
|
13
|
+
{
|
14
|
+
:id => 100,
|
15
|
+
:pin => 1234,
|
16
|
+
:greeting_message => nil,
|
17
|
+
:send_email => true,
|
18
|
+
:email_address => "lpradovera@mojolingo.com"
|
19
|
+
}
|
20
|
+
end
|
21
|
+
let(:message) do
|
22
|
+
{
|
23
|
+
:id => 123,
|
24
|
+
:from => "+39-335135335",
|
25
|
+
:received => Time.local(2012, 5, 1, 9, 0, 0),
|
26
|
+
:uri => "/path/to/file"
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:storage_instance) { flexmock('StorageInstance') }
|
31
|
+
|
32
|
+
let(:controller){ Voicemail::MailboxMessagesController.new call, metadata }
|
33
|
+
subject { flexmock controller }
|
34
|
+
|
35
|
+
before(:each) do
|
36
|
+
storage_instance.should_receive(:get_mailbox).with(metadata[:mailbox]).and_return(mailbox)
|
37
|
+
flexmock(Storage).should_receive(:instance).and_return(storage_instance)
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#message_loop" do
|
41
|
+
it "calls #next_message if there are new messages" do
|
42
|
+
storage_instance.should_receive(:count_new_messages).once.with(mailbox[:id]).and_return(3)
|
43
|
+
subject.should_receive(:next_message).once
|
44
|
+
controller.message_loop
|
45
|
+
end
|
46
|
+
|
47
|
+
it "plays a message and goes to the main menu if there are no new messages" do
|
48
|
+
storage_instance.should_receive(:count_new_messages).once.with(mailbox[:id]).and_return(0)
|
49
|
+
subject.should_receive(:play).with(config.messages.no_new_messages).once
|
50
|
+
subject.should_receive(:main_menu).once
|
51
|
+
controller.message_loop
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#next_message" do
|
56
|
+
it "gets the next message and calls #handle_message" do
|
57
|
+
storage_instance.should_receive(:next_new_message).once.with(mailbox[:id]).and_return(message)
|
58
|
+
subject.should_receive(:handle_message).once.with(message)
|
59
|
+
subject.should_receive(:message_loop).once
|
60
|
+
controller.next_message
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#handle_message" do
|
65
|
+
it "invokes MailboxPlayMessageController" do
|
66
|
+
should_invoke Voicemail::MailboxPlayMessageController, message: message, mailbox: mailbox[:id]
|
67
|
+
controller.handle_message message
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Voicemail::MailboxPlayMessageController do
|
4
|
+
include VoicemailControllerSpecHelper
|
5
|
+
|
6
|
+
let(:message) do
|
7
|
+
{
|
8
|
+
id: 123,
|
9
|
+
from: "+39-335135335",
|
10
|
+
received: Time.local(2012, 5, 1, 9, 0, 0),
|
11
|
+
uri: "/path/to/file"
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#archive_message" do
|
16
|
+
it "archives the message" do
|
17
|
+
subject.should_receive(:current_message).once.and_return(message)
|
18
|
+
storage_instance.should_receive(:archive_message).once.with(mailbox[:id], message[:id])
|
19
|
+
controller.archive_message
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#delete_message" do
|
24
|
+
it "deletes the message" do
|
25
|
+
subject.should_receive(:current_message).once.and_return(message)
|
26
|
+
storage_instance.should_receive(:delete_message).once.with(mailbox[:id], message[:id])
|
27
|
+
controller.delete_message
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#intro_message" do
|
32
|
+
it "plays the message introduction" do
|
33
|
+
subject.should_receive(:current_message).and_return(message)
|
34
|
+
should_play config.messages.message_received_on
|
35
|
+
subject.should_receive(:play_time).once.with(message[:received], format: config.datetime_format)
|
36
|
+
should_play config.messages.from
|
37
|
+
subject.should_receive(:execute).once.with("SayDigits", "39335135335")
|
38
|
+
controller.intro_message
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#play_message" do
|
43
|
+
it "plays the message, followed by the menu" do
|
44
|
+
subject.should_receive(:current_message).once.and_return(message)
|
45
|
+
subject.should_receive(:menu).once.with(message[:uri], config.messages.menu,
|
46
|
+
{ timeout: config.menu_timeout, tries: config.menu_tries }, Proc)
|
47
|
+
subject.play_message
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#load_message" do
|
52
|
+
|
53
|
+
context "with a message" do
|
54
|
+
let(:metadata) { {message: "foo"} }
|
55
|
+
|
56
|
+
it "loads the messge" do
|
57
|
+
subject.load_message
|
58
|
+
subject.current_message.should == "foo"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "with no message passed" do
|
63
|
+
let(:metadata) { {message: nil} }
|
64
|
+
|
65
|
+
it "raises an error" do
|
66
|
+
expect { subject.load_message }.to raise_error ArgumentError
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Voicemail::MailboxSetGreetingController do
|
4
|
+
include VoicemailControllerSpecHelper
|
5
|
+
|
6
|
+
describe "#section_menu" do
|
7
|
+
it "calls #menu with the proper parameters" do
|
8
|
+
subject.should_receive(:menu).once.with(config.set_greeting.prompt,
|
9
|
+
{ timeout: config.menu_timeout,
|
10
|
+
tries: config.menu_tries }, Proc)
|
11
|
+
controller.section_menu
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#listen_to_current_greeting" do
|
16
|
+
context "without a greeting message" do
|
17
|
+
it "plays the default greeting if one is not specified" do
|
18
|
+
should_play config.set_greeting.no_personal_greeting
|
19
|
+
subject.should_receive(:section_menu).once.and_return(true)
|
20
|
+
controller.listen_to_current_greeting
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "with a specified greeting message" do
|
25
|
+
let(:greeting_message) { "Howdy!" }
|
26
|
+
|
27
|
+
it "plays the specific greeting message" do
|
28
|
+
should_play greeting_message
|
29
|
+
subject.should_receive(:section_menu).once.and_return(true)
|
30
|
+
controller.listen_to_current_greeting
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#record_greeting" do
|
36
|
+
let(:recording_component) { flexmock 'Record' }
|
37
|
+
let(:file_path) { "/path/to/file" }
|
38
|
+
|
39
|
+
it "plays the appropriate sounds, records, plays back recording, and calls the recording menu" do
|
40
|
+
should_play config.set_greeting.before_record
|
41
|
+
recording_component.should_receive("complete_event.recording.uri").and_return(file_path)
|
42
|
+
subject.should_receive(:record).once.with(config.set_greeting.recording.to_hash.merge(interruptible: true, max_duration: 30_000)).and_return(recording_component)
|
43
|
+
should_play file_path
|
44
|
+
subject.should_receive(:menu).once.with(config.set_greeting.after_record,
|
45
|
+
{ timeout: config.menu_timeout,
|
46
|
+
tries: config.menu_tries }, Proc)
|
47
|
+
controller.record_greeting
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#save_greeting" do
|
52
|
+
let(:file_path) { "/path/to/file" }
|
53
|
+
|
54
|
+
it "saves the greeting and goes to the main menu" do
|
55
|
+
subject.should_receive(:temp_recording).once.and_return(file_path)
|
56
|
+
storage_instance.should_receive(:save_greeting_for_mailbox).with(mailbox[:id], file_path)
|
57
|
+
subject.should_receive(:main_menu)
|
58
|
+
controller.save_greeting
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Voicemail::MailboxSetPinController do
|
4
|
+
include VoicemailControllerSpecHelper
|
5
|
+
|
6
|
+
describe "#section_menu" do
|
7
|
+
it "calls #menu with the proper parameters" do
|
8
|
+
subject.should_receive(:menu).once.with(config.set_pin.menu,
|
9
|
+
{ timeout: config.menu_timeout,
|
10
|
+
tries: config.menu_tries }, Proc)
|
11
|
+
controller.section_menu
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#set_pin" do
|
16
|
+
let(:pin) { "4321" }
|
17
|
+
let(:not_matching_pin) { "1234" }
|
18
|
+
let(:short_pin) { "9" }
|
19
|
+
|
20
|
+
it "makes the user enter a PIN and repeat it" do
|
21
|
+
should_ask(config.set_pin.prompt, terminator: "#").and_return(pin).ordered
|
22
|
+
should_ask(config.set_pin.repeat_prompt, terminator: "#").and_return(pin).ordered
|
23
|
+
should_play(config.set_pin.change_ok).ordered
|
24
|
+
storage_instance.should_receive(:change_pin_for_mailbox).with(mailbox[:id], pin).once.ordered
|
25
|
+
subject.should_receive(:main_menu).once
|
26
|
+
controller.set_pin
|
27
|
+
end
|
28
|
+
|
29
|
+
it "makes the user start over if the PIN is too short" do
|
30
|
+
should_ask(config.set_pin.prompt, terminator: "#").and_return(short_pin).ordered
|
31
|
+
should_ask(config.set_pin.repeat_prompt, terminator: "#").and_return(short_pin).ordered
|
32
|
+
should_play(config.set_pin.pin_error).ordered
|
33
|
+
should_ask(config.set_pin.prompt, terminator: "#").and_return(pin).ordered
|
34
|
+
should_ask(config.set_pin.repeat_prompt, terminator: "#").and_return(pin).ordered
|
35
|
+
should_play(config.set_pin.change_ok).ordered
|
36
|
+
storage_instance.should_receive(:change_pin_for_mailbox).with(mailbox[:id], pin).once.ordered
|
37
|
+
subject.should_receive(:main_menu).once
|
38
|
+
controller.set_pin
|
39
|
+
end
|
40
|
+
|
41
|
+
it "makes the user start over if the PIN does not match confirmation" do
|
42
|
+
should_ask(config.set_pin.prompt, terminator: "#").and_return(pin).ordered
|
43
|
+
should_ask(config.set_pin.repeat_prompt, terminator: "#").and_return(not_matching_pin).ordered
|
44
|
+
should_play(config.set_pin.match_error).ordered
|
45
|
+
should_ask(config.set_pin.prompt, terminator: "#").and_return(pin).ordered
|
46
|
+
should_ask(config.set_pin.repeat_prompt, terminator: "#").and_return(pin).ordered
|
47
|
+
should_play(config.set_pin.change_ok).ordered
|
48
|
+
storage_instance.should_receive(:change_pin_for_mailbox).with(mailbox[:id], pin).once.ordered
|
49
|
+
subject.should_receive(:main_menu).once
|
50
|
+
controller.set_pin
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Voicemail
|
4
|
+
describe StoragePstore do
|
5
|
+
let(:mailbox) do
|
6
|
+
{
|
7
|
+
id: 100,
|
8
|
+
pin: 1234,
|
9
|
+
greeting_message: nil,
|
10
|
+
send_email: true,
|
11
|
+
email_address: 'lpradovera@mojolingo.com'
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:config) { Voicemail::Plugin.config }
|
16
|
+
|
17
|
+
subject :storage do
|
18
|
+
basedir = File.expand_path("../../../tmp/", __FILE__)
|
19
|
+
pstore_path = File.join(basedir, 'voicemail.pstore')
|
20
|
+
File.unlink(pstore_path) if File.exists?(pstore_path)
|
21
|
+
config.storage.pstore_location = pstore_path
|
22
|
+
StoragePstore.new.tap do |storage|
|
23
|
+
storage.store.transaction do
|
24
|
+
storage.store[:mailboxes][100] = mailbox
|
25
|
+
end
|
26
|
+
flexmock storage
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "is a PStore" do
|
31
|
+
storage.store.should be_a PStore
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#get_mailbox" do
|
35
|
+
it "returns the mailbox if it exists" do
|
36
|
+
storage.get_mailbox(100).should == mailbox
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns nil if the mailbox does not exist" do
|
40
|
+
storage.get_mailbox(400).should be_nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Voicemail::Storage do
|
4
|
+
describe "#instance" do
|
5
|
+
it "returns a StorageMain object" do
|
6
|
+
Voicemail::Storage.instance.should be_a Voicemail::StoragePstore
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns the same instance every time" do
|
10
|
+
Voicemail::Storage.instance.should be Voicemail::Storage.instance
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|