malone 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Cyril David
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,32 @@
1
+ Originally taken from my initial draft [here][blogpost].
2
+
3
+ [blogpost]: http://www.pipetodevnull.com/past/2010/11/27/simple_mailer/
4
+
5
+ ## USAGE
6
+
7
+ $ gem install malone
8
+
9
+ require "malone"
10
+
11
+ # typically you would do this somewhere in the bootstrapping
12
+ # part of your application
13
+
14
+ Malone.configure(
15
+ host: "smtp.gmail.com",
16
+ port: 587,
17
+ tls: true,
18
+ domain: "mydomain.com",
19
+ user: "me@mydomain.com",
20
+ pass: "mypass",
21
+ auth: :login,
22
+ from: "no-reply@mydomain.com"
23
+ )
24
+
25
+ Malone.deliver(from: "me@me.com", to: "you@me.com",
26
+ subject: "Test subject", body: "Great!")
27
+
28
+ That's it!
29
+
30
+ ## LICENSE
31
+
32
+ MIT
@@ -0,0 +1,48 @@
1
+ require "net/smtp"
2
+ require "ostruct"
3
+ require "mailfactory"
4
+
5
+ class Malone
6
+ VERSION = "0.0.1"
7
+
8
+ attr :envelope
9
+
10
+ def self.deliver(params = {})
11
+ new(params).deliver
12
+ end
13
+
14
+ def self.configure(hash)
15
+ @config = OpenStruct.new(hash)
16
+ end
17
+
18
+ def self.config
19
+ @config
20
+ end
21
+
22
+ def initialize(params = {})
23
+ @envelope = MailFactory.new
24
+ @envelope.from = params[:from]
25
+ @envelope.to = params[:to]
26
+ @envelope.text = params[:body]
27
+ @envelope.subject = params[:subject]
28
+ end
29
+
30
+ def deliver
31
+ smtp = Net::SMTP.new config.host, config.port
32
+ smtp.enable_starttls if config.tls
33
+
34
+ begin
35
+ smtp.start(config.domain, config.user, config.pass, config.auth)
36
+ smtp.send_message(envelope.to_s, envelope.from.first, envelope.to)
37
+ ensure
38
+ smtp.finish
39
+ end
40
+ end
41
+
42
+ private
43
+ NotConfigured = Class.new(StandardError)
44
+
45
+ def config
46
+ self.class.config or raise(NotConfigured)
47
+ end
48
+ end
@@ -0,0 +1,53 @@
1
+ require "cutest"
2
+ require "flexmock/base"
3
+
4
+ require File.expand_path("../lib/malone", File.dirname(__FILE__))
5
+
6
+ class FlexMock
7
+ class CutestFrameworkAdapter
8
+ def assert_block(msg, &block)
9
+ unless yield
10
+ puts msg
11
+ flunk(7)
12
+ end
13
+ end
14
+
15
+ def assert_equal(a, b, msg=nil)
16
+ flunk unless a == b
17
+ end
18
+
19
+ class AssertionFailedError < StandardError; end
20
+
21
+ def assertion_failed_error
22
+ Cutest::AssertionFailed
23
+ end
24
+ end
25
+
26
+ @framework_adapter = CutestFrameworkAdapter.new
27
+ end
28
+
29
+ module Cutest::Flexmocked
30
+ def test(*args, &block)
31
+ super
32
+
33
+ flexmock_verify
34
+ ensure
35
+ flexmock_close
36
+ end
37
+ end
38
+
39
+ class Cutest::Scope
40
+ include FlexMock::ArgumentTypes
41
+ include FlexMock::MockContainer
42
+
43
+ include Cutest::Flexmocked
44
+ end
45
+
46
+ module Kernel
47
+ def flunk(offset = 1)
48
+ exception = Cutest::AssertionFailed.new
49
+ exception.set_backtrace([caller[offset]])
50
+
51
+ raise exception
52
+ end
53
+ end
@@ -0,0 +1,121 @@
1
+ require File.expand_path("helper", File.dirname(__FILE__))
2
+
3
+ setup do
4
+ m = Malone.new(from: "me@me.com", to: "you@me.com",
5
+ body: "FooBar", subject: "Hello World")
6
+ end
7
+
8
+ test "envelope" do |m|
9
+ assert m.envelope.from == ["me@me.com"]
10
+ assert m.envelope.to == ["you@me.com"]
11
+
12
+ assert m.envelope.instance_variable_get(:@text) == "FooBar"
13
+ assert m.envelope.get_header("subject") == ["=?utf-8?Q?Hello_World?="]
14
+ end
15
+
16
+ test "delivering with no config" do |m|
17
+ assert_raise Malone::NotConfigured do
18
+ m.deliver
19
+ end
20
+ end
21
+
22
+ test "configuring" do
23
+ Malone.configure(
24
+ host: "smtp.gmail.com",
25
+ port: 587,
26
+ domain: "mydomain.com",
27
+ tls: true,
28
+ user: "me@mydomain.com",
29
+ pass: "mypass",
30
+ auth: :login
31
+ )
32
+
33
+ assert Malone.config.host == "smtp.gmail.com"
34
+ assert Malone.config.port == 587
35
+ assert Malone.config.domain == "mydomain.com"
36
+ assert Malone.config.tls == true
37
+ assert Malone.config.user == "me@mydomain.com"
38
+ assert Malone.config.pass == "mypass"
39
+ assert Malone.config.auth == :login
40
+ end
41
+
42
+ scope do
43
+ setup do
44
+ Malone.configure(
45
+ host: "smtp.gmail.com",
46
+ port: 587,
47
+ domain: "mydomain.com",
48
+ tls: true,
49
+ user: "me@mydomain.com",
50
+ pass: "mypass",
51
+ auth: :login
52
+ )
53
+ end
54
+
55
+ test "delivering successfully" do
56
+ malone = Malone.new(to: "you@me.com", from: "me@me.com",
57
+ subject: "My subject", body: "My body")
58
+
59
+ # Let's begin the mocking fun
60
+ sender = flexmock("smtp sender")
61
+
62
+ # We start out by capturing the Net::SMTP.new part
63
+ flexmock(Net::SMTP).should_receive(:new).and_return(sender)
64
+
65
+ # Since we configured it with tls: true, then enable_starttls
66
+ # should be called
67
+ sender.should_receive(:enable_starttls).once
68
+
69
+ # Now we verify that start was indeed called exactly with the arguments
70
+ # we passed in
71
+ sender.should_receive(:start).once.with(
72
+ "mydomain.com", "me@mydomain.com", "mypass", :login,
73
+ )
74
+
75
+ # This is a bit of a hack, since envelope.to_s changes everytime.
76
+ # Specifically, The Message-ID part changes.
77
+ envelope_to_s = malone.envelope.to_s
78
+
79
+ # So we get one result of envelope.to_s
80
+ flexmock(malone.envelope).should_receive(:to_s).and_return(envelope_to_s)
81
+
82
+ # And then we make sure that that value of envelope.to_s is used
83
+ # instead of making it generate a new Message-ID
84
+ sender.should_receive(:send_message).once.with(
85
+ envelope_to_s, "me@me.com", ["you@me.com"]
86
+ ).and_return("OK")
87
+
88
+ # I think this is important, otherwise the connection to the
89
+ # smtp server won't be closed properly
90
+ sender.should_receive(:finish).once
91
+
92
+ # One important part of the API of malone is that deliver
93
+ # should return the result of Net::SMTP#send_message.
94
+ assert "OK" == malone.deliver
95
+ end
96
+
97
+ test "delivering and failing" do
98
+ malone = Malone.new(to: "you@me.com", from: "me@me.com",
99
+ subject: "My subject", body: "My body")
100
+
101
+ # This is more or less the same example as above,
102
+ # except that here we make send_message fail
103
+ # and verify that finish is still called
104
+ sender = flexmock("smtp sender")
105
+
106
+ flexmock(Net::SMTP).should_receive(:new).and_return(sender)
107
+
108
+ sender.should_receive(:enable_starttls).once
109
+
110
+ sender.should_receive(:start).once.with(
111
+ "mydomain.com", "me@mydomain.com", "mypass", :login,
112
+ )
113
+
114
+ sender.should_receive(:send_message).once.and_raise(StandardError)
115
+ sender.should_receive(:finish).once
116
+
117
+ assert_raise StandardError do
118
+ assert nil == malone.deliver
119
+ end
120
+ end
121
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: malone
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Cyril David
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-28 00:00:00 +08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: mailfactory
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: cutest
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: flexmock
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id003
59
+ description:
60
+ email: cyx@pipetodevnull.com
61
+ executables: []
62
+
63
+ extensions: []
64
+
65
+ extra_rdoc_files: []
66
+
67
+ files:
68
+ - lib/malone.rb
69
+ - README.markdown
70
+ - LICENSE
71
+ - test/helper.rb
72
+ - test/malone_test.rb
73
+ has_rdoc: true
74
+ homepage: http://github.com/cyx/malone
75
+ licenses: []
76
+
77
+ post_install_message:
78
+ rdoc_options: []
79
+
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.3.7
102
+ signing_key:
103
+ specification_version: 2
104
+ summary: Dead-simple Ruby mailing solution which always delivers.
105
+ test_files: []
106
+