voicemail 0.1.0
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.
- 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
|