diff options
-rw-r--r-- | lib/Sietima.pm | 56 | ||||
-rw-r--r-- | lib/Sietima/Message.pm | 6 | ||||
-rw-r--r-- | lib/Sietima/Subscriber.pm | 22 | ||||
-rw-r--r-- | lib/Sietima/Types.pm | 33 | ||||
-rw-r--r-- | t/tests/sietima.t | 76 |
5 files changed, 165 insertions, 28 deletions
diff --git a/lib/Sietima.pm b/lib/Sietima.pm index 85468bb..2049d2c 100644 --- a/lib/Sietima.pm +++ b/lib/Sietima.pm @@ -3,46 +3,60 @@ use 5.020; use Moo; use Types::Standard qw(ArrayRef Object FileHandle Maybe); use Type::Params qw(compile); -use Sietima::Types qw(Address EmailMIME Message Subscriber Transport); +use Sietima::Types qw(Address AddressFromStr + EmailMIME Message + Subscriber SubscriberFromAddress SubscriberFromStr + Transport); use Sietima::Message; -use Email::Sender::Simple qw(sendmail); +use Sietima::Subscriber; +use Email::Sender::Simple qw(); +use Email::Sender; +use Email::Address; use namespace::clean; has return_path => ( isa => Address, is => 'ro', required => 1, + coerce => AddressFromStr, ); +my $subscribers_array = ArrayRef[ + Subscriber->plus_coercions( + SubscriberFromAddress, + SubscriberFromStr, + ) +]; has subscribers => ( - isa => ArrayRef[Subscriber], + isa => $subscribers_array, is => 'lazy', + coerce => $subscribers_array->coercion, ); sub _build_subscribers { +[] } has transport => ( - isa => Maybe[Transport], + isa => Transport, is => 'lazy', ); -sub _build_transport { } +sub _build_transport { Email::Sender::Simple->default_transport } -sub handle_message { - state $check = compile(Obect,EmailMIME); - my ($self,$incoming_message) = $check->(@_); +sub handle_mail { + state $check = compile(Object,EmailMIME); + my ($self,$incoming_mail) = $check->(@_); - my (@outgoing_messages) = $self->munge_message($incoming_message); + my (@outgoing_messages) = $self->munge_mail($incoming_mail); for my $outgoing_message (@outgoing_messages) { $self->send_message($outgoing_message); } return; } -sub munge_message { - state $check = compile(Obect,EmailMIME); - my ($self,$incoming_message) = $check->(@_); +sub munge_mail { + state $check = compile(Object,EmailMIME); + my ($self,$incoming_mail) = $check->(@_); return Sietima::Message->new({ - mail => $incoming_message, + mail => $incoming_mail, from => $self->return_path, to => [ map { $_->address } @{$self->subscribers} @@ -51,16 +65,16 @@ sub munge_message { } sub send_message { - state $check = compile(Obect,Message); + state $check = compile(Object,Message); my ($self,$outgoing_message) = $check->(@_); - sendmail( - $outgoing_message->mail, - { - %{$outgoing_message->envelope}, - transport => $self->transport, - }, - ); + my $envelope = $outgoing_message->envelope; + if ($envelope->{to} && @{$envelope->{to}}) { + $self->transport->send( + $outgoing_message->mail, + $envelope, + ); + } return; } diff --git a/lib/Sietima/Message.pm b/lib/Sietima/Message.pm index 547077a..7202269 100644 --- a/lib/Sietima/Message.pm +++ b/lib/Sietima/Message.pm @@ -2,7 +2,7 @@ package Sietima::Message; use 5.020; use Moo; use Types::Standard qw(ArrayRef Object); -use Sietima::Types qw(Address EmailMIME); +use Sietima::Types qw(Address AddressFromStr EmailMIME); use Email::MIME; use namespace::clean; @@ -18,9 +18,11 @@ has from => ( required => 1, ); +my $address_array = ArrayRef[Address->plus_coercions(AddressFromStr)]; has to => ( + isa => $address_array, is => 'ro', - isa => ArrayRef[Address], + coerce => $address_array->coercion, required => 1, ); diff --git a/lib/Sietima/Subscriber.pm b/lib/Sietima/Subscriber.pm new file mode 100644 index 0000000..cb71513 --- /dev/null +++ b/lib/Sietima/Subscriber.pm @@ -0,0 +1,22 @@ +package Sietima::Subscriber; +use 5.020; +use Moo; +use Types::Standard qw(HashRef); +use Sietima::Types qw(Address AddressFromStr); +use namespace::clean; + +has raw_address => ( + isa => Address, + is => 'ro', + required => 1, + coerce => AddressFromStr, + handles => [qw(address name original)], +); + +has prefs => ( + isa => HashRef, + is => 'ro', + default => sub { +{} }, +); + +1; diff --git a/lib/Sietima/Types.pm b/lib/Sietima/Types.pm new file mode 100644 index 0000000..95d1f88 --- /dev/null +++ b/lib/Sietima/Types.pm @@ -0,0 +1,33 @@ +package Sietima::Types; +use 5.020; +use strict; +use warnings; +use Type::Utils -all; +use Types::Standard qw(Str); +use namespace::clean; +use Type::Library + -base, + -declare => qw(Address AddressFromStr + EmailMIME Message + Subscriber SubscriberFromAddress SubscriberFromStr + Transport); + +class_type EmailMIME, { class => 'Email::MIME' }; +role_type Transport, { role => 'Email::Sender::Transport' }; + +class_type Address, { class => 'Email::Address' }; +declare_coercion AddressFromStr, + to_type Address, from Str, + q{ (Email::Address->parse($_))[0] }; + +class_type Message, { class => 'Sietima::Message' }; + +class_type Subscriber, { class => 'Sietima::Subscriber' }; +declare_coercion SubscriberFromAddress, + to_type Subscriber, from Address, + q{ Sietima::Subscriber->new(raw_address=>$_) }; +declare_coercion SubscriberFromStr, + to_type Subscriber, from Str, + q{ Sietima::Subscriber->new(raw_address=>(Email::Address->parse($_))[0]) }; + +1; diff --git a/t/tests/sietima.t b/t/tests/sietima.t index 217c06d..b0367b6 100644 --- a/t/tests/sietima.t +++ b/t/tests/sietima.t @@ -2,12 +2,78 @@ use strict; use warnings; use 5.020; -use Test::Most; +use Test2::Bundle::Extended; +use Test2::Plugin::DieOnFail; +use Email::Stuffer; +use Email::Sender::Transport::Test; +use Data::Printer; use Sietima; -ok( - my $s=Sietima->new, - 'should instantiate', -); +my $return_path = 'sietima-test@list.example.com', +my $transport = Email::Sender::Transport::Test->new; +sub make_sietima { + $transport->clear_deliveries; + Sietima->new({ + return_path => $return_path, + transport => $transport, + @_, + }); +} + +sub make_mail { + my (%args) = @_; + Email::Stuffer + ->from($args{from}||'someone@users.example.com') + ->to($args{no}||$return_path) + ->text_body($args{body}||'some simple message') + ->email; +} + +ok(make_sietima(),'should instantiate') or bail_out; + +subtest 'no subscribers' => sub { + my $s = make_sietima(); + my $m = make_mail(); + + ok( + lives { $s->handle_mail($m) }, + 'should handle the mail', + $@, + ); + + my @deliveries = $transport->deliveries; + is( + \@deliveries, + [], + 'nothing should be delivered', + np @deliveries, + ); +}; + +subtest 'with subscribers' => sub { + my $s = make_sietima( + subscribers => [ + 'one@users.example.com', + 'two@users.example.com', + ], + ); + my $m = make_mail(); + + ok( + lives { $s->handle_mail($m) }, + 'should handle the mail', + $@, + ); + + my @deliveries = $transport->deliveries; + is( + \@deliveries, + array { + # we'd need a 'bag' comparison check here! + }, + 'there should be two deliveries', + np @deliveries, + ); +}; done_testing; |