dmarc 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
1
  module DMARC
2
2
  # dmarc version
3
- VERSION = '0.2.0'
3
+ VERSION = '0.3.0'
4
4
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'dmarc'
3
+
4
+ describe DMARC do
5
+ subject { described_class }
6
+
7
+ describe ".query" do
8
+ context "when given a domain" do
9
+ let(:domain) { 'google.com' }
10
+
11
+ it "should query and parse the DMARC record" do
12
+ record = subject.query(domain)
13
+
14
+ expect(record).to be == 'v=DMARC1; p=quarantine; rua=mailto:mailauth-reports@google.com'
15
+ end
16
+ end
17
+
18
+ context "when given a bad domain" do
19
+ it "should raise a DNS error" do
20
+ expect(subject.query('foobar.com')).to be_nil
21
+ end
22
+ end
23
+ end
24
+ end
@@ -2,301 +2,322 @@ require 'spec_helper'
2
2
  require 'dmarc/parser'
3
3
 
4
4
  describe Parser do
5
- describe '#dmarc_uri' do
6
- subject { described_class.new.dmarc_uri }
5
+ describe "rules" do
6
+ describe 'dmarc_uri' do
7
+ subject { described_class.new.dmarc_uri }
7
8
 
8
- let(:uri) { 'mailto:user@example.org' }
9
+ let(:uri) { 'mailto:user@example.org' }
9
10
 
10
- it 'parses mailto URIs' do
11
- expect(subject.parse(uri)).to eq(uri: uri)
12
- end
11
+ it 'parses mailto URIs' do
12
+ expect(subject.parse(uri)).to eq(uri: uri)
13
+ end
13
14
 
14
- it 'parses mailto URIs with size' do
15
- expect(subject.parse(uri + '!20')).to eq(uri: uri, size: '20')
16
- end
15
+ it 'parses mailto URIs with size' do
16
+ expect(subject.parse(uri + '!20')).to eq(uri: uri, size: '20')
17
+ end
17
18
 
18
- it 'parses mailto URIs with size and unit' do
19
- expect(subject.parse(uri + '!20k')).to eq(uri: uri, size: '20', unit: 'k')
19
+ it 'parses mailto URIs with size and unit' do
20
+ expect(subject.parse(uri + '!20k')).to eq(uri: uri, size: '20', unit: 'k')
21
+ end
20
22
  end
21
- end
22
23
 
23
- describe '#dmarc_record' do
24
- subject { described_class.new.dmarc_record }
24
+ describe 'dmarc_record' do
25
+ subject { described_class.new.dmarc_record }
25
26
 
26
- it 'parses version and policy' do
27
- record = 'v=DMARC1;p=none'
28
- expect(subject.parse record).to eq([
29
- {v: 'DMARC1'},
30
- {p: 'none'}
31
- ])
32
- end
27
+ it 'parses version and policy' do
28
+ record = 'v=DMARC1;p=none'
29
+ expect(subject.parse record).to eq([
30
+ {v: 'DMARC1'},
31
+ {p: 'none'}
32
+ ])
33
+ end
33
34
 
34
- it 'parses version, policy, and other tags' do
35
- record = 'v=DMARC1;p=none;sp=reject;adkim=r;aspf=r'
36
- expect(subject.parse(record)).to eq([
37
- {v: 'DMARC1'},
38
- {p: 'none'},
39
- {sp: 'reject'},
40
- {adkim: 'r'},
41
- {aspf: 'r'}
42
- ])
43
- end
35
+ it 'parses version, policy, and other tags' do
36
+ record = 'v=DMARC1;p=none;sp=reject;adkim=r;aspf=r'
37
+ expect(subject.parse(record)).to eq([
38
+ {v: 'DMARC1'},
39
+ {p: 'none'},
40
+ {sp: 'reject'},
41
+ {adkim: 'r'},
42
+ {aspf: 'r'}
43
+ ])
44
+ end
44
45
 
45
- it 'parses version, policy, and rua' do
46
- record = 'v=DMARC1;p=quarantine;rua=mailto:foo@example.com,mailto:bar@example.com'
47
- expect(subject.parse record).to eq([
48
- {v: 'DMARC1'},
49
- {p: 'quarantine'},
50
- {rua: [
51
- {uri: 'mailto:foo@example.com'},
52
- {uri: 'mailto:bar@example.com'}
53
- ]}
54
- ])
55
- end
46
+ it 'parses version, policy, and rua' do
47
+ record = 'v=DMARC1;p=quarantine;rua=mailto:foo@example.com,mailto:bar@example.com'
48
+ expect(subject.parse record).to eq([
49
+ {v: 'DMARC1'},
50
+ {p: 'quarantine'},
51
+ {rua: [
52
+ {uri: 'mailto:foo@example.com'},
53
+ {uri: 'mailto:bar@example.com'}
54
+ ]}
55
+ ])
56
+ end
56
57
 
57
- it 'ignores spacing' do
58
- record1 = 'v=DMARC1;p=none;sp=reject'
59
- record2 = 'v = DMARC1 ; p = none ; sp = reject'
60
- expect(subject.parse record1).to eq(subject.parse record2)
61
- end
58
+ it 'ignores order of tags' do
59
+ record = 'v=DMARC1; rua=mailto:foo@example.com; p=none'
62
60
 
63
- it "ignores unknown tags" do
64
- record = 'v=DMARC1;p=none;foo=xxx;sp=reject;bar=xxx;adkim=r;aspf=r'
65
- expect(subject.parse(record)).to eq([
66
- {v: 'DMARC1'},
67
- {p: 'none'},
68
- {sp: 'reject'},
69
- {adkim: 'r'},
70
- {aspf: 'r'}
71
- ])
72
- end
61
+ expect(subject.parse(record)).to eq([
62
+ {v: 'DMARC1'},
63
+ {rua: {uri: 'mailto:foo@example.com'}},
64
+ {p: 'none'}
65
+ ])
66
+ end
73
67
 
74
- it "ignores syntax errors" do
75
- record = 'v=DMARC1;p=none;sp;adkim=X;aspf='
76
- expect(subject.parse(record)).to eq([
77
- {v: 'DMARC1'},
78
- {p: 'none'}
79
- ])
80
- end
81
- end
68
+ it 'ignores spacing' do
69
+ record1 = 'v=DMARC1;p=none;sp=reject'
70
+ record2 = 'v = DMARC1 ; p = none ; sp = reject'
71
+ expect(subject.parse record1).to eq(subject.parse record2)
72
+ end
82
73
 
83
- describe '#dmarc_version' do
84
- subject { described_class.new.dmarc_version }
74
+ it 'ignores trailing separators' do
75
+ record = 'v=DMARC1; p=none; '
85
76
 
86
- it 'parses DMARC versions' do
87
- expect(subject.parse('v=DMARC1')).to eq(v: 'DMARC1')
88
- end
77
+ expect(subject.parse(record)).to eq([
78
+ {v: 'DMARC1'},
79
+ {p: 'none'}
80
+ ])
81
+ end
89
82
 
90
- it 'ignores spacing' do
91
- expect(subject.parse 'v = DMARC1').to eq(subject.parse 'v=DMARC1')
83
+ it "ignores unknown tags" do
84
+ record = 'v=DMARC1;p=none;foo=xxx;sp=reject;bar=xxx;adkim=r;aspf=r'
85
+ expect(subject.parse(record)).to eq([
86
+ {v: 'DMARC1'},
87
+ {p: 'none'},
88
+ {sp: 'reject'},
89
+ {adkim: 'r'},
90
+ {aspf: 'r'}
91
+ ])
92
+ end
93
+
94
+ it "ignores syntax errors" do
95
+ record = 'v=DMARC1;p=none;sp;adkim=X;aspf='
96
+ expect(subject.parse(record)).to eq([
97
+ {v: 'DMARC1'},
98
+ {p: 'none'}
99
+ ])
100
+ end
92
101
  end
93
- end
94
102
 
95
- describe '#dmarc_request' do
96
- subject { described_class.new.dmarc_request }
103
+ describe 'dmarc_version' do
104
+ subject { described_class.new.dmarc_version }
97
105
 
98
- it 'parses "none" requests' do
99
- expect(subject.parse('p=none')).to eq(p: 'none')
100
- end
106
+ it 'parses DMARC versions' do
107
+ expect(subject.parse('v=DMARC1')).to eq(v: 'DMARC1')
108
+ end
101
109
 
102
- it 'parses quarantine requests' do
103
- expect(subject.parse('p=quarantine')).to eq(p: 'quarantine')
110
+ it 'ignores spacing' do
111
+ expect(subject.parse 'v = DMARC1').to eq(subject.parse 'v=DMARC1')
112
+ end
104
113
  end
105
114
 
106
- it 'parses reject requests' do
107
- expect(subject.parse('p=reject')).to eq(p: 'reject')
108
- end
115
+ describe 'dmarc_request' do
116
+ subject { described_class.new.dmarc_request }
109
117
 
110
- it 'ingores spacing' do
111
- expect(subject.parse 'p=none').to eq(subject.parse 'p = none')
112
- end
113
- end
118
+ it 'parses "none" requests' do
119
+ expect(subject.parse('p=none')).to eq(p: 'none')
120
+ end
114
121
 
115
- describe '#dmarc_srequest' do
116
- subject { described_class.new.dmarc_srequest }
122
+ it 'parses quarantine requests' do
123
+ expect(subject.parse('p=quarantine')).to eq(p: 'quarantine')
124
+ end
117
125
 
118
- it 'parses "none" requests' do
119
- expect(subject.parse('sp=none')).to eq(sp: 'none')
120
- end
126
+ it 'parses reject requests' do
127
+ expect(subject.parse('p=reject')).to eq(p: 'reject')
128
+ end
121
129
 
122
- it 'parses quarantine requests' do
123
- expect(subject.parse('sp=quarantine')).to eq(sp: 'quarantine')
130
+ it 'ingores spacing' do
131
+ expect(subject.parse 'p=none').to eq(subject.parse 'p = none')
132
+ end
124
133
  end
125
134
 
126
- it 'parses reject requests' do
127
- expect(subject.parse('sp=reject')).to eq(sp: 'reject')
128
- end
135
+ describe 'dmarc_srequest' do
136
+ subject { described_class.new.dmarc_srequest }
129
137
 
130
- it 'ignores spacing' do
131
- expect(subject.parse 'sp=none').to eq(subject.parse 'sp = none')
132
- end
133
- end
138
+ it 'parses "none" requests' do
139
+ expect(subject.parse('sp=none')).to eq(sp: 'none')
140
+ end
134
141
 
135
- describe '#dmarc_auri' do
136
- subject { described_class.new.dmarc_auri }
142
+ it 'parses quarantine requests' do
143
+ expect(subject.parse('sp=quarantine')).to eq(sp: 'quarantine')
144
+ end
137
145
 
138
- it 'parses one URI' do
139
- expect(subject.parse('rua=mailto:user@example.org')).to eq(
140
- rua: {
141
- uri: 'mailto:user@example.org'
142
- }
143
- )
144
- end
146
+ it 'parses reject requests' do
147
+ expect(subject.parse('sp=reject')).to eq(sp: 'reject')
148
+ end
145
149
 
146
- it 'parses many URIs' do
147
- expect(
148
- subject.parse('rua = mailto:user1@example.org, mailto:user2@example.org')
149
- ).to eq(
150
- rua: [
151
- {uri: 'mailto:user1@example.org'},
152
- {uri: 'mailto:user2@example.org'}
153
- ]
154
- )
150
+ it 'ignores spacing' do
151
+ expect(subject.parse 'sp=none').to eq(subject.parse 'sp = none')
152
+ end
155
153
  end
156
154
 
157
- it 'parses maximum report size' do
158
- expect(subject.parse('rua = mailto:user1@example.com!20m')).to eq(
159
- rua: {
160
- uri: 'mailto:user1@example.com',
161
- size: '20',
162
- unit: 'm'
163
- }
164
- )
165
- end
166
- end
155
+ describe 'dmarc_auri' do
156
+ subject { described_class.new.dmarc_auri }
167
157
 
168
- describe '#dmarc_ainterval' do
169
- subject { described_class.new.dmarc_ainterval }
158
+ it 'parses one URI' do
159
+ expect(subject.parse('rua=mailto:user@example.org')).to eq(
160
+ rua: {
161
+ uri: 'mailto:user@example.org'
162
+ }
163
+ )
164
+ end
170
165
 
171
- it 'parses a one digit interval' do
172
- expect(subject.parse('ri=1')).to eq(ri: '1')
173
- end
166
+ it 'parses many URIs' do
167
+ expect(
168
+ subject.parse('rua = mailto:user1@example.org, mailto:user2@example.org')
169
+ ).to eq(
170
+ rua: [
171
+ {uri: 'mailto:user1@example.org'},
172
+ {uri: 'mailto:user2@example.org'}
173
+ ]
174
+ )
175
+ end
174
176
 
175
- it 'parses a many digit interval' do
176
- expect(subject.parse('ri=86400')).to eq(ri: '86400')
177
+ it 'parses maximum report size' do
178
+ expect(subject.parse('rua = mailto:user1@example.com!20m')).to eq(
179
+ rua: {
180
+ uri: 'mailto:user1@example.com',
181
+ size: '20',
182
+ unit: 'm'
183
+ }
184
+ )
185
+ end
177
186
  end
178
187
 
179
- it 'ignores spacing' do
180
- expect(subject.parse 'ri = 86400').to eq(subject.parse 'ri=86400')
181
- end
182
- end
188
+ describe 'dmarc_ainterval' do
189
+ subject { described_class.new.dmarc_ainterval }
183
190
 
184
- describe '#dmarc_furi' do
185
- subject { described_class.new.dmarc_furi }
191
+ it 'parses a one digit interval' do
192
+ expect(subject.parse('ri=1')).to eq(ri: '1')
193
+ end
186
194
 
187
- it 'parses one URI' do
188
- expect(subject.parse('ruf=mailto:user@example.org')).to eq(
189
- ruf: {
190
- uri: 'mailto:user@example.org'
191
- }
192
- )
193
- end
195
+ it 'parses a many digit interval' do
196
+ expect(subject.parse('ri=86400')).to eq(ri: '86400')
197
+ end
194
198
 
195
- it 'parses many URIs' do
196
- expect(
197
- subject.parse('ruf = mailto:user1@example.org, mailto:user2@example.org')
198
- ).to eq(
199
- ruf: [
200
- {uri: 'mailto:user1@example.org'},
201
- {uri: 'mailto:user2@example.org'}
202
- ]
203
- )
199
+ it 'ignores spacing' do
200
+ expect(subject.parse 'ri = 86400').to eq(subject.parse 'ri=86400')
201
+ end
204
202
  end
205
203
 
206
- it 'parses maximum report size' do
207
- expect(subject.parse('ruf = mailto:user1@example.com!20m')).to eq(
208
- ruf: {
209
- uri: 'mailto:user1@example.com',
210
- size: '20',
211
- unit: 'm'
212
- }
213
- )
204
+ describe 'dmarc_furi' do
205
+ subject { described_class.new.dmarc_furi }
206
+
207
+ it 'parses one URI' do
208
+ expect(subject.parse('ruf=mailto:user@example.org')).to eq(
209
+ ruf: {
210
+ uri: 'mailto:user@example.org'
211
+ }
212
+ )
213
+ end
214
+
215
+ it 'parses many URIs' do
216
+ expect(
217
+ subject.parse('ruf = mailto:user1@example.org, mailto:user2@example.org')
218
+ ).to eq(
219
+ ruf: [
220
+ {uri: 'mailto:user1@example.org'},
221
+ {uri: 'mailto:user2@example.org'}
222
+ ]
223
+ )
224
+ end
225
+
226
+ it 'parses maximum report size' do
227
+ expect(subject.parse('ruf = mailto:user1@example.com!20m')).to eq(
228
+ ruf: {
229
+ uri: 'mailto:user1@example.com',
230
+ size: '20',
231
+ unit: 'm'
232
+ }
233
+ )
234
+ end
214
235
  end
215
- end
216
236
 
217
- describe '#dmarc_fo' do
218
- let(:fo) { described_class.new.dmarc_fo }
237
+ describe 'dmarc_fo' do
238
+ let(:fo) { described_class.new.dmarc_fo }
219
239
 
220
- context 'one value' do
221
- %w[0 1 d s].each do |value|
222
- it "parses #{value}" do
223
- expect(fo.parse("fo=#{value}")).to eq(fo: {fo_opt: value})
240
+ context 'one value' do
241
+ %w[0 1 d s].each do |value|
242
+ it "parses #{value}" do
243
+ expect(fo.parse("fo=#{value}")).to eq(fo: {fo_opt: value})
244
+ end
224
245
  end
225
246
  end
226
- end
227
247
 
228
- it 'parses many values' do
229
- expect(fo.parse('fo=0:1:d:s')).to eq(
230
- fo: [{fo_opt: '0'}, {fo_opt: '1'}, {fo_opt: 'd'}, {fo_opt: 's'}]
231
- )
248
+ it 'parses many values' do
249
+ expect(fo.parse('fo=0:1:d:s')).to eq(
250
+ fo: [{fo_opt: '0'}, {fo_opt: '1'}, {fo_opt: 'd'}, {fo_opt: 's'}]
251
+ )
252
+ end
232
253
  end
233
- end
234
254
 
235
- describe '#dmarc_rfmt' do
236
- subject { described_class.new.dmarc_rfmt }
255
+ describe 'dmarc_rfmt' do
256
+ subject { described_class.new.dmarc_rfmt }
237
257
 
238
- it 'parses afrf format' do
239
- expect(subject.parse('rf=afrf')).to eq(rf: 'afrf')
240
- end
258
+ it 'parses afrf format' do
259
+ expect(subject.parse('rf=afrf')).to eq(rf: 'afrf')
260
+ end
241
261
 
242
- it 'parses iodef format' do
243
- expect(subject.parse('rf=iodef')).to eq(rf: 'iodef')
244
- end
262
+ it 'parses iodef format' do
263
+ expect(subject.parse('rf=iodef')).to eq(rf: 'iodef')
264
+ end
245
265
 
246
- it 'ignores spacing' do
247
- expect(subject.parse 'rf=iodef').to eq(subject.parse 'rf = iodef')
266
+ it 'ignores spacing' do
267
+ expect(subject.parse 'rf=iodef').to eq(subject.parse 'rf = iodef')
268
+ end
248
269
  end
249
- end
250
270
 
251
- describe '#dmarc_percent' do
252
- subject { described_class.new.dmarc_percent }
271
+ describe 'dmarc_percent' do
272
+ subject { described_class.new.dmarc_percent }
253
273
 
254
- it 'parses a one-digit percent' do
255
- expect(subject.parse('pct=1')).to eq(pct: '1')
256
- end
274
+ it 'parses a one-digit percent' do
275
+ expect(subject.parse('pct=1')).to eq(pct: '1')
276
+ end
257
277
 
258
- it 'parses a two-digit percent' do
259
- expect(subject.parse('pct=10')).to eq(pct: '10')
260
- end
278
+ it 'parses a two-digit percent' do
279
+ expect(subject.parse('pct=10')).to eq(pct: '10')
280
+ end
261
281
 
262
- it 'parses a three-digit percent' do
263
- expect(subject.parse('pct=100')).to eq(pct: '100')
264
- end
282
+ it 'parses a three-digit percent' do
283
+ expect(subject.parse('pct=100')).to eq(pct: '100')
284
+ end
265
285
 
266
- it 'ignores spacing' do
267
- expect(subject.parse 'pct = 100').to eq(subject.parse 'pct=100')
286
+ it 'ignores spacing' do
287
+ expect(subject.parse 'pct = 100').to eq(subject.parse 'pct=100')
288
+ end
268
289
  end
269
- end
270
290
 
271
- describe '#dmarc_adkim' do
272
- subject { described_class.new.dmarc_adkim }
291
+ describe 'dmarc_adkim' do
292
+ subject { described_class.new.dmarc_adkim }
273
293
 
274
- it 'parses a relaxed DKIM policy' do
275
- expect(subject.parse('adkim=r')).to eq(adkim: 'r')
276
- end
294
+ it 'parses a relaxed DKIM policy' do
295
+ expect(subject.parse('adkim=r')).to eq(adkim: 'r')
296
+ end
277
297
 
278
- it 'parses a strict DKIM policy' do
279
- expect(subject.parse('adkim=s')).to eq(adkim: 's')
280
- end
298
+ it 'parses a strict DKIM policy' do
299
+ expect(subject.parse('adkim=s')).to eq(adkim: 's')
300
+ end
281
301
 
282
- it 'ignores spacing' do
283
- expect(subject.parse 'adkim=r').to eq(subject.parse 'adkim = r')
302
+ it 'ignores spacing' do
303
+ expect(subject.parse 'adkim=r').to eq(subject.parse 'adkim = r')
304
+ end
284
305
  end
285
- end
286
306
 
287
- describe '#dmarc_aspf' do
288
- subject { described_class.new.dmarc_aspf }
307
+ describe 'dmarc_aspf' do
308
+ subject { described_class.new.dmarc_aspf }
289
309
 
290
- it 'parses a relaxed SPF policy' do
291
- expect(subject.parse('aspf=r')).to eq(aspf: 'r')
292
- end
310
+ it 'parses a relaxed SPF policy' do
311
+ expect(subject.parse('aspf=r')).to eq(aspf: 'r')
312
+ end
293
313
 
294
- it 'parses a strict SPF policy' do
295
- expect(subject.parse('aspf=s')).to eq(aspf: 's')
296
- end
314
+ it 'parses a strict SPF policy' do
315
+ expect(subject.parse('aspf=s')).to eq(aspf: 's')
316
+ end
297
317
 
298
- it 'ignores spacing' do
299
- expect(subject.parse 'aspf=s').to eq(subject.parse 'aspf = s')
318
+ it 'ignores spacing' do
319
+ expect(subject.parse 'aspf=s').to eq(subject.parse 'aspf = s')
320
+ end
300
321
  end
301
322
  end
302
323
 
@@ -305,17 +326,29 @@ describe Parser do
305
326
  [
306
327
  {v: 'DMARC1'},
307
328
  {p: 'none'},
329
+ {sp: 'reject'},
308
330
  {pct: '100'},
309
- {fo: [{fo_opt: '0'}, {fo_opt: '1'}, {fo_opt: 'd'}, {fo_opt: 's'}]}
331
+ {adkim: 'r'},
332
+ {aspf: 'r'},
333
+ {fo: [{fo_opt: '0'}, {fo_opt: '1'}, {fo_opt: 'd'}, {fo_opt: 's'}]},
334
+ {rua: {uri: "mailto:d@rua.agari.com"}}
310
335
  ]
311
336
  end
312
337
 
313
338
  subject { described_class.new.apply(tree) }
314
339
 
340
+ it "should coerce :v into a Symbol" do
341
+ expect(subject).to include(v: :DMARC1)
342
+ end
343
+
315
344
  it "should coerce :p into a Symbol" do
316
345
  expect(subject).to include(p: :none)
317
346
  end
318
347
 
348
+ it "should coerce :sp into a Symbol" do
349
+ expect(subject).to include(sp: :reject)
350
+ end
351
+
319
352
  it "should flatten :fo options" do
320
353
  expect(subject).to include(fo: %w[0 1 d s])
321
354
  end
@@ -323,34 +356,47 @@ describe Parser do
323
356
  it "should coerce :pct into an Integer" do
324
357
  expect(subject).to include(pct: 100)
325
358
  end
359
+
360
+ it "should coerce :adkim into a Symbol" do
361
+ expect(subject).to include(adkim: :r)
362
+ end
363
+
364
+ it "should coerce :aspf into a Symbol" do
365
+ expect(subject).to include(aspf: :r)
366
+ end
367
+
368
+ it "should convert {uri: ...} to URI objects" do
369
+ expect(subject).to include(rua: [URI("mailto:d@rua.agari.com")])
370
+ end
326
371
  end
327
372
 
328
- describe "#parse" do
373
+ describe ".parse" do
374
+ subject { described_class }
375
+
329
376
  let(:record) { "v=DMARC1;p=none;pct=100;fo=0:1:d:s" }
330
377
 
331
378
  it "should combine all tags into one Hash" do
332
379
  expect(subject.parse(record)).to eq(
333
- v: 'DMARC1',
380
+ v: :DMARC1,
334
381
  p: :none,
335
382
  pct: 100,
336
383
  fo: ['0', '1', 'd', 's']
337
384
  )
338
385
  end
339
386
 
340
- end
341
-
342
- context "Alexa Top 500", :gauntlet do
343
- require 'csv'
387
+ context "Alexa Top 500", :gauntlet do
388
+ require 'csv'
344
389
 
345
- path = File.expand_path('../data/alexa.csv', __FILE__)
346
- csv = CSV.new(open(path), headers: false)
390
+ path = File.expand_path('../data/alexa.csv', __FILE__)
391
+ csv = CSV.new(open(path), headers: false)
347
392
 
348
- csv.each do |row|
349
- rank, domain, dmarc = row
393
+ csv.each do |row|
394
+ rank, domain, dmarc = row
350
395
 
351
- if dmarc
352
- it "should parse #{dmarc.inspect}" do
353
- expect { subject.parse(dmarc) }.to_not raise_error
396
+ if dmarc
397
+ it "should parse #{dmarc.inspect}" do
398
+ expect { subject.parse(dmarc) }.to_not raise_error
399
+ end
354
400
  end
355
401
  end
356
402
  end