aws-ses-v4 0.8.1

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.
data/test/base_test.rb ADDED
@@ -0,0 +1,104 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class BaseTest < Test::Unit::TestCase
4
+ def test_connection_established
5
+ instance = Base.new(:access_key_id => '123', :secret_access_key => 'abc')
6
+
7
+ assert_not_nil instance.instance_variable_get("@http")
8
+ end
9
+
10
+ def test_failed_response
11
+ @base = generate_base
12
+ mock_connection(@base, {:code => 403, :body => %{
13
+ <ErrorResponse>
14
+ <Error>
15
+ <Type>
16
+ Sender
17
+ </Type>
18
+ <Code>
19
+ ValidationError
20
+ </Code>
21
+ <Message>
22
+ Value null at 'message.subject' failed to satisfy constraint: Member must not be null
23
+ </Message>
24
+ </Error>
25
+ <RequestId>
26
+ 42d59b56-7407-4c4a-be0f-4c88daeea257
27
+ </RequestId>
28
+ </ErrorResponse>
29
+ }})
30
+
31
+ assert_raises ResponseError do
32
+ result = @base.request('', {})
33
+ end
34
+
35
+ # assert !result.success?
36
+ # assert result.error?
37
+ # assert result.error.error?
38
+ # assert_equal 'ValidationError', result.error.code
39
+ end
40
+
41
+ def test_ses_authorization_header_v2
42
+ aws_access_key_id = 'fake_aws_key_id'
43
+ aws_secret_access_key = 'fake_aws_access_key'
44
+ time = Time.new(2021, 4, 8, 14, 07, 58, '+00:00')
45
+ ::Timecop.freeze(time)
46
+ base = ::AWS::SES::Base.new(
47
+ access_key_id: aws_access_key_id,
48
+ secret_access_key: aws_secret_access_key,
49
+ signature_version: 2
50
+ )
51
+
52
+ assert_equal 'AWS3-HTTPS AWSAccessKeyId=fake_aws_key_id, Algorithm=HmacSHA256, Signature=Yi984ReKUv7ckcrwvsBgzLlQX/1kyva74+SF+PlrwZ0=', base.get_aws_auth_header_v2
53
+ Timecop.return
54
+ end
55
+
56
+ def test_ses_authorization_header_v4
57
+ aws_access_key_id = 'fake_aws_key_id'
58
+ aws_secret_access_key = 'fake_aws_access_key'
59
+ time = Time.new(2020, 7, 2, 7, 17, 58, '+00:00')
60
+ ::Timecop.freeze(time)
61
+
62
+ base = ::AWS::SES::Base.new(
63
+ server: 'ec2.amazonaws.com',
64
+ access_key_id: aws_access_key_id,
65
+ secret_access_key: aws_secret_access_key
66
+ )
67
+
68
+ assert_equal 'AWS4-HMAC-SHA256 Credential=fake_aws_key_id/20200702/us-east-1/ses/aws4_request, SignedHeaders=host;x-amz-date, Signature=fb25a4a91c6f5c17637c81744998ac664d16ce70982c5ca92c0a62199ef4e7d6', base.get_aws_auth_header_v4
69
+ Timecop.return
70
+ end
71
+
72
+ def test_ses_authorization_header_v4_changed_host
73
+ aws_access_key_id = 'fake_aws_key_id'
74
+ aws_secret_access_key = 'fake_aws_access_key'
75
+ time = Time.new(2020, 7, 2, 7, 17, 58, '+00:00')
76
+ ::Timecop.freeze(time)
77
+
78
+ base = ::AWS::SES::Base.new(
79
+ server: 'email.us-east-1.amazonaws.com',
80
+ access_key_id: aws_access_key_id,
81
+ secret_access_key: aws_secret_access_key
82
+ )
83
+
84
+ assert_equal 'AWS4-HMAC-SHA256 Credential=fake_aws_key_id/20200702/us-east-1/ses/aws4_request, SignedHeaders=host;x-amz-date, Signature=c77a9d002342ac5b210c8f4a054712f9e00335ce9555c359ea8982acfa32db4c', base.get_aws_auth_header_v4
85
+ Timecop.return
86
+ end
87
+
88
+ def test_ses_authorization_header_v4_changed_region
89
+ aws_access_key_id = 'fake_aws_key_id'
90
+ aws_secret_access_key = 'fake_aws_access_key'
91
+ time = Time.new(2020, 7, 2, 7, 17, 58, '+00:00')
92
+ ::Timecop.freeze(time)
93
+
94
+ base = ::AWS::SES::Base.new(
95
+ server: 'email.us-east-1.amazonaws.com',
96
+ access_key_id: aws_access_key_id,
97
+ secret_access_key: aws_secret_access_key,
98
+ region: 'eu-west-1'
99
+ )
100
+
101
+ assert_not_equal 'AWS4-HMAC-SHA256 Credential=fake_aws_key_id/20200702/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-date, Signature=b872601457070ab98e7038bdcd4dc1f5eab586ececf9908525474408b0740515', base.get_aws_auth_header_v4
102
+ Timecop.return
103
+ end
104
+ end
@@ -0,0 +1,111 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class KerneltExtensionsTest < Test::Unit::TestCase
4
+ class Foo
5
+ def foo
6
+ __method__
7
+ end
8
+
9
+ def bar
10
+ foo
11
+ end
12
+
13
+ def baz
14
+ bar
15
+ end
16
+ end
17
+
18
+ class Bar
19
+ def foo
20
+ calling_method
21
+ end
22
+
23
+ def bar
24
+ calling_method
25
+ end
26
+
27
+ def calling_method
28
+ __method__(1)
29
+ end
30
+ end
31
+
32
+ def test___method___works_regardless_of_nesting
33
+ f = Foo.new
34
+ [:foo, :bar, :baz].each do |method|
35
+ assert_equal 'foo', f.send(method)
36
+ end
37
+ end
38
+
39
+ def test___method___depth
40
+ b = Bar.new
41
+ assert_equal 'foo', b.foo
42
+ assert_equal 'bar', b.bar
43
+ end
44
+ end if RUBY_VERSION <= '1.8.7'
45
+
46
+ class ModuleExtensionsTest < Test::Unit::TestCase
47
+ class Foo
48
+ def foo(reload = false)
49
+ expirable_memoize(reload) do
50
+ Time.now
51
+ end
52
+ end
53
+
54
+ def bar(reload = false)
55
+ expirable_memoize(reload, :baz) do
56
+ Time.now
57
+ end
58
+ end
59
+
60
+ def quux
61
+ Time.now
62
+ end
63
+ memoized :quux
64
+ end
65
+
66
+ def setup
67
+ @instance = Foo.new
68
+ end
69
+
70
+ def test_memoize
71
+ assert !instance_variables_of(@instance).include?('@foo')
72
+ cached_result = @instance.foo
73
+ assert_equal cached_result, @instance.foo
74
+ assert instance_variables_of(@instance).include?('@foo')
75
+ assert_equal cached_result, @instance.send(:instance_variable_get, :@foo)
76
+ assert_not_equal cached_result, new_cache = @instance.foo(:reload)
77
+ assert_equal new_cache, @instance.foo
78
+ assert_equal new_cache, @instance.send(:instance_variable_get, :@foo)
79
+ end
80
+
81
+ def test_customizing_memoize_storage
82
+ assert !instance_variables_of(@instance).include?('@bar')
83
+ assert !instance_variables_of(@instance).include?('@baz')
84
+ cached_result = @instance.bar
85
+ assert !instance_variables_of(@instance).include?('@bar')
86
+ assert instance_variables_of(@instance).include?('@baz')
87
+ assert_equal cached_result, @instance.bar
88
+ assert_equal cached_result, @instance.send(:instance_variable_get, :@baz)
89
+ assert_nil @instance.send(:instance_variable_get, :@bar)
90
+ end
91
+
92
+ def test_memoized
93
+ assert !instance_variables_of(@instance).include?('@quux')
94
+ cached_result = @instance.quux
95
+ assert_equal cached_result, @instance.quux
96
+ assert instance_variables_of(@instance).include?('@quux')
97
+ assert_equal cached_result, @instance.send(:instance_variable_get, :@quux)
98
+ assert_not_equal cached_result, new_cache = @instance.quux(:reload)
99
+ assert_equal new_cache, @instance.quux
100
+ assert_equal new_cache, @instance.send(:instance_variable_get, :@quux)
101
+ end
102
+
103
+ private
104
+ # For 1.9 compatibility
105
+ def instance_variables_of(object)
106
+ object.instance_variables.map do |instance_variable|
107
+ instance_variable.to_s
108
+ end
109
+ end
110
+
111
+ end
data/test/fixtures.rb ADDED
@@ -0,0 +1,89 @@
1
+ require 'yaml'
2
+
3
+ module AWS
4
+ module SES
5
+ # When this file is loaded, for each fixture file, a module is created within the Fixtures module
6
+ # with the same name as the fixture file. For each fixture in that fixture file, a singleton method is
7
+ # added to the module with the name of the given fixture, returning the value of the fixture.
8
+ #
9
+ # For example:
10
+ #
11
+ # A fixture in <tt>buckets.yml</tt> named <tt>empty_bucket_list</tt> with value <tt><foo>hi!</foo></tt>
12
+ # would be made available like so:
13
+ #
14
+ # Fixtures::Buckets.empty_bucket_list
15
+ # => "<foo>hi!</foo>"
16
+ #
17
+ # Alternatively you can treat the fixture module like a hash
18
+ #
19
+ # Fixtures::Buckets[:empty_bucket_list]
20
+ # => "<foo>hi!</foo>"
21
+ #
22
+ # You can find out all available fixtures by calling
23
+ #
24
+ # Fixtures.fixtures
25
+ # => ["Buckets"]
26
+ #
27
+ # And all the fixtures contained in a given fixture by calling
28
+ #
29
+ # Fixtures::Buckets.fixtures
30
+ # => ["bucket_list_with_more_than_one_bucket", "bucket_list_with_one_bucket", "empty_bucket_list"]
31
+ module Fixtures
32
+ class << self
33
+ def create_fixtures
34
+ files.each do |file|
35
+ create_fixture_for(file)
36
+ end
37
+ end
38
+
39
+ def create_fixture_for(file)
40
+ fixtures = YAML.load_file(path(file))
41
+ fixture_module = Module.new
42
+
43
+ fixtures.each do |name, value|
44
+ fixture_module.module_eval(<<-EVAL, __FILE__, __LINE__)
45
+ def #{name}
46
+ #{value.inspect}
47
+ end
48
+ module_function :#{name}
49
+ EVAL
50
+ end
51
+
52
+ fixture_module.module_eval(<<-EVAL, __FILE__, __LINE__)
53
+ module_function
54
+
55
+ def fixtures
56
+ #{fixtures.keys.sort.inspect}
57
+ end
58
+
59
+ def [](name)
60
+ send(name) if fixtures.include?(name.to_s)
61
+ end
62
+ EVAL
63
+
64
+ const_set(module_name(file), fixture_module)
65
+ end
66
+
67
+ def fixtures
68
+ constants.sort
69
+ end
70
+
71
+ private
72
+
73
+ def files
74
+ Dir.glob(File.dirname(__FILE__) + '/fixtures/*.yml').map {|fixture| File.basename(fixture)}
75
+ end
76
+
77
+ def module_name(file_name)
78
+ File.basename(file_name, '.*').capitalize
79
+ end
80
+
81
+ def path(file_name)
82
+ File.join(File.dirname(__FILE__), 'fixtures', file_name)
83
+ end
84
+ end
85
+
86
+ create_fixtures
87
+ end
88
+ end
89
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda-context'
12
+
13
+ begin
14
+ require 'ruby-debug'
15
+ rescue LoadError
16
+ end
17
+
18
+ require 'flexmock'
19
+ require 'flexmock/test_unit'
20
+
21
+ require File.dirname(__FILE__) + '/mocks/fake_response'
22
+ require File.dirname(__FILE__) + '/fixtures'
23
+
24
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
25
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
26
+ require 'aws/ses'
27
+ require 'timecop'
28
+
29
+ class Test::Unit::TestCase
30
+ require 'net/http'
31
+ require 'net/https'
32
+
33
+ include AWS::SES
34
+
35
+ def mock_connection(object, data = {})
36
+ return_values = case data
37
+ when Hash
38
+ FakeResponse.new(data)
39
+ when Array
40
+ data.map {|hash| FakeResponse.new(hash)}
41
+ else
42
+ abort "Response data for mock connection must be a Hash or an Array. Was #{data.inspect}."
43
+ end
44
+
45
+ connection = flexmock('Net::HTTP.new') do |mock|
46
+ mock.should_receive(:post).and_return(*return_values).at_least.once
47
+ end
48
+
49
+ mock = flexmock(object)
50
+ mock.should_receive(:connection).and_return(connection)
51
+ mock
52
+ end
53
+
54
+ def generate_base
55
+ Base.new(:access_key_id=>'123', :secret_access_key=>'abc')
56
+ end
57
+ end
58
+
59
+ # Deals w/ http://github.com/thoughtbot/shoulda/issues/issue/117, see
60
+ # http://stackoverflow.com/questions/3657972/nameerror-uninitialized-constant-testunitassertionfailederror-when-upgradin
61
+ unless defined?(Test::Unit::AssertionFailedError)
62
+ Test::Unit::AssertionFailedError = ActiveSupport::TestCase::Assertion
63
+ end
data/test/info_test.rb ADDED
@@ -0,0 +1,108 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class InfoTest < Test::Unit::TestCase
4
+ context 'getting send quota' do
5
+ setup do
6
+ @base = generate_base
7
+ end
8
+
9
+ should 'return the correct response on success' do
10
+ mock_connection(@base, :body => %{
11
+ <GetSendQuotaResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
12
+ <GetSendQuotaResult>
13
+ <SentLast24Hours>0.0</SentLast24Hours>
14
+ <Max24HourSend>1000.0</Max24HourSend>
15
+ <MaxSendRate>1.0</MaxSendRate>
16
+ </GetSendQuotaResult>
17
+ <ResponseMetadata>
18
+ <RequestId>abc-123</RequestId>
19
+ </ResponseMetadata>
20
+ </GetSendQuotaResponse>
21
+ })
22
+
23
+ result = @base.quota
24
+ assert result.success?
25
+ assert_equal 'abc-123', result.request_id
26
+ assert_equal '0.0', result.sent_last_24_hours
27
+ assert_equal '1000.0', result.max_24_hour_send
28
+ assert_equal '1.0', result.max_send_rate
29
+ end
30
+ end
31
+
32
+ context 'getting send statistics' do
33
+ setup do
34
+ @base = generate_base
35
+ end
36
+
37
+ should 'return the correct response on success' do
38
+ mock_connection(@base, :body => %{
39
+ <GetSendStatisticsResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
40
+ <GetSendStatisticsResult>
41
+ <SendDataPoints>
42
+ <member>
43
+ <DeliveryAttempts>3</DeliveryAttempts>
44
+ <Timestamp>2011-01-31T15:31:00Z</Timestamp>
45
+ <Rejects>2</Rejects>
46
+ <Bounces>4</Bounces>
47
+ <Complaints>1</Complaints>
48
+ </member>
49
+ <member>
50
+ <DeliveryAttempts>3</DeliveryAttempts>
51
+ <Timestamp>2011-01-31T16:01:00Z</Timestamp>
52
+ <Rejects>0</Rejects>
53
+ <Bounces>0</Bounces>
54
+ <Complaints>0</Complaints>
55
+ </member>
56
+ <member>
57
+ <DeliveryAttempts>1</DeliveryAttempts>
58
+ <Timestamp>2011-01-26T16:31:00Z</Timestamp>
59
+ <Rejects>0</Rejects>
60
+ <Bounces>0</Bounces>
61
+ <Complaints>0</Complaints>
62
+ </member>
63
+ </SendDataPoints>
64
+ </GetSendStatisticsResult>
65
+ <ResponseMetadata>
66
+ <RequestId>abc-123</RequestId>
67
+ </ResponseMetadata>
68
+ </GetSendStatisticsResponse>
69
+ })
70
+
71
+ result = @base.statistics
72
+
73
+ assert result.success?
74
+ assert_equal 'abc-123', result.request_id
75
+
76
+ assert_equal 3, result.data_points.size
77
+
78
+ d = result.data_points.first
79
+
80
+ assert_equal '2', d['Rejects']
81
+ assert_equal '3', d['DeliveryAttempts']
82
+ assert_equal '4', d['Bounces']
83
+ assert_equal '1', d['Complaints']
84
+ end
85
+ end
86
+
87
+
88
+ context 'deleting a verified addressess' do
89
+ setup do
90
+ @base = generate_base
91
+ end
92
+
93
+ should 'return the correct response on success' do
94
+ mock_connection(@base, :body => %{
95
+ <DeleteVerifiedEmailAddressResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
96
+ <ResponseMetadata>
97
+ <RequestId>abc-123</RequestId>
98
+ </ResponseMetadata>
99
+ </DeleteVerifiedEmailAddressResponse>
100
+ })
101
+
102
+ result = @base.addresses.delete('user1@example.com')
103
+
104
+ assert result.success?
105
+ assert_equal 'abc-123', result.request_id
106
+ end
107
+ end
108
+ end