harleytt-gvoice-ruby 0.3.3
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/.bundle/config +2 -0
- data/.gitignore +5 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +24 -0
- data/README.rdoc +90 -0
- data/Rakefile +12 -0
- data/VERSION +1 -0
- data/bin/gv-notifier +78 -0
- data/bin/gv-place-call +22 -0
- data/bin/gv-send-sms +16 -0
- data/config/gvoice-ruby-config.yml.sample +11 -0
- data/gvoice-ruby.gemspec +34 -0
- data/lib/gvoice-ruby/call.rb +9 -0
- data/lib/gvoice-ruby/client.rb +277 -0
- data/lib/gvoice-ruby/compatibility.rb +75 -0
- data/lib/gvoice-ruby/config.rb +39 -0
- data/lib/gvoice-ruby/errors.rb +5 -0
- data/lib/gvoice-ruby/inbox_parser.rb +126 -0
- data/lib/gvoice-ruby/sms.rb +9 -0
- data/lib/gvoice-ruby/user.rb +12 -0
- data/lib/gvoice-ruby/version.rb +4 -0
- data/lib/gvoice-ruby/voicemail.rb +10 -0
- data/lib/gvoice-ruby.rb +5 -0
- data/test/client_test.rb +59 -0
- data/test/compatibility_test.rb +47 -0
- data/test/config_test.rb +50 -0
- data/test/fixtures/config_fixture.yml +11 -0
- data/test/fixtures/inbox.json +1 -0
- data/test/fixtures/inbox.yml +206 -0
- data/test/fixtures/inbox_fixture.html +2657 -0
- data/test/fixtures/login_fixture.html +567 -0
- data/test/gvoice-ruby_test.rb +9 -0
- data/test/inbox_parser_test.rb +53 -0
- data/test/test_helper.rb +20 -0
- metadata +223 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
# Pathname#ancestor takes an integer argument and walks up the path the same number of steps as the integer argument (starting from zero).
|
5
|
+
# Hence, given the path /Users/foo/bar/baz/bat/quux, Pathname#ancestor(3) would return /Users/foo/bar.
|
6
|
+
Pathname.class_eval do
|
7
|
+
def ancestor(num)
|
8
|
+
temp = self
|
9
|
+
num.downto(1) do
|
10
|
+
temp = temp.parent
|
11
|
+
end
|
12
|
+
return temp
|
13
|
+
end unless method_defined?(:ancestor)
|
14
|
+
end
|
15
|
+
|
16
|
+
if RUBY_VERSION > '1.9'
|
17
|
+
module GvoiceRuby
|
18
|
+
class Call
|
19
|
+
alias_method :orig_display_start_date_time, :display_start_date_time
|
20
|
+
|
21
|
+
def display_start_date_time # New Date class in Ruby 1.9.2 only accepts strictly formatted strings Date.parse
|
22
|
+
if self.send(:caller).first.include?('inbox_parser')
|
23
|
+
orig_display_start_date_time
|
24
|
+
else
|
25
|
+
# Capture the original date string and parse into month, day, year variables
|
26
|
+
# warn "#{self.send(:caller)}"
|
27
|
+
|
28
|
+
orig_display_start_date_time.match(/^(\d)\/(\d{1,2})\/(\d{2})\s(.+)\z/)
|
29
|
+
# month = $1
|
30
|
+
# day = $2
|
31
|
+
year = "20" + $3
|
32
|
+
# warn "Month is: #{month}\nDay is: #{day}\nYear is: #{year}"
|
33
|
+
"#{year}-#{$1}-#{$2} #{$4}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
if RUBY_VERSION < '1.9'
|
41
|
+
|
42
|
+
class Symbol
|
43
|
+
def to_proc
|
44
|
+
proc { |obj, *args| obj.send(self, *args) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Array
|
49
|
+
def sort_by!(&given_proc)
|
50
|
+
if block_given?
|
51
|
+
self.sort! { |a,b| given_proc.call(a) <=> given_proc.call(b) }
|
52
|
+
else
|
53
|
+
raise ArgumentError "No valid proc object created from argument."
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
#
|
59
|
+
# class Thing
|
60
|
+
# def initialize
|
61
|
+
# @foo = rand(100)
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# attr_accessor :foo
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# a = []
|
68
|
+
#
|
69
|
+
# 10.times do
|
70
|
+
# a << Thing.new
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# a.sort_by!(&:foo)
|
74
|
+
#
|
75
|
+
# p a
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# $:.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
module GvoiceRuby
|
5
|
+
class Configurator
|
6
|
+
PROJECT_ROOT = File.expand_path(Pathname.new(__FILE__).ancestor(3))
|
7
|
+
|
8
|
+
def self.load_config(config_file = File.join(PROJECT_ROOT, 'config', 'gvoice-ruby-config.yml'))
|
9
|
+
# Load our config
|
10
|
+
begin
|
11
|
+
if File.exists?(config_file)
|
12
|
+
config_hash = File.open(config_file) { |yf| YAML::load(yf) }
|
13
|
+
else
|
14
|
+
raise IOError
|
15
|
+
end
|
16
|
+
rescue IOError
|
17
|
+
STDERR.puts "Failed to open file #{File.expand_path(config_file)} for reading. File doesn't seem to exist. (#{$!})"
|
18
|
+
raise
|
19
|
+
end
|
20
|
+
return config_hash
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.write_config(config_hash, config_file = File.join(PROJECT_ROOT, 'config', 'gvoice-ruby-config.yml'))
|
24
|
+
# Clean things up and put them away
|
25
|
+
begin
|
26
|
+
if File.exists?(config_file)
|
27
|
+
File.open(config_file, 'w' ) do |out_file|
|
28
|
+
YAML.dump(config_hash, out_file)
|
29
|
+
end
|
30
|
+
else
|
31
|
+
raise IOError
|
32
|
+
end
|
33
|
+
rescue IOError
|
34
|
+
STDERR.puts "Failed to open #{File.expand_path(config_file)} for writing. File doesn't seem to exist: (#{$!})"
|
35
|
+
raise
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module GvoiceRuby
|
3
|
+
class InboxParser
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@smss = []
|
7
|
+
@voicemails = []
|
8
|
+
@calls = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse_page(page_obj)
|
12
|
+
doc = Nokogiri::XML.parse(page_obj.body_str)
|
13
|
+
|
14
|
+
# p doc
|
15
|
+
|
16
|
+
@html_fragment = Nokogiri::HTML::DocumentFragment.parse(doc.to_html)
|
17
|
+
|
18
|
+
# p @html_fragment
|
19
|
+
|
20
|
+
m = doc.css('json').first.to_s.scan(/CDATA\[(.+)\]\]/).flatten
|
21
|
+
|
22
|
+
inbox = JSON.parse(m.first)
|
23
|
+
return inbox
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_sms_messages(messages, page_fragment = @html_fragment)
|
27
|
+
messages.each do |txt|
|
28
|
+
if txt[1]['type'].to_i == 2
|
29
|
+
next
|
30
|
+
else
|
31
|
+
txt_obj = Sms.new
|
32
|
+
txt_obj.id = txt[0]
|
33
|
+
txt_obj.start_time = txt[1]['startTime'].to_i
|
34
|
+
txt_obj.is_read = txt[1]['isRead']
|
35
|
+
txt_obj.display_start_time = txt[1]['displayStartTime']
|
36
|
+
txt_obj.relative_start_time = txt[1]['relativeStartTime']
|
37
|
+
txt_obj.display_number = txt[1]['displayNumber']
|
38
|
+
txt_obj.display_start_date_time = txt[1]['displayStartDateTime']
|
39
|
+
txt_obj.labels = txt[1]['labels']
|
40
|
+
@smss << txt_obj
|
41
|
+
@smss.sort_by!(&:start_time) #if @smss.respond_to?(:sort_by!)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
@smss.each do |txt_obj|
|
46
|
+
page_fragment.css("div.gc-message-sms-row").each do |row|
|
47
|
+
if row.css('span.gc-message-sms-from').inner_html.strip! =~ /Me:/
|
48
|
+
next
|
49
|
+
elsif row.css('span.gc-message-sms-time').inner_html =~ Regexp.new(txt_obj.display_start_time)
|
50
|
+
txt_obj.to = 'Me'
|
51
|
+
txt_obj.from = row.css('span.gc-message-sms-from').inner_html.strip!.gsub!(':', '')
|
52
|
+
txt_obj.text = row.css('span.gc-message-sms-text').inner_html
|
53
|
+
# txt_obj.time = row.css('span.gc-message-sms-time').inner_html
|
54
|
+
else
|
55
|
+
next
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def parse_voicemail_messages(messages, page_fragment = @html_fragment)
|
62
|
+
# p messages
|
63
|
+
messages.each do |msg|
|
64
|
+
if msg[1]['type'].to_i == 2
|
65
|
+
vm_obj = Voicemail.new
|
66
|
+
vm_obj.id = msg[0]
|
67
|
+
vm_obj.start_time = msg[1]['startTime'].to_i
|
68
|
+
vm_obj.is_read = msg[1]['isRead']
|
69
|
+
vm_obj.display_start_time = msg[1]['displayStartTime']
|
70
|
+
vm_obj.relative_start_time = msg[1]['relativeStartTime']
|
71
|
+
vm_obj.display_number = msg[1]['displayNumber']
|
72
|
+
vm_obj.display_start_date_time = msg[1]['displayStartDateTime']
|
73
|
+
vm_obj.labels = msg[1]['labels']
|
74
|
+
@voicemails << vm_obj
|
75
|
+
@voicemails.sort_by!(&:start_time)
|
76
|
+
else
|
77
|
+
next
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
@voicemails.each do |vm_obj|
|
82
|
+
page_fragment.css('table.gc-message-tbl').each do |row|
|
83
|
+
if row.css('span.gc-message-time').text =~ Regexp.new(vm_obj.display_start_date_time)
|
84
|
+
vm_obj.to = 'Me'
|
85
|
+
vm_obj.from = row.css('a.gc-under.gc-message-name-link').inner_html
|
86
|
+
vm_obj.transcript = row.css('div.gc-message-message-display').inner_text.to_s.gsub(/\n/, "").squeeze(" ").strip!
|
87
|
+
# vm_obj.time = row.css('span.gc-message-time').inner_html
|
88
|
+
else
|
89
|
+
next
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def parse_calls(messages, page_fragment = @html_fragment)
|
96
|
+
messages.each do |msg|
|
97
|
+
call_obj = Call.new
|
98
|
+
call_obj.id = msg[0]
|
99
|
+
call_obj.start_time = msg[1]['startTime'].to_i
|
100
|
+
call_obj.is_read = msg[1]['isRead']
|
101
|
+
call_obj.display_start_time = msg[1]['displayStartTime']
|
102
|
+
call_obj.relative_start_time = msg[1]['relativeStartTime']
|
103
|
+
call_obj.display_number = msg[1]['displayNumber']
|
104
|
+
call_obj.display_start_date_time = msg[1]['displayStartDateTime']
|
105
|
+
call_obj.labels = msg[1]['labels']
|
106
|
+
|
107
|
+
@calls << call_obj
|
108
|
+
@calls.sort_by!(&:start_time)
|
109
|
+
end
|
110
|
+
|
111
|
+
@calls.each do |call_obj|
|
112
|
+
page_fragment.css('table.gc-message-tbl').each do |row|
|
113
|
+
if row.css('span.gc-message-time').text =~ Regexp.new(call_obj.display_start_date_time)
|
114
|
+
call_obj.to = 'Me'
|
115
|
+
call_obj.from = call_obj.display_number
|
116
|
+
# call_obj.from = row.css('a.gc-under.gc-message-name-link').inner_html
|
117
|
+
# call_obj.transcript = row.css('div.gc-message-message-display').inner_text.to_s.gsub(/\n/, "").squeeze(" ").strip!
|
118
|
+
# call_obj.time = row.css('span.gc-message-time').inner_html
|
119
|
+
else
|
120
|
+
next
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module GvoiceRuby
|
3
|
+
class Sms < Struct.new(:id, :start_time, :display_number, :display_start_date_time, :display_start_time, :relative_start_time, :is_read, :starred, :labels, :from, :to, :text)
|
4
|
+
#attr_accessor :id, :start_time, :display_number, :display_start_date_time, :display_start_time, :relative_start_time, :is_read, :labels, :from, :to, :text
|
5
|
+
#
|
6
|
+
#def initialize
|
7
|
+
#end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module GvoiceRuby
|
3
|
+
class User
|
4
|
+
# User is not a struct because we require email and password attributes
|
5
|
+
attr_accessor :email, :password
|
6
|
+
|
7
|
+
def initialize(email, password)
|
8
|
+
@email = email
|
9
|
+
@password = password
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module GvoiceRuby
|
3
|
+
class Voicemail < Struct.new(:id, :start_time, :display_number, :display_start_date_time, :display_start_time, :relative_start_time, :is_read, :starred, :labels, :from, :to, :transcript, :file)
|
4
|
+
#attr_accessor :id, :start_time, :display_number, :display_start_date_time, :display_start_time, :relative_start_time, :is_read, :labels, :from, :to, :transcript, :file
|
5
|
+
#
|
6
|
+
#def initialize
|
7
|
+
#
|
8
|
+
#end
|
9
|
+
end
|
10
|
+
end
|
data/lib/gvoice-ruby.rb
ADDED
data/test/client_test.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.unshift "." # Ruby 1.9.2 does not include current directory in the path
|
3
|
+
require File.dirname(__FILE__) + "/test_helper"
|
4
|
+
require 'mocha'
|
5
|
+
|
6
|
+
class ClientTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@config_file = File.join(File.dirname(__FILE__), 'fixtures', 'config_fixture.yml')
|
9
|
+
@page_body = String.new(File.read(File.join(File.dirname(__FILE__), 'fixtures', 'login_fixture.html')))
|
10
|
+
end
|
11
|
+
|
12
|
+
should "raise argument error if username nil" do
|
13
|
+
assert_raise(ArgumentError) { GvoiceRuby::Client.new({ :google_account_email => nil }) }
|
14
|
+
end
|
15
|
+
|
16
|
+
should "raise argument error if password nil" do
|
17
|
+
assert_raise(ArgumentError) { GvoiceRuby::Client.new({ :google_account_password => nil }) }
|
18
|
+
end
|
19
|
+
|
20
|
+
should "accept a simple hash as parameters" do
|
21
|
+
Curl::Easy.any_instance.stubs(:perform).returns(true)
|
22
|
+
Curl::Easy.any_instance.stubs(:body_str).returns(@page_body)
|
23
|
+
client = GvoiceRuby::Client.new({:google_account_email => 'google_test_account@gmail.com', :google_account_password => "bar"})
|
24
|
+
assert_kind_of(GvoiceRuby::Client, client)
|
25
|
+
# assert_equal(File.join(File.dirname(File.dirname(__FILE__)), 'log', 'gvoice-ruby.log'),
|
26
|
+
# client.logger.instance_variable_get(:@logdev).instance_variable_get(:@filename))
|
27
|
+
end
|
28
|
+
|
29
|
+
should "raise an error when unable to connect to Google" do
|
30
|
+
# Curl::Easy.any_instance.stubs(:perform).returns(false)
|
31
|
+
# Curl::Easy.any_instance.stubs(:response_code).returns()
|
32
|
+
client = GvoiceRuby::Client.new(GvoiceRuby::Configurator.load_config(@config_file))
|
33
|
+
assert_equal(client.instance_variable_get(:@curb_instance).response_code, 405)
|
34
|
+
end
|
35
|
+
|
36
|
+
should "raise an error when failing to login" do
|
37
|
+
Curl::Easy.any_instance.stubs(:perform).returns(false)
|
38
|
+
assert_raise(GvoiceRuby::LoginFailed) do
|
39
|
+
GvoiceRuby::Client.new({:google_account_email => 'google_test_account@gmail.com', :google_account_password => "bar"})
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
should "login" do
|
44
|
+
Curl::Easy.any_instance.stubs(:body_str).returns(@page_body)
|
45
|
+
client = GvoiceRuby::Client.new(GvoiceRuby::Configurator.load_config(@config_file))
|
46
|
+
assert client.logged_in?
|
47
|
+
assert_kind_of(Curl::Easy, client.instance_variable_get(:@curb_instance))
|
48
|
+
end
|
49
|
+
|
50
|
+
should "logout" do
|
51
|
+
Curl::Easy.any_instance.stubs(:body_str).returns(@page_body)
|
52
|
+
client = GvoiceRuby::Client.new(GvoiceRuby::Configurator.load_config(@config_file))
|
53
|
+
assert client.logged_in?
|
54
|
+
assert_kind_of(Curl::Easy, client.instance_variable_get(:@curb_instance))
|
55
|
+
Curl::Easy.any_instance.stubs(:perform).returns(true)
|
56
|
+
client.logout
|
57
|
+
deny client.logged_in?
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.unshift "." # Ruby 1.9.2 does not include current directory in the path
|
3
|
+
require File.dirname(__FILE__) + "/test_helper"
|
4
|
+
require 'mocha'
|
5
|
+
|
6
|
+
class CompatibilityTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@page_body = String.new(File.read(File.join(File.dirname(__FILE__), 'fixtures', 'inbox_fixture.html')))
|
10
|
+
@inbox_fixture = File.open(File.join(File.dirname(__FILE__), 'fixtures', 'inbox.yml')) { |yf| YAML::load(yf) }
|
11
|
+
@page_obj = mock()
|
12
|
+
@page_obj.stubs(:body_str).returns(@page_body)
|
13
|
+
end
|
14
|
+
|
15
|
+
should "add an instance method to Pathname" do
|
16
|
+
assert Pathname.new("/blah").respond_to?(:ancestor)
|
17
|
+
end
|
18
|
+
|
19
|
+
should "return the appropriate ancestor path" do
|
20
|
+
path = Pathname.new("/Users/foo/bar/baz/bat/quux")
|
21
|
+
assert_equal(Pathname.new("/Users/foo/bar"), path.ancestor(3))
|
22
|
+
end
|
23
|
+
|
24
|
+
if RUBY_VERSION > '1.9'
|
25
|
+
context "Using Ruby 1.9" do
|
26
|
+
should "Provide correct format of the display_start_date_time method" do
|
27
|
+
GvoiceRuby::Client.any_instance.stubs(:fetch_page).returns(true)
|
28
|
+
parser = GvoiceRuby::InboxParser.new
|
29
|
+
inbox = parser.parse_page(@page_obj)
|
30
|
+
parser.parse_calls(inbox['messages'])
|
31
|
+
assert_equal(parser.instance_variable_get(:@calls)[0].display_start_date_time, "2010-2-17 11:36 AM")
|
32
|
+
assert_not_equal(parser.instance_variable_get(:@calls)[0].display_start_date_time, "2/17/2010 11:36 AM")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
else
|
36
|
+
context "Using Ruby 1.8" do
|
37
|
+
should "Provide correct format of the display_start_date_time method" do
|
38
|
+
GvoiceRuby::Client.any_instance.stubs(:fetch_page).returns(true)
|
39
|
+
parser = GvoiceRuby::InboxParser.new
|
40
|
+
inbox = parser.parse_page(@page_obj)
|
41
|
+
parser.parse_calls(inbox['messages'])
|
42
|
+
assert_not_equal(parser.instance_variable_get(:@calls)[0].display_start_date_time, "2010-2-17 11:36 AM")
|
43
|
+
assert_equal(parser.instance_variable_get(:@calls)[0].display_start_date_time, "2/17/10 11:36 AM")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/test/config_test.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.dirname(__FILE__) + "/test_helper"
|
3
|
+
|
4
|
+
class ConfigTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@config_file = File.join(File.dirname(__FILE__), 'fixtures', 'config_fixture.yml')
|
8
|
+
@config = GvoiceRuby::Configurator.load_config(@config_file)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "have project root constant" do
|
12
|
+
assert_equal(File.expand_path(File.dirname(__FILE__) + '/..'), GvoiceRuby::Configurator.const_get(:PROJECT_ROOT).to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
should "load configuration file correctly" do
|
16
|
+
@config.each_pair do |k,v|
|
17
|
+
assert_equal(v, @config[k.to_sym])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
should "write configuration file" do
|
22
|
+
@config[:foo] = 'bar'
|
23
|
+
GvoiceRuby::Configurator.write_config(@config, File.dirname(__FILE__) + '/fixtures/config_fixture.yml')
|
24
|
+
newly_loaded_config = GvoiceRuby::Configurator.load_config(File.dirname(__FILE__) + '/fixtures/config_fixture.yml')
|
25
|
+
assert_equal('bar', newly_loaded_config[:foo].to_s)
|
26
|
+
@config.delete(:foo)
|
27
|
+
GvoiceRuby::Configurator.write_config(@config, File.dirname(__FILE__) + '/fixtures/config_fixture.yml')
|
28
|
+
end
|
29
|
+
|
30
|
+
should "raise IOError when config file not loaded" do
|
31
|
+
begin
|
32
|
+
assert_raise(IOError) { GvoiceRuby::Configurator.load_config('foo') }
|
33
|
+
rescue StandardError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
should "raise IOError when config file not written" do
|
38
|
+
begin
|
39
|
+
assert_raise(IOError) { GvoiceRuby::Configurator.write_config(@config, 'foo') }
|
40
|
+
rescue StandardError
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
should "Load a logger" do
|
45
|
+
assert_equal(@config[:logfile], './log/test_log.log')
|
46
|
+
assert_not_nil(GvoiceRuby::Client.new(@config).logger)
|
47
|
+
assert_not_nil(File.read('./log/test_log.log'))
|
48
|
+
assert_match(/^# Log/, File.read('./log/test_log.log'))
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
---
|
2
|
+
:bot_password: foo
|
3
|
+
:google_service: grandcentral
|
4
|
+
:last_message_start_time: 1252936650000
|
5
|
+
:google_voice_feed_url: https://www.google.com/voice/inbox/recent
|
6
|
+
:google_account_email: google_test_account@gmail.com
|
7
|
+
:bot_name: test_case@jabber.org
|
8
|
+
:google_account_password: bar
|
9
|
+
:logfile: ./log/test_log.log
|
10
|
+
:continue_url: https://www.google.com/voice
|
11
|
+
:google_auth_url: https://www.google.com/accounts/ServiceLoginAuth
|
@@ -0,0 +1 @@
|
|
1
|
+
"{\"messages\":{\"9f051f4869a4aab44b00962187680eb558408343\":{\"id\":\"9f051f4869a4aab44b00962187680eb558408343\",\"phoneNumber\":\"+15555555555\",\"displayNumber\":\"(555) 555-5555\",\"startTime\":\"1252546280464\",\"displayStartDateTime\":\"9/9/09 8:31 PM\",\"displayStartTime\":\"8:31 PM\",\"relativeStartTime\":\"40 hours ago\",\"note\":\"\",\"isRead\":true,\"isSpam\":false,\"isTrash\":false,\"star\":false,\"labels\":[\"inbox\",\"sms\",\"all\"],\"type\":10,\"children\":\"\"},\"1c09172ec9043a80b5fe30b6310d84faa8aa1b12\":{\"id\":\"1c09172ec9043a80b5fe30b6310d84faa8aa1b12\",\"phoneNumber\":\"+15555555555\",\"displayNumber\":\"(555) 555-5555\",\"startTime\":\"1252525590500\",\"displayStartDateTime\":\"9/9/09 2:46 PM\",\"displayStartTime\":\"2:46 PM\",\"relativeStartTime\":\"46 hours ago\",\"note\":\"\",\"isRead\":true,\"isSpam\":false,\"isTrash\":false,\"star\":false,\"labels\":[\"inbox\",\"sms\",\"all\"],\"type\":10,\"children\":\"\"},\"0cc0fa9a10c91187a182c76a10519185747a05be\":{\"id\":\"0cc0fa9a10c91187a182c76a10519185747a05be\",\"phoneNumber\":\"+15555555555\",\"displayNumber\":\"(555) 555-5555\",\"startTime\":\"1252517413901\",\"displayStartDateTime\":\"9/9/09 12:30 PM\",\"displayStartTime\":\"12:30 PM\",\"relativeStartTime\":\"2 days ago\",\"note\":\"\",\"isRead\":true,\"isSpam\":false,\"isTrash\":false,\"star\":false,\"labels\":[\"inbox\",\"sms\",\"all\"],\"type\":10,\"children\":\"\"},\"d8a7642677249d3b35fb029fd806730fe77fa309\":{\"id\":\"d8a7642677249d3b35fb029fd806730fe77fa309\",\"phoneNumber\":\"+15555555555\",\"displayNumber\":\"(555) 555-5555\",\"startTime\":\"1252449746310\",\"displayStartDateTime\":\"9/8/09 5:42 PM\",\"displayStartTime\":\"5:42 PM\",\"relativeStartTime\":\"2 days ago\",\"note\":\"\",\"isRead\":true,\"isSpam\":false,\"isTrash\":false,\"star\":false,\"labels\":[\"inbox\",\"sms\",\"all\"],\"type\":10,\"children\":\"\"},\"5ccf9f66a6c3ae9fe05b716d8811a14d2c505a2f\":{\"id\":\"5ccf9f66a6c3ae9fe05b716d8811a14d2c505a2f\",\"phoneNumber\":\"+15555555555\",\"displayNumber\":\"(555) 555-5555\",\"startTime\":\"1252443634536\",\"displayStartDateTime\":\"9/8/09 4:00 PM\",\"displayStartTime\":\"4:00 PM\",\"relativeStartTime\":\"2 days ago\",\"note\":\"\",\"isRead\":true,\"isSpam\":false,\"isTrash\":false,\"star\":false,\"labels\":[\"inbox\",\"sms\",\"all\"],\"type\":10,\"children\":\"\"},\"8b710ab3b55926fd5171b0e0394350ec4a38b5ac\":{\"id\":\"8b710ab3b55926fd5171b0e0394350ec4a38b5ac\",\"phoneNumber\":\"+15555555555\",\"displayNumber\":\"(555) 555-5555\",\"startTime\":\"1252374029866\",\"displayStartDateTime\":\"9/7/09 8:40 PM\",\"displayStartTime\":\"8:40 PM\",\"relativeStartTime\":\"3 days ago\",\"note\":\"\",\"isRead\":true,\"isSpam\":false,\"isTrash\":false,\"star\":false,\"labels\":[\"inbox\",\"sms\",\"all\"],\"type\":10,\"children\":\"\"},\"38fb0f098daa670ec648b2e947f2a6e4dcfc58a6\":{\"id\":\"38fb0f098daa670ec648b2e947f2a6e4dcfc58a6\",\"phoneNumber\":\"+15555555555\",\"displayNumber\":\"(555) 555-5555\",\"startTime\":\"1252278164000\",\"displayStartDateTime\":\"9/6/09 6:02 PM\",\"displayStartTime\":\"6:02 PM\",\"relativeStartTime\":\"4 days ago\",\"note\":\"\",\"isRead\":true,\"isSpam\":false,\"isTrash\":false,\"star\":false,\"labels\":[\"inbox\",\"voicemail\",\"all\"],\"type\":2,\"children\":\"\"},\"833332d3f90330a4d929eb698b4240ad1f79780f\":{\"id\":\"833332d3f90330a4d929eb698b4240ad1f79780f\",\"phoneNumber\":\"+15555555555\",\"displayNumber\":\"(555) 555-5555\",\"startTime\":\"1252265039929\",\"displayStartDateTime\":\"9/6/09 2:23 PM\",\"displayStartTime\":\"2:23 PM\",\"relativeStartTime\":\"4 days ago\",\"note\":\"\",\"isRead\":true,\"isSpam\":false,\"isTrash\":false,\"star\":false,\"labels\":[\"inbox\",\"sms\",\"all\"],\"type\":11,\"children\":\"\"},\"79d84552fecdba8160669e479d7897d368a1efb2\":{\"id\":\"79d84552fecdba8160669e479d7897d368a1efb2\",\"phoneNumber\":\"+15555555555\",\"displayNumber\":\"(555) 555-5555\",\"startTime\":\"1252210001428\",\"displayStartDateTime\":\"9/5/09 11:06 PM\",\"displayStartTime\":\"11:06 PM\",\"relativeStartTime\":\"5 days ago\",\"note\":\"\",\"isRead\":true,\"isSpam\":false,\"isTrash\":false,\"star\":false,\"labels\":[\"inbox\",\"sms\",\"all\"],\"type\":10,\"children\":\"\"},\"23459dc9b09799115ff5b4c2f0c502a99e934025\":{\"id\":\"23459dc9b09799115ff5b4c2f0c502a99e934025\",\"phoneNumber\":\"+15555555555\",\"displayNumber\":\"(555) 555-5555\",\"startTime\":\"1252180801154\",\"displayStartDateTime\":\"9/5/09 3:00 PM\",\"displayStartTime\":\"3:00 PM\",\"relativeStartTime\":\"5 days ago\",\"note\":\"\",\"isRead\":true,\"isSpam\":false,\"isTrash\":false,\"star\":false,\"labels\":[\"inbox\",\"sms\",\"all\"],\"type\":10,\"children\":\"\"}},\"totalSize\":47,\"unreadCounts\":{\"all\":0,\"inbox\":0,\"missed\":0,\"placed\":0,\"received\":0,\"recorded\":0,\"sms\":0,\"trash\":0,\"unread\":0,\"voicemail\":0},\"resultsPerPage\":10}"
|