spec/inputs/imap_spec.rb in logstash-input-imap-3.1.0 vs spec/inputs/imap_spec.rb in logstash-input-imap-3.2.0
- old
+ new
@@ -1,15 +1,14 @@
# encoding: utf-8
require "logstash/devutils/rspec/spec_helper"
-require "insist"
require "logstash/devutils/rspec/shared_examples"
+require 'logstash/plugin_mixins/ecs_compatibility_support/spec_helper'
require "logstash/inputs/imap"
require "mail"
require "net/imap"
require "base64"
-
describe LogStash::Inputs::IMAP do
context "when interrupting the plugin" do
it_behaves_like "an interruptible input plugin" do
let(:config) do
@@ -34,140 +33,235 @@
end
end
end
-describe LogStash::Inputs::IMAP do
+describe LogStash::Inputs::IMAP, :ecs_compatibility_support do
user = "logstash"
password = "secret"
msg_time = Time.new
msg_text = "foo\nbar\nbaz"
msg_html = "<p>a paragraph</p>\n\n"
msg_binary = "\x42\x43\x44"
msg_unencoded = "raw text 🐐"
- subject do
+ let(:config) do
+ { "host" => "localhost", "user" => "#{user}", "password" => "#{password}" }
+ end
+
+ subject(:input) do
+ LogStash::Inputs::IMAP.new config
+ end
+
+ let(:mail) do
Mail.new do
from "me@example.com"
to "you@example.com"
subject "logstash imap input test"
date msg_time
body msg_text
+ message_id '<123@message.id>' # 'Message-ID' header
+ # let's have some headers:
+ header['X-Priority'] = '3'
+ header['X-Bot-ID'] = '111'
+ header['X-AES-Category'] = 'LEGIT'
+ header['X-Spam-Category'] = 'LEGIT'
+ header['Spam-Stopper-Id'] = '464bbb1a-1b86-4006-8a09-ce797fb56346'
+ header['Spam-Stopper-v2'] = 'Yes'
+ header['X-Mailer'] = 'Microsoft Outlook Express 6.00.2800.1106'
+ header['X-MimeOLE'] = 'Produced By Microsoft MimeOLE V6.00.2800.1106'
add_file :filename => "some.html", :content => msg_html
add_file :filename => "image.png", :content => msg_binary
add_file :filename => "unencoded.data", :content => msg_unencoded, :content_transfer_encoding => "7bit"
end
end
- context "with both text and html parts" do
+ before do
+ input.register
+ end
+
+ ecs_compatibility_matrix(:disabled, :v1, :v8) do |ecs_select|
+
+ let(:ecs_compatibility?) { ecs_select.active_mode != :disabled }
+
+ let (:config) { super().merge('ecs_compatibility' => ecs_select.active_mode) }
+
context "when no content-type selected" do
it "should select text/plain part" do
- config = {"type" => "imap", "host" => "localhost",
- "user" => "#{user}", "password" => "#{password}"}
-
- input = LogStash::Inputs::IMAP.new config
- input.register
- event = input.parse_mail(subject)
- insist { event.get("message") } == msg_text
+ event = input.parse_mail(mail)
+ expect( event.get("message") ).to eql msg_text
end
end
context "when text/html content-type selected" do
- it "should select text/html part" do
- config = {"type" => "imap", "host" => "localhost",
- "user" => "#{user}", "password" => "#{password}",
- "content_type" => "text/html"}
+ let(:config) { super().merge("content_type" => "text/html") }
- input = LogStash::Inputs::IMAP.new config
- input.register
- event = input.parse_mail(subject)
- insist { event.get("message") } == msg_html
+ it "should select text/html part" do
+ event = input.parse_mail(mail)
+ expect( event.get("message") ).to eql msg_html
end
end
- end
- context "when subject is in RFC 2047 encoded-word format" do
- it "should be decoded" do
- subject.subject = "=?iso-8859-1?Q?foo_:_bar?="
- config = {"type" => "imap", "host" => "localhost",
- "user" => "#{user}", "password" => "#{password}"}
+ context "mail headers" do
+ let(:config) { super().merge("lowercase_headers" => true) } # default
- input = LogStash::Inputs::IMAP.new config
- input.register
- event = input.parse_mail(subject)
- insist { event.get("subject") } == "foo : bar"
+ before { @event = input.parse_mail(mail) }
+
+ it "sets all header fields" do
+ if ecs_compatibility?
+ expect( @event.get("[@metadata][input][imap][headers][x-spam-category]") ).to eql 'LEGIT'
+ expect( @event.get("[@metadata][input][imap][headers][x-aes-category]") ).to eql 'LEGIT'
+ expect( @event.get("[@metadata][input][imap][headers][x-bot-id]") ).to eql '111'
+ ['spam-stopper-id', 'spam-stopper-v2', 'x-mimeole', 'message-id', 'x-priority'].each do |name|
+ expect( @event.include?("[@metadata][input][imap][headers][#{name}]") ).to be true
+ end
+ expect( @event.get("[@metadata][input][imap][headers][from]") ).to eql 'me@example.com'
+ expect( @event.get("[@metadata][input][imap][headers][to]") ).to eql 'you@example.com'
+ expect( @event.get("[@metadata][input][imap][headers][subject]") ).to eql 'logstash imap input test'
+ else
+ expect( @event.get("x-spam-category") ).to eql 'LEGIT'
+ expect( @event.get("x-aes-category") ).to eql 'LEGIT'
+ expect( @event.get("x-bot-id") ).to eql '111'
+ ['spam-stopper-id', 'spam-stopper-v2', 'x-mimeole', 'message-id', 'x-priority'].each do |name|
+ expect( @event.include?(name) ).to be true
+ end
+ expect( @event.get("from") ).to eql 'me@example.com'
+ expect( @event.get("to") ).to eql 'you@example.com'
+ expect( @event.get("subject") ).to eql 'logstash imap input test'
+ end
+ end
+
+ it 'does include the date header' do
+ expect( @event.include?('date') ).to be true unless ecs_compatibility?
+ expect( @event.include?('Date') ).to be false
+ end
end
- end
- context "with multiple values for same header" do
- it "should add 2 values as array in event" do
- subject.received = "test1"
- subject.received = "test2"
+ context "mail headers (not lower-cased)" do
+ let(:config) { super().merge("lowercase_headers" => false) }
- config = {"type" => "imap", "host" => "localhost",
- "user" => "#{user}", "password" => "#{password}"}
+ before { @event = input.parse_mail(mail) }
- input = LogStash::Inputs::IMAP.new config
- input.register
- event = input.parse_mail(subject)
- insist { event.get("received") } == ["test1", "test2"]
+ it "sets all header fields" do
+ if ecs_compatibility?
+ expect( @event.get("[@metadata][input][imap][headers][X-Spam-Category]") ).to eql 'LEGIT'
+ expect( @event.get("[@metadata][input][imap][headers][X-AES-Category]") ).to eql 'LEGIT'
+ expect( @event.get("[@metadata][input][imap][headers][X-Bot-ID]") ).to eql '111'
+ ['Spam-Stopper-Id', 'Spam-Stopper-v2', 'X-MimeOLE', 'Message-ID', 'X-Priority'].each do |name|
+ expect( @event.include?("[@metadata][input][imap][headers][#{name}]") ).to be true
+ end
+ expect( @event.get("[@metadata][input][imap][headers][From]") ).to eql 'me@example.com'
+ expect( @event.get("[@metadata][input][imap][headers][To]") ).to eql 'you@example.com'
+ expect( @event.get("[@metadata][input][imap][headers][Subject]") ).to eql 'logstash imap input test'
+ else
+ expect( @event.get("X-Spam-Category") ).to eql 'LEGIT'
+ expect( @event.get("X-AES-Category") ).to eql 'LEGIT'
+ expect( @event.get("X-Bot-ID") ).to eql '111'
+ ['Spam-Stopper-Id', 'Spam-Stopper-v2', 'X-MimeOLE', 'Message-ID', 'X-Priority'].each do |name|
+ expect( @event.include?(name) ).to be true
+ end
+ expect( @event.get("From") ).to eql 'me@example.com'
+ expect( @event.get("To") ).to eql 'you@example.com'
+ expect( @event.get("Subject") ).to eql 'logstash imap input test'
+ end
+ end
+
+ it 'does include the date header' do
+ expect( @event.include?('Date') ).to be true unless ecs_compatibility?
+ end
end
- it "should add more than 2 values as array in event" do
- subject.received = "test1"
- subject.received = "test2"
- subject.received = "test3"
+ context "headers_target => ''" do
+ let(:config) { super().merge("headers_target" => '') }
- config = {"type" => "imap", "host" => "localhost",
- "user" => "#{user}", "password" => "#{password}"}
+ before { @event = input.parse_mail(mail) }
- input = LogStash::Inputs::IMAP.new config
- input.register
- event = input.parse_mail(subject)
- insist { event.get("received") } == ["test1", "test2", "test3"]
+ it "does not set any header fields" do
+ ['From', 'To', 'Subject', 'subject', 'Date', 'date'].each do |name|
+ expect( @event.include?(name) ).to be false # legacy
+ expect( @event.include?("[@metadata][input][imap][headers][#{name}]") ).to be false # ecs
+ end
+ end
end
- end
- context "when a header field is nil" do
- it "should parse mail" do
- subject.header['X-Custom-Header'] = nil
- config = {"type" => "imap", "host" => "localhost",
- "user" => "#{user}", "password" => "#{password}"}
+ context "when subject is in RFC 2047 encoded-word format" do
+ before do
+ mail.subject = "=?iso-8859-1?Q?foo_:_bar?="
+ end
- input = LogStash::Inputs::IMAP.new config
- input.register
- event = input.parse_mail(subject)
- insist { event.get("message") } == msg_text
+ it "should be decoded" do
+ event = input.parse_mail(mail)
+ if ecs_compatibility?
+ expect( event.get("[@metadata][input][imap][headers][subject]") ).to eql "foo : bar"
+ else
+ expect( event.get("subject") ).to eql "foo : bar"
+ end
+ end
end
- end
- context "with attachments" do
- it "should extract filenames" do
- config = {"type" => "imap", "host" => "localhost",
- "user" => "#{user}", "password" => "#{password}"}
+ context "with multiple values for same header" do
+ it "should add 2 values as array in event" do
+ mail.received = "test1"
+ mail.received = "test2"
- input = LogStash::Inputs::IMAP.new config
- input.register
- event = input.parse_mail(subject)
- insist { event.get("attachments") } == [
- {"filename"=>"some.html"},
- {"filename"=>"image.png"},
- {"filename"=>"unencoded.data"}
- ]
+ event = input.parse_mail(mail)
+ expected_value = ["test1", "test2"]
+ if ecs_compatibility?
+ expect( event.get("[@metadata][input][imap][headers][received]") ).to eql expected_value
+ else
+ expect( event.get("received") ).to eql expected_value
+ end
+ end
+
+ it "should add more than 2 values as array in event" do
+ mail.received = "test1"
+ mail.received = "test2"
+ mail.received = "test3"
+
+ event = input.parse_mail(mail)
+ expected_value = ["test1", "test2", "test3"]
+ if ecs_compatibility?
+ expect( event.get("[@metadata][input][imap][headers][received]") ).to eql expected_value
+ else
+ expect( event.get("received") ).to eql expected_value
+ end
+ end
end
- it "should extract the encoded content" do
- config = {"type" => "imap", "host" => "localhost",
- "user" => "#{user}", "password" => "#{password}",
- "save_attachments" => true}
+ context "when a header field is nil" do
+ it "should parse mail" do
+ mail.header['X-Custom-Header'] = nil
- input = LogStash::Inputs::IMAP.new config
- input.register
- event = input.parse_mail(subject)
- insist { event.get("attachments") } == [
- {"data"=> Base64.encode64(msg_html).encode(crlf_newline: true), "filename"=>"some.html"},
- {"data"=> Base64.encode64(msg_binary).encode(crlf_newline: true), "filename"=>"image.png"},
- {"data"=> msg_unencoded, "filename"=>"unencoded.data"}
- ]
+ event = input.parse_mail(mail)
+ expect( event.get("message") ).to eql msg_text
end
+ end
+
+ context "attachments" do
+ it "should extract filenames" do
+ event = input.parse_mail(mail)
+ target = ecs_compatibility? ? '[@metadata][input][imap][attachments]' : 'attachments'
+ expect( event.get(target) ).to eql [
+ {"filename"=>"some.html"},
+ {"filename"=>"image.png"},
+ {"filename"=>"unencoded.data"}
+ ]
+ end
+ end
+
+ context "with attachments saving" do
+ let(:config) { super().merge("save_attachments" => true) }
+
+ it "should extract the encoded content" do
+ event = input.parse_mail(mail)
+ target = ecs_compatibility? ? '[@metadata][input][imap][attachments]' : 'attachments'
+ expect( event.get(target) ).to eql [
+ {"data"=> Base64.encode64(msg_html).encode(crlf_newline: true), "filename"=>"some.html"},
+ {"data"=> Base64.encode64(msg_binary).encode(crlf_newline: true), "filename"=>"image.png"},
+ {"data"=> msg_unencoded, "filename"=>"unencoded.data"}
+ ]
+ end
+ end
+
end
+
end