gmail-britta 0.1.6 → 0.1.7
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/.travis.yml +5 -8
- data/.yardopts +2 -1
- data/Gemfile +3 -2
- data/Gemfile.lock +66 -21
- data/README.md +3 -1
- data/THANKS.md +15 -0
- data/TODO.org +6 -0
- data/VERSION +1 -1
- data/examples/Gemfile.lock +2 -2
- data/examples/asf.rb +29 -2
- data/gmail-britta.gemspec +14 -11
- data/lib/gmail-britta.rb +2 -0
- data/lib/gmail-britta/chaining_filter.rb +82 -0
- data/lib/gmail-britta/filter.rb +117 -62
- data/lib/gmail-britta/filter_set.rb +5 -2
- data/lib/gmail-britta/single_write_accessors.rb +54 -21
- data/test/test_gmail-britta.rb +249 -21
- metadata +24 -39
data/test/test_gmail-britta.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
|
1
4
|
require 'bundler/setup'
|
2
5
|
require 'minitest/unit'
|
3
6
|
require 'nokogiri'
|
@@ -6,15 +9,6 @@ require 'minitest/autorun'
|
|
6
9
|
require 'gmail-britta'
|
7
10
|
|
8
11
|
describe GmailBritta do
|
9
|
-
def simple_filterset
|
10
|
-
fs = GmailBritta.filterset() do
|
11
|
-
filter {
|
12
|
-
has %w{to:asf@boinkor.net}
|
13
|
-
label 'ohai'
|
14
|
-
}.archive_unless_directed
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
12
|
def dom(filterset)
|
19
13
|
text = filterset.generate
|
20
14
|
#puts text
|
@@ -29,33 +23,267 @@ describe GmailBritta do
|
|
29
23
|
end
|
30
24
|
|
31
25
|
it "runs" do
|
32
|
-
|
26
|
+
fs = GmailBritta.filterset() do
|
27
|
+
filter {
|
28
|
+
has 'to:asf@boinkor.net'
|
29
|
+
label 'ohai'
|
30
|
+
}
|
31
|
+
end
|
32
|
+
filters = fs.generate
|
33
33
|
assert(filters, "Should generate something")
|
34
34
|
assert(filters.is_a?(String), "Generated filters should be a string")
|
35
35
|
end
|
36
36
|
|
37
|
-
it "generates
|
38
|
-
|
37
|
+
it "generates 'label' properties" do
|
38
|
+
fs = GmailBritta.filterset() do
|
39
|
+
filter {
|
40
|
+
has 'to:asf@boinkor.net'
|
41
|
+
label 'ohai'
|
42
|
+
}
|
43
|
+
end
|
39
44
|
|
40
|
-
|
41
|
-
assert_equal(
|
45
|
+
filters = dom(fs)
|
46
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="label"]',ns).length, "Should have exactly one 'label' property")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "also generates 'smartLabelToApply' properties" do
|
50
|
+
groups = {
|
51
|
+
'forums' => :group,
|
52
|
+
'Forums' => :group,
|
53
|
+
'notifications' => :notification,
|
54
|
+
'Notifications' => :notification,
|
55
|
+
'updates' => :notification,
|
56
|
+
'Updates' => :notification,
|
57
|
+
'promotions' => :promo,
|
58
|
+
'Promotions' => :promo,
|
59
|
+
'social' => :social,
|
60
|
+
'Social' => :social
|
61
|
+
}
|
62
|
+
|
63
|
+
groups.each do |key, value|
|
64
|
+
fs = GmailBritta.filterset() do
|
65
|
+
filter {
|
66
|
+
has 'to:asf@boinkor.net'
|
67
|
+
label 'ohai'
|
68
|
+
smart_label key
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
filters = dom(fs)
|
73
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="label"]',ns).length, "Should have exactly one 'label' property")
|
74
|
+
|
75
|
+
smart_labels = filters.xpath('/a:feed/a:entry/apps:property[@name="smartLabelToApply"]',ns)
|
76
|
+
assert_equal(1, smart_labels.length, "Should have exactly one 'smartLabelToApply' property")
|
77
|
+
smart_label_value = smart_labels.first['value']
|
78
|
+
assert_equal("^smartlabel_#{value}", smart_label_value, "Should use the smartlabel_ value")
|
79
|
+
end
|
80
|
+
|
81
|
+
err = assert_raises RuntimeError do
|
82
|
+
fs = GmailBritta.filterset() do
|
83
|
+
filter {
|
84
|
+
has 'to:asf@boinkor.net'
|
85
|
+
label 'ohai'
|
86
|
+
smart_label 'Foobar'
|
87
|
+
}
|
88
|
+
end
|
89
|
+
dom(fs)
|
90
|
+
end
|
91
|
+
assert_equal('invalid category "Foobar"', err.message)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "generates simple 'has' condition xml" do
|
95
|
+
filters = dom(
|
96
|
+
GmailBritta.filterset() do
|
97
|
+
filter {
|
98
|
+
has %w{to:asf@boinkor.net}
|
99
|
+
label 'ohai'
|
100
|
+
archive
|
101
|
+
}
|
102
|
+
end
|
103
|
+
)
|
104
|
+
|
105
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry',ns).length, "Should have exactly one filter entry")
|
106
|
+
assert_equal(3, filters.xpath('/a:feed/a:entry/apps:property',ns).length, "Should have two properties")
|
107
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="label"]',ns).length, "Should have exactly one 'label' property")
|
108
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="shouldArchive"]',ns).length, "Should have exactly one 'shouldArchive' property")
|
109
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="hasTheWord"]',ns).length, "Should have exactly one 'has' property")
|
110
|
+
end
|
111
|
+
|
112
|
+
it "generates simple 'has_not' condition xml" do
|
113
|
+
filters = dom(
|
114
|
+
GmailBritta.filterset() do
|
115
|
+
filter {
|
116
|
+
has_not %w{to:asf@boinkor.net}
|
117
|
+
label 'ohai'
|
118
|
+
archive
|
119
|
+
}
|
120
|
+
end
|
121
|
+
)
|
122
|
+
|
123
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry',ns).length, "Should have exactly one filter entry")
|
124
|
+
assert_equal(3, filters.xpath('/a:feed/a:entry/apps:property',ns).length, "Should have two properties")
|
42
125
|
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="label"]',ns).length, "Should have exactly one 'label' property")
|
43
126
|
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="shouldArchive"]',ns).length, "Should have exactly one 'shouldArchive' property")
|
44
|
-
assert_equal(
|
127
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="doesNotHaveTheWord"]',ns).length, "Should have exactly one 'has_not' property")
|
45
128
|
end
|
46
129
|
|
47
|
-
|
48
|
-
|
130
|
+
it "generates simple 'from' condition xml" do
|
131
|
+
filters = dom(
|
132
|
+
GmailBritta.filterset() do
|
133
|
+
filter {
|
134
|
+
from %w{asf@boinkor.net}
|
135
|
+
label 'ohai'
|
136
|
+
}
|
137
|
+
end
|
138
|
+
)
|
139
|
+
|
140
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="from"]',ns).length, "Should have exactly one 'from' property")
|
141
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@value="asf@boinkor.net"]',ns).length, "Should have exactly one 'from' value")
|
142
|
+
end
|
143
|
+
|
144
|
+
it "generates an error for multiple accessors" do
|
145
|
+
err = assert_raises RuntimeError do
|
146
|
+
GmailBritta.filterset() do
|
147
|
+
filter {
|
148
|
+
from %w{asf@boinkor.net}
|
149
|
+
from %w{asf@boinkor.net}
|
150
|
+
label 'ohai'
|
151
|
+
}
|
152
|
+
end
|
153
|
+
end
|
154
|
+
assert_equal('Only one use of from is permitted per filter', err.message)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "generates an error for multiple boolean accessors" do
|
158
|
+
err = assert_raises RuntimeError do
|
159
|
+
GmailBritta.filterset() do
|
160
|
+
filter {
|
161
|
+
from %w{asf@boinkor.net}
|
162
|
+
archive
|
163
|
+
archive
|
164
|
+
}
|
165
|
+
end
|
166
|
+
end
|
167
|
+
assert_equal('Only one use of archive is permitted per filter', err.message)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "generates multiple 'from' condition xml" do
|
171
|
+
filters = dom(
|
172
|
+
GmailBritta.filterset() do
|
173
|
+
filter {
|
174
|
+
from ['asf@boinkor.net', 'abc@boinkor.net']
|
175
|
+
label 'ohai'
|
176
|
+
}
|
177
|
+
end
|
178
|
+
)
|
179
|
+
|
180
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="from"]',ns).length, "Should have exactly one 'from' property")
|
181
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@value="asf@boinkor.net abc@boinkor.net"]',ns).length, "Should have both addresses in 'from' property")
|
182
|
+
end
|
183
|
+
|
184
|
+
it "uses .otherwise for single 'from' condition" do
|
185
|
+
filters = dom(
|
186
|
+
GmailBritta.filterset() do
|
187
|
+
filter {
|
188
|
+
from %w{asf@boinkor.net}
|
189
|
+
label 'ohai'
|
190
|
+
}.otherwise {
|
191
|
+
label 'bai'
|
192
|
+
}
|
193
|
+
end
|
194
|
+
)
|
195
|
+
|
196
|
+
assert_equal(2, filters.xpath('/a:feed/a:entry/apps:property[@name="from"]',ns).length, "Should have two 'from' properties")
|
197
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@value="asf@boinkor.net"]',ns).length, "Should have the address positively exactly once")
|
198
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@value="-asf@boinkor.net"]',ns).length, "Should have the address negatively exactly once")
|
199
|
+
end
|
200
|
+
|
201
|
+
it "uses .also for single 'to' condition" do
|
202
|
+
filters = dom(
|
203
|
+
GmailBritta.filterset() do
|
204
|
+
filter {
|
205
|
+
from %w{from@boinkor.net}
|
206
|
+
label 'ohai'
|
207
|
+
}.also {
|
208
|
+
to %w{to@boinkor.net}
|
209
|
+
}
|
210
|
+
end
|
211
|
+
)
|
212
|
+
|
213
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="from"][@value="from@boinkor.net"]',ns).length, "Should have the from address")
|
214
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="to"][@value="to@boinkor.net"]',ns).length, "Should have the to address")
|
215
|
+
end
|
216
|
+
|
217
|
+
it "understands me" do
|
218
|
+
fs = GmailBritta.filterset(:me => ['thisisme@my-private.org', 'this-is-me@bigco.example.com']) do
|
219
|
+
filter {
|
220
|
+
to_me = me.map {|address| "to:#{address}"}
|
221
|
+
has [{:or => to_me}]
|
222
|
+
}
|
223
|
+
end
|
224
|
+
filters = dom(fs)
|
225
|
+
|
226
|
+
filter_text = filters.xpath('/a:feed/a:entry/apps:property[@name="hasTheWord"]',ns).first['value']
|
227
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="hasTheWord"]',ns).length, "Should have exactly one 'has' property")
|
228
|
+
assert_equal('(to:thisisme@my-private.org OR to:this-is-me@bigco.example.com)', filter_text, "Should have exactly one 'has' property")
|
229
|
+
end
|
230
|
+
|
231
|
+
it "doesn't fail issue #4 - correctly-parenthesised nested ANDs" do
|
232
|
+
fs = GmailBritta.filterset do
|
233
|
+
filter {
|
234
|
+
has :or => [['subject:whee', 'from:zot@spammer.com'], 'from:bob@bob.com', 'from:foo@foo.com']
|
235
|
+
label 'yay'
|
236
|
+
}
|
237
|
+
end
|
238
|
+
filters = dom(fs)
|
239
|
+
|
240
|
+
filter_text = filters.xpath('/a:feed/a:entry/apps:property[@name="hasTheWord"]',ns).first['value']
|
241
|
+
assert_equal('(subject:whee from:zot@spammer.com) OR from:bob@bob.com OR from:foo@foo.com', filter_text)
|
242
|
+
end
|
243
|
+
|
244
|
+
it "uses .otherwise for multiple 'from' condition" do
|
245
|
+
filters = dom(
|
246
|
+
GmailBritta.filterset() do
|
247
|
+
filter {
|
248
|
+
from ['asf@boinkor.net', 'abc@boinkor.net']
|
249
|
+
label 'ohai'
|
250
|
+
}.otherwise {
|
251
|
+
label 'bai'
|
252
|
+
}
|
253
|
+
end
|
254
|
+
)
|
255
|
+
|
256
|
+
assert_equal(2, filters.xpath('/a:feed/a:entry/apps:property[@name="from"]',ns).length, "Should have two 'from' properties")
|
257
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@value="asf@boinkor.net abc@boinkor.net"]',ns).length, "Should have both addresses positively in one 'from' property")
|
258
|
+
assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@value="-asf@boinkor.net -abc@boinkor.net"]',ns).length, "Should have both addresses negated in one 'from' property")
|
259
|
+
end
|
260
|
+
|
261
|
+
describe "subject" do
|
262
|
+
it "works with single subject" do
|
49
263
|
fs = GmailBritta.filterset do
|
50
264
|
filter {
|
51
|
-
|
52
|
-
label '
|
265
|
+
subject 'SPAM: '
|
266
|
+
label 'important'
|
53
267
|
}
|
54
268
|
end
|
269
|
+
|
270
|
+
filters = dom(fs)
|
271
|
+
|
272
|
+
filter_text = filters.xpath('//apps:property[@name="subject"]', ns).first['value']
|
273
|
+
assert_equal('SPAM: ', filter_text)
|
274
|
+
end
|
275
|
+
|
276
|
+
it "works with hash of subjects" do
|
277
|
+
fs = GmailBritta.filterset do
|
278
|
+
filter {
|
279
|
+
subject :or => ['SPAM', 'HAM']
|
280
|
+
}
|
281
|
+
end
|
282
|
+
|
55
283
|
filters = dom(fs)
|
56
284
|
|
57
|
-
filter_text = filters.xpath('
|
58
|
-
assert_equal('
|
285
|
+
filter_text = filters.xpath('//apps:property[@name="subject"]', ns).first['value']
|
286
|
+
assert_equal('SPAM OR HAM', filter_text)
|
59
287
|
end
|
60
288
|
end
|
61
289
|
end
|
metadata
CHANGED
@@ -1,110 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gmail-britta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.7
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Andreas Fuchs
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2016-01-29 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: haml
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 3.1.6
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 3.1.6
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: 0.9.2
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 0.9.2
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: shoulda
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - ">="
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - ">="
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: bundler
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - ">="
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: 1.2.0
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - ">="
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: 1.2.0
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: minitest
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - ">="
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - ">="
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: nokogiri
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - ">="
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - ">="
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '0'
|
110
97
|
description: This gem helps create large (>50) gmail filter chains by writing xml
|
@@ -116,14 +103,15 @@ extra_rdoc_files:
|
|
116
103
|
- LICENSE.txt
|
117
104
|
- README.md
|
118
105
|
files:
|
119
|
-
- .document
|
120
|
-
- .travis.yml
|
121
|
-
- .yardopts
|
106
|
+
- ".document"
|
107
|
+
- ".travis.yml"
|
108
|
+
- ".yardopts"
|
122
109
|
- Gemfile
|
123
110
|
- Gemfile.lock
|
124
111
|
- LICENSE.txt
|
125
112
|
- README.md
|
126
113
|
- Rakefile
|
114
|
+
- THANKS.md
|
127
115
|
- TODO.org
|
128
116
|
- VERSION
|
129
117
|
- examples/Gemfile
|
@@ -132,6 +120,7 @@ files:
|
|
132
120
|
- examples/asf.rb
|
133
121
|
- gmail-britta.gemspec
|
134
122
|
- lib/gmail-britta.rb
|
123
|
+
- lib/gmail-britta/chaining_filter.rb
|
135
124
|
- lib/gmail-britta/filter.rb
|
136
125
|
- lib/gmail-britta/filter_set.rb
|
137
126
|
- lib/gmail-britta/single_write_accessors.rb
|
@@ -139,29 +128,25 @@ files:
|
|
139
128
|
homepage: http://github.com/antifuchs/gmail-britta
|
140
129
|
licenses:
|
141
130
|
- MIT
|
131
|
+
metadata: {}
|
142
132
|
post_install_message:
|
143
133
|
rdoc_options: []
|
144
134
|
require_paths:
|
145
135
|
- lib
|
146
136
|
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
-
none: false
|
148
137
|
requirements:
|
149
|
-
- -
|
138
|
+
- - ">="
|
150
139
|
- !ruby/object:Gem::Version
|
151
140
|
version: '0'
|
152
|
-
segments:
|
153
|
-
- 0
|
154
|
-
hash: -4216942302698371957
|
155
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
|
-
none: false
|
157
142
|
requirements:
|
158
|
-
- -
|
143
|
+
- - ">="
|
159
144
|
- !ruby/object:Gem::Version
|
160
145
|
version: '0'
|
161
146
|
requirements: []
|
162
147
|
rubyforge_project:
|
163
|
-
rubygems_version:
|
148
|
+
rubygems_version: 2.2.5
|
164
149
|
signing_key:
|
165
|
-
specification_version:
|
150
|
+
specification_version: 4
|
166
151
|
summary: Create complex gmail filtersets with a ruby DSL.
|
167
152
|
test_files: []
|