google-gmail-api 0.0.14
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/.bundle/config +1 -0
- data/.gitignore +32 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +40 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +294 -0
- data/Rakefile +32 -0
- data/TODO.md +3 -0
- data/account.yml.example +17 -0
- data/gmail.gemspec +41 -0
- data/lib/gmail.rb +159 -0
- data/lib/gmail/api_resource.rb +12 -0
- data/lib/gmail/base/create.rb +16 -0
- data/lib/gmail/base/delete.rb +31 -0
- data/lib/gmail/base/get.rb +17 -0
- data/lib/gmail/base/list.rb +54 -0
- data/lib/gmail/base/modify.rb +66 -0
- data/lib/gmail/base/trash.rb +33 -0
- data/lib/gmail/base/update.rb +26 -0
- data/lib/gmail/draft.rb +54 -0
- data/lib/gmail/gmail_object.rb +147 -0
- data/lib/gmail/label.rb +52 -0
- data/lib/gmail/message.rb +242 -0
- data/lib/gmail/thread.rb +38 -0
- data/lib/gmail/util.rb +45 -0
- data/lib/gmail/version.rb +3 -0
- data/test/gmail/api_resource_test.rb +47 -0
- data/test/gmail/draft_test.rb +104 -0
- data/test/gmail/gmail_object_test.rb +39 -0
- data/test/gmail/label_test.rb +129 -0
- data/test/gmail/message_test.rb +365 -0
- data/test/gmail/thread_test.rb +184 -0
- data/test/gmail/util_test.rb +18 -0
- data/test/test_data.rb +127 -0
- data/test/test_helper.rb +38 -0
- metadata +262 -0
data/lib/gmail/thread.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Gmail
|
2
|
+
class Thread < APIResource
|
3
|
+
include Base::List
|
4
|
+
include Base::Delete
|
5
|
+
include Base::Get
|
6
|
+
include Base::Modify
|
7
|
+
include Base::Trash
|
8
|
+
|
9
|
+
def messages
|
10
|
+
|
11
|
+
if @values.messages.is_a? Array
|
12
|
+
if @values.messages.first.is_a? Message
|
13
|
+
@values.messages
|
14
|
+
else
|
15
|
+
@values.messages = Util.convert_to_gmail_object(to_hash[:messages], key="message")
|
16
|
+
end
|
17
|
+
else
|
18
|
+
self.detailed!
|
19
|
+
messages
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def unread_messages
|
25
|
+
|
26
|
+
messages.select{|m| m.unread?}
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def sent_messages
|
32
|
+
|
33
|
+
messages.select{|m| m.sent?}
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
data/lib/gmail/util.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Gmail
|
2
|
+
module Util
|
3
|
+
|
4
|
+
def self.object_classes
|
5
|
+
@object_classes ||= {
|
6
|
+
# data structures
|
7
|
+
|
8
|
+
# business objects
|
9
|
+
'draft' => Draft,
|
10
|
+
'label' => Label,
|
11
|
+
'message' => Message,
|
12
|
+
'thread' => Thread
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.convert_to_gmail_object(resp, key=nil)
|
17
|
+
case resp
|
18
|
+
when Array
|
19
|
+
resp.map { |i| convert_to_gmail_object(i, key) }
|
20
|
+
when Hash
|
21
|
+
# Try converting to a known object class. If none available, fall back to generic StripeObject
|
22
|
+
object_classes.fetch(key , GmailObject).new(resp)
|
23
|
+
else
|
24
|
+
resp
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def self.symbolize_names(object)
|
30
|
+
case object
|
31
|
+
when Hash
|
32
|
+
new_hash = {}
|
33
|
+
object.each do |key, value|
|
34
|
+
key = (key.to_sym rescue key) || key
|
35
|
+
new_hash[key] = symbolize_names(value)
|
36
|
+
end
|
37
|
+
new_hash
|
38
|
+
when Array
|
39
|
+
object.map { |value| symbolize_names(value) }
|
40
|
+
else
|
41
|
+
object
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.expand_path('../../test_helper', __FILE__)
|
3
|
+
|
4
|
+
module Gmail
|
5
|
+
class ApiResourceTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
should "creating a new APIResource should not fetch over the network" do
|
8
|
+
@mock.expects(:execute).never
|
9
|
+
Gmail::Label.new({
|
10
|
+
name: "test"
|
11
|
+
})
|
12
|
+
end
|
13
|
+
|
14
|
+
should "setting an attribute should not cause a network request" do
|
15
|
+
@mock.expects(:execute).never
|
16
|
+
m = Gmail::Message.new({subject: "test"})
|
17
|
+
m.body = "this is a test body"
|
18
|
+
end
|
19
|
+
|
20
|
+
should "accessing id should not issue a fetch" do
|
21
|
+
@mock.expects(:execute).never
|
22
|
+
c = Gmail::Message.new({subject: "test"})
|
23
|
+
c.id
|
24
|
+
end
|
25
|
+
|
26
|
+
should "construct URL properly with base query parameters" do
|
27
|
+
response = test_response(test_thread_list)
|
28
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.threads.list, parameters: {userId: "me"}, headers: {'Content-Type' => 'application/json'}).returns(response)
|
29
|
+
Gmail::Thread.all
|
30
|
+
|
31
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.threads.list, parameters: {maxResults: 150, userId: "test@test.com"}, headers: {'Content-Type' => 'application/json'}).returns(response)
|
32
|
+
Gmail::Thread.all(maxResults: 150, userId: "test@test.com")
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
should "deleting should return true" do
|
37
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.delete, parameters: {userId: "me", id: test_draft[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(""))
|
38
|
+
|
39
|
+
d = Gmail::Draft.new test_draft
|
40
|
+
|
41
|
+
assert_equal true, d.delete
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.expand_path('../../test_helper', __FILE__)
|
3
|
+
|
4
|
+
module Gmail
|
5
|
+
class DraftTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
should "Draft should be retrievable by id" do
|
8
|
+
|
9
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.get, parameters: {userId: "me", id: test_draft[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_draft))
|
10
|
+
d = Gmail::Draft.get(test_draft[:id])
|
11
|
+
assert d.kind_of?Gmail::Draft
|
12
|
+
assert_equal test_draft[:id], d.id
|
13
|
+
end
|
14
|
+
|
15
|
+
should "drafts should be listable" do
|
16
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.list, parameters: {userId: "me"}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_draft_list))
|
17
|
+
list = Gmail::Draft.all
|
18
|
+
assert list.kind_of? Array
|
19
|
+
assert list[0].kind_of? Gmail::Draft
|
20
|
+
end
|
21
|
+
|
22
|
+
context "Message Object in draft" do
|
23
|
+
should "retrieved Draft should not generate call to get Message Object" do
|
24
|
+
draft = Gmail::Draft.new(test_draft)
|
25
|
+
@mock.expects(:execute).never
|
26
|
+
assert draft.message.kind_of?Gmail::Message
|
27
|
+
end
|
28
|
+
|
29
|
+
should "Draft get from a draft list should generate call to get Message Object" do
|
30
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.list, parameters: {userId: "me"}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_draft_list))
|
31
|
+
list = Gmail::Draft.all
|
32
|
+
draft = list.first
|
33
|
+
|
34
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.get, parameters: {userId: "me", id: test_draft[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_draft))
|
35
|
+
|
36
|
+
assert draft.message.kind_of?Gmail::Message
|
37
|
+
assert_not_nil draft.message.payload
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
should "drafts should be deletable" do
|
43
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.delete, parameters: {userId: "me", id: test_draft[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(""))
|
44
|
+
d = Gmail::Draft.new(test_draft)
|
45
|
+
r = d.delete
|
46
|
+
assert r
|
47
|
+
end
|
48
|
+
|
49
|
+
should "drafts should be updateable" do
|
50
|
+
draft_hash = test_draft
|
51
|
+
draft_hash[:message].merge!({labelIds: ["COOL LABEL"]})
|
52
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.get, parameters: {id: test_draft[:id], userId: "me"} , headers: {'Content-Type' => 'application/json'}).once.returns(test_response(draft_hash))
|
53
|
+
|
54
|
+
d = Gmail::Draft.new(id: test_draft[:id]).detailed
|
55
|
+
# those two lines are required because raw generation change between two calls...
|
56
|
+
raw = d.message.raw
|
57
|
+
d.message.raw = raw
|
58
|
+
###
|
59
|
+
assert_equal ["COOL LABEL"], d.message.labelIds
|
60
|
+
|
61
|
+
draft_hash[:message].merge!({labelIds: ["INBOX"]})
|
62
|
+
|
63
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.update, parameters: {id: test_draft[:id], userId: "me"}, body_object:{message: {raw: d.message.raw, threadId: test_draft[:message][:threadId], labelIds: ["INBOX"]}} , headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(draft_hash))
|
64
|
+
|
65
|
+
|
66
|
+
d.message.labelIds = ["INBOX"]
|
67
|
+
new_d = d.save
|
68
|
+
assert_equal ["INBOX"], new_d.message.labelIds
|
69
|
+
assert_not_equal d.object_id, new_d.object_id
|
70
|
+
new_d = d.save!
|
71
|
+
assert_equal d.object_id, new_d.object_id
|
72
|
+
end
|
73
|
+
|
74
|
+
should "create should return a new Draft" do
|
75
|
+
draft_hash = test_draft
|
76
|
+
draft_hash.delete(:id)
|
77
|
+
d = Gmail::Draft.new draft_hash
|
78
|
+
# those two lines are required because raw generation change between two calls...
|
79
|
+
raw = d.message.raw
|
80
|
+
d.message.raw = raw
|
81
|
+
###
|
82
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.create, parameters: {userId: "me"}, body_object:{message: {raw: d.message.raw, threadId: draft_hash[:message][:threadId], labelIds: draft_hash[:message][:labelIds]}} , headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_draft))
|
83
|
+
created_d = d.save!
|
84
|
+
assert_equal Gmail::Draft, created_d.class
|
85
|
+
assert_equal test_draft[:id], d.id
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
should "Draft should be sendable and return a Message" do
|
90
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.to_h['gmail.users.drafts.send'], parameters: {userId: "me"}, body_object:{id: test_draft[:id]} , headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_message))
|
91
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.get, parameters: {userId: "me", id: test_message[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_message))
|
92
|
+
|
93
|
+
d = Gmail::Draft.new test_draft
|
94
|
+
m = d.deliver
|
95
|
+
|
96
|
+
assert m.kind_of?Gmail::Message
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Gmail
|
4
|
+
class GmailObjectTest < Test::Unit::TestCase
|
5
|
+
should "implement #respond_to correctly" do
|
6
|
+
obj = Gmail::GmailObject.new({ :id => 1, :foo => 'bar' })
|
7
|
+
assert_not_nil obj.id
|
8
|
+
assert_not_nil obj.foo
|
9
|
+
assert_nil obj.other
|
10
|
+
end
|
11
|
+
|
12
|
+
should "detail and refresh a Gmail object correctly" do
|
13
|
+
obj = Gmail::GmailObject.new test_message
|
14
|
+
exception = assert_raise do obj.refresh end
|
15
|
+
assert_equal "Can't refresh a generic GmailObject. It needs to be a Thread, Message, Draft or Label", exception.message
|
16
|
+
exception = assert_raise do obj.detailed end
|
17
|
+
assert_equal "Can't detail a generic GmailObject. It needs to be a Thread, Message, Draft or Label", exception.message
|
18
|
+
|
19
|
+
not_generic_object = Gmail::Message.new test_message
|
20
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.get, parameters: {userId: "me", id: test_message[:id]}, headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
21
|
+
|
22
|
+
new_o = not_generic_object.detailed
|
23
|
+
assert_not_equal new_o.object_id, not_generic_object.object_id
|
24
|
+
|
25
|
+
new_o = not_generic_object.refresh
|
26
|
+
assert_equal new_o.object_id, not_generic_object.object_id
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
should "recursively call to_hash on GmailObject" do
|
31
|
+
nested = Gmail::GmailObject.new({ :id => 7, :foo => 'bar' })
|
32
|
+
obj = Gmail::GmailObject.new({ :id => 1})
|
33
|
+
obj.nested = nested
|
34
|
+
expected_hash = { :id => 1, :nested => {:id => 7, :foo => 'bar'} }
|
35
|
+
assert_equal expected_hash, obj.to_hash
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.expand_path('../../test_helper', __FILE__)
|
3
|
+
|
4
|
+
module Gmail
|
5
|
+
class LabelTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
should "Labels should be listable" do
|
8
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.labels.list, parameters: {userId: "me"}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_label_list))
|
9
|
+
list = Gmail::Label.all
|
10
|
+
assert list.kind_of? Array
|
11
|
+
assert list[0].kind_of? Gmail::Label
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
context "Retrieve a Label" do
|
16
|
+
should "Label should be retrievable by id" do
|
17
|
+
|
18
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.labels.get, parameters: {userId: "me", id: test_label[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_label))
|
19
|
+
l = Gmail::Label.get(test_label[:id])
|
20
|
+
assert l.kind_of?Gmail::Label
|
21
|
+
assert_equal test_label[:id], l.id
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
[:inbox, :sent, :trash, :important, :starred, :draft, :spam, :unread, :category_updates, :category_promotions, :category_social, :category_personal, :category_forums ].each do |label_id|
|
26
|
+
should "System Label should be retrievable by calling #{label_id.to_s}" do
|
27
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.labels.get, parameters: {userId: "me", id: label_id.to_s.upcase}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_label_list[:labels].select{|l| l[:id] == label_id.to_s.upcase}.first))
|
28
|
+
l = Gmail::Label.send(label_id.to_s)
|
29
|
+
assert l.kind_of?Gmail::Label
|
30
|
+
assert_equal label_id.to_s.upcase, l.id
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
context "Access list of Messages from Label" do
|
38
|
+
should "Access list of Messages" do
|
39
|
+
label = Gmail::Label.new test_label
|
40
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.list, parameters: {userId: "me", labelIds: [test_label[:id]]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_message_list))
|
41
|
+
list = label.messages
|
42
|
+
assert list.kind_of? Array
|
43
|
+
assert list[0].kind_of? Gmail::Message
|
44
|
+
end
|
45
|
+
|
46
|
+
should 'Access list of unread Messages' do
|
47
|
+
label = Gmail::Label.new test_label
|
48
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.list, parameters: {userId: "me", labelIds: [test_label[:id], "UNREAD"]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_message_list))
|
49
|
+
list = label.unread_messages
|
50
|
+
assert list.kind_of? Array
|
51
|
+
assert list[0].kind_of? Gmail::Message
|
52
|
+
end
|
53
|
+
|
54
|
+
should 'Access filtered Messages' do
|
55
|
+
label = Gmail::Label.new test_label
|
56
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.list, parameters: {userId: "me", labelIds: ["IMPORTANT", "COOL", test_label[:id]], threadId: "1"}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_message_list))
|
57
|
+
list = label.messages(threadId: "1", labelIds: ["IMPORTANT", "COOL"])
|
58
|
+
assert list.kind_of? Array
|
59
|
+
assert list[0].kind_of? Gmail::Message
|
60
|
+
end
|
61
|
+
|
62
|
+
should "Access list of Threads" do
|
63
|
+
label = Gmail::Label.new test_label
|
64
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.threads.list, parameters: {userId: "me", labelIds: [test_label[:id]]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_thread_list))
|
65
|
+
list = label.threads
|
66
|
+
assert list.kind_of? Array
|
67
|
+
assert list[0].kind_of? Gmail::Thread
|
68
|
+
end
|
69
|
+
|
70
|
+
should 'Access list of unread Threads' do
|
71
|
+
label = Gmail::Label.new test_label
|
72
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.threads.list, parameters: {userId: "me", labelIds: [test_label[:id], "UNREAD"]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_thread_list))
|
73
|
+
list = label.unread_threads
|
74
|
+
assert list.kind_of? Array
|
75
|
+
assert list[0].kind_of? Gmail::Thread
|
76
|
+
end
|
77
|
+
|
78
|
+
should 'Access filtered Threads' do
|
79
|
+
label = Gmail::Label.new test_label
|
80
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.threads.list, parameters: {userId: "me", labelIds: ["IMPORTANT", "COOL", test_label[:id]], threadId: "1"}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_thread_list))
|
81
|
+
list = label.threads(threadId: "1", labelIds: ["IMPORTANT", "COOL"])
|
82
|
+
assert list.kind_of? Array
|
83
|
+
assert list[0].kind_of? Gmail::Thread
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
should "Label should be deletable" do
|
92
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.labels.delete, parameters: {userId: "me", id: test_label[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(""))
|
93
|
+
d = Gmail::Label.new(test_label)
|
94
|
+
r = d.delete
|
95
|
+
assert r
|
96
|
+
end
|
97
|
+
|
98
|
+
should "Label should be updateable" do
|
99
|
+
|
100
|
+
label = Gmail::Label.new test_label(:messageListVisibility=>"show")
|
101
|
+
|
102
|
+
assert_equal "show", label.messageListVisibility
|
103
|
+
|
104
|
+
|
105
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.labels.update, parameters: {id: test_label[:id], userId: "me"}, body_object:test_label(:messageListVisibility=>"hide") , headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_label(:messageListVisibility=>"hide")))
|
106
|
+
|
107
|
+
label.messageListVisibility = "hide"
|
108
|
+
new_l = label.save
|
109
|
+
assert_equal "hide", new_l.messageListVisibility
|
110
|
+
assert_not_equal label.object_id, new_l.object_id
|
111
|
+
new_l = label.save!
|
112
|
+
assert_equal label.object_id, new_l.object_id
|
113
|
+
end
|
114
|
+
|
115
|
+
should "create should return a new Label" do
|
116
|
+
label_hash = test_label
|
117
|
+
label_hash.delete(:id)
|
118
|
+
label = Gmail::Label.new label_hash
|
119
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.labels.create, parameters: {userId: "me"}, body_object:label_hash , headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_label))
|
120
|
+
created_l = label.save!
|
121
|
+
assert_equal Gmail::Label, created_l.class
|
122
|
+
assert_equal test_label[:id], label.id
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,365 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# encoding: utf-8
|
3
|
+
require File.expand_path('../../test_helper', __FILE__)
|
4
|
+
|
5
|
+
module Gmail
|
6
|
+
class MessageTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
should "messages should be listable" do
|
9
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.list, parameters: {userId: "me"}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_message_list))
|
10
|
+
list = Gmail::Message.all
|
11
|
+
assert_equal Array, list.class
|
12
|
+
assert_equal Gmail::Message, list[0].class
|
13
|
+
end
|
14
|
+
|
15
|
+
should "message should be retrievable by id" do
|
16
|
+
|
17
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.get, parameters: {userId: "me", id: test_message[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_message))
|
18
|
+
t = Gmail::Message.get(test_message[:id])
|
19
|
+
assert_equal Gmail::Message, t.class
|
20
|
+
assert_equal test_message[:id], t.id
|
21
|
+
end
|
22
|
+
|
23
|
+
should "message construct should set some basics values" do
|
24
|
+
|
25
|
+
m = Gmail::Message.new(test_message)
|
26
|
+
["From", "To", "Cc", "Subject", "Bcc", "Date", "Message-ID", "References", "In-Reply-To", "Delivered-To"].each do |method|
|
27
|
+
assert_equal test_message[:payload][:headers].select{|h| h[:name].downcase == method.downcase}.first[:value], m.send(method.downcase.tr("-", "_"))
|
28
|
+
end
|
29
|
+
assert_not_nil m.text || m.body || m.html
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
should "message (with strange format) construct should set at least body, text or html" do
|
34
|
+
|
35
|
+
m = Gmail::Message.new(test_strange_message)
|
36
|
+
assert_not_nil m.text || m.body || m.html
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
should "Access thread from message" do
|
44
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.threads.get, parameters: {userId: "me", id: test_message[:threadId]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_thread))
|
45
|
+
m = Gmail::Message.new(test_message)
|
46
|
+
t = m.thread
|
47
|
+
assert_equal test_message[:threadId], m.thread_id
|
48
|
+
assert_equal Gmail::Thread, t.class
|
49
|
+
end
|
50
|
+
|
51
|
+
should "message should be deletable" do
|
52
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.delete, parameters: {userId: "me", id: test_message[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(""))
|
53
|
+
t = Gmail::Message.new(test_message)
|
54
|
+
r = t.delete
|
55
|
+
assert r
|
56
|
+
end
|
57
|
+
|
58
|
+
should "message should be thrashable" do
|
59
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.trash, parameters: {userId: "me", id: test_message[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_message))
|
60
|
+
t = Gmail::Message.new(test_message)
|
61
|
+
r = t.trash
|
62
|
+
assert_equal Gmail::Message, r.class
|
63
|
+
end
|
64
|
+
|
65
|
+
should "message should be unthrashable" do
|
66
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.untrash, parameters: {userId: "me", id: test_message[:id]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_message))
|
67
|
+
t = Gmail::Message.new(test_message)
|
68
|
+
r = t.untrash
|
69
|
+
assert_equal Gmail::Message, r.class
|
70
|
+
end
|
71
|
+
|
72
|
+
context "Modifying Labels" do
|
73
|
+
should "message should be starrable" do
|
74
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.modify, parameters: {userId: "me", id: test_message[:id]}, body_object: {addLabelIds: ["STARRED"], removeLabelIds: []} , headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
75
|
+
t = Gmail::Message.new(test_message)
|
76
|
+
r = t.star
|
77
|
+
assert_equal Gmail::Message, r.class
|
78
|
+
assert_not_equal t.object_id, r.object_id
|
79
|
+
|
80
|
+
r = t.star!
|
81
|
+
|
82
|
+
assert_equal t.object_id, r.object_id
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
should "message should be unstarrable" do
|
87
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.modify, parameters: {userId: "me", id: test_message[:id]}, body_object: {addLabelIds: [], removeLabelIds: ["STARRED"]} , headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
88
|
+
t = Gmail::Message.new(test_message)
|
89
|
+
r = t.unstar
|
90
|
+
assert_equal Gmail::Message, r.class
|
91
|
+
|
92
|
+
assert_not_equal t.object_id, r.object_id
|
93
|
+
|
94
|
+
r = t.unstar!
|
95
|
+
|
96
|
+
assert_equal t.object_id, r.object_id
|
97
|
+
end
|
98
|
+
|
99
|
+
should "message should be archivable" do
|
100
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.modify, parameters: {userId: "me", id: test_message[:id]}, body_object: {addLabelIds: [], removeLabelIds: ["INBOX"]} , headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
101
|
+
t = Gmail::Message.new(test_message)
|
102
|
+
r = t.archive
|
103
|
+
assert_equal Gmail::Message, r.class
|
104
|
+
assert_not_equal t.object_id, r.object_id
|
105
|
+
|
106
|
+
r = t.archive!
|
107
|
+
|
108
|
+
assert_equal t.object_id, r.object_id
|
109
|
+
end
|
110
|
+
|
111
|
+
should "message should be unarchivable" do
|
112
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.modify, parameters: {userId: "me", id: test_message[:id]}, body_object: {addLabelIds: ["INBOX"], removeLabelIds: []} , headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
113
|
+
t = Gmail::Message.new(test_message)
|
114
|
+
r = t.unarchive
|
115
|
+
assert_equal Gmail::Message, r.class
|
116
|
+
assert_not_equal t.object_id, r.object_id
|
117
|
+
|
118
|
+
r = t.unarchive!
|
119
|
+
|
120
|
+
assert_equal t.object_id, r.object_id
|
121
|
+
end
|
122
|
+
|
123
|
+
should "message should be markable as read" do
|
124
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.modify, parameters: {userId: "me", id: test_message[:id]}, body_object: {addLabelIds: [], removeLabelIds: ["UNREAD"]} , headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
125
|
+
t = Gmail::Message.new(test_message)
|
126
|
+
r = t.mark_as_read
|
127
|
+
assert_equal Gmail::Message, r.class
|
128
|
+
assert_not_equal t.object_id, r.object_id
|
129
|
+
|
130
|
+
r = t.mark_as_read!
|
131
|
+
|
132
|
+
assert_equal t.object_id, r.object_id
|
133
|
+
end
|
134
|
+
|
135
|
+
should "message should be markable as unread" do
|
136
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.modify, parameters: {userId: "me", id: test_message[:id]}, body_object: {addLabelIds: ["UNREAD"], removeLabelIds: []} , headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
137
|
+
t = Gmail::Message.new(test_message)
|
138
|
+
r = t.mark_as_unread
|
139
|
+
assert_equal Gmail::Message, r.class
|
140
|
+
assert_not_equal t.object_id, r.object_id
|
141
|
+
|
142
|
+
r = t.mark_as_unread!
|
143
|
+
|
144
|
+
assert_equal t.object_id, r.object_id
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
should "message label should be modifiable as wish" do
|
149
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.modify, parameters: {userId: "me", id: test_message[:id]}, body_object: {addLabelIds: ["UNREAD", "SOME COOL LABEL"], removeLabelIds: ["INBOX", "SOME NOT COOL LABEL"]} , headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
150
|
+
t = Gmail::Message.new(test_message)
|
151
|
+
r = t.modify ["UNREAD", "SOME COOL LABEL"], ["INBOX", "SOME NOT COOL LABEL"]
|
152
|
+
assert_equal Gmail::Message, r.class
|
153
|
+
assert_not_equal t.object_id, r.object_id
|
154
|
+
|
155
|
+
r = t.modify! ["UNREAD", "SOME COOL LABEL"], ["INBOX", "SOME NOT COOL LABEL"]
|
156
|
+
|
157
|
+
assert_equal t.object_id, r.object_id
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
should "Helpers should work" do
|
164
|
+
m = Gmail::Message.new test_message
|
165
|
+
assert_false m.sent?
|
166
|
+
assert_false m.inbox?
|
167
|
+
assert_false m.unread?
|
168
|
+
m = Gmail::Message.new test_inbox_message
|
169
|
+
assert_false m.sent?
|
170
|
+
assert m.inbox?
|
171
|
+
assert_false m.unread?
|
172
|
+
m = Gmail::Message.new test_sent_message
|
173
|
+
assert m.sent?
|
174
|
+
assert_false m.inbox?
|
175
|
+
assert_false m.unread?
|
176
|
+
m = Gmail::Message.new test_unread_message
|
177
|
+
assert_false m.sent?
|
178
|
+
assert_false m.inbox?
|
179
|
+
assert m.unread?
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
should "Message should be searcheable" do
|
184
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.list, parameters: {userId: "me", q: "from:(me) to:(you) subject:(subject) in:inbox before:2014/12/1 after:2014/11/1 test -{real}", labelIds:["UNREAD"]}, headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_message_list))
|
185
|
+
list = Gmail::Message.search(from:"me", to: "you", subject: "subject", in: "inbox", before: "2014/12/1", after: "2014/11/1", has_words: "test", has_not_words: "real", labelIds: ["UNREAD"])
|
186
|
+
assert_equal Array, list.class
|
187
|
+
assert_equal Gmail::Message, list[0].class
|
188
|
+
end
|
189
|
+
|
190
|
+
should "Message should construct RAW string correctly" do
|
191
|
+
m = Gmail::Message.new test_message
|
192
|
+
raw = Mail.new(Base64.urlsafe_decode64(m.raw))
|
193
|
+
assert raw.from
|
194
|
+
assert raw.to
|
195
|
+
assert raw.cc
|
196
|
+
assert_equal m.bcc, raw.header['Bcc'].value
|
197
|
+
assert_equal m.subject, raw.subject
|
198
|
+
assert_equal m.in_reply_to, "<#{raw.in_reply_to}>"
|
199
|
+
assert_equal m.references.tr("<", "").tr(">", "").split(" "), raw.references
|
200
|
+
assert raw.text_part.body.raw_source
|
201
|
+
assert raw.html_part.body.raw_source
|
202
|
+
end
|
203
|
+
|
204
|
+
should "Draft can be created from Message" do
|
205
|
+
m = Gmail::Message.new test_message
|
206
|
+
# raw generation change between two calls because date won't be the same...
|
207
|
+
m.raw = m.raw
|
208
|
+
###
|
209
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.drafts.create, parameters: {userId: "me"}, body_object:{message: {raw: m.raw, threadId: test_message[:threadId], labelIds: test_message[:labelIds]}} , headers: {'Content-Type' => 'application/json'}).once.returns(test_response(test_draft))
|
210
|
+
d = m.create_draft
|
211
|
+
assert_equal Gmail::Draft, d.class
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
should "Message should be sendable and return a Message" do
|
216
|
+
|
217
|
+
m = Gmail::Message.new test_message
|
218
|
+
m.raw = m.raw
|
219
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.to_h['gmail.users.messages.send'], parameters: {userId: "me"}, body_object:{raw: m.raw, labelIds: test_message[:labelIds], threadId: test_message[:threadId]} , headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
220
|
+
|
221
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.get, parameters: {userId: "me", id: test_message[:id]}, headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
222
|
+
|
223
|
+
|
224
|
+
new_m = m.deliver
|
225
|
+
assert_equal Gmail::Message, new_m.class
|
226
|
+
assert_not_equal new_m.object_id, m.object_id
|
227
|
+
|
228
|
+
new_m = m.deliver!
|
229
|
+
assert_equal Gmail::Message, new_m.class
|
230
|
+
assert_equal new_m.object_id, m.object_id
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
should "Reply to sender contruct should be easy" do
|
235
|
+
m = Gmail::Message.new test_to_reply_message
|
236
|
+
reply_message = Gmail::Message.new test_reply_message
|
237
|
+
@mock.expects(:execute).never
|
238
|
+
expected_msg = Gmail::Message.new test_replied_message
|
239
|
+
new_m = m.reply_sender_with reply_message
|
240
|
+
|
241
|
+
assert_equal expected_msg.to, new_m.to
|
242
|
+
assert_nil new_m.cc
|
243
|
+
assert_nil new_m.bcc
|
244
|
+
assert_equal expected_msg.subject, new_m.subject
|
245
|
+
assert_equal expected_msg.references, new_m.references
|
246
|
+
assert_equal expected_msg.in_reply_to, new_m.in_reply_to
|
247
|
+
assert_equal expected_msg.thread_id, new_m.thread_id
|
248
|
+
assert_equal expected_msg.body, new_m.body
|
249
|
+
assert_nil new_m.html
|
250
|
+
assert_nil new_m.text
|
251
|
+
|
252
|
+
new_m = m.reply_sender_with(Gmail::Message.new test_reply_message_with_html)
|
253
|
+
expected_msg = Gmail::Message.new(test_replied_message_with_html)
|
254
|
+
|
255
|
+
assert_equal expected_msg.text, new_m.text
|
256
|
+
assert_equal expected_msg.html, new_m.html
|
257
|
+
assert_nil new_m.body
|
258
|
+
|
259
|
+
end
|
260
|
+
|
261
|
+
should "Reply to all construct should be easy" do
|
262
|
+
m = Gmail::Message.new test_to_reply_message
|
263
|
+
reply_message = Gmail::Message.new test_reply_message
|
264
|
+
@mock.expects(:execute).never
|
265
|
+
new_m = m.reply_all_with reply_message
|
266
|
+
expected_msg = Gmail::Message.new test_replied_message
|
267
|
+
|
268
|
+
assert_equal expected_msg.to, new_m.to
|
269
|
+
assert_equal expected_msg.cc, new_m.cc
|
270
|
+
assert_nil new_m.bcc
|
271
|
+
assert_equal expected_msg.subject, new_m.subject
|
272
|
+
assert_equal expected_msg.references, new_m.references
|
273
|
+
assert_equal expected_msg.in_reply_to, new_m.in_reply_to
|
274
|
+
assert_equal expected_msg.thread_id, new_m.thread_id
|
275
|
+
assert_equal expected_msg.body, new_m.body
|
276
|
+
assert_nil new_m.html
|
277
|
+
assert_nil new_m.text
|
278
|
+
|
279
|
+
new_m = m.reply_all_with(Gmail::Message.new test_reply_message_with_html)
|
280
|
+
expected_msg = Gmail::Message.new(test_replied_message_with_html)
|
281
|
+
|
282
|
+
assert_equal expected_msg.text, new_m.text
|
283
|
+
assert_equal expected_msg.html, new_m.html
|
284
|
+
assert_nil new_m.body
|
285
|
+
|
286
|
+
|
287
|
+
end
|
288
|
+
|
289
|
+
should "Construct correctly set_headers_for_reply" do
|
290
|
+
m = Gmail::Message.new({body: ""})
|
291
|
+
m.from = "\"John, Malkovich\" john@malkovich.com"
|
292
|
+
m.to = "\"Julie, Desk\"julie@juliedesk.com, \"Judith, Desk\"judith@juliedesk.com"
|
293
|
+
m.delivered_to = "julie@juliedesk.com"
|
294
|
+
new_msg = m.send(:set_headers_for_reply, Gmail::Message.new({body: ""}))
|
295
|
+
|
296
|
+
#assert_equal new_msg.from, "\"Julie, Desk\"julie@juliedesk.com"
|
297
|
+
assert_equal new_msg.to, "\"John, Malkovich\" john@malkovich.com"
|
298
|
+
assert_equal new_msg.cc, "\"Judith, Desk\"judith@juliedesk.com"
|
299
|
+
end
|
300
|
+
|
301
|
+
should "Reply to all construct should be easy and call getProfile if delivered_to is not set" do
|
302
|
+
m = Gmail::Message.new test_to_reply_message2
|
303
|
+
reply_message = Gmail::Message.new test_reply_message
|
304
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.to_h['gmail.users.getProfile'],parameters: {userId: "me"} , headers: {'Content-Type' => 'application/json'}).once.returns(test_response({emailAddress: "julie@juliedesk.com"}))
|
305
|
+
new_m = m.reply_all_with reply_message
|
306
|
+
expected_msg = Gmail::Message.new test_replied_message
|
307
|
+
|
308
|
+
assert_equal expected_msg.to, new_m.to
|
309
|
+
assert_equal expected_msg.cc, new_m.cc
|
310
|
+
assert_nil new_m.bcc
|
311
|
+
assert_equal expected_msg.subject, new_m.subject
|
312
|
+
assert_equal expected_msg.references, new_m.references
|
313
|
+
assert_equal expected_msg.in_reply_to, new_m.in_reply_to
|
314
|
+
assert_equal expected_msg.thread_id, new_m.thread_id
|
315
|
+
assert_equal expected_msg.body, new_m.body
|
316
|
+
assert_nil new_m.html
|
317
|
+
assert_nil new_m.text
|
318
|
+
|
319
|
+
|
320
|
+
end
|
321
|
+
|
322
|
+
should "forward construct should be easy" do
|
323
|
+
m = Gmail::Message.new test_to_reply_message
|
324
|
+
forward_message = Gmail::Message.new(test_forward_message)
|
325
|
+
@mock.expects(:execute).never
|
326
|
+
new_m = m.forward_with forward_message
|
327
|
+
expected_msg = Gmail::Message.new test_forwarded_message
|
328
|
+
# to be completed to be fully tested
|
329
|
+
|
330
|
+
assert_equal expected_msg.to, new_m.to
|
331
|
+
assert_equal expected_msg.cc, new_m.cc
|
332
|
+
assert_nil new_m.bcc
|
333
|
+
assert_equal expected_msg.subject, new_m.subject
|
334
|
+
assert_equal expected_msg.references, new_m.references
|
335
|
+
assert_equal expected_msg.in_reply_to, new_m.in_reply_to
|
336
|
+
assert_equal expected_msg.thread_id, new_m.thread_id
|
337
|
+
assert_equal expected_msg.body, new_m.body
|
338
|
+
assert_nil new_m.html
|
339
|
+
assert_nil new_m.text
|
340
|
+
|
341
|
+
forward_message = Gmail::Message.new({to: "test@test.com", bbc: "coucou", cc: "test@couocu.com, second@second.com", subject: "cool subject", html: "<b>test</b>", text: "test"})
|
342
|
+
new_m = m.forward_with forward_message
|
343
|
+
expected_msg = Gmail::Message.new test_forwarded_message_with_html
|
344
|
+
|
345
|
+
assert_equal expected_msg.text, new_m.text
|
346
|
+
assert_equal expected_msg.html, new_m.html
|
347
|
+
assert_nil new_m.body
|
348
|
+
end
|
349
|
+
|
350
|
+
should "Insert call should be easy" do
|
351
|
+
m = Gmail::Message.new test_message
|
352
|
+
m.raw = m.raw
|
353
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.insert, parameters: {userId: "me"}, body_object:{raw: m.raw, labelIds: test_message[:labelIds], threadId: test_message[:threadId]} , headers: {'Content-Type' => 'application/json'} ).twice.returns(test_response(test_message))
|
354
|
+
@mock.expects(:execute).with(api_method: Gmail.service.users.messages.get, parameters: {userId: "me", id: test_message[:id]}, headers: {'Content-Type' => 'application/json'}).twice.returns(test_response(test_message))
|
355
|
+
|
356
|
+
|
357
|
+
new_m = m.insert
|
358
|
+
|
359
|
+
assert_not_equal m.object_id, new_m.object_id
|
360
|
+
new_m = m.insert!
|
361
|
+
assert_equal m.object_id, new_m.object_id
|
362
|
+
end
|
363
|
+
|
364
|
+
end
|
365
|
+
end
|