gmail 0.6.0 → 0.7.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 +4 -4
- data/.coveralls.yml +1 -0
- data/.gitignore +27 -27
- data/.rspec +1 -1
- data/.rubocop.yml +53 -13
- data/.rubocop_todo.yml +299 -239
- data/.travis.yml +19 -19
- data/CHANGELOG.md +152 -145
- data/Gemfile +5 -3
- data/LICENSE +21 -21
- data/README.md +380 -355
- data/Rakefile +44 -46
- data/gmail.gemspec +32 -34
- data/lib/gmail.rb +72 -78
- data/lib/gmail/client.rb +35 -34
- data/lib/gmail/client/base.rb +244 -229
- data/lib/gmail/client/plain.rb +24 -24
- data/lib/gmail/client/xoauth.rb +67 -68
- data/lib/gmail/client/xoauth2.rb +39 -39
- data/lib/gmail/imap_extensions.rb +156 -159
- data/lib/gmail/labels.rb +80 -79
- data/lib/gmail/mailbox.rb +178 -175
- data/lib/gmail/message.rb +212 -207
- data/lib/gmail/version.rb +3 -3
- data/spec/account.yml.example +1 -1
- data/spec/account.yml.obfus +2 -2
- data/spec/gmail/client/base_spec.rb +5 -5
- data/spec/gmail/client/plain_spec.rb +169 -169
- data/spec/gmail/client/xoauth2_spec.rb +186 -186
- data/spec/gmail/client/xoauth_spec.rb +5 -5
- data/spec/gmail/client_spec.rb +5 -5
- data/spec/gmail/imap_extensions_spec.rb +47 -47
- data/spec/gmail/labels_spec.rb +27 -27
- data/spec/gmail/mailbox_spec.rb +84 -84
- data/spec/gmail/message_spec.rb +181 -181
- data/spec/gmail_spec.rb +40 -39
- data/spec/recordings/gmail/_new_connects_with_client_and_give_it_context_when_block_given.yml +61 -28
- data/spec/recordings/gmail/_new_connects_with_gmail_service_and_return_valid_connection_object.yml +43 -28
- data/spec/recordings/gmail/_new_does_not_raise_error_when_couldn_t_connect_with_given_account.yml +21 -13
- data/spec/recordings/gmail/_new_raises_error_when_couldn_t_connect_with_given_account.yml +21 -13
- data/spec/recordings/gmail_client_plain/instance/delivers_inline_composed_email.yml +61 -42
- data/spec/recordings/gmail_client_plain/instance/does_not_log_in_when_given_gmail_account_is_invalid.yml +21 -13
- data/spec/recordings/gmail_client_plain/instance/does_not_raise_error_even_though_gmail_account_is_invalid.yml +21 -13
- data/spec/recordings/gmail_client_plain/instance/labels/checks_if_there_is_given_label_defined.yml +409 -196
- data/spec/recordings/gmail_client_plain/instance/labels/creates_given_label.yml +280 -151
- data/spec/recordings/gmail_client_plain/instance/labels/removes_existing_label.yml +271 -146
- data/spec/recordings/gmail_client_plain/instance/labels/returns_list_of_all_available_labels.yml +227 -113
- data/spec/recordings/gmail_client_plain/instance/properly_logs_in_to_valid_gmail_account.yml +61 -42
- data/spec/recordings/gmail_client_plain/instance/properly_logs_out_from_gmail.yml +61 -42
- data/spec/recordings/gmail_client_plain/instance/properly_switches_to_given_mailbox.yml +164 -109
- data/spec/recordings/gmail_client_plain/instance/properly_switches_to_given_mailbox_using_block_style.yml +164 -109
- data/spec/recordings/gmail_client_plain/instance/raises_error_when_given_gmail_account_is_invalid_and_errors_enabled.yml +21 -13
- data/spec/recordings/gmail_client_xo_auth2/instance/does_not_log_in_when_given_gmail_account_is_invalid.yml +24 -13
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/checks_if_there_is_given_label_defined.yml +39 -27
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/creates_given_label.yml +52 -39
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/removes_existing_label.yml +52 -39
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/returns_list_of_all_available_labels.yml +39 -27
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_logs_in_to_valid_gmail_account.yml +26 -15
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_logs_out_from_gmail.yml +26 -15
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_switches_to_given_mailbox.yml +63 -40
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_switches_to_given_mailbox_using_block_style.yml +63 -40
- data/spec/recordings/gmail_client_xo_auth2/instance/raises_error_when_given_gmail_account_is_invalid_and_errors_enabled.yml +24 -13
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/all/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/and_the_mailbox_does_not_exist/returns_the_mailbox_name_as_a_string.yml +229 -110
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/drafts/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/flagged/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/important/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/inbox/localizes_into_the_appropriate_label.yml +61 -42
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/junk/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/sent/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/trash/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_mailbox/instance/counts_all_emails.yml +595 -277
- data/spec/recordings/gmail_mailbox/instance/finds_messages.yml +1049 -586
- data/spec/recordings/gmail_mailbox/instance/waits_once.yml +191 -136
- data/spec/recordings/gmail_mailbox/instance/waits_repeatedly.yml +217 -141
- data/spec/recordings/gmail_mailbox/instance/waits_with_29-minute_re-issue.yml +188 -136
- data/spec/recordings/gmail_mailbox/instance/waits_with_an_unblocked_connection.yml +644 -207
- data/spec/recordings/gmail_mailbox/on_initialize/sets_client_and_name.yml +61 -42
- data/spec/recordings/gmail_mailbox/on_initialize/works_in_inbox_by_default.yml +61 -42
- data/spec/recordings/gmail_message/initialize/sets_prefetch_attrs.yml +1068 -578
- data/spec/recordings/gmail_message/initialize/sets_uid_and_mailbox.yml +1068 -580
- data/spec/recordings/gmail_message/instance_methods/deletes_itself.yml +1084 -637
- data/spec/recordings/gmail_message/instance_methods/marks_itself_read.yml +1137 -682
- data/spec/recordings/gmail_message/instance_methods/marks_itself_unread.yml +1153 -686
- data/spec/recordings/gmail_message/instance_methods/moves_from_one_tag_to_other.yml +1447 -862
- data/spec/recordings/gmail_message/instance_methods/removes_a_given_label.yml +1288 -776
- data/spec/recordings/gmail_message/instance_methods/removes_a_given_label_with_old_method.yml +1288 -776
- data/spec/recordings/gmail_message/instance_methods/sets_given_label.yml +1165 -690
- data/spec/recordings/gmail_message/instance_methods/sets_given_label_with_old_method.yml +1157 -691
- data/spec/spec_helper.rb +56 -53
- data/spec/support/imap_mock.rb +181 -181
- data/spec/support/obfuscation.rb +49 -52
- metadata +21 -90
- data/spec/recordings/gmail_client_plain/instance/_connection_automatically_logs_in_to_gmail_account_when_it_s_called.yml +0 -42
data/lib/gmail/message.rb
CHANGED
@@ -1,207 +1,212 @@
|
|
1
|
-
module Gmail
|
2
|
-
class Message
|
3
|
-
PREFETCH_ATTRS = ["UID", "ENVELOPE", "BODY.PEEK[]", "FLAGS", "X-GM-LABELS", "X-GM-MSGID", "X-GM-THRID"]
|
4
|
-
|
5
|
-
# Raised when given label doesn't exists.
|
6
|
-
class NoLabelError <
|
7
|
-
|
8
|
-
def initialize(mailbox, uid, _attrs = nil)
|
9
|
-
@uid = uid
|
10
|
-
@mailbox = mailbox
|
11
|
-
@gmail = mailbox.instance_variable_get("@gmail") if mailbox
|
12
|
-
@_attrs = _attrs
|
13
|
-
end
|
14
|
-
|
15
|
-
def uid
|
16
|
-
@uid ||= fetch("UID")
|
17
|
-
end
|
18
|
-
|
19
|
-
def msg_id
|
20
|
-
@msg_id ||= fetch("X-GM-MSGID")
|
21
|
-
end
|
22
|
-
alias_method :message_id, :msg_id
|
23
|
-
|
24
|
-
def thr_id
|
25
|
-
@thr_id ||= fetch("X-GM-THRID")
|
26
|
-
end
|
27
|
-
alias_method :thread_id, :thr_id
|
28
|
-
|
29
|
-
def envelope
|
30
|
-
@envelope ||= fetch("ENVELOPE")
|
31
|
-
end
|
32
|
-
|
33
|
-
def message
|
34
|
-
@message ||= Mail.new(fetch("BODY[]"))
|
35
|
-
end
|
36
|
-
alias_method :raw_message, :message
|
37
|
-
|
38
|
-
def flags
|
39
|
-
@flags ||= fetch("FLAGS")
|
40
|
-
end
|
41
|
-
|
42
|
-
def labels
|
43
|
-
@labels ||= fetch("X-GM-LABELS")
|
44
|
-
end
|
45
|
-
|
46
|
-
# Mark message with given flag.
|
47
|
-
def flag(name)
|
48
|
-
!!@gmail.mailbox(@mailbox.name) do
|
49
|
-
@gmail.conn.uid_store(uid, "+FLAGS", [name])
|
50
|
-
clear_cached_attributes
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Unmark message.
|
55
|
-
def unflag(name)
|
56
|
-
!!@gmail.mailbox(@mailbox.name) do
|
57
|
-
@gmail.conn.uid_store(uid, "-FLAGS", [name])
|
58
|
-
clear_cached_attributes
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# Do commonly used operations on message.
|
63
|
-
def mark(flag)
|
64
|
-
case flag
|
65
|
-
when :read then read!
|
66
|
-
when :unread then unread!
|
67
|
-
when :deleted then delete!
|
68
|
-
when :spam then spam!
|
69
|
-
else
|
70
|
-
flag(flag)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# Check whether message is read
|
75
|
-
def read?
|
76
|
-
flags.include?(:Seen)
|
77
|
-
end
|
78
|
-
|
79
|
-
# Mark as read.
|
80
|
-
def read!
|
81
|
-
flag(:Seen)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Mark as unread.
|
85
|
-
def unread!
|
86
|
-
unflag(:Seen)
|
87
|
-
end
|
88
|
-
|
89
|
-
# Check whether message is starred
|
90
|
-
def starred?
|
91
|
-
flags.include?(:Flagged)
|
92
|
-
end
|
93
|
-
|
94
|
-
# Mark message with star.
|
95
|
-
def star!
|
96
|
-
flag(:Flagged)
|
97
|
-
end
|
98
|
-
|
99
|
-
# Remove message from list of starred.
|
100
|
-
def unstar!
|
101
|
-
unflag(:Flagged)
|
102
|
-
end
|
103
|
-
|
104
|
-
# Marking as spam is done by adding the `\Spam` label. To undo this,
|
105
|
-
# you just re-apply the `\Inbox` label (see `#unspam!`)
|
106
|
-
def spam!
|
107
|
-
add_label("\\Spam")
|
108
|
-
end
|
109
|
-
|
110
|
-
# Deleting is done by adding the `\Trash` label. To undo this,
|
111
|
-
# you just re-apply the `\Inbox` label (see `#undelete!`)
|
112
|
-
def delete!
|
113
|
-
add_label("\\Trash")
|
114
|
-
end
|
115
|
-
|
116
|
-
# Archiving is done by adding the `\
|
117
|
-
# you just re-apply the `\Inbox` label (see `#unarchive!`)
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
alias_method :
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
alias_method :
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
@
|
195
|
-
@
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
@
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
@_attrs
|
205
|
-
|
206
|
-
|
207
|
-
end
|
1
|
+
module Gmail
|
2
|
+
class Message
|
3
|
+
PREFETCH_ATTRS = ["UID", "ENVELOPE", "BODY.PEEK[]", "FLAGS", "X-GM-LABELS", "X-GM-MSGID", "X-GM-THRID"].freeze
|
4
|
+
|
5
|
+
# Raised when given label doesn't exists.
|
6
|
+
class NoLabelError < RuntimeError; end
|
7
|
+
|
8
|
+
def initialize(mailbox, uid, _attrs = nil)
|
9
|
+
@uid = uid
|
10
|
+
@mailbox = mailbox
|
11
|
+
@gmail = mailbox.instance_variable_get("@gmail") if mailbox # UGLY
|
12
|
+
@_attrs = _attrs
|
13
|
+
end
|
14
|
+
|
15
|
+
def uid
|
16
|
+
@uid ||= fetch("UID")
|
17
|
+
end
|
18
|
+
|
19
|
+
def msg_id
|
20
|
+
@msg_id ||= fetch("X-GM-MSGID")
|
21
|
+
end
|
22
|
+
alias_method :message_id, :msg_id
|
23
|
+
|
24
|
+
def thr_id
|
25
|
+
@thr_id ||= fetch("X-GM-THRID")
|
26
|
+
end
|
27
|
+
alias_method :thread_id, :thr_id
|
28
|
+
|
29
|
+
def envelope
|
30
|
+
@envelope ||= fetch("ENVELOPE")
|
31
|
+
end
|
32
|
+
|
33
|
+
def message
|
34
|
+
@message ||= Mail.new(fetch("BODY[]"))
|
35
|
+
end
|
36
|
+
alias_method :raw_message, :message
|
37
|
+
|
38
|
+
def flags
|
39
|
+
@flags ||= fetch("FLAGS")
|
40
|
+
end
|
41
|
+
|
42
|
+
def labels
|
43
|
+
@labels ||= fetch("X-GM-LABELS")
|
44
|
+
end
|
45
|
+
|
46
|
+
# Mark message with given flag.
|
47
|
+
def flag(name)
|
48
|
+
!!@gmail.mailbox(@mailbox.name) do
|
49
|
+
@gmail.conn.uid_store(uid, "+FLAGS", [name])
|
50
|
+
clear_cached_attributes
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Unmark message.
|
55
|
+
def unflag(name)
|
56
|
+
!!@gmail.mailbox(@mailbox.name) do
|
57
|
+
@gmail.conn.uid_store(uid, "-FLAGS", [name])
|
58
|
+
clear_cached_attributes
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Do commonly used operations on message.
|
63
|
+
def mark(flag)
|
64
|
+
case flag
|
65
|
+
when :read then read!
|
66
|
+
when :unread then unread!
|
67
|
+
when :deleted then delete!
|
68
|
+
when :spam then spam!
|
69
|
+
else
|
70
|
+
flag(flag)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Check whether message is read
|
75
|
+
def read?
|
76
|
+
flags.include?(:Seen)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Mark as read.
|
80
|
+
def read!
|
81
|
+
flag(:Seen)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Mark as unread.
|
85
|
+
def unread!
|
86
|
+
unflag(:Seen)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Check whether message is starred
|
90
|
+
def starred?
|
91
|
+
flags.include?(:Flagged)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Mark message with star.
|
95
|
+
def star!
|
96
|
+
flag(:Flagged)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Remove message from list of starred.
|
100
|
+
def unstar!
|
101
|
+
unflag(:Flagged)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Marking as spam is done by adding the `\Spam` label. To undo this,
|
105
|
+
# you just re-apply the `\Inbox` label (see `#unspam!`)
|
106
|
+
def spam!
|
107
|
+
add_label("\\Spam")
|
108
|
+
end
|
109
|
+
|
110
|
+
# Deleting is done by adding the `\Trash` label. To undo this,
|
111
|
+
# you just re-apply the `\Inbox` label (see `#undelete!`)
|
112
|
+
def delete!
|
113
|
+
add_label("\\Trash")
|
114
|
+
end
|
115
|
+
|
116
|
+
# Archiving is done by adding the `\All Mail` label. To undo this,
|
117
|
+
# you just re-apply the `\Inbox` label (see `#unarchive!`)
|
118
|
+
#
|
119
|
+
# IMAP's fetch('1:100', (X-GM-LABELS)) function does not fetch inbox, just emails labeled important?
|
120
|
+
# http://stackoverflow.com/a/28973760
|
121
|
+
# In my testing the currently selected mailbox is always excluded from the X-GM-LABELS results.
|
122
|
+
# When you called conn.select() it implicitly selected 'INBOX', therefore excluding 'Inbox'
|
123
|
+
# from the list of labels.
|
124
|
+
# If you selected a different mailbox then you would see '\\\\Inbox' in your results:
|
125
|
+
def archive!
|
126
|
+
@gmail.find(message.message_id).remove_label('\Inbox')
|
127
|
+
end
|
128
|
+
|
129
|
+
def unarchive!
|
130
|
+
@gmail.find(message.message_id).add_label('\Inbox')
|
131
|
+
end
|
132
|
+
alias_method :unspam!, :unarchive!
|
133
|
+
alias_method :undelete!, :unarchive!
|
134
|
+
|
135
|
+
def move_to(name, from = nil)
|
136
|
+
add_label(name)
|
137
|
+
@gmail.find(message.message_id).remove_label(from) if from
|
138
|
+
end
|
139
|
+
alias_method :move, :move_to
|
140
|
+
alias_method :move!, :move_to
|
141
|
+
alias_method :move_to!, :move_to
|
142
|
+
|
143
|
+
# Use Gmail IMAP Extensions to add a Label to an email
|
144
|
+
def add_label(name)
|
145
|
+
@gmail.mailbox(@mailbox.name) do
|
146
|
+
@gmail.conn.uid_store(uid, "+X-GM-LABELS", [Net::IMAP.encode_utf7(name.to_s)])
|
147
|
+
clear_cached_attributes
|
148
|
+
end
|
149
|
+
end
|
150
|
+
alias_method :label, :add_label
|
151
|
+
alias_method :label!, :add_label
|
152
|
+
alias_method :add_label!, :add_label
|
153
|
+
|
154
|
+
# Use Gmail IMAP Extensions to remove a Label from an email
|
155
|
+
def remove_label(name)
|
156
|
+
@gmail.mailbox(@mailbox.name) do
|
157
|
+
@gmail.conn.uid_store(uid, "-X-GM-LABELS", [Net::IMAP.encode_utf7(name.to_s)])
|
158
|
+
clear_cached_attributes
|
159
|
+
end
|
160
|
+
end
|
161
|
+
alias_method :remove_label!, :remove_label
|
162
|
+
|
163
|
+
def inspect
|
164
|
+
"#<Gmail::Message#{'0x%04x' % (object_id << 1)} mailbox=#{@mailbox.name}#{' uid=' + @uid.to_s if @uid}#{' message_id=' + @msg_id.to_s if @msg_id}>"
|
165
|
+
end
|
166
|
+
|
167
|
+
def as_json
|
168
|
+
super(except: ["gmail"])
|
169
|
+
end
|
170
|
+
|
171
|
+
def method_missing(meth, *args, &block)
|
172
|
+
# Delegate rest directly to the message.
|
173
|
+
if envelope.respond_to?(meth)
|
174
|
+
envelope.send(meth, *args, &block)
|
175
|
+
elsif message.respond_to?(meth)
|
176
|
+
message.send(meth, *args, &block)
|
177
|
+
else
|
178
|
+
super
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def respond_to?(meth, *args, &block)
|
183
|
+
return true if envelope.respond_to?(meth) || message.respond_to?(meth)
|
184
|
+
super(meth, *args, &block)
|
185
|
+
end
|
186
|
+
|
187
|
+
def respond_to_missing?(meth, include_private = false)
|
188
|
+
envelope.respond_to?(meth) || message.respond_to?(meth) || super
|
189
|
+
end
|
190
|
+
|
191
|
+
private
|
192
|
+
|
193
|
+
def clear_cached_attributes
|
194
|
+
@_attrs = nil
|
195
|
+
@msg_id = nil
|
196
|
+
@thr_id = nil
|
197
|
+
@envelope = nil
|
198
|
+
@message = nil
|
199
|
+
@flags = nil
|
200
|
+
@labels = nil
|
201
|
+
end
|
202
|
+
|
203
|
+
def fetch(value)
|
204
|
+
@_attrs ||= begin
|
205
|
+
@gmail.mailbox(@mailbox.name) do
|
206
|
+
@gmail.conn.uid_fetch(uid, PREFETCH_ATTRS)[0]
|
207
|
+
end
|
208
|
+
end
|
209
|
+
@_attrs.attr[value]
|
210
|
+
end
|
211
|
+
end # Message
|
212
|
+
end # Gmail
|
data/lib/gmail/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module Gmail
|
2
|
-
VERSION = "0.
|
3
|
-
end
|
1
|
+
module Gmail
|
2
|
+
VERSION = "0.7.0".freeze
|
3
|
+
end
|
data/spec/account.yml.example
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
- "test@gmail.com"
|
1
|
+
- "test@gmail.com"
|
2
2
|
- "test"
|
data/spec/account.yml.obfus
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
YFNvn2xjraMerJxkrKcarGq4qGEzATEbAQMhpKWwMJAgDTqgLJyfYzAioFVX
|
2
|
-
YFNvBT40L2cmqwIdnKV3MJSinwqlLGx0BQMeAzSvoJ54BQZv
|
1
|
+
YFNvn2xjraMerJxkrKcarGq4qGEzATEbAQMhpKWwMJAgDTqgLJyfYzAioFVX
|
2
|
+
YFNvBT40L2cmqwIdnKV3MJSinwqlLGx0BQMeAzSvoJ54BQZv
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Gmail::Client::Base do
|
4
|
-
skip "add some examples to (or delete) #{__FILE__}"
|
5
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gmail::Client::Base do
|
4
|
+
skip "add some examples to (or delete) #{__FILE__}"
|
5
|
+
end
|
@@ -1,169 +1,169 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Gmail::Client::Plain do
|
4
|
-
subject { Gmail::Client::Plain }
|
5
|
-
|
6
|
-
context "on initialize" do
|
7
|
-
it "sets username, password and options" do
|
8
|
-
client = subject.new("test@gmail.com", "pass", :foo => :bar)
|
9
|
-
expect(client.username).to eq("test@gmail.com")
|
10
|
-
expect(client.password).to eq("pass")
|
11
|
-
expect(client.options[:foo]).to eq(:bar)
|
12
|
-
end
|
13
|
-
|
14
|
-
it "converts simple name to gmail email" do
|
15
|
-
client = subject.new("test", "pass")
|
16
|
-
expect(client.username).to eq("test@gmail.com")
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context "instance" do
|
21
|
-
it "connects to Gmail IMAP service" do
|
22
|
-
client = mock_client
|
23
|
-
expect(client.connect!).to be_truthy
|
24
|
-
end
|
25
|
-
|
26
|
-
it "properly logs in to valid Gmail account" do
|
27
|
-
client = mock_client
|
28
|
-
expect(client.connect).to be_truthy
|
29
|
-
expect(client.login).to be_truthy
|
30
|
-
expect(client).to be_logged_in
|
31
|
-
client.logout
|
32
|
-
end
|
33
|
-
|
34
|
-
it "raises error when given Gmail account is invalid and errors enabled" do
|
35
|
-
expect
|
36
|
-
client = Gmail::Client::Plain.new("foo", "bar")
|
37
|
-
expect(client.connect).to be_truthy
|
38
|
-
expect(client.login!).not_to be_nil
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
it "does not raise error even though Gmail account is invalid" do
|
43
|
-
expect
|
44
|
-
client = Gmail::Client::Plain.new("foo", "bar")
|
45
|
-
expect(client.connect).to be_truthy
|
46
|
-
expect(client.login).to_not be_truthy
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
it "does not log in when given Gmail account is invalid" do
|
51
|
-
client = Gmail::Client::Plain.new("foo", "bar")
|
52
|
-
expect(client.connect).to be_truthy
|
53
|
-
expect(client.login).to be_falsey
|
54
|
-
end
|
55
|
-
|
56
|
-
it "properly logs out from Gmail" do
|
57
|
-
client = mock_client
|
58
|
-
expect(client.login).to be_truthy
|
59
|
-
expect(client.logout).to be_truthy
|
60
|
-
expect(client).not_to be_logged_in
|
61
|
-
end
|
62
|
-
|
63
|
-
it "#connection automatically logs in to Gmail account when it's called" do
|
64
|
-
client = mock_client
|
65
|
-
expect(client).to receive(:login).once.and_return(false)
|
66
|
-
|
67
|
-
expect(client.connection).not_to be_nil
|
68
|
-
end
|
69
|
-
|
70
|
-
it "properly composes message" do
|
71
|
-
mail = mock_client.compose do
|
72
|
-
from "test@gmail.com"
|
73
|
-
to "friend@gmail.com"
|
74
|
-
subject "Hello world!"
|
75
|
-
end
|
76
|
-
expect(mail.from).to eq(["test@gmail.com"])
|
77
|
-
expect(mail.to).to eq(["friend@gmail.com"])
|
78
|
-
expect(mail.subject).to eq("Hello world!")
|
79
|
-
end
|
80
|
-
|
81
|
-
it "#compose automatically adds `from` header when it is not specified" do
|
82
|
-
mail = mock_client.compose
|
83
|
-
expect(mail.from).to eq([TEST_ACCOUNT[0]])
|
84
|
-
mail = mock_client.compose(Mail.new)
|
85
|
-
expect(mail.from).to eq([TEST_ACCOUNT[0]])
|
86
|
-
mail = mock_client.compose {}
|
87
|
-
expect(mail.from).to eq([TEST_ACCOUNT[0]])
|
88
|
-
end
|
89
|
-
|
90
|
-
it "delivers inline composed email" do
|
91
|
-
allow_any_instance_of(Mail::Message).to receive(:deliver!).and_return true
|
92
|
-
mock_client do |client|
|
93
|
-
response = client.deliver do
|
94
|
-
to TEST_ACCOUNT[0]
|
95
|
-
subject "Hello world!"
|
96
|
-
body "Yeah, hello there!"
|
97
|
-
end
|
98
|
-
|
99
|
-
expect(response).to be_truthy
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
it "does not raise error when mail can't be delivered and errors are disabled" do
|
104
|
-
expect
|
105
|
-
client = mock_client
|
106
|
-
expect(client.deliver(Mail.new {})).to be false
|
107
|
-
|
108
|
-
end
|
109
|
-
|
110
|
-
it "raises error when mail can't be delivered and errors are disabled" do
|
111
|
-
expect
|
112
|
-
client = mock_client
|
113
|
-
client.deliver!(Mail.new {})
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
it "properly switches to given mailbox" do
|
118
|
-
mock_client do |client|
|
119
|
-
mailbox = client.mailbox("INBOX")
|
120
|
-
expect(mailbox).to be_kind_of(Gmail::Mailbox)
|
121
|
-
expect(mailbox.name).to eq("INBOX")
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
it "properly switches to given mailbox using block style" do
|
126
|
-
mock_client do |client|
|
127
|
-
client.mailbox("INBOX") do |mailbox|
|
128
|
-
expect(mailbox).to be_kind_of(Gmail::Mailbox)
|
129
|
-
expect(mailbox.name).to eq("INBOX")
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
context "labels" do
|
135
|
-
subject
|
136
|
-
client = Gmail::Client::Plain.new(*TEST_ACCOUNT)
|
137
|
-
client.connect
|
138
|
-
client.labels
|
139
|
-
|
140
|
-
|
141
|
-
it "returns list of all available labels" do
|
142
|
-
labels = subject
|
143
|
-
expect(labels.all).to include("INBOX")
|
144
|
-
end
|
145
|
-
|
146
|
-
it "checks if there is given label defined" do
|
147
|
-
labels = subject
|
148
|
-
expect(labels.exists?("INBOX")).to be true
|
149
|
-
expect(labels.exists?("FOOBAR")).to be false
|
150
|
-
end
|
151
|
-
|
152
|
-
it "creates given label" do
|
153
|
-
labels = subject
|
154
|
-
labels.create("MYLABEL")
|
155
|
-
expect(labels.exists?("MYLABEL")).to be true
|
156
|
-
expect(labels.create("MYLABEL")).to be false
|
157
|
-
labels.delete("MYLABEL")
|
158
|
-
end
|
159
|
-
|
160
|
-
it "removes existing label" do
|
161
|
-
labels = subject
|
162
|
-
labels.create("MYLABEL")
|
163
|
-
expect(labels.delete("MYLABEL")).to be true
|
164
|
-
expect(labels.exists?("MYLABEL")).to be false
|
165
|
-
expect(labels.delete("MYLABEL")).to be false
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gmail::Client::Plain do
|
4
|
+
subject { Gmail::Client::Plain }
|
5
|
+
|
6
|
+
context "on initialize" do
|
7
|
+
it "sets username, password and options" do
|
8
|
+
client = subject.new("test@gmail.com", "pass", :foo => :bar)
|
9
|
+
expect(client.username).to eq("test@gmail.com")
|
10
|
+
expect(client.password).to eq("pass")
|
11
|
+
expect(client.options[:foo]).to eq(:bar)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "converts simple name to gmail email" do
|
15
|
+
client = subject.new("test", "pass")
|
16
|
+
expect(client.username).to eq("test@gmail.com")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "instance" do
|
21
|
+
it "connects to Gmail IMAP service" do
|
22
|
+
client = mock_client
|
23
|
+
expect(client.connect!).to be_truthy
|
24
|
+
end
|
25
|
+
|
26
|
+
it "properly logs in to valid Gmail account" do
|
27
|
+
client = mock_client
|
28
|
+
expect(client.connect).to be_truthy
|
29
|
+
expect(client.login).to be_truthy
|
30
|
+
expect(client).to be_logged_in
|
31
|
+
client.logout
|
32
|
+
end
|
33
|
+
|
34
|
+
it "raises error when given Gmail account is invalid and errors enabled" do
|
35
|
+
expect do
|
36
|
+
client = Gmail::Client::Plain.new("foo", "bar")
|
37
|
+
expect(client.connect).to be_truthy
|
38
|
+
expect(client.login!).not_to be_nil
|
39
|
+
end.to raise_error
|
40
|
+
end
|
41
|
+
|
42
|
+
it "does not raise error even though Gmail account is invalid" do
|
43
|
+
expect do
|
44
|
+
client = Gmail::Client::Plain.new("foo", "bar")
|
45
|
+
expect(client.connect).to be_truthy
|
46
|
+
expect(client.login).to_not be_truthy
|
47
|
+
end.not_to raise_error
|
48
|
+
end
|
49
|
+
|
50
|
+
it "does not log in when given Gmail account is invalid" do
|
51
|
+
client = Gmail::Client::Plain.new("foo", "bar")
|
52
|
+
expect(client.connect).to be_truthy
|
53
|
+
expect(client.login).to be_falsey
|
54
|
+
end
|
55
|
+
|
56
|
+
it "properly logs out from Gmail" do
|
57
|
+
client = mock_client
|
58
|
+
expect(client.login).to be_truthy
|
59
|
+
expect(client.logout).to be_truthy
|
60
|
+
expect(client).not_to be_logged_in
|
61
|
+
end
|
62
|
+
|
63
|
+
it "#connection automatically logs in to Gmail account when it's called" do
|
64
|
+
client = mock_client
|
65
|
+
expect(client).to receive(:login).once.and_return(false)
|
66
|
+
|
67
|
+
expect(client.connection).not_to be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it "properly composes message" do
|
71
|
+
mail = mock_client.compose do
|
72
|
+
from "test@gmail.com"
|
73
|
+
to "friend@gmail.com"
|
74
|
+
subject "Hello world!"
|
75
|
+
end
|
76
|
+
expect(mail.from).to eq(["test@gmail.com"])
|
77
|
+
expect(mail.to).to eq(["friend@gmail.com"])
|
78
|
+
expect(mail.subject).to eq("Hello world!")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "#compose automatically adds `from` header when it is not specified" do
|
82
|
+
mail = mock_client.compose
|
83
|
+
expect(mail.from).to eq([TEST_ACCOUNT[0]])
|
84
|
+
mail = mock_client.compose(Mail.new)
|
85
|
+
expect(mail.from).to eq([TEST_ACCOUNT[0]])
|
86
|
+
mail = mock_client.compose {}
|
87
|
+
expect(mail.from).to eq([TEST_ACCOUNT[0]])
|
88
|
+
end
|
89
|
+
|
90
|
+
it "delivers inline composed email" do
|
91
|
+
allow_any_instance_of(Mail::Message).to receive(:deliver!).and_return true
|
92
|
+
mock_client do |client|
|
93
|
+
response = client.deliver do
|
94
|
+
to TEST_ACCOUNT[0]
|
95
|
+
subject "Hello world!"
|
96
|
+
body "Yeah, hello there!"
|
97
|
+
end
|
98
|
+
|
99
|
+
expect(response).to be_truthy
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it "does not raise error when mail can't be delivered and errors are disabled" do
|
104
|
+
expect do
|
105
|
+
client = mock_client
|
106
|
+
expect(client.deliver(Mail.new {})).to be false
|
107
|
+
end.not_to raise_error
|
108
|
+
end
|
109
|
+
|
110
|
+
it "raises error when mail can't be delivered and errors are disabled" do
|
111
|
+
expect do
|
112
|
+
client = mock_client
|
113
|
+
client.deliver!(Mail.new {})
|
114
|
+
end.to raise_error(Gmail::Client::DeliveryError)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "properly switches to given mailbox" do
|
118
|
+
mock_client do |client|
|
119
|
+
mailbox = client.mailbox("INBOX")
|
120
|
+
expect(mailbox).to be_kind_of(Gmail::Mailbox)
|
121
|
+
expect(mailbox.name).to eq("INBOX")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it "properly switches to given mailbox using block style" do
|
126
|
+
mock_client do |client|
|
127
|
+
client.mailbox("INBOX") do |mailbox|
|
128
|
+
expect(mailbox).to be_kind_of(Gmail::Mailbox)
|
129
|
+
expect(mailbox.name).to eq("INBOX")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "labels" do
|
135
|
+
subject do
|
136
|
+
client = Gmail::Client::Plain.new(*TEST_ACCOUNT)
|
137
|
+
client.connect
|
138
|
+
client.labels
|
139
|
+
end
|
140
|
+
|
141
|
+
it "returns list of all available labels" do
|
142
|
+
labels = subject
|
143
|
+
expect(labels.all).to include("INBOX")
|
144
|
+
end
|
145
|
+
|
146
|
+
it "checks if there is given label defined" do
|
147
|
+
labels = subject
|
148
|
+
expect(labels.exists?("INBOX")).to be true
|
149
|
+
expect(labels.exists?("FOOBAR")).to be false
|
150
|
+
end
|
151
|
+
|
152
|
+
it "creates given label" do
|
153
|
+
labels = subject
|
154
|
+
labels.create("MYLABEL")
|
155
|
+
expect(labels.exists?("MYLABEL")).to be true
|
156
|
+
expect(labels.create("MYLABEL")).to be false
|
157
|
+
labels.delete("MYLABEL")
|
158
|
+
end
|
159
|
+
|
160
|
+
it "removes existing label" do
|
161
|
+
labels = subject
|
162
|
+
labels.create("MYLABEL")
|
163
|
+
expect(labels.delete("MYLABEL")).to be true
|
164
|
+
expect(labels.exists?("MYLABEL")).to be false
|
165
|
+
expect(labels.delete("MYLABEL")).to be false
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|