commit ef68cb26ee7648961f59e617ced0c7dcbca790ca
Author: Marc Dequènes (Duck) <Duck@DuckCorp.org>
Date:   Thu Jan 2 03:20:43 2014 +0100

    [tests] test infrastructure with important CyborgHood::Mail tests

diff --git a/Rakefile b/Rakefile
index 8cb8a7a..e4c2cc9 100644
--- a/Rakefile
+++ b/Rakefile
@@ -27,3 +27,13 @@ namespace :i18n do
     end
   end
 end
+
+namespace :test do
+  require 'rake/testtask'
+
+  Rake::TestTask.new(:spec) do |t|
+    t.libs.push "spec"
+    t.test_files = FileList['spec/**/*.rb']
+    t.verbose = true
+  end
+end
diff --git a/spec/cyborghood/mail_spec.rb b/spec/cyborghood/mail_spec.rb
new file mode 100644
index 0000000..a592264
--- /dev/null
+++ b/spec/cyborghood/mail_spec.rb
@@ -0,0 +1,176 @@
+require 'spec_helper'
+
+require 'cyborghood/mail'
+require 'tmpdir'
+require 'mocha/setup'
+
+
+CyborgHood::Config.load("postman")
+
+
+describe CyborgHood::Mail do
+  before do
+    @config = CyborgHood::Config.instance
+  end
+
+  KEY_NAME = "My Test"
+  KEY_PASSPHRASE = "stuff"
+  KEY_EMAIL = "taiste@mydom.tld"
+
+  def work_with_key
+    @gpgdir = Dir.mktmpdir
+    ENV['GNUPGHOME'] = @gpgdir
+    ENV['GPG_AGENT_INFO'] = nil
+
+    GPGME::Ctx.new do |ctx|
+      ctx.genkey(<<-EOF, nil, nil)
+        <GnupgKeyParms format="internal">
+        Key-Type: DSA
+        Key-Length: 1024
+        Subkey-Type: ELG-E
+        Subkey-Length: 1024
+        Name-Real: #{KEY_NAME}
+        Name-Comment: CyborgHood test key
+        Name-Email: #{KEY_EMAIL}
+        Expire-Date: 0
+        Passphrase: #{KEY_PASSPHRASE}
+        </GnupgKeyParms>
+        EOF
+      key = ctx.keys.first
+      @key_id = key.subkeys.first.fingerprint
+
+      yield(ctx)
+    end
+
+    FileUtils.remove_entry_secure @gpgdir
+  end
+
+  describe "basics" do
+    before do
+      @mail_empty = CyborgHood::Mail.new
+    end
+
+    it "should have GPG support" do
+      @mail_empty.must_respond_to :is_pgp_signed?
+      @mail_empty.must_respond_to :is_pgp_encrypted?
+      @mail_empty.must_respond_to :verify_pgp_signature
+      @mail_empty.must_respond_to :pgp_signed_part
+      @mail_empty.must_respond_to :pgp_decrypt
+      @mail_empty.must_respond_to :create_signed
+      @mail_empty.must_respond_to :create_encrypted
+    end
+
+    it "should be able to create an empty clear mail" do
+      @mail_empty.body.decoded.must_be_empty
+      @mail_empty.is_pgp_signed?.must_equal false
+      @mail_empty.is_pgp_encrypted?.must_equal false
+    end
+
+    it "should set custom headers" do
+      @mail_empty['Organization'].to_s.must_equal @config.mail.organization
+    end
+  end
+
+  describe "parsing emails" do
+    it "should parse a clear email" do
+      CyborgHood::Mail.read(fixture('emails', 'mail_clear.eml'))
+    end
+
+    it "should parse a signed email" do
+      CyborgHood::Mail.read(fixture('emails', 'mail_signed.eml'))
+    end
+  end
+
+  describe "creating replies" do
+    before do
+      @test_from = "z@z.net"
+
+      @mail = CyborgHood::Mail.new
+      @mail.subject = "test"
+      @mail.to = KEY_EMAIL
+      @mail.from = @test_from
+      @mail.body = "hello world!"
+      @mail.add_message_id
+    end
+
+    it "should create a reply" do
+      @mail.user = mock()
+
+      mail_reply = @mail.reply
+
+      # must_be_kind_of works badly with Delegator
+      mail_reply.class.must_equal CyborgHood::Mail
+      mail_reply.to.must_equal @mail.from
+      mail_reply.user.must_equal @mail.user
+    end
+  end
+
+  describe "unsecure emails handling" do
+    it "should reject an unsecure mail" do
+      mail_clear = CyborgHood::Mail.read(fixture('emails', 'mail_clear.eml'))
+
+      r = mail_clear.process
+      r.must_be_kind_of CyborgHood::MailReport
+      r.ok?.must_equal false
+    end
+  end
+
+  describe "secure emails handling" do
+    before do
+      @mail = CyborgHood::Mail.new
+      @mail.subject = "test"
+      @mail.to = KEY_EMAIL
+      @mail.body = "hello world!"
+      @mail.add_message_id
+    end
+
+    def create_fake_user
+      fake_user_uid = 'test'
+
+      fake_user = mock()
+      fake_user.expects(:uid).returns(fake_user_uid).at_least(2)
+      fake_user.expects(:cn).returns('Test User').at_least_once
+      CyborgHood::Person.stubs(:find_by_fingerprint).with(@key_id).returns(fake_user)
+
+      fake_user_uid
+    end
+
+    it "should process a signed mail and identify sender" do
+      work_with_key do |ctx|
+        mail_signed = @mail.create_signed(@key_id) { KEY_PASSPHRASE }
+        mail_recv = CyborgHood::Mail.new(mail_signed.encoded)
+
+        mail_recv.is_pgp_signed?.must_equal true
+
+        fake_user_uid = create_fake_user()
+        r = mail_recv.process
+        r.must_be_kind_of CyborgHood::MailReport
+        r.ok?.must_equal true
+
+        user = r.user
+        user.wont_be_nil
+        user.uid.must_equal fake_user_uid
+      end
+    end
+
+    it "should create a properly signed mail, process it, and identify sender" do
+      work_with_key do |ctx|
+        @config.mail.key_id = @key_id
+        @config.mail.key_passphrase = KEY_PASSPHRASE
+        mail_signed = @mail.sign
+        mail_recv = CyborgHood::Mail.new(mail_signed.encoded)
+
+        mail_recv.is_pgp_signed?.must_equal true
+
+        fake_user_uid = create_fake_user()
+        r = mail_recv.process
+        r.must_be_kind_of CyborgHood::MailReport
+        r.ok?.must_equal true
+
+        user = r.user
+        user.wont_be_nil
+        user.uid.must_equal fake_user_uid
+      end
+    end
+  end
+end
diff --git a/spec/fixtures/emails/mail_clear.eml b/spec/fixtures/emails/mail_clear.eml
new file mode 100644
index 0000000..e796bd0
--- /dev/null
+++ b/spec/fixtures/emails/mail_clear.eml
@@ -0,0 +1,68 @@
+From duck@duckcorp.org Sun Feb 24 15:00:51 2013
+Return-Path: <duck@duckcorp.org>
+Delivered-To: duck+test@duckcorp.dl
+Received: from duckcorp.org (localhost [127.0.0.1])
+	by mx1.duckcorp.org (Postfix) with ESMTP id CDDD24AFD4
+	for <duck+test@duckcorp.org>; Sun, 24 Feb 2013 15:00:51 +0100 (CET)
+Received: from 2001:7a8:810:6969:3285:a9ff:fe8e:2f3b
+ ([2001:7a8:810:6969:3285:a9ff:fe8e:2f3b]) by webdesk.duckcorp.org (Horde
+ Framework) with HTTP; Sun, 24 Feb 2013 15:00:51 +0100
+Message-ID: <20130224150051.13515wwc862ohw5v@webdesk.duckcorp.org>
+X-Priority: 3 (Normal)
+Date: Sun, 24 Feb 2013 15:00:51 +0100
+From: "Marc =?utf-8?b?RGVxdcOobmVz?= (Duck)" <duck@duckcorp.org>
+To: duck+test@duckcorp.org
+Subject: clear test
+MIME-Version: 1.0
+Content-Type: text/plain;
+ charset=UTF-8;
+ DelSp="Yes";
+ format="flowed"
+Content-Disposition: inline
+Content-Transfer-Encoding: 8bit
+User-Agent: Internet Messaging Program (IMP) H3 (4.3.10)
+X-Originating-IP: 2001:7a8:810:6969:3285:a9ff:fe8e:2f3b
+X-Remote-Browser: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12)
+ Gecko/20100101 Firefox/10.0.12 Iceweasel/10.0.12
+X-WebMail-Company: DuckCorp
+X-DSPAM-Result: Innocent
+X-DSPAM-Processed: Sun Feb 24 15:00:52 2013
+X-DSPAM-Confidence: 0.9926
+X-DSPAM-Improbability: 1 in 13457 chance of being spam
+X-DSPAM-Probability: 0.0000
+X-DSPAM-Signature: 24,512a1d1477851496993127
+X-DSPAM-Factors: 27,
+	Marc+#+Duck, 0.00028,
+	Dequ%c3%a8nes+Duck, 0.00044,
+	Received*from+2001, 0.00065,
+	Received*7a8+#+6969, 0.00103,
+	Received*2001+#+#+6969, 0.00103,
+	Received*810+6969, 0.00104,
+	Marc+Dequ%c3%a8nes, 0.00239,
+	From*Marc+Dequ%c3%a8nes, 0.00380,
+	Received*2001+#+#+#+3285, 0.01000,
+	Received*810+#+3285, 0.01000,
+	Received*3285+#+#+2f3b, 0.01000,
+	Received*810+#+#+#+fe8e, 0.01000,
+	Received*6969+#+#+#+2f3b, 0.01000,
+	Received*3285+a9ff, 0.01000,
+	Received*3285+#+fe8e, 0.01000,
+	Received*duckcorp.org+#+127.0.0.1, 0.01000,
+	Received*duckcorp.org+localhost, 0.01000,
+	Received*810+#+#+a9ff, 0.01000,
+	Received*7a8+#+#+3285, 0.01000,
+	Received*7a8+#+#+#+a9ff, 0.01000,
+	Received*a9ff+fe8e, 0.01000,
+	Received*from+duckcorp.org, 0.01000,
+	Received*6969+#+#+fe8e, 0.01000,
+	Received*a9ff+#+2f3b, 0.01000,
+	Received*6969+#+a9ff, 0.01000,
+	Received*6969+3285, 0.01000,
+	Received*fe8e+2f3b, 0.01000
+
+DNS INFO
+
+-- 
+Marc Dequènes (Duck)
+
+
diff --git a/spec/fixtures/emails/mail_signed.eml b/spec/fixtures/emails/mail_signed.eml
new file mode 100644
index 0000000..8635392
--- /dev/null
+++ b/spec/fixtures/emails/mail_signed.eml
@@ -0,0 +1,92 @@
+From duck@duckcorp.org Sun Feb 24 15:03:03 2013
+Return-Path: <duck@duckcorp.org>
+Delivered-To: duck+test@duckcorp.dl
+Received: from duckcorp.org (localhost [127.0.0.1])
+	by mx1.duckcorp.org (Postfix) with ESMTP id EAA284AFD4
+	for <duck+test@duckcorp.org>; Sun, 24 Feb 2013 15:03:03 +0100 (CET)
+Received: from 2001:7a8:810:6969:3285:a9ff:fe8e:2f3b
+ ([2001:7a8:810:6969:3285:a9ff:fe8e:2f3b]) by webdesk.duckcorp.org (Horde
+ Framework) with HTTP; Sun, 24 Feb 2013 15:03:03 +0100
+Message-ID: <20130224150303.14376yjjeosrxac7@webdesk.duckcorp.org>
+X-Priority: 3 (Normal)
+Date: Sun, 24 Feb 2013 15:03:03 +0100
+From: "Marc =?utf-8?b?RGVxdcOobmVz?= (Duck)" <duck@duckcorp.org>
+To: duck+test@duckcorp.org
+Subject: signed test
+MIME-Version: 1.0
+Content-Type: multipart/signed;
+ boundary="=_1h4i9pk9tzda";
+ protocol="application/pgp-signature";
+ micalg="pgp-sha1"
+Content-Transfer-Encoding: 7bit
+User-Agent: Internet Messaging Program (IMP) H3 (4.3.10)
+X-Originating-IP: 2001:7a8:810:6969:3285:a9ff:fe8e:2f3b
+X-Remote-Browser: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12)
+ Gecko/20100101 Firefox/10.0.12 Iceweasel/10.0.12
+X-WebMail-Company: DuckCorp
+X-DSPAM-Result: Innocent
+X-DSPAM-Processed: Sun Feb 24 15:03:04 2013
+X-DSPAM-Confidence: 0.9987
+X-DSPAM-Improbability: 1 in 78886 chance of being spam
+X-DSPAM-Probability: 0.0000
+X-DSPAM-Signature: 24,512a1d9890485307695085
+X-DSPAM-Factors: 27,
+	Marc+#+Duck, 0.00028,
+	Content-Type*protocol+#+pgp-signature, 0.00041,
+	Content-Type*application+pgp-signature, 0.00044,
+	Content-Type*application+pgp-signature, 0.00044,
+	Content-Type*protocol+application, 0.00044,
+	Dequ%c3%a8nes+Duck, 0.00044,
+	Content-Type*multipart+signed, 0.00044,
+	Content-Type*micalg+pgp-sha1, 0.00058,
+	Received*from+2001, 0.00065,
+	PGP+signed, 0.00096,
+	Received*7a8+#+6969, 0.00103,
+	Received*2001+#+#+6969, 0.00103,
+	Received*810+6969, 0.00104,
+	has+#+PGP, 0.00116,
+	has+#+#+signed, 0.00119,
+	and+#+#+PGP, 0.00119,
+	format+#+has, 0.00120,
+	MIME+#+#+has, 0.00120,
+	format+#+#+#+PGP, 0.00120,
+	been+PGP, 0.00120,
+	Content-Description*Digital+Signature, 0.00135,
+	Content-Description*PGP+#+Signature, 0.00136,
+	Content-Description*PGP+Digital, 0.00136,
+	Marc+Dequ%c3%a8nes, 0.00239,
+	From*Marc+Dequ%c3%a8nes, 0.00376,
+	been+#+signed, 0.00954,
+	Received*2001+#+#+#+3285, 0.01000
+
+This message is in MIME format and has been PGP signed.
+
+--=_1h4i9pk9tzda
+Content-Type: text/plain;
+ charset=UTF-8;
+ DelSp="Yes";
+ format="flowed"
+Content-Disposition: inline
+Content-Transfer-Encoding: quoted-printable
+
+DNS INFO
+
+--=20
+Marc Dequ=C3=A8nes (Duck)
+
+--=_1h4i9pk9tzda
+Content-Type: application/pgp-signature
+Content-Description: PGP Digital Signature
+Content-Disposition: inline
+Content-Transfer-Encoding: 7bit
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.12 (GNU/Linux)
+
+iEYEABECAAYFAlEqHZcACgkQsczZcpAmcIa+eACfckx2dO6JEq+h9rIGiMkoOWNP
+vCYAmwWDZC1W+TeKUk3UItIERwVz82Nf
+=EOPB
+-----END PGP SIGNATURE-----
+
+--=_1h4i9pk9tzda--
+
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..82c77f9
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,12 @@
+require 'minitest/autorun'
+
+require 'cyborghood'
+
+
+unless defined?(SPEC_ROOT)
+  SPEC_ROOT = File.join(File.dirname(__FILE__))
+end
+
+def fixture(*name)
+  File.join(SPEC_ROOT, 'fixtures', name)
+end
