postmark-1.22.0/ 0000755 0001751 0001751 00000000000 14123042137 013613 5 ustar vivekdeb vivekdeb postmark-1.22.0/spec/ 0000755 0001751 0001751 00000000000 14123042137 014545 5 ustar vivekdeb vivekdeb postmark-1.22.0/spec/unit/ 0000755 0001751 0001751 00000000000 14123042137 015524 5 ustar vivekdeb vivekdeb postmark-1.22.0/spec/unit/postmark_spec.rb 0000644 0001751 0001751 00000012135 14123042137 020725 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark do
let(:api_token) { double }
let(:secure) { double }
let(:proxy_host) { double }
let(:proxy_port) { double }
let(:proxy_user) { double }
let(:proxy_pass) { double }
let(:host) { double }
let(:port) { double }
let(:path_prefix) { double }
let(:max_retries) { double }
before do
subject.api_token = api_token
subject.secure = secure
subject.proxy_host = proxy_host
subject.proxy_port = proxy_port
subject.proxy_user = proxy_user
subject.proxy_pass = proxy_pass
subject.host = host
subject.port = port
subject.path_prefix = path_prefix
subject.max_retries = max_retries
end
context "attr readers" do
it { expect(subject).to respond_to(:secure) }
it { expect(subject).to respond_to(:api_key) }
it { expect(subject).to respond_to(:api_token) }
it { expect(subject).to respond_to(:proxy_host) }
it { expect(subject).to respond_to(:proxy_port) }
it { expect(subject).to respond_to(:proxy_user) }
it { expect(subject).to respond_to(:proxy_pass) }
it { expect(subject).to respond_to(:host) }
it { expect(subject).to respond_to(:port) }
it { expect(subject).to respond_to(:path_prefix) }
it { expect(subject).to respond_to(:http_open_timeout) }
it { expect(subject).to respond_to(:http_read_timeout) }
it { expect(subject).to respond_to(:max_retries) }
end
context "attr writers" do
it { expect(subject).to respond_to(:secure=) }
it { expect(subject).to respond_to(:api_key=) }
it { expect(subject).to respond_to(:api_token=) }
it { expect(subject).to respond_to(:proxy_host=) }
it { expect(subject).to respond_to(:proxy_port=) }
it { expect(subject).to respond_to(:proxy_user=) }
it { expect(subject).to respond_to(:proxy_pass=) }
it { expect(subject).to respond_to(:host=) }
it { expect(subject).to respond_to(:port=) }
it { expect(subject).to respond_to(:path_prefix=) }
it { expect(subject).to respond_to(:http_open_timeout=) }
it { expect(subject).to respond_to(:http_read_timeout=) }
it { expect(subject).to respond_to(:max_retries=) }
it { expect(subject).to respond_to(:response_parser_class=) }
it { expect(subject).to respond_to(:api_client=) }
end
describe ".response_parser_class" do
after do
subject.instance_variable_set(:@response_parser_class, nil)
end
it "returns :ActiveSupport when ActiveSupport::JSON is available" do
expect(subject.response_parser_class).to eq :ActiveSupport
end
it "returns :Json when ActiveSupport::JSON is not available" do
hide_const("ActiveSupport::JSON")
expect(subject.response_parser_class).to eq :Json
end
end
describe ".configure" do
it 'yields itself to the block' do
expect { |b| subject.configure(&b) }.to yield_with_args(subject)
end
end
describe ".api_client" do
let(:api_client) { double }
context "when shared client instance already exists" do
it 'returns the existing instance' do
subject.instance_variable_set(:@api_client, api_client)
expect(subject.api_client).to eq api_client
end
end
context "when shared client instance does not exist" do
it 'creates a new instance of Postmark::ApiClient' do
allow(Postmark::ApiClient).to receive(:new).
with(api_token,
:secure => secure,
:proxy_host => proxy_host,
:proxy_port => proxy_port,
:proxy_user => proxy_user,
:proxy_pass => proxy_pass,
:host => host,
:port => port,
:path_prefix => path_prefix,
:max_retries => max_retries).
and_return(api_client)
expect(subject.api_client).to eq api_client
end
end
end
describe ".deliver_message" do
let(:api_client) { double }
let(:message) { double }
before do
subject.api_client = api_client
end
it 'delegates the method to the shared api client instance' do
allow(api_client).to receive(:deliver_message).with(message)
subject.deliver_message(message)
end
it 'is also accessible as .send_through_postmark' do
allow(api_client).to receive(:deliver_message).with(message)
subject.send_through_postmark(message)
end
end
describe ".deliver_messages" do
let(:api_client) { double }
let(:message) { double }
before do
subject.api_client = api_client
end
it 'delegates the method to the shared api client instance' do
allow(api_client).to receive(:deliver_messages).with(message)
subject.deliver_messages(message)
end
end
describe ".delivery_stats" do
let(:api_client) { double }
before do
subject.api_client = api_client
end
it 'delegates the method to the shared api client instance' do
allow(api_client).to receive(:delivery_stats)
subject.delivery_stats
end
end
end postmark-1.22.0/spec/unit/postmark/ 0000755 0001751 0001751 00000000000 14123042137 017364 5 ustar vivekdeb vivekdeb postmark-1.22.0/spec/unit/postmark/message_extensions/ 0000755 0001751 0001751 00000000000 14123042137 023267 5 ustar vivekdeb vivekdeb postmark-1.22.0/spec/unit/postmark/message_extensions/mail_spec.rb 0000644 0001751 0001751 00000026031 14123042137 025552 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Mail::Message do
before do
allow(Kernel).to receive(:warn)
end
let(:mail_message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
body "Hello Sheldon!"
end
end
let(:mail_html_message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
content_type 'text/html; charset=UTF-8'
body "Hello Sheldon!"
end
end
let(:templated_message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
template_alias "Hello!"
template_model :name => "Sheldon"
end
end
describe '#tag' do
it 'value set on tag=' do
mail_message.tag='value'
expect(mail_message.tag).to eq 'value'
end
it 'value set on tag()' do
mail_message.tag('value')
expect(mail_message.tag).to eq 'value'
end
end
describe '#track_opens' do
it 'returns nil if unset' do
expect(mail_message.track_opens).to eq ''
end
context 'when assigned via #track_opens=' do
it 'returns assigned value to track opens' do
mail_message.track_opens = true
expect(mail_message.track_opens).to eq 'true'
end
it 'returns assigned value to not track opens' do
mail_message.track_opens = false
expect(mail_message.track_opens).to eq 'false'
end
end
context 'flag set on track_opens()' do
it 'true' do
mail_message.track_opens(true)
expect(mail_message.track_opens).to eq 'true'
end
it 'false' do
mail_message.track_opens(false)
expect(mail_message.track_opens).to eq 'false'
end
end
end
describe '#metadata' do
let(:metadata) { { :test => 'test' } }
it 'returns a mutable empty hash if unset' do
expect(mail_message.metadata).to eq({})
expect(mail_message.metadata.equal?(mail_message.metadata)).to be true
end
it 'supports assigning non-null values (for the builder DSL)' do
expect { mail_message.metadata(metadata) }.to change { mail_message.metadata }.to(metadata)
expect { mail_message.metadata(nil) }.to_not change { mail_message.metadata }
end
it 'returns value assigned via metadata=' do
expect { mail_message.metadata = metadata }.to change { mail_message.metadata }.to(metadata)
end
end
describe '#track_links' do
it 'return empty string when if unset' do
expect(mail_message.track_links).to eq ''
end
context 'when assigned via #track_links=' do
it 'returns track html only body value in Postmark format' do
mail_message.track_links=:html_only
expect(mail_message.track_links).to eq 'HtmlOnly'
end
end
context 'when assigned via track_links()' do
it 'returns track html only body value in Postmark format' do
mail_message.track_links(:html_only)
expect(mail_message.track_links).to eq 'HtmlOnly'
end
end
end
describe "#html?" do
it 'is true for html only email' do
expect(mail_html_message).to be_html
end
end
describe "#body_html" do
it 'returns html body if present' do
expect(mail_html_message.body_html).to eq "Hello Sheldon!"
end
end
describe "#body_text" do
it 'returns text body if present' do
expect(mail_message.body_text).to eq "Hello Sheldon!"
end
end
describe "#postmark_attachments=" do
let(:attached_hash) { {'Name' => 'picture.jpeg',
'ContentType' => 'image/jpeg'} }
it "stores attachments as an array" do
mail_message.postmark_attachments = attached_hash
expect(mail_message.instance_variable_get(:@_attachments)).to include(attached_hash)
end
it "is deprecated" do
expect(Kernel).to receive(:warn).with(/deprecated/)
mail_message.postmark_attachments = attached_hash
end
end
describe "#postmark_attachments" do
let(:attached_file) { double("file") }
let(:attached_hash) { {'Name' => 'picture.jpeg',
'ContentType' => 'image/jpeg'} }
let(:exported_file) { {'Name' => 'file.jpeg',
'ContentType' => 'application/octet-stream',
'Content' => ''} }
before do
allow(attached_file).to receive(:is_a?) { |arg| arg == File ? true : false }
allow(attached_file).to receive(:path) { '/tmp/file.jpeg' }
end
it "supports multiple attachment formats" do
expect(IO).to receive(:read).with("/tmp/file.jpeg").and_return("")
mail_message.postmark_attachments = [attached_hash, attached_file]
attachments = mail_message.export_attachments
expect(attachments).to include(attached_hash)
expect(attachments).to include(exported_file)
end
it "is deprecated" do
mail_message.postmark_attachments = attached_hash
expect(Kernel).to receive(:warn).with(/deprecated/)
mail_message.postmark_attachments
end
end
describe "#export_attachments" do
let(:file_data) { 'binarydatahere' }
let(:exported_data) {
{'Name' => 'face.jpeg',
'Content' => "YmluYXJ5ZGF0YWhlcmU=\n",
'ContentType' => 'image/jpeg'}
}
context 'given a regular attachment' do
it "exports native attachments" do
mail_message.attachments["face.jpeg"] = file_data
expect(mail_message.export_attachments).to include(exported_data)
end
it "still supports the deprecated attachments API" do
mail_message.attachments["face.jpeg"] = file_data
mail_message.postmark_attachments = exported_data
expect(mail_message.export_attachments).to eq [exported_data, exported_data]
end
end
context 'given an inline attachment' do
it "exports the attachment with related content id" do
mail_message.attachments.inline["face.jpeg"] = file_data
attachments = mail_message.export_attachments
expect(attachments.count).to_not be_zero
expect(attachments.first).to include(exported_data)
expect(attachments.first).to have_key('ContentID')
expect(attachments.first['ContentID']).to start_with('cid:')
end
end
end
describe "#export_headers" do
let(:mail_message_with_reserved_headers) do
mail_message.header['Return-Path'] = 'bounce@wildbit.com'
mail_message.header['From'] = 'info@wildbit.com'
mail_message.header['Sender'] = 'info@wildbit.com'
mail_message.header['Received'] = 'from mta.pstmrk.it ([72.14.252.155]:54907)'
mail_message.header['Date'] = 'January 25, 2013 3:30:58 PM PDT'
mail_message.header['Content-Type'] = 'application/json'
mail_message.header['To'] = 'lenard@bigbangtheory.com'
mail_message.header['Cc'] = 'sheldon@bigbangtheory.com'
mail_message.header['Bcc'] = 'penny@bigbangtheory.com'
mail_message.header['Subject'] = 'You want not to use a bogus header'
mail_message.header['Tag'] = 'bogus-tag'
mail_message.header['Attachment'] = 'anydatahere'
mail_message.header['Allowed-Header'] = 'value'
mail_message.header['TRACK-OPENS'] = 'true'
mail_message.header['TRACK-LINKS'] = 'HtmlOnly'
mail_message
end
it 'only allowed headers' do
headers = mail_message_with_reserved_headers.export_headers
header_names = headers.map { |h| h['Name'] }
aggregate_failures do
expect(header_names).to include('Allowed-Header')
expect(header_names.count).to eq 1
end
end
it 'custom header character case preserved' do
custom_header = {"Name"=>"custom-Header", "Value"=>"cUsTomHeaderValue"}
mail_message.header[custom_header['Name']] = custom_header['Value']
expect(mail_message.export_headers.first).to match(custom_header)
end
end
describe "#to_postmark_hash" do
# See mail_message_converter_spec.rb
end
describe '#templated?' do
it { expect(mail_message).to_not be_templated }
it { expect(templated_message).to be_templated }
end
describe '#prerender' do
let(:model) { templated_message.template_model }
let(:model_text) { model[:name] }
let(:template_response) do
{
:html_body => '
{{ name }}',
:text_body => '{{ name }}'
}
end
let(:successful_render_response) do
{
:all_content_is_valid => true,
:subject => {
:rendered_content => 'Subject'
},
:text_body => {
:rendered_content => model_text
},
:html_body => {
:rendered_content => "#{model_text}"
}
}
end
let(:failed_render_response) do
{
:all_content_is_valid => false,
:subject => {
:rendered_content => 'Subject'
},
:text_body => {
:rendered_content => model_text
},
:html_body => {
:rendered_content => nil,
:validation_errors => [
{ :message => 'The syntax for this template is invalid.', :line => 1, :character_position => 1 }
]
}
}
end
subject(:rendering) { message.prerender }
context 'when called on a non-templated message' do
let(:message) { mail_message }
it 'raises a Postmark::Error' do
expect { rendering }.to raise_error(Postmark::Error, /Cannot prerender/)
end
end
context 'when called on a templated message' do
let(:message) { templated_message }
before do
message.delivery_method delivery_method
end
context 'and using a non-Postmark delivery method' do
let(:delivery_method) { Mail::SMTP }
it { expect { rendering }.to raise_error(Postmark::MailAdapterError) }
end
context 'and using a Postmark delivery method' do
let(:delivery_method) { Mail::Postmark }
before do
expect_any_instance_of(Postmark::ApiClient).
to receive(:get_template).with(message.template_alias).
and_return(template_response)
expect_any_instance_of(Postmark::ApiClient).
to receive(:validate_template).with(template_response.merge(:test_render_model => model)).
and_return(render_response)
end
context 'and rendering succeeds' do
let(:render_response) { successful_render_response }
it 'sets HTML and Text parts to rendered values' do
expect { rendering }.
to change { message.subject }.to(render_response[:subject][:rendered_content]).
and change { message.body_text }.to(render_response[:text_body][:rendered_content]).
and change { message.body_html }.to(render_response[:html_body][:rendered_content])
end
end
context 'and rendering fails' do
let(:render_response) { failed_render_response }
it 'raises Postmark::InvalidTemplateError' do
expect { rendering }.to raise_error(Postmark::InvalidTemplateError)
end
end
end
end
end
end
postmark-1.22.0/spec/unit/postmark/mail_message_converter_spec.rb 0000644 0001751 0001751 00000030555 14123042137 025450 0 ustar vivekdeb vivekdeb # encoding: utf-8
require 'spec_helper'
describe Postmark::MailMessageConverter do
subject {Postmark::MailMessageConverter}
let(:mail_message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
body "Hello Sheldon!"
end
end
let(:mail_html_message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
content_type 'text/html; charset=UTF-8'
body "Hello Sheldon!"
end
end
let(:mail_message_with_open_tracking) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
content_type 'text/html; charset=UTF-8'
body "Hello Sheldon!"
track_opens true
end
end
let(:mail_message_with_open_tracking_disabled) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
content_type 'text/html; charset=UTF-8'
body "Hello Sheldon!"
track_opens false
end
end
let(:mail_message_with_open_tracking_set_variable) do
mail = mail_html_message
mail.track_opens = true
mail
end
let(:mail_message_with_open_tracking_disabled_set_variable) do
mail = mail_html_message
mail.track_opens = false
mail
end
let(:mail_message_with_link_tracking_all) do
mail = mail_html_message
mail.track_links :html_and_text
mail
end
let(:mail_message_with_link_tracking_html) do
mail = mail_html_message
mail.track_links = :html_only
mail
end
let(:mail_message_with_link_tracking_text) do
mail = mail_html_message
mail.track_links = :text_only
mail
end
let(:mail_message_with_link_tracking_none) do
mail = mail_html_message
mail.track_links = :none
mail
end
let(:tagged_mail_message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
body "Hello Sheldon!"
tag "sheldon"
end
end
let(:mail_message_without_body) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
end
end
let(:mail_multipart_message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
text_part do
body "Hello Sheldon!"
end
html_part do
body "Hello Sheldon!"
end
end
end
let(:mail_message_with_attachment) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
body "Hello Sheldon!"
add_file empty_gif_path
end
end
let(:mail_message_with_named_addresses) do
Mail.new do
from "Sheldon "
to "\"Leonard Hofstadter\" "
subject "Hello!"
body "Hello Sheldon!"
reply_to '"Penny The Neighbor" '
end
end
let(:mail_message_quoted_printable) do
Mail.new do
from "Sheldon "
to "\"Leonard Hofstadter\" "
subject "Hello!"
content_type 'text/plain; charset=utf-8'
content_transfer_encoding 'quoted-printable'
body 'Он здесь бывал: еще не в галифе.'
reply_to '"Penny The Neighbor" '
end
end
let(:multipart_message_quoted_printable) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
text_part do
content_type 'text/plain; charset=utf-8'
content_transfer_encoding 'quoted-printable'
body 'Загадочное послание.'
end
html_part do
content_type 'text/html; charset=utf-8'
content_transfer_encoding 'quoted-printable'
body 'Загадочное послание.'
end
end
end
let(:templated_message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
template_alias "hello"
template_model :name => "Sheldon"
end
end
it 'converts plain text messages correctly' do
expect(subject.new(mail_message).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"TextBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com"})
end
it 'converts tagged text messages correctly' do
expect(subject.new(tagged_mail_message).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"TextBody" => "Hello Sheldon!",
"Tag" => "sheldon",
"To" => "lenard@bigbangtheory.com"})
end
it 'converts plain text messages without body correctly' do
expect(subject.new(mail_message_without_body).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"To" => "lenard@bigbangtheory.com"})
end
it 'converts html messages correctly' do
expect(subject.new(mail_html_message).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"HtmlBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com"})
end
it 'converts multipart messages correctly' do
expect(subject.new(mail_multipart_message).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"HtmlBody" => "Hello Sheldon!",
"TextBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com"})
end
it 'converts messages with attachments correctly' do
expect(subject.new(mail_message_with_attachment).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"Attachments" => [{"Name" => "empty.gif",
"Content" => encoded_empty_gif_data,
"ContentType" => "image/gif"}],
"TextBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com"})
end
it 'converts messages with named addresses correctly' do
expect(subject.new(mail_message_with_named_addresses).run).to eq({
"From" => "Sheldon ",
"Subject" => "Hello!",
"TextBody" => "Hello Sheldon!",
"To" => "Leonard Hofstadter ",
"ReplyTo" => 'Penny The Neighbor '})
end
it 'convertes templated messages correctly' do
expect(subject.new(templated_message).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"TemplateAlias" => "hello",
"TemplateModel" => {:name => "Sheldon"},
"To" => "lenard@bigbangtheory.com"})
end
context 'open tracking' do
context 'setup inside of mail' do
it 'converts open tracking enabled messages correctly' do
expect(subject.new(mail_message_with_open_tracking).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"HtmlBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com",
"TrackOpens" => true})
end
it 'converts open tracking disabled messages correctly' do
expect(subject.new(mail_message_with_open_tracking_disabled).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"HtmlBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com",
"TrackOpens" => false})
end
end
context 'setup with tracking variable' do
it 'converts open tracking enabled messages correctly' do
expect(subject.new(mail_message_with_open_tracking_set_variable).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"HtmlBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com",
"TrackOpens" => true})
end
it 'converts open tracking disabled messages correctly' do
expect(subject.new(mail_message_with_open_tracking_disabled_set_variable).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"HtmlBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com",
"TrackOpens" => false})
end
end
end
context 'link tracking' do
it 'converts html and text link tracking enabled messages correctly' do
expect(subject.new(mail_message_with_link_tracking_all).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"HtmlBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com",
"TrackLinks" => 'HtmlAndText'})
end
it 'converts html only link tracking enabled messages correctly' do
expect(subject.new(mail_message_with_link_tracking_html).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"HtmlBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com",
"TrackLinks" => 'HtmlOnly'})
end
it 'converts text only link tracking enabled messages correctly' do
expect(subject.new(mail_message_with_link_tracking_text).run).to eq({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"HtmlBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com",
"TrackLinks" => 'TextOnly'})
end
it 'converts link tracking disabled messages correctly' do
expect(subject.new(mail_message_with_link_tracking_none).run).to eq ({
"From" => "sheldon@bigbangtheory.com",
"Subject" => "Hello!",
"HtmlBody" => "Hello Sheldon!",
"To" => "lenard@bigbangtheory.com",
"TrackLinks" => 'None'})
end
it 'converts link tracking options when set via header' do
msg = mail_html_message
msg[:track_links] = :html_and_text
expect(subject.new(msg).run).to include('TrackLinks' => 'HtmlAndText')
end
end
context 'metadata' do
it 'converts single metadata field' do
metadata = {:test => 'test'}
msg = mail_html_message
msg.metadata = metadata
expect(subject.new(msg).run).to include('Metadata' => metadata)
end
it 'converts unicode metadata field metadata' do
metadata = {:test => "Велик"}
msg = mail_html_message
msg.metadata = metadata
expect(subject.new(msg).run).to include('Metadata' => metadata)
end
it 'converts multiple metadata fields' do
metadata = {}
10.times {|i| metadata["test#{i + 1}"] = "t" * 80}
msg = mail_html_message
msg.metadata = metadata
expect(subject.new(msg).run).to include('Metadata' => metadata)
end
end
it 'correctly decodes unicode in messages transfered as quoted-printable' do
expect(subject.new(mail_message_quoted_printable).run).to include('TextBody' => 'Он здесь бывал: еще не в галифе.')
end
it 'correctly decodes unicode in multipart quoted-printable messages' do
expect(subject.new(multipart_message_quoted_printable).run).to include(
'TextBody' => 'Загадочное послание.',
'HtmlBody' => 'Загадочное послание.')
end
context 'when bcc is empty' do
it 'excludes bcc from message' do
mail_message.bcc = nil
expect(mail_message.to_postmark_hash.keys).not_to include('Bcc')
end
end
context 'when cc is empty' do
it 'excludes cc from message' do
mail_message.cc = nil
expect(mail_message.to_postmark_hash.keys).not_to include('Cc')
end
end
describe 'passing message stream' do
context 'when not set' do
specify { expect(subject.new(mail_message).run).not_to include('MessageStream') }
end
context 'when set' do
before do
mail_message.message_stream = 'weekly-newsletter'
end
it 'passes message stream to the API call' do
expect(subject.new(mail_message).run).to include('MessageStream' => 'weekly-newsletter')
end
end
end
end
postmark-1.22.0/spec/unit/postmark/json_spec.rb 0000644 0001751 0001751 00000001530 14123042137 021673 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark::Json do
let(:data) { {"bar" => "foo", "foo" => "bar"} }
shared_examples "json parser" do
it 'encodes and decodes data correctly' do
hash = Postmark::Json.decode(Postmark::Json.encode(data))
expect(hash).to have_key("bar")
expect(hash).to have_key("foo")
end
end
context "given response parser is JSON" do
before do
Postmark.response_parser_class = :Json
end
it_behaves_like "json parser"
end
context "given response parser is ActiveSupport::JSON" do
before do
Postmark.response_parser_class = :ActiveSupport
end
it_behaves_like "json parser"
end
context "given response parser is Yajl", :skip_for_platform => 'java' do
before do
Postmark.response_parser_class = :Yajl
end
it_behaves_like "json parser"
end
end postmark-1.22.0/spec/unit/postmark/inflector_spec.rb 0000644 0001751 0001751 00000002253 14123042137 022712 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark::Inflector do
describe ".to_postmark" do
it 'converts rubyish underscored format to camel cased symbols accepted by the Postmark API' do
expect(subject.to_postmark(:foo_bar)).to eq 'FooBar'
expect(subject.to_postmark(:_bar)).to eq 'Bar'
expect(subject.to_postmark(:really_long_long_long_long_symbol)).to eq 'ReallyLongLongLongLongSymbol'
expect(subject.to_postmark(:foo_bar_1)).to eq 'FooBar1'
end
it 'accepts strings as well' do
expect(subject.to_postmark('foo_bar')).to eq 'FooBar'
end
it 'acts idempotentely' do
expect(subject.to_postmark('FooBar')).to eq 'FooBar'
end
end
describe ".to_ruby" do
it 'converts camel cased symbols returned by the Postmark API to underscored Ruby symbols' do
expect(subject.to_ruby('FooBar')).to eq :foo_bar
expect(subject.to_ruby('LongTimeAgoInAFarFarGalaxy')).to eq :long_time_ago_in_a_far_far_galaxy
expect(subject.to_ruby('MessageID')).to eq :message_id
end
it 'acts idempotentely' do
expect(subject.to_ruby(:foo_bar)).to eq :foo_bar
expect(subject.to_ruby(:foo_bar_1)).to eq :foo_bar_1
end
end
end postmark-1.22.0/spec/unit/postmark/inbound_spec.rb 0000644 0001751 0001751 00000011307 14123042137 022363 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark::Inbound do
# http://developer.postmarkapp.com/developer-inbound-parse.html#example-hook
let(:example_inbound) { '{"From":"myUser@theirDomain.com","FromFull":{"Email":"myUser@theirDomain.com","Name":"John Doe"},"To":"451d9b70cf9364d23ff6f9d51d870251569e+ahoy@inbound.postmarkapp.com","ToFull":[{"Email":"451d9b70cf9364d23ff6f9d51d870251569e+ahoy@inbound.postmarkapp.com","Name":""}],"Cc":"\"Full name\" , \"Another Cc\" ","CcFull":[{"Email":"sample.cc@emailDomain.com","Name":"Full name"},{"Email":"another.cc@emailDomain.com","Name":"Another Cc"}],"ReplyTo":"myUsersReplyAddress@theirDomain.com","Subject":"This is an inbound message","MessageID":"22c74902-a0c1-4511-804f2-341342852c90","Date":"Thu, 5 Apr 2012 16:59:01 +0200","MailboxHash":"ahoy","TextBody":"[ASCII]","HtmlBody":"[HTML(encoded)]","Tag":"","Headers":[{"Name":"X-Spam-Checker-Version","Value":"SpamAssassin 3.3.1 (2010-03-16) onrs-ord-pm-inbound1.wildbit.com"},{"Name":"X-Spam-Status","Value":"No"},{"Name":"X-Spam-Score","Value":"-0.1"},{"Name":"X-Spam-Tests","Value":"DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,SPF_PASS"},{"Name":"Received-SPF","Value":"Pass (sender SPF authorized) identity=mailfrom; client-ip=209.85.160.180; helo=mail-gy0-f180.google.com; envelope-from=myUser@theirDomain.com; receiver=451d9b70cf9364d23ff6f9d51d870251569e+ahoy@inbound.postmarkapp.com"},{"Name":"DKIM-Signature","Value":"v=1; a=rsa-sha256; c=relaxed\/relaxed; d=wildbit.com; s=google; h=mime-version:reply-to:date:message-id:subject:from:to:cc :content-type; bh=cYr\/+oQiklaYbBJOQU3CdAnyhCTuvemrU36WT7cPNt0=; b=QsegXXbTbC4CMirl7A3VjDHyXbEsbCUTPL5vEHa7hNkkUTxXOK+dQA0JwgBHq5C+1u iuAJMz+SNBoTqEDqte2ckDvG2SeFR+Edip10p80TFGLp5RucaYvkwJTyuwsA7xd78NKT Q9ou6L1hgy\/MbKChnp2kxHOtYNOrrszY3JfQM="},{"Name":"MIME-Version","Value":"1.0"},{"Name":"Message-ID","Value":""}],"Attachments":[{"Name":"myimage.png","Content":"[BASE64-ENCODED CONTENT]","ContentType":"image/png","ContentLength":4096},{"Name":"mypaper.doc","Content":"[BASE64-ENCODED CONTENT]","ContentType":"application/msword","ContentLength":16384}]}' }
context "given a serialized inbound document" do
subject { Postmark::Inbound.to_ruby_hash(example_inbound) }
it { expect(subject).to have_key(:from) }
it { expect(subject).to have_key(:from_full) }
it { expect(subject).to have_key(:to) }
it { expect(subject).to have_key(:to_full) }
it { expect(subject).to have_key(:cc) }
it { expect(subject).to have_key(:cc_full) }
it { expect(subject).to have_key(:reply_to) }
it { expect(subject).to have_key(:subject) }
it { expect(subject).to have_key(:message_id) }
it { expect(subject).to have_key(:date) }
it { expect(subject).to have_key(:mailbox_hash) }
it { expect(subject).to have_key(:text_body) }
it { expect(subject).to have_key(:html_body) }
it { expect(subject).to have_key(:tag) }
it { expect(subject).to have_key(:headers) }
it { expect(subject).to have_key(:attachments) }
context "cc" do
it 'has 2 CCs' do
expect(subject[:cc_full].count).to eq 2
end
it 'stores CCs as an array of Ruby hashes' do
cc = subject[:cc_full].last
expect(cc).to have_key(:email)
expect(cc).to have_key(:name)
end
end
context "to" do
it 'has 1 recipients' do
expect(subject[:to_full].count).to eq 1
end
it 'stores TOs as an array of Ruby hashes' do
cc = subject[:to_full].last
expect(cc).to have_key(:email)
expect(cc).to have_key(:name)
end
end
context "from" do
it 'is a hash' do
expect(subject[:from_full]).to be_a Hash
end
it 'has all required fields' do
expect(subject[:from_full]).to have_key(:email)
expect(subject[:from_full]).to have_key(:name)
end
end
context "headers" do
it 'has 8 headers' do
expect(subject[:headers].count).to eq 8
end
it 'stores headers as an array of Ruby hashes' do
header = subject[:headers].last
expect(header).to have_key(:name)
expect(header).to have_key(:value)
end
end
context "attachments" do
it 'has 2 attachments' do
expect(subject[:attachments].count).to eq 2
end
it 'stores attachemnts as an array of Ruby hashes' do
attachment = subject[:attachments].last
expect(attachment).to have_key(:name)
expect(attachment).to have_key(:content)
expect(attachment).to have_key(:content_type)
expect(attachment).to have_key(:content_length)
end
end
end
end postmark-1.22.0/spec/unit/postmark/http_client_spec.rb 0000644 0001751 0001751 00000023513 14123042137 023244 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark::HttpClient do
def response_body(status, message = "")
{"ErrorCode" => status, "Message" => message}.to_json
end
let(:api_token) { "provided-postmark-api-token" }
let(:http_client) { Postmark::HttpClient.new(api_token) }
subject { http_client }
context "attr writers" do
it { expect(subject).to respond_to(:api_token=) }
it { expect(subject).to respond_to(:api_key=) }
end
context "attr readers" do
it { expect(subject).to respond_to(:http) }
it { expect(subject).to respond_to(:secure) }
it { expect(subject).to respond_to(:api_token) }
it { expect(subject).to respond_to(:api_key) }
it { expect(subject).to respond_to(:proxy_host) }
it { expect(subject).to respond_to(:proxy_port) }
it { expect(subject).to respond_to(:proxy_user) }
it { expect(subject).to respond_to(:proxy_pass) }
it { expect(subject).to respond_to(:host) }
it { expect(subject).to respond_to(:port) }
it { expect(subject).to respond_to(:path_prefix) }
it { expect(subject).to respond_to(:http_open_timeout) }
it { expect(subject).to respond_to(:http_read_timeout) }
it { expect(subject).to respond_to(:http_ssl_version) }
end
context "when it is created without options" do
its(:api_token) { is_expected.to eq api_token }
its(:api_key) { is_expected.to eq api_token }
its(:host) { is_expected.to eq 'api.postmarkapp.com' }
its(:port) { is_expected.to eq 443 }
its(:secure) { is_expected.to be true }
its(:path_prefix) { is_expected.to eq '/' }
its(:http_read_timeout) { is_expected.to eq 15 }
its(:http_open_timeout) { is_expected.to eq 5 }
it 'does not provide a default which utilizes the Net::HTTP default', :skip_ruby_version => ['1.8.7'] do
http_client = subject.http
expect(http_client.ssl_version).to eq nil
end
end
context "when it is created with options" do
let(:secure) { true }
let(:proxy_host) { "providedproxyhostname.com" }
let(:proxy_port) { 42 }
let(:proxy_user) { "provided proxy user" }
let(:proxy_pass) { "provided proxy pass" }
let(:host) { "providedhostname.org" }
let(:port) { 4443 }
let(:path_prefix) { "/provided/path/prefix" }
let(:http_open_timeout) { 42 }
let(:http_read_timeout) { 42 }
let(:http_ssl_version) { :TLSv1_2}
subject { Postmark::HttpClient.new(api_token,
:secure => secure,
:proxy_host => proxy_host,
:proxy_port => proxy_port,
:proxy_user => proxy_user,
:proxy_pass => proxy_pass,
:host => host,
:port => port,
:path_prefix => path_prefix,
:http_open_timeout => http_open_timeout,
:http_read_timeout => http_read_timeout,
:http_ssl_version => http_ssl_version) }
its(:api_token) { is_expected.to eq api_token }
its(:api_key) { is_expected.to eq api_token }
its(:secure) { is_expected.to eq secure }
its(:proxy_host) { is_expected.to eq proxy_host }
its(:proxy_port) { is_expected.to eq proxy_port }
its(:proxy_user) { is_expected.to eq proxy_user }
its(:proxy_pass) { is_expected.to eq proxy_pass }
its(:host) { is_expected.to eq host }
its(:port) { is_expected.to eq port }
its(:path_prefix) { is_expected.to eq path_prefix }
its(:http_open_timeout) { is_expected.to eq http_open_timeout }
its(:http_read_timeout) { is_expected.to eq http_read_timeout }
its(:http_ssl_version) { is_expected.to eq http_ssl_version }
it 'uses port 80 for plain HTTP connections' do
expect(Postmark::HttpClient.new(api_token, :secure => false).port).to eq(80)
end
it 'uses port 443 for secure HTTP connections' do
expect(Postmark::HttpClient.new(api_token, :secure => true).port).to eq(443)
end
it 'respects port over secure option' do
client = Postmark::HttpClient.new(api_token, :port => 80, :secure => true)
expect(client.port).to eq(80)
expect(client.protocol).to eq('https')
end
end
describe "#post" do
let(:target_path) { "path/on/server" }
let(:target_url) { "https://api.postmarkapp.com/#{target_path}" }
it "sends a POST request to provided URI" do
FakeWeb.register_uri(:post, target_url, :body => response_body(200))
subject.post(target_path)
expect(FakeWeb.last_request.method).to eq('POST')
expect(FakeWeb.last_request.path).to eq('/' + target_path)
end
it "raises a custom error when API token authorization fails" do
FakeWeb.register_uri(:post, target_url, :body => response_body(401), :status => [ "401", "Unauthorized" ])
expect { subject.post(target_path) }.to raise_error Postmark::InvalidApiKeyError
end
it "raises a custom error when sent JSON was not valid" do
FakeWeb.register_uri(:post, target_url, :body => response_body(422), :status => [ "422", "Invalid" ])
expect { subject.post(target_path) }.to raise_error Postmark::InvalidMessageError
end
it "raises a custom error when server fails to process the request" do
FakeWeb.register_uri(:post, target_url, :body => response_body(500),
:status => [ "500", "Internal Server Error" ])
expect { subject.post(target_path) }.to raise_error Postmark::InternalServerError
end
it "raises a custom error when the request times out" do
expect(subject.http).to receive(:post).at_least(:once).and_raise(Timeout::Error)
expect { subject.post(target_path) }.to raise_error Postmark::TimeoutError
end
it "raises a default error when unknown issue occurs" do
FakeWeb.register_uri(:post, target_url, :body => response_body(485),
:status => [ "485", "Custom HTTP response status" ])
expect { subject.post(target_path) }.to raise_error Postmark::UnknownError
end
end
describe "#get" do
let(:target_path) { "path/on/server" }
let(:target_url) { "https://api.postmarkapp.com/#{target_path}" }
it "sends a GET request to provided URI" do
FakeWeb.register_uri(:get, target_url, :body => response_body(200))
subject.get(target_path)
expect(FakeWeb.last_request.method).to eq('GET')
expect(FakeWeb.last_request.path).to eq('/' + target_path)
end
it "raises a custom error when API token authorization fails" do
FakeWeb.register_uri(:get, target_url, :body => response_body(401), :status => [ "401", "Unauthorized" ])
expect { subject.get(target_path) }.to raise_error Postmark::InvalidApiKeyError
end
it "raises a custom error when sent JSON was not valid" do
FakeWeb.register_uri(:get, target_url, :body => response_body(422), :status => [ "422", "Invalid" ])
expect { subject.get(target_path) }.to raise_error Postmark::InvalidMessageError
end
it "raises a custom error when server fails to process the request" do
FakeWeb.register_uri(:get, target_url, :body => response_body(500),
:status => [ "500", "Internal Server Error" ])
expect { subject.get(target_path) }.to raise_error Postmark::InternalServerError
end
it "raises a custom error when the request times out" do
expect(subject.http).to receive(:get).at_least(:once).and_raise(Timeout::Error)
expect { subject.get(target_path) }.to raise_error Postmark::TimeoutError
end
it "raises a default error when unknown issue occurs" do
FakeWeb.register_uri(:get, target_url, :body => response_body(485),
:status => [ "485", "Custom HTTP response status" ])
expect { subject.get(target_path) }.to raise_error Postmark::UnknownError
end
end
describe "#put" do
let(:target_path) { "path/on/server" }
let(:target_url) { "https://api.postmarkapp.com/#{target_path}" }
it "sends a PUT request to provided URI" do
FakeWeb.register_uri(:put, target_url, :body => response_body(200))
subject.put(target_path)
expect(FakeWeb.last_request.method).to eq('PUT')
expect(FakeWeb.last_request.path).to eq('/' + target_path)
end
it "raises a custom error when API token authorization fails" do
FakeWeb.register_uri(:put, target_url, :body => response_body(401),
:status => [ "401", "Unauthorized" ])
expect { subject.put(target_path) }.to raise_error Postmark::InvalidApiKeyError
end
it "raises a custom error when sent JSON was not valid" do
FakeWeb.register_uri(:put, target_url, :body => response_body(422),
:status => [ "422", "Invalid" ])
expect { subject.put(target_path) }.to raise_error Postmark::InvalidMessageError
end
it "raises a custom error when server fails to process the request" do
FakeWeb.register_uri(:put, target_url, :body => response_body(500),
:status => [ "500", "Internal Server Error" ])
expect { subject.put(target_path) }.to raise_error Postmark::InternalServerError
end
it "raises a custom error when the request times out" do
expect(subject.http).to receive(:put).at_least(:once).and_raise(Timeout::Error)
expect { subject.put(target_path) }.to raise_error Postmark::TimeoutError
end
it "raises a default error when unknown issue occurs" do
FakeWeb.register_uri(:put, target_url, :body => response_body(485),
:status => [ "485", "Custom HTTP response status" ])
expect { subject.put(target_path) }.to raise_error Postmark::UnknownError
end
end
end
postmark-1.22.0/spec/unit/postmark/helpers/ 0000755 0001751 0001751 00000000000 14123042137 021026 5 ustar vivekdeb vivekdeb postmark-1.22.0/spec/unit/postmark/helpers/message_helper_spec.rb 0000644 0001751 0001751 00000013615 14123042137 025356 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark::MessageHelper do
let(:attachments) {
[
File.open(empty_gif_path),
{:name => "img2.gif",
:content => Postmark::MessageHelper.encode_in_base64(File.read(empty_gif_path)),
:content_type => "application/octet-stream"}
]
}
let(:postmark_attachments) {
content = Postmark::MessageHelper.encode_in_base64(File.read(empty_gif_path))
[
{"Name" => "empty.gif",
"Content" => content,
"ContentType" => "application/octet-stream"},
{"Name" => "img2.gif",
"Content" => content,
"ContentType" => "application/octet-stream"}
]
}
let(:headers) {
[{:name => "CUSTOM-HEADER", :value => "value"}]
}
let(:postmark_headers) {
[{"Name" => "CUSTOM-HEADER", "Value" => "value"}]
}
describe ".to_postmark" do
let(:message) {
{
:from => "sender@example.com",
:to => "receiver@example.com",
:cc => "copied@example.com",
:bcc => "blank-copied@example.com",
:subject => "Test",
:tag => "Invitation",
:html_body => "Hello",
:text_body => "Hello",
:reply_to => "reply@example.com"
}
}
let(:postmark_message) {
{
"From" => "sender@example.com",
"To" => "receiver@example.com",
"Cc" => "copied@example.com",
"Bcc"=> "blank-copied@example.com",
"Subject" => "Test",
"Tag" => "Invitation",
"HtmlBody" => "Hello",
"TextBody" => "Hello",
"ReplyTo" => "reply@example.com",
}
}
let(:message_with_headers) {
message.merge(:headers => headers)
}
let(:postmark_message_with_headers) {
postmark_message.merge("Headers" => postmark_headers)
}
let(:message_with_headers_and_attachments) {
message_with_headers.merge(:attachments => attachments)
}
let(:postmark_message_with_headers_and_attachments) {
postmark_message_with_headers.merge("Attachments" => postmark_attachments)
}
let(:message_with_open_tracking) {
message.merge(:track_opens => true)
}
let(:message_with_open_tracking_false) {
message.merge(:track_opens => false)
}
let(:postmark_message_with_open_tracking) {
postmark_message.merge("TrackOpens" => true)
}
let(:postmark_message_with_open_tracking_false) {
postmark_message.merge("TrackOpens" => false)
}
it 'converts messages without custom headers and attachments correctly' do
expect(subject.to_postmark(message)).to eq postmark_message
end
it 'converts messages with custom headers and without attachments correctly' do
expect(subject.to_postmark(message_with_headers)).to eq postmark_message_with_headers
end
it 'converts messages with custom headers and attachments correctly' do
expect(subject.to_postmark(message_with_headers_and_attachments)).to eq postmark_message_with_headers_and_attachments
end
context 'open tracking' do
it 'converts messages with open tracking flag set to true correctly' do
expect(subject.to_postmark(message_with_open_tracking)).to eq(postmark_message_with_open_tracking)
end
it 'converts messages with open tracking flag set to false correctly' do
expect(subject.to_postmark(message_with_open_tracking_false)).to eq(postmark_message_with_open_tracking_false)
end
end
context 'metadata' do
it 'converts messages with metadata correctly' do
metadata = {"test" => "value"}
data= message.merge(:metadata => metadata)
expect(subject.to_postmark(data)).to include(postmark_message.merge("Metadata" => metadata))
end
end
context 'link tracking' do
let(:message_with_link_tracking_html) { message.merge(:track_links => :html_only) }
let(:message_with_link_tracking_text) { message.merge(:track_links => :text_only) }
let(:message_with_link_tracking_all) { message.merge(:track_links => :html_and_text) }
let(:message_with_link_tracking_none) { message.merge(:track_links => :none) }
let(:postmark_message_with_link_tracking_html) { postmark_message.merge("TrackLinks" => 'HtmlOnly') }
let(:postmark_message_with_link_tracking_text) { postmark_message.merge("TrackLinks" => 'TextOnly') }
let(:postmark_message_with_link_tracking_all) { postmark_message.merge("TrackLinks" => 'HtmlAndText') }
let(:postmark_message_with_link_tracking_none) { postmark_message.merge("TrackLinks" => 'None') }
it 'converts html body link tracking to Postmark format' do
expect(subject.to_postmark(message_with_link_tracking_html)).to eq(postmark_message_with_link_tracking_html)
end
it 'converts text body link tracking to Postmark format' do
expect(subject.to_postmark(message_with_link_tracking_text)).to eq(postmark_message_with_link_tracking_text)
end
it 'converts html and text body link tracking to Postmark format' do
expect(subject.to_postmark(message_with_link_tracking_all)).to eq(postmark_message_with_link_tracking_all)
end
it 'converts no link tracking to Postmark format' do
expect(subject.to_postmark(message_with_link_tracking_none)).to eq(postmark_message_with_link_tracking_none)
end
end
end
describe ".headers_to_postmark" do
it 'converts headers to Postmark format' do
expect(subject.headers_to_postmark(headers)).to eq postmark_headers
end
it 'accepts single header as a non-array' do
expect(subject.headers_to_postmark(headers.first)).to eq [postmark_headers.first]
end
end
describe ".attachments_to_postmark" do
it 'converts attachments to Postmark format' do
expect(subject.attachments_to_postmark(attachments)).to eq postmark_attachments
end
it 'accepts single attachment as a non-array' do
expect(subject.attachments_to_postmark(attachments.first)).to eq [postmark_attachments.first]
end
end
end postmark-1.22.0/spec/unit/postmark/helpers/hash_helper_spec.rb 0000644 0001751 0001751 00000005200 14123042137 024644 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark::HashHelper do
describe ".to_postmark" do
let(:source) do
{
:level_one => {
:level_two => {
:level_three => [{ :array_item => 1 }]
}
}
}
end
describe 'default behaviour' do
let(:target) do
{
'LevelOne' => {
:level_two => {
:level_three => [{ :array_item => 1 }]
}
}
}
end
it 'does not convert nested elements' do
expect(subject.to_postmark(source)).to eq(target)
end
end
describe 'deep conversion' do
let(:target) do
{
'LevelOne' => {
'LevelTwo' => {
'LevelThree' => [{ 'ArrayItem' => 1 }]
}
}
}
end
it 'converts nested elements when requested' do
expect(subject.to_postmark(source, :deep => true)).to eq(target)
end
end
it 'leaves CamelCase keys untouched' do
expect(subject.to_postmark('ReplyTo' => 'alice@example.com')).to eq('ReplyTo' => 'alice@example.com')
end
end
describe ".to_ruby" do
let(:source) do
{
'LevelOne' => {
'LevelTwo' => {
'LevelThree' => [{ 'ArrayItem' => 1 }]
}
}
}
end
describe 'default behaviour' do
let(:target) do
{
:level_one => {
'LevelTwo' => {
'LevelThree' => [{ 'ArrayItem' => 1 }]
}
}
}
end
it 'does not convert nested elements' do
expect(subject.to_ruby(source)).to eq(target)
end
end
describe 'deep conversion' do
let(:target) do
{
:level_one => {
:level_two => {
:level_three => [{ :array_item => 1 }]
}
}
}
end
it 'converts nested elements when requested' do
expect(subject.to_ruby(source, :deep => true)).to eq(target)
end
end
describe 'compatibility mode' do
let(:target) do
{
:level_one => {
'LevelTwo' => {
'LevelThree' => [{ 'ArrayItem' => 1 }]
}
},
'LevelOne' => {
'LevelTwo' => {
'LevelThree' => [{ 'ArrayItem' => 1 }]
}
}
}
end
it 'preserves the original structure' do
expect(subject.to_ruby(source, :compatible => true)).to eq target
end
end
it 'leaves symbol keys untouched' do
expect(subject.to_ruby(:reply_to => 'alice@example.com')).to eq(:reply_to => 'alice@example.com')
end
end
end postmark-1.22.0/spec/unit/postmark/handlers/ 0000755 0001751 0001751 00000000000 14123042137 021164 5 ustar vivekdeb vivekdeb postmark-1.22.0/spec/unit/postmark/handlers/mail_spec.rb 0000644 0001751 0001751 00000005111 14123042137 023443 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Mail::Postmark do
let(:message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
subject "Hello!"
body "Hello Sheldon!"
end
end
before do
message.delivery_method Mail::Postmark
end
subject(:handler) { message.delivery_method }
it "can be set as delivery_method" do
message.delivery_method Mail::Postmark
is_expected.to be_a(Mail::Postmark)
end
describe '#deliver!' do
it "returns self by default" do
expect_any_instance_of(Postmark::ApiClient).to receive(:deliver_message).with(message)
expect(message.deliver).to eq message
end
it "returns the actual response if :return_response setting is present" do
expect_any_instance_of(Postmark::ApiClient).to receive(:deliver_message).with(message)
message.delivery_method Mail::Postmark, :return_response => true
expect(message.deliver).to eq message
end
it "allows setting the api token" do
message.delivery_method Mail::Postmark, :api_token => 'api-token'
expect(message.delivery_method.settings[:api_token]).to eq 'api-token'
end
it 'uses provided API token' do
message.delivery_method Mail::Postmark, :api_token => 'api-token'
expect(Postmark::ApiClient).to receive(:new).with('api-token', {}).and_return(double(:deliver_message => true))
message.deliver
end
it 'uses API token provided as legacy api_key' do
message.delivery_method Mail::Postmark, :api_key => 'api-token'
expect(Postmark::ApiClient).to receive(:new).with('api-token', {}).and_return(double(:deliver_message => true))
message.deliver
end
context 'when sending a pre-rendered message' do
it "uses ApiClient#deliver_message to send the message" do
expect_any_instance_of(Postmark::ApiClient).to receive(:deliver_message).with(message)
message.deliver
end
end
context 'when sending a Postmark template' do
let(:message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
template_alias "hello"
template_model :name => "Sheldon"
end
end
it 'uses ApiClient#deliver_message_with_template to send the message' do
expect_any_instance_of(Postmark::ApiClient).to receive(:deliver_message_with_template).with(message)
message.deliver
end
end
end
describe '#api_client' do
subject { handler.api_client }
it { is_expected.to be_a(Postmark::ApiClient) }
end
end
postmark-1.22.0/spec/unit/postmark/error_spec.rb 0000644 0001751 0001751 00000017570 14123042137 022066 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe(Postmark::Error) do
it {is_expected.to be_a(StandardError)}
end
describe(Postmark::HttpClientError) do
it {is_expected.to be_a(Postmark::Error)}
it {expect(subject.retry?).to be true}
end
describe(Postmark::HttpServerError) do
it {is_expected.to be_a(Postmark::Error)}
describe '.build' do
context 'picks an appropriate subclass for code' do
subject {Postmark::HttpServerError.build(code, Postmark::Json.encode({}))}
context '401' do
let(:code) {'401'}
it {is_expected.to be_a(Postmark::InvalidApiKeyError)}
its(:status_code) {is_expected.to eq 401}
end
context '422' do
let(:code) {'422'}
it {is_expected.to be_a(Postmark::ApiInputError)}
its(:status_code) {is_expected.to eq 422}
end
context '500' do
let(:code) {'500'}
it {is_expected.to be_a(Postmark::InternalServerError)}
its(:status_code) {is_expected.to eq 500}
end
context 'others' do
let(:code) {'999'}
it {is_expected.to be_a(Postmark::UnexpectedHttpResponseError)}
its(:status_code) {is_expected.to eq code.to_i}
end
end
end
describe '#retry?' do
it 'is true for 5XX status codes' do
(500...600).each do |code|
expect(Postmark::HttpServerError.new(code).retry?).to be true
end
end
it 'is false for other codes except 5XX' do
[200, 300, 400].each do |code|
expect(Postmark::HttpServerError.new(code).retry?).to be false
end
end
end
describe '#message ' do
it 'uses "Message" field on postmark response if available' do
data = {'Message' => 'Postmark error message'}
error = Postmark::HttpServerError.new(502, Postmark::Json.encode(data), data)
expect(error.message).to eq data['Message']
end
it 'falls back to a message generated from status code' do
error = Postmark::HttpServerError.new(502, '')
expect(error.message).to match(/The Postmark API responded with HTTP status \d+/)
end
end
end
describe(Postmark::ApiInputError) do
describe '.build' do
context 'picks an appropriate subclass for error code' do
let(:response) {{'ErrorCode' => code}}
subject do
Postmark::ApiInputError.build(Postmark::Json.encode(response), response)
end
shared_examples_for 'api input error' do
its(:status_code) {is_expected.to eq 422}
it {expect(subject.retry?).to be false}
it {is_expected.to be_a(Postmark::ApiInputError)}
it {is_expected.to be_a(Postmark::HttpServerError)}
end
context '406' do
let(:code) {Postmark::ApiInputError::INACTIVE_RECIPIENT}
it {is_expected.to be_a(Postmark::InactiveRecipientError)}
it_behaves_like 'api input error'
end
context '300' do
let(:code) {Postmark::ApiInputError::INVALID_EMAIL_ADDRESS}
it {is_expected.to be_a(Postmark::InvalidEmailAddressError)}
it_behaves_like 'api input error'
end
context 'others' do
let(:code) {'9999'}
it_behaves_like 'api input error'
end
end
end
end
describe Postmark::InvalidTemplateError do
subject(:error) {Postmark::InvalidTemplateError.new(:foo => 'bar')}
it 'is created with a response' do
expect(error.message).to start_with('Failed to render the template.')
expect(error.postmark_response).to eq(:foo => 'bar')
end
end
describe(Postmark::TimeoutError) do
it {is_expected.to be_a(Postmark::Error)}
it {expect(subject.retry?).to be true}
end
describe(Postmark::UnknownMessageType) do
it 'exists for backward compatibility' do
is_expected.to be_a(Postmark::Error)
end
end
describe(Postmark::InvalidApiKeyError) do
it {is_expected.to be_a(Postmark::Error)}
end
describe(Postmark::InternalServerError) do
it {is_expected.to be_a(Postmark::Error)}
end
describe(Postmark::UnexpectedHttpResponseError) do
it {is_expected.to be_a(Postmark::Error)}
end
describe(Postmark::MailAdapterError) do
it {is_expected.to be_a(Postmark::Error)}
end
describe(Postmark::InvalidEmailAddressError) do
describe '.new' do
let(:response) {{'Message' => message}}
subject do
Postmark::InvalidEmailAddressError.new(
Postmark::ApiInputError::INVALID_EMAIL_ADDRESS, Postmark::Json.encode(response), response)
end
let(:message) do
"Error parsing 'To': Illegal email address 'johne.xample.com'. It must contain the '@' symbol."
end
it 'body is set' do
expect(subject.body).to eq(Postmark::Json.encode(response))
end
it 'parsed body is set' do
expect(subject.parsed_body).to eq(response)
end
it 'error code is set' do
expect(subject.error_code).to eq(Postmark::ApiInputError::INVALID_EMAIL_ADDRESS)
end
end
end
describe(Postmark::InactiveRecipientError) do
describe '.parse_recipients' do
let(:recipients) do
%w(nothing@wildbit.com noth.ing+2@wildbit.com noth.ing+2-1@wildbit.com)
end
subject {Postmark::InactiveRecipientError.parse_recipients(message)}
context '1/1 inactive' do
let(:message) do
'You tried to send to a recipient that has been marked as ' \
"inactive.\nFound inactive addresses: #{recipients[0]}.\n" \
'Inactive recipients are ones that have generated a hard ' \
'bounce or a spam complaint.'
end
it {is_expected.to eq(recipients.take(1))}
end
context 'i/n inactive, n > 1, i < n - new message format' do
let(:message) { "Message OK, but will not deliver to these inactive addresses: #{recipients[0...2].join(', ')}" }
it {is_expected.to eq(recipients.take(2))}
end
context 'i/n inactive, n > 1, i < n' do
let(:message) do
'Message OK, but will not deliver to these inactive addresses: ' \
"#{recipients[0...2].join(', ')}. Inactive recipients are ones that " \
'have generated a hard bounce or a spam complaint.'
end
it {is_expected.to eq(recipients.take(2))}
end
context 'n/n inactive, n > 1' do
let(:message) do
'You tried to send to recipients that have all been marked as ' \
"inactive.\nFound inactive addresses: #{recipients.join(', ')}.\n" \
'Inactive recipients are ones that have generated a hard bounce or a spam complaint.'
end
it {is_expected.to eq(recipients)}
end
context 'unknown error format' do
let(:message) {recipients.join(', ')}
it {is_expected.to eq([])}
end
end
describe '.new' do
let(:address) {'user@example.org'}
let(:response) {{'Message' => message}}
subject do
Postmark::InactiveRecipientError.new(
Postmark::ApiInputError::INACTIVE_RECIPIENT,
Postmark::Json.encode(response),
response)
end
let(:message) do
'You tried to send to a recipient that has been marked as ' \
"inactive.\nFound inactive addresses: #{address}.\n" \
'Inactive recipients are ones that have generated a hard ' \
'bounce or a spam complaint.'
end
it 'parses recipients from json payload' do
expect(subject.recipients).to eq([address])
end
it 'body is set' do
expect(subject.body).to eq(Postmark::Json.encode(response))
end
it 'parsed body is set' do
expect(subject.parsed_body).to eq(response)
end
it 'error code is set' do
expect(subject.error_code).to eq(Postmark::ApiInputError::INACTIVE_RECIPIENT)
end
end
end
describe(Postmark::DeliveryError) do
it 'is an alias to Error for backwards compatibility' do
expect(subject.class).to eq(Postmark::Error)
end
end
describe(Postmark::InvalidMessageError) do
it 'is an alias to Error for backwards compatibility' do
expect(subject.class).to eq(Postmark::ApiInputError)
end
end
describe(Postmark::UnknownError) do
it 'is an alias for backwards compatibility' do
expect(subject.class).to eq(Postmark::UnexpectedHttpResponseError)
end
end
postmark-1.22.0/spec/unit/postmark/client_spec.rb 0000644 0001751 0001751 00000002743 14123042137 022207 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark::Client do
subject { Postmark::Client.new('abcd-efgh') }
describe 'instance' do
describe '#find_each' do
let(:path) { 'resources' }
let(:name) { 'Resources' }
let(:response) {
{
'TotalCount' => 10,
name => [{'Foo' => 'bar'}, {'Bar' => 'foo'}]
}
}
it 'returns an enumerator' do
expect(subject.find_each(path, name)).to be_kind_of(Enumerable)
end
it 'can be iterated' do
collection = [{:foo => 'bar'}, {:bar => 'foo'}].cycle(5)
allow(subject.http_client).
to receive(:get).with(path, an_instance_of(Hash)).
exactly(5).times.and_return(response)
expect { |b| subject.find_each(path, name, :count => 2).each(&b) }.
to yield_successive_args(*collection)
end
# Only Ruby >= 2.0.0 supports Enumerator#size
it 'lazily calculates the collection size',
:skip_ruby_version => ['1.8.7', '1.9'] do
allow(subject.http_client).
to receive(:get).exactly(1).times.and_return(response)
collection = subject.find_each(path, name, :count => 2)
expect(collection.size).to eq(10)
end
it 'iterates over the collection to count it' do
allow(subject.http_client).
to receive(:get).exactly(5).times.and_return(response)
expect(subject.find_each(path, name, :count => 2).count).to eq(10)
end
end
end
end postmark-1.22.0/spec/unit/postmark/bounce_spec.rb 0000644 0001751 0001751 00000010544 14123042137 022202 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark::Bounce do
let(:bounce_data) { {:type => "HardBounce",
:message_id => "d12c2f1c-60f3-4258-b163-d17052546ae4",
:type_code => 1,
:description => "The server was unable to deliver your message (ex: unknown user, mailbox not found).",
:details => "test bounce",
:email => "jim@test.com",
:bounced_at => "2013-04-22 18:06:48 +0800",
:dump_available => true,
:inactive => false,
:can_activate => true,
:id => 42,
:subject => "Hello from our app!"} }
let(:bounce_data_postmark) { Postmark::HashHelper.to_postmark(bounce_data) }
let(:bounces_data) { [bounce_data, bounce_data, bounce_data] }
let(:bounce) { Postmark::Bounce.new(bounce_data) }
subject { bounce }
context "attr readers" do
it { expect(subject).to respond_to(:email) }
it { expect(subject).to respond_to(:bounced_at) }
it { expect(subject).to respond_to(:type) }
it { expect(subject).to respond_to(:description) }
it { expect(subject).to respond_to(:details) }
it { expect(subject).to respond_to(:name) }
it { expect(subject).to respond_to(:id) }
it { expect(subject).to respond_to(:server_id) }
it { expect(subject).to respond_to(:tag) }
it { expect(subject).to respond_to(:message_id) }
it { expect(subject).to respond_to(:subject) }
end
context "given a bounce created from bounce_data" do
it 'is not inactive' do
expect(subject).not_to be_inactive
end
it 'allows to activate the bounce' do
expect(subject.can_activate?).to be true
end
it 'has an available dump' do
expect(subject.dump_available?).to be true
end
its(:type) { is_expected.to eq bounce_data[:type] }
its(:message_id) { is_expected.to eq bounce_data[:message_id] }
its(:description) { is_expected.to eq bounce_data[:description] }
its(:details) { is_expected.to eq bounce_data[:details] }
its(:email) { is_expected.to eq bounce_data[:email] }
its(:bounced_at) { is_expected.to eq Time.parse(bounce_data[:bounced_at]) }
its(:id) { is_expected.to eq bounce_data[:id] }
its(:subject) { is_expected.to eq bounce_data[:subject] }
end
context "given a bounce created from bounce_data_postmark" do
subject { Postmark::Bounce.new(bounce_data_postmark) }
it 'is not inactive' do
expect(subject).not_to be_inactive
end
it 'allows to activate the bounce' do
expect(subject.can_activate?).to be true
end
it 'has an available dump' do
expect(subject.dump_available?).to be true
end
its(:type) { is_expected.to eq bounce_data[:type] }
its(:message_id) { is_expected.to eq bounce_data[:message_id] }
its(:details) { is_expected.to eq bounce_data[:details] }
its(:email) { is_expected.to eq bounce_data[:email] }
its(:bounced_at) { is_expected.to eq Time.parse(bounce_data[:bounced_at]) }
its(:id) { is_expected.to eq bounce_data[:id] }
its(:subject) { is_expected.to eq bounce_data[:subject] }
end
describe "#dump" do
let(:bounce_body) { double }
let(:response) { {:body => bounce_body} }
let(:api_client) { Postmark.api_client }
it "calls #dump_bounce on shared api_client instance" do
expect(Postmark.api_client).to receive(:dump_bounce).with(bounce.id) { response }
expect(bounce.dump).to eq bounce_body
end
end
describe "#activate" do
let(:api_client) { Postmark.api_client }
it "calls #activate_bounce on shared api_client instance" do
expect(api_client).to receive(:activate_bounce).with(bounce.id) { bounce_data }
expect(bounce.activate).to be_a Postmark::Bounce
end
end
describe ".find" do
let(:api_client) { Postmark.api_client }
it "calls #get_bounce on shared api_client instance" do
expect(api_client).to receive(:get_bounce).with(42) { bounce_data }
expect(Postmark::Bounce.find(42)).to be_a Postmark::Bounce
end
end
describe ".all" do
let(:response) { bounces_data }
let(:api_client) { Postmark.api_client }
it "calls #get_bounces on shared api_client instance" do
expect(api_client).to receive(:get_bounces) { response }
expect(Postmark::Bounce.all.count).to eq(3)
end
end
end postmark-1.22.0/spec/unit/postmark/api_client_spec.rb 0000644 0001751 0001751 00000127662 14123042137 023050 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark::ApiClient do
let(:api_client) {Postmark::ApiClient.new(api_token)}
let(:api_token) {"provided-api-token"}
let(:message_hash) {{:from => "support@postmarkapp.com"}}
let(:message) do
Mail.new do
from "support@postmarkapp.com"
delivery_method Mail::Postmark
end
end
let(:templated_message) do
Mail.new do
from "sheldon@bigbangtheory.com"
to "lenard@bigbangtheory.com"
template_alias "hello"
template_model :name => "Sheldon"
end
end
let(:http_client) {api_client.http_client}
shared_examples "retryable" do |response|
let(:api_client) do
Postmark::ApiClient.new(
api_token,
max_retries.nil? ? {} : {:max_retries => max_retries}
)
end
let(:max_retries) {nil}
context 'with no retries' do
let(:max_retries) {nil}
it "doesn't retry failed requests" do
expect(http_client).to receive(:post).once.and_raise(Postmark::InternalServerError)
expect {subject}.to raise_error(Postmark::InternalServerError)
end
end
context 'with 3 retries' do
let(:max_retries) {3}
it 'retries 3 times' do
expect(http_client).to receive(:post).twice.and_raise(Postmark::InternalServerError)
expect(http_client).to receive(:post).and_return(response)
expect {subject}.not_to raise_error
end
it 'gives up after 3 retries' do
expect(http_client).to receive(:post).thrice.and_raise(Postmark::InternalServerError)
expect {subject}.to raise_error(Postmark::InternalServerError)
end
it "retries on timeout" do
expect(http_client).to receive(:post).and_raise(Postmark::TimeoutError)
expect(http_client).to receive(:post).and_return(response)
expect {subject}.not_to raise_error
end
end
end
describe "attr readers" do
it { expect(api_client).to respond_to(:http_client) }
it { expect(api_client).to respond_to(:max_retries) }
end
context "when it's created without options" do
let(:api_client) {Postmark::ApiClient.new(api_token)}
specify { expect(api_client.max_retries).to eq 0 }
end
context "when it's created with user options" do
let(:api_client) {Postmark::ApiClient.new(api_token, options)}
let(:options) { {:max_retries => 42, :foo => :bar} }
it "sets max_retries" do
expect(api_client.max_retries).to eq 42
end
it 'passes other options to HttpClient instance' do
expect(Postmark::HttpClient).to receive(:new).with(api_token, :foo => :bar)
api_client
end
end
describe "#api_token=" do
let(:api_token) {"new-api-token-value"}
it 'assigns the api token to the http client instance' do
api_client.api_token = api_token
expect(api_client.http_client.api_token).to eq api_token
end
it 'is aliased as api_key=' do
api_client.api_key = api_token
expect(api_client.http_client.api_token).to eq api_token
end
end
describe "#deliver" do
subject {api_client.deliver(message_hash)}
let(:email) {Postmark::MessageHelper.to_postmark(message_hash)}
let(:email_json) {Postmark::Json.encode(email)}
let(:response) {{"MessageID" => 42}}
it 'converts message hash to Postmark format and posts it to expected enpoint' do
expect(http_client).to receive(:post).with('email', email_json) {response}
subject
end
it 'converts response to ruby format' do
expect(http_client).to receive(:post).with('email', email_json) {response}
expect(subject).to have_key(:message_id)
end
it_should_behave_like "retryable"
end
describe "#deliver_in_batches" do
subject {api_client.deliver_in_batches([message_hash, message_hash, message_hash])}
let(:email) {Postmark::MessageHelper.to_postmark(message_hash)}
let(:emails) {[email, email, email]}
let(:emails_json) {Postmark::Json.encode(emails)}
let(:response) {[{'ErrorCode' => 0}, {'ErrorCode' => 0}, {'ErrorCode' => 0}]}
it 'turns array of messages into a JSON document and posts it to expected endpoint' do
expect(http_client).to receive(:post).with('email/batch', emails_json) {response}
subject
end
it 'converts response to ruby format' do
expect(http_client).to receive(:post).with('email/batch', emails_json) {response}
response = subject
expect(response.first).to have_key(:error_code)
end
it_should_behave_like "retryable"
end
describe "#deliver_message" do
subject {api_client.deliver_message(message)}
let(:email) {message.to_postmark_hash}
let(:email_json) {Postmark::Json.encode(email)}
context 'when given a templated message' do
let(:message) {templated_message}
specify do
expect { subject }.to raise_error(ArgumentError, /Please use Postmark::ApiClient\#deliver_message_with_template/)
end
end
it 'turns message into a JSON document and posts it to /email' do
expect(http_client).to receive(:post).with('email', email_json)
subject
end
it "proxies errors" do
allow(http_client).to receive(:post).and_raise(Postmark::TimeoutError)
expect {subject}.to raise_error(Postmark::TimeoutError)
end
it_should_behave_like "retryable"
end
describe "#deliver_message_with_template" do
subject {api_client.deliver_message_with_template(templated_message)}
let(:email) {templated_message.to_postmark_hash}
let(:email_json) {Postmark::Json.encode(email)}
context 'when given a non-templated message' do
let(:templated_message) {message}
specify do
expect { subject }.to raise_error(ArgumentError, 'Templated delivery requested, but the template is missing.')
end
end
it 'turns message into a JSON document and posts it to expected endpoint' do
expect(http_client).to receive(:post).with('email/withTemplate', email_json)
subject
end
it "proxies errors" do
allow(http_client).to receive(:post).and_raise(Postmark::TimeoutError)
expect {subject}.to raise_error(Postmark::TimeoutError)
end
it_should_behave_like "retryable"
end
describe "#deliver_messages" do
subject {api_client.deliver_messages(messages)}
let(:messages) {[message, message, message]}
let(:email) {message.to_postmark_hash}
let(:emails_json) {Postmark::Json.encode(Array.new(3) { email })}
let(:response) {[{}, {}, {}]}
context 'when given templated messages' do
let(:messages) {[templated_message]}
specify do
expect { subject }.to raise_error(ArgumentError, /Please use Postmark::ApiClient\#deliver_messages_with_templates/)
end
end
it 'turns array of messages into a JSON document and posts it to /email/batch' do
expect(http_client).to receive(:post).with('email/batch', emails_json) {response}
subject
end
it_should_behave_like 'retryable', []
end
describe "#deliver_messages_with_templates" do
subject {api_client.deliver_messages_with_templates(messages)}
let(:email) {templated_message.to_postmark_hash}
let(:emails_json) {Postmark::Json.encode(:Messages => Array.new(3) { email })}
let(:response) {[{}, {}, {}]}
let(:messages) { Array.new(3) { templated_message } }
context 'when given a non-templated message' do
let(:messages) {[message]}
it 'raises an error ' do
expect { subject }.
to raise_error(ArgumentError, 'Templated delivery requested, but one or more messages lack templates.')
end
end
it 'turns array of messages into a JSON document and posts it to expected endpoint' do
expect(http_client).to receive(:post).with('email/batchWithTemplates', emails_json) {response}
subject
end
it_should_behave_like 'retryable', []
end
describe "#delivery_stats" do
let(:response) {{"Bounces" => [{"Foo" => "Bar"}]}}
it 'requests data at /deliverystats' do
expect(http_client).to receive(:get).with("deliverystats") {response}
expect(api_client.delivery_stats).to have_key(:bounces)
end
end
describe '#messages' do
context 'given outbound' do
let(:response) {{'TotalCount' => 5, 'Messages' => [{}].cycle(5).to_a}}
it 'returns an enumerator' do
expect(api_client.messages).to be_kind_of(Enumerable)
end
it 'loads outbound messages' do
allow(api_client.http_client).to receive(:get).
with('messages/outbound', an_instance_of(Hash)).and_return(response)
expect(api_client.messages.count).to eq(5)
end
end
context 'given inbound' do
let(:response) {{'TotalCount' => 5, 'InboundMessages' => [{}].cycle(5).to_a}}
it 'returns an enumerator' do
expect(api_client.messages(:inbound => true)).to be_kind_of(Enumerable)
end
it 'loads inbound messages' do
allow(api_client.http_client).to receive(:get).with('messages/inbound', an_instance_of(Hash)).and_return(response)
expect(api_client.messages(:inbound => true).count).to eq(5)
end
end
end
describe '#get_messages' do
context 'given outbound' do
let(:response) {{"TotalCount" => 1, "Messages" => [{}]}}
it 'requests data at /messages/outbound' do
expect(http_client).to receive(:get).
with('messages/outbound', :offset => 50, :count => 50).
and_return(response)
api_client.get_messages(:offset => 50, :count => 50)
end
end
context 'given inbound' do
let(:response) {{"TotalCount" => 1, "InboundMessages" => [{}]}}
it 'requests data at /messages/inbound' do
expect(http_client).to receive(:get).with('messages/inbound', :offset => 50, :count => 50).and_return(response)
expect(api_client.get_messages(:inbound => true, :offset => 50, :count => 50)).to be_an(Array)
end
end
end
describe '#get_messages_count' do
let(:response) {{'TotalCount' => 42}}
context 'given outbound' do
it 'requests and returns outbound messages count' do
allow(api_client.http_client).to receive(:get).
with('messages/outbound', an_instance_of(Hash)).and_return(response)
expect(api_client.get_messages_count).to eq(42)
expect(api_client.get_messages_count(:inbound => false)).to eq(42)
end
end
context 'given inbound' do
it 'requests and returns inbound messages count' do
allow(api_client.http_client).to receive(:get).
with('messages/inbound', an_instance_of(Hash)).and_return(response)
expect(api_client.get_messages_count(:inbound => true)).to eq(42)
end
end
end
describe '#get_message' do
let(:id) {'8ad0e8b0-xxxx-xxxx-951d-223c581bb467'}
let(:response) {{"To" => "leonard@bigbangtheory.com"}}
context 'given outbound' do
it 'requests a single message by id at /messages/outbound/:id/details' do
expect(http_client).to receive(:get).
with("messages/outbound/#{id}/details", {}).
and_return(response)
expect(api_client.get_message(id)).to have_key(:to)
end
end
context 'given inbound' do
it 'requests a single message by id at /messages/inbound/:id/details' do
expect(http_client).to receive(:get).
with("messages/inbound/#{id}/details", {}).
and_return(response)
expect(api_client.get_message(id, :inbound => true)).to have_key(:to)
end
end
end
describe '#dump_message' do
let(:id) {'8ad0e8b0-xxxx-xxxx-951d-223c581bb467'}
let(:response) {{"Body" => "From: \r\n ..."}}
context 'given outbound' do
it 'requests a single message by id at /messages/outbound/:id/dump' do
expect(http_client).to receive(:get).
with("messages/outbound/#{id}/dump", {}).
and_return(response)
expect(api_client.dump_message(id)).to have_key(:body)
end
end
context 'given inbound' do
it 'requests a single message by id at /messages/inbound/:id/dump' do
expect(http_client).to receive(:get).
with("messages/inbound/#{id}/dump", {}).
and_return(response)
expect(api_client.dump_message(id, :inbound => true)).to have_key(:body)
end
end
end
describe '#bounces' do
it 'returns an Enumerator' do
expect(api_client.bounces).to be_kind_of(Enumerable)
end
it 'requests data at /bounces' do
allow(api_client.http_client).to receive(:get).
with('bounces', an_instance_of(Hash)).
and_return('TotalCount' => 1, 'Bounces' => [{}])
expect(api_client.bounces.first(5).count).to eq(1)
end
end
describe "#get_bounces" do
let(:options) {{:foo => :bar}}
let(:response) {{"Bounces" => []}}
it 'requests data at /bounces' do
allow(http_client).to receive(:get).with("bounces", options) {response}
expect(api_client.get_bounces(options)).to be_an(Array)
expect(api_client.get_bounces(options).count).to be_zero
end
end
describe "#get_bounce" do
let(:id) {42}
it 'requests a single bounce by ID at /bounces/:id' do
expect(http_client).to receive(:get).with("bounces/#{id}")
api_client.get_bounce(id)
end
end
describe "#dump_bounce" do
let(:id) {42}
it 'requests a specific bounce data at /bounces/:id/dump' do
expect(http_client).to receive(:get).with("bounces/#{id}/dump")
api_client.dump_bounce(id)
end
end
describe "#activate_bounce" do
let(:id) {42}
let(:response) {{"Bounce" => {}}}
it 'activates a specific bounce by sending a PUT request to /bounces/:id/activate' do
expect(http_client).to receive(:put).with("bounces/#{id}/activate") {response}
api_client.activate_bounce(id)
end
end
describe '#opens' do
it 'returns an Enumerator' do
expect(api_client.opens).to be_kind_of(Enumerable)
end
it 'performs a GET request to /opens/tags' do
allow(api_client.http_client).to receive(:get).
with('messages/outbound/opens', an_instance_of(Hash)).
and_return('TotalCount' => 1, 'Opens' => [{}])
expect(api_client.opens.first(5).count).to eq(1)
end
end
describe '#clicks' do
it 'returns an Enumerator' do
expect(api_client.clicks).to be_kind_of(Enumerable)
end
it 'performs a GET request to /clicks/tags' do
allow(api_client.http_client).to receive(:get).
with('messages/outbound/clicks', an_instance_of(Hash)).
and_return('TotalCount' => 1, 'Clicks' => [{}])
expect(api_client.clicks.first(5).count).to eq(1)
end
end
describe '#get_opens' do
let(:options) {{:offset => 5}}
let(:response) {{'Opens' => [], 'TotalCount' => 0}}
it 'performs a GET request to /messages/outbound/opens' do
allow(http_client).to receive(:get).with('messages/outbound/opens', options) {response}
expect(api_client.get_opens(options)).to be_an(Array)
expect(api_client.get_opens(options).count).to be_zero
end
end
describe '#get_clicks' do
let(:options) {{:offset => 5}}
let(:response) {{'Clicks' => [], 'TotalCount' => 0}}
it 'performs a GET request to /messages/outbound/clicks' do
allow(http_client).to receive(:get).with('messages/outbound/clicks', options) {response}
expect(api_client.get_clicks(options)).to be_an(Array)
expect(api_client.get_clicks(options).count).to be_zero
end
end
describe '#get_opens_by_message_id' do
let(:message_id) {42}
let(:options) {{:offset => 5}}
let(:response) {{'Opens' => [], 'TotalCount' => 0}}
it 'performs a GET request to /messages/outbound/opens' do
allow(http_client).to receive(:get).with("messages/outbound/opens/#{message_id}", options).and_return(response)
expect(api_client.get_opens_by_message_id(message_id, options)).to be_an(Array)
expect(api_client.get_opens_by_message_id(message_id, options).count).to be_zero
end
end
describe '#get_clicks_by_message_id' do
let(:message_id) {42}
let(:options) {{:offset => 5}}
let(:response) {{'Clicks' => [], 'TotalCount' => 0}}
it 'performs a GET request to /messages/outbound/clicks' do
allow(http_client).to receive(:get).with("messages/outbound/clicks/#{message_id}", options).and_return(response)
expect(api_client.get_clicks_by_message_id(message_id, options)).to be_an(Array)
expect(api_client.get_clicks_by_message_id(message_id, options).count).to be_zero
end
end
describe '#opens_by_message_id' do
let(:message_id) {42}
it 'returns an Enumerator' do
expect(api_client.opens_by_message_id(message_id)).to be_kind_of(Enumerable)
end
it 'performs a GET request to /opens/tags' do
allow(api_client.http_client).to receive(:get).
with("messages/outbound/opens/#{message_id}", an_instance_of(Hash)).
and_return('TotalCount' => 1, 'Opens' => [{}])
expect(api_client.opens_by_message_id(message_id).first(5).count).to eq(1)
end
end
describe '#clicks_by_message_id' do
let(:message_id) {42}
it 'returns an Enumerator' do
expect(api_client.clicks_by_message_id(message_id)).to be_kind_of(Enumerable)
end
it 'performs a GET request to /clicks/tags' do
allow(api_client.http_client).to receive(:get).
with("messages/outbound/clicks/#{message_id}", an_instance_of(Hash)).
and_return('TotalCount' => 1, 'Clicks' => [{}])
expect(api_client.clicks_by_message_id(message_id).first(5).count).to eq(1)
end
end
describe '#create_trigger' do
context 'inbound rules' do
let(:options) {{:rule => 'example.com'}}
let(:response) {{'Rule' => 'example.com'}}
it 'performs a POST request to /triggers/inboundrules with given options' do
allow(http_client).to receive(:post).with('triggers/inboundrules',
{'Rule' => 'example.com'}.to_json)
api_client.create_trigger(:inbound_rules, options)
end
it 'symbolizes response keys' do
allow(http_client).to receive(:post).and_return(response)
expect(api_client.create_trigger(:inbound_rules, options)).to eq(:rule => 'example.com')
end
end
end
describe '#get_trigger' do
let(:id) {42}
it 'performs a GET request to /triggers/tags/:id' do
allow(http_client).to receive(:get).with("triggers/tags/#{id}")
api_client.get_trigger(:tags, id)
end
it 'symbolizes response keys' do
allow(http_client).to receive(:get).and_return('Foo' => 'Bar')
expect(api_client.get_trigger(:tags, id)).to eq(:foo => 'Bar')
end
end
describe '#delete_trigger' do
context 'tags' do
let(:id) {42}
it 'performs a DELETE request to /triggers/tags/:id' do
allow(http_client).to receive(:delete).with("triggers/tags/#{id}")
api_client.delete_trigger(:tags, id)
end
it 'symbolizes response keys' do
allow(http_client).to receive(:delete).and_return('Foo' => 'Bar')
expect(api_client.delete_trigger(:tags, id)).to eq(:foo => 'Bar')
end
end
context 'inbound rules' do
let(:id) {42}
it 'performs a DELETE request to /triggers/inboundrules/:id' do
allow(http_client).to receive(:delete).with("triggers/inboundrules/#{id}")
api_client.delete_trigger(:inbound_rules, id)
end
it 'symbolizes response keys' do
allow(http_client).to receive(:delete).and_return('Rule' => 'example.com')
expect(api_client.delete_trigger(:tags, id)).to eq(:rule => 'example.com')
end
end
end
describe '#get_triggers' do
let(:options) {{:offset => 5}}
context 'inbound rules' do
let(:response) {{'InboundRules' => [], 'TotalCount' => 0}}
it 'performs a GET request to /triggers/inboundrules' do
allow(http_client).to receive(:get).with('triggers/inboundrules', options) {response}
expect(api_client.get_triggers(:inbound_rules, options)).to be_an(Array)
expect(api_client.get_triggers(:inbound_rules, options).count).to be_zero
end
end
end
describe '#triggers' do
it 'returns an Enumerator' do
expect(api_client.triggers(:tags)).to be_kind_of(Enumerable)
end
it 'performs a GET request to /triggers/tags' do
allow(api_client.http_client).to receive(:get).
with('triggers/tags', an_instance_of(Hash)).
and_return('TotalCount' => 1, 'Tags' => [{}])
expect(api_client.triggers(:tags).first(5).count).to eq(1)
end
end
describe "#server_info" do
let(:response) {
{
"Name" => "Testing",
"Color" => "blue",
"InboundHash" => "c2425d77f74f8643e5f6237438086c81",
"SmtpApiActivated" => true
}
}
it 'requests server info from Postmark and converts it to ruby format' do
expect(http_client).to receive(:get).with('server') {response}
expect(api_client.server_info).to have_key(:inbound_hash)
end
end
describe "#update_server_info" do
let(:response) {
{
"Name" => "Testing",
"Color" => "blue",
"InboundHash" => "c2425d77f74f8643e5f6237438086c81",
"SmtpApiActivated" => false
}
}
let(:update) {{:smtp_api_activated => false}}
it 'updates server info in Postmark and converts it to ruby format' do
expect(http_client).to receive(:put).with('server', anything) {response}
expect(api_client.update_server_info(update)[:smtp_api_activated]).to be false
end
end
describe '#get_templates' do
let(:response) do
{
'TotalCount' => 31,
'Templates' => [
{
'Active' => true,
'TemplateId' => 123,
'Name' => 'ABC'
},
{
'Active' => true,
'TemplateId' => 456,
'Name' => 'DEF'
}
]
}
end
it 'gets templates info and converts it to ruby format' do
expect(http_client).to receive(:get).with('templates', :offset => 0, :count => 2).and_return(response)
count, templates = api_client.get_templates(:count => 2)
expect(count).to eq(31)
expect(templates.first[:template_id]).to eq(123)
expect(templates.first[:name]).to eq('ABC')
end
end
describe '#templates' do
it 'returns an Enumerator' do
expect(api_client.templates).to be_kind_of(Enumerable)
end
it 'requests data at /templates' do
allow(api_client.http_client).to receive(:get).
with('templates', an_instance_of(Hash)).
and_return('TotalCount' => 1, 'Templates' => [{}])
expect(api_client.templates.first(5).count).to eq(1)
end
end
describe '#get_template' do
let(:response) do
{
'Name' => 'Template Name',
'TemplateId' => 123,
'Subject' => 'Subject',
'HtmlBody' => 'Html',
'TextBody' => 'Text',
'AssociatedServerId' => 456,
'Active' => true
}
end
it 'gets single template and converts it to ruby format' do
expect(http_client).to receive(:get).with('templates/123').and_return(response)
template = api_client.get_template('123')
expect(template[:name]).to eq('Template Name')
expect(template[:template_id]).to eq(123)
expect(template[:html_body]).to eq('Html')
end
end
describe '#create_template' do
let(:response) do
{
'TemplateId' => 123,
'Name' => 'template name',
'Active' => true
}
end
it 'performs a POST request to /templates with the given attributes' do
expect(http_client).to receive(:post).
with('templates', json_representation_of('Name' => 'template name')).
and_return(response)
template = api_client.create_template(:name => 'template name')
expect(template[:name]).to eq('template name')
expect(template[:template_id]).to eq(123)
end
end
describe '#update_template' do
let(:response) do
{
'TemplateId' => 123,
'Name' => 'template name',
'Active' => true
}
end
it 'performs a PUT request to /templates with the given attributes' do
expect(http_client).to receive(:put).
with('templates/123', json_representation_of('Name' => 'template name')).
and_return(response)
template = api_client.update_template(123, :name => 'template name')
expect(template[:name]).to eq('template name')
expect(template[:template_id]).to eq(123)
end
end
describe '#delete_template' do
let(:response) do
{
'ErrorCode' => 0,
'Message' => 'Template 123 removed.'
}
end
it 'performs a DELETE request to /templates/:id' do
expect(http_client).to receive(:delete).with('templates/123').and_return(response)
resp = api_client.delete_template(123)
expect(resp[:error_code]).to eq(0)
end
end
describe '#validate_template' do
context 'when template is valid' do
let(:response) do
{
'AllContentIsValid' => true,
'HtmlBody' => {
'ContentIsValid' => true,
'ValidationErrors' => [],
'RenderedContent' => 'MyName_Value'
},
'TextBody' => {
'ContentIsValid' => true,
'ValidationErrors' => [],
'RenderedContent' => 'MyName_Value'
},
'Subject' => {
'ContentIsValid' => true,
'ValidationErrors' => [],
'RenderedContent' => 'MyName_Value'
},
'SuggestedTemplateModel' => {
'MyName' => 'MyName_Value'
}
}
end
it 'performs a POST request and returns unmodified suggested template model' do
expect(http_client).to receive(:post).
with('templates/validate',
json_representation_of('HtmlBody' => '{{MyName}}',
'TextBody' => '{{MyName}}',
'Subject' => '{{MyName}}')).
and_return(response)
resp = api_client.validate_template(:html_body => '{{MyName}}',
:text_body => '{{MyName}}',
:subject => '{{MyName}}')
expect(resp[:all_content_is_valid]).to be true
expect(resp[:html_body][:content_is_valid]).to be true
expect(resp[:html_body][:validation_errors]).to be_empty
expect(resp[:suggested_template_model]['MyName']).to eq('MyName_Value')
end
end
context 'when template is invalid' do
let(:response) do
{
'AllContentIsValid' => false,
'HtmlBody' => {
'ContentIsValid' => false,
'ValidationErrors' => [
{
'Message' => 'The \'each\' block being opened requires a model path to be specified in the form \'{#each }\'.',
'Line' => 1,
'CharacterPosition' => 1
}
],
'RenderedContent' => nil
},
'TextBody' => {
'ContentIsValid' => true,
'ValidationErrors' => [],
'RenderedContent' => 'MyName_Value'
},
'Subject' => {
'ContentIsValid' => true,
'ValidationErrors' => [],
'RenderedContent' => 'MyName_Value'
},
'SuggestedTemplateModel' => nil
}
end
it 'performs a POST request and returns validation errors' do
expect(http_client).
to receive(:post).with('templates/validate',
json_representation_of('HtmlBody' => '{{#each}}',
'TextBody' => '{{MyName}}',
'Subject' => '{{MyName}}')).and_return(response)
resp = api_client.validate_template(:html_body => '{{#each}}',
:text_body => '{{MyName}}',
:subject => '{{MyName}}')
expect(resp[:all_content_is_valid]).to be false
expect(resp[:text_body][:content_is_valid]).to be true
expect(resp[:html_body][:content_is_valid]).to be false
expect(resp[:html_body][:validation_errors].first[:character_position]).to eq(1)
expect(resp[:html_body][:validation_errors].first[:message]).to eq('The \'each\' block being opened requires a model path to be specified in the form \'{#each }\'.')
end
end
end
describe "#deliver_with_template" do
subject {api_client.deliver_with_template(message_hash)}
let(:email) {Postmark::MessageHelper.to_postmark(message_hash)}
let(:response) {{"MessageID" => 42}}
it 'converts message hash to Postmark format and posts it to /email/withTemplate' do
expect(http_client).to receive(:post).with('email/withTemplate', json_representation_of(email)) {response}
subject
end
it 'converts response to ruby format' do
expect(http_client).to receive(:post).with('email/withTemplate', json_representation_of(email)) {response}
expect(subject).to have_key(:message_id)
end
it_should_behave_like "retryable"
end
describe '#deliver_in_batches_with_templates' do
let(:max_batch_size) {50}
let(:factor) {3.5}
let(:postmark_response) do
{
'ErrorCode' => 0,
'Message' => 'OK',
'SubmittedAt' => '2018-03-14T09:56:50.4288265-04:00',
'To' => 'recipient@example.org'
}
end
let(:message_hashes) do
Array.new((factor * max_batch_size).to_i) do
{
:template_id => 42,
:alias => 'alias',
:template_model => {:Foo => 'attr_value'},
:from => 'sender@example.org',
:to => 'recipient@example.org'
}
end
end
before {api_client.max_batch_size = max_batch_size}
it 'performs a total of (bath_size / max_batch_size) requests' do
expect(http_client).
to receive(:post).with('email/batchWithTemplates', a_postmark_json).
at_most(factor.to_i).times do
Array.new(max_batch_size) {postmark_response}
end
expect(http_client).
to receive(:post).with('email/batchWithTemplates', a_postmark_json).
exactly((factor - factor.to_i).ceil).times do
response = Array.new(((factor - factor.to_i) * max_batch_size).to_i) do
postmark_response
end
response
end
response = api_client.deliver_in_batches_with_templates(message_hashes)
expect(response).to be_an Array
expect(response.size).to eq message_hashes.size
response.each do |message_status|
expect(message_status).to have_key(:error_code)
expect(message_status).to have_key(:message)
expect(message_status).to have_key(:to)
expect(message_status).to have_key(:submitted_at)
end
end
end
describe '#get_stats_totals' do
let(:response) do
{
"Sent" => 615,
"BounceRate" => 10.406,
}
end
it 'converts response to ruby format' do
expect(http_client).to receive(:get).with('stats/outbound', {:tag => 'foo'}) {response}
response = api_client.get_stats_totals(:tag => 'foo')
expect(response).to have_key(:sent)
expect(response).to have_key(:bounce_rate)
end
end
describe '#get_stats_counts' do
let(:response) do
{
"Days" => [
{
"Date" => "2014-01-01",
"Sent" => 140
},
{
"Date" => "2014-01-02",
"Sent" => 160
},
{
"Date" => "2014-01-04",
"Sent" => 50
},
{
"Date" => "2014-01-05",
"Sent" => 115
}
],
"Sent" => 615
}
end
it 'converts response to ruby format' do
expect(http_client).to receive(:get).with('stats/outbound/sends', {:tag => 'foo'}) {response}
response = api_client.get_stats_counts(:sends, :tag => 'foo')
expect(response).to have_key(:days)
expect(response).to have_key(:sent)
first_day = response[:days].first
expect(first_day).to have_key(:date)
expect(first_day).to have_key(:sent)
end
it 'uses fromdate that is passed in' do
expect(http_client).to receive(:get).with('stats/outbound/sends', {:tag => 'foo', :fromdate => '2015-01-01'}) {response}
response = api_client.get_stats_counts(:sends, :tag => 'foo', :fromdate => '2015-01-01')
expect(response).to have_key(:days)
expect(response).to have_key(:sent)
first_day = response[:days].first
expect(first_day).to have_key(:date)
expect(first_day).to have_key(:sent)
end
it 'uses stats type that is passed in' do
expect(http_client).to receive(:get).with('stats/outbound/opens/readtimes', {:tag => 'foo', :type => :readtimes}) {response}
response = api_client.get_stats_counts(:opens, :type => :readtimes, :tag => 'foo')
expect(response).to have_key(:days)
expect(response).to have_key(:sent)
first_day = response[:days].first
expect(first_day).to have_key(:date)
expect(first_day).to have_key(:sent)
end
end
describe '#get_message_streams' do
subject(:result) { api_client.get_message_streams(:offset => 22, :count => 33) }
before do
allow(http_client).to receive(:get).
with('message-streams', :offset => 22, :count => 33).
and_return({ 'TotalCount' => 1, 'MessageStreams' => [{'Name' => 'abc'}]})
end
it { is_expected.to be_an(Array) }
describe 'returned item' do
subject { result.first }
it { is_expected.to match(:name => 'abc') }
end
end
describe '#message_streams' do
subject { api_client.message_streams }
it { is_expected.to be_kind_of(Enumerable) }
it 'requests data at /message-streams' do
allow(http_client).to receive(:get).
with('message-streams', anything).
and_return('TotalCount' => 1, 'MessageStreams' => [{}])
expect(subject.first(5).count).to eq(1)
end
end
describe '#get_message_stream' do
subject(:result) { api_client.get_message_stream(123) }
before do
allow(http_client).to receive(:get).
with('message-streams/123').
and_return({
'Id' => 'xxx',
'Name' => 'My Stream',
'ServerID' => 321,
'MessageStreamType' => 'Transactional'
})
end
it {
is_expected.to match(
:id => 'xxx',
:name => 'My Stream',
:server_id => 321,
:message_stream_type => 'Transactional'
)
}
end
describe '#create_message_stream' do
subject { api_client.create_message_stream(attrs) }
let(:attrs) do
{
:name => 'My Stream',
:id => 'my-stream',
:message_stream_type => 'Broadcasts',
:subscription_management_configuration => {
:unsubscribe_handling_type => 'Custom'
}
}
end
let(:response) do
{
'Name' => 'My Stream',
'Id' => 'my-stream',
'MessageStreamType' => 'Broadcasts',
'ServerId' => 222,
'CreatedAt' => '2020-04-01T03:33:33.333-03:00',
'SubscriptionManagementConfiguration' => {
'UnsubscribeHandlingType' => 'Custom'
}
}
end
before do
allow(http_client).to receive(:post) { response }
end
specify do
expect(http_client).to receive(:post).
with('message-streams',
json_representation_of({
'Name' => 'My Stream',
'Id' => 'my-stream',
'MessageStreamType' => 'Broadcasts',
'SubscriptionManagementConfiguration' => {
'UnsubscribeHandlingType' => 'Custom'
}
}))
subject
end
it {
is_expected.to match(
:id => 'my-stream',
:name => 'My Stream',
:server_id => 222,
:message_stream_type => 'Broadcasts',
:created_at => '2020-04-01T03:33:33.333-03:00',
:subscription_management_configuration => {
:unsubscribe_handling_type => 'Custom'
}
)
}
end
describe '#update_message_stream' do
subject { api_client.update_message_stream('xxx', attrs) }
let(:attrs) do
{
:name => 'My Stream XXX',
:subscription_management_configuration => {
:unsubscribe_handling_type => 'Custom'
}
}
end
let(:response) do
{
'Name' => 'My Stream XXX',
'Id' => 'xxx',
'MessageStreamType' => 'Broadcasts',
'ServerId' => 222,
'CreatedAt' => '2020-04-01T03:33:33.333-03:00',
'SubscriptionManagementConfiguration' => {
'UnsubscribeHandlingType' => 'Custom'
}
}
end
before do
allow(http_client).to receive(:patch) { response }
end
specify do
expect(http_client).to receive(:patch).
with('message-streams/xxx',
match_json({
'Name' => 'My Stream XXX',
'SubscriptionManagementConfiguration' => {
'UnsubscribeHandlingType' => 'Custom'
}
}))
subject
end
it {
is_expected.to match(
:id => 'xxx',
:name => 'My Stream XXX',
:server_id => 222,
:message_stream_type => 'Broadcasts',
:created_at => '2020-04-01T03:33:33.333-03:00',
:subscription_management_configuration => {
:unsubscribe_handling_type => 'Custom'
}
)
}
end
describe '#archive_message_stream' do
subject { api_client.archive_message_stream(stream_id) }
let(:stream_id) { 'my-stream'}
let(:server_id) { 123 }
let(:purge_date) { '2030-08-30T12:30:00.00-04:00' }
let(:api_endpoint) { "message-streams/#{stream_id}/archive" }
let(:api_response) {{ 'ID' => stream_id, 'ServerID' => server_id, 'ExpectedPurgeDate' => purge_date }}
before do
allow(http_client).to receive(:post).with(api_endpoint) { api_response }
end
it 'calls the API endpoint' do
expect(http_client).to receive(:post).with(api_endpoint)
subject
end
it 'transforms the API response' do
expect(subject).to eq({ :id => stream_id, :server_id => server_id, :expected_purge_date => purge_date })
end
end
describe '#unarchive_message_stream' do
subject { api_client.unarchive_message_stream(stream_id) }
let(:stream_id) { 'my-stream'}
let(:server_id) { 123 }
let(:api_endpoint) { "message-streams/#{stream_id}/unarchive" }
let(:api_response) {
{ 'ID' => stream_id, 'ServerID' => server_id, 'Name' => 'My Stream',
'Description' => 'My test stream.', 'MessageStreamType' => 'Transactional',
'CreatedAt' => '2030-08-30T12:30:00.00-04:00', 'UpdatedAt' => '2030-09-30T12:30:00.00-04:00',
'ArchivedAt'=> nil, 'ExpectedPurgeDate' => nil,
'SubscriptionManagementConfiguration' => { 'UnsubscribeHandlingType' => 'None' } }
}
before do
allow(http_client).to receive(:post).with(api_endpoint) { api_response }
end
it 'calls the API endpoint' do
expect(http_client).to receive(:post).with(api_endpoint)
subject
end
it 'transforms the API response' do
expect(subject).to eq({ :id => stream_id, :server_id => server_id, :name => 'My Stream',
:description => 'My test stream.', :message_stream_type => 'Transactional',
:created_at => '2030-08-30T12:30:00.00-04:00',
:updated_at => '2030-09-30T12:30:00.00-04:00',
:archived_at => nil , :expected_purge_date => nil ,
:subscription_management_configuration => { 'UnsubscribeHandlingType' => 'None' }})
end
end
describe '#create_suppressions' do
let(:email_addresses) { nil }
let(:message_stream_id) { 'outbound' }
subject { api_client.create_suppressions(message_stream_id, email_addresses) }
context '1 email address as string' do
let(:email_addresses) { 'A@example.com' }
specify do
expect(http_client).to receive(:post).
with('message-streams/outbound/suppressions',
match_json({
:Suppressions => [
{ :EmailAddress => 'A@example.com' }
]}))
subject
end
end
context '1 email address as string & non-default stream' do
let(:email_addresses) { 'A@example.com' }
let(:message_stream_id) { 'xxxx' }
specify do
expect(http_client).to receive(:post).
with('message-streams/xxxx/suppressions',
match_json({
:Suppressions => [
{ :EmailAddress => 'A@example.com' }
]}))
subject
end
end
context '1 email address as array of strings' do
let(:email_addresses) { ['A@example.com'] }
specify do
expect(http_client).to receive(:post).
with('message-streams/outbound/suppressions',
match_json({
:Suppressions => [
{ :EmailAddress => 'A@example.com' }
]}))
subject
end
end
context 'many email addresses as array of strings' do
let(:email_addresses) { ['A@example.com', 'B@example.com'] }
specify do
expect(http_client).to receive(:post).
with('message-streams/outbound/suppressions',
match_json({
:Suppressions => [
{ :EmailAddress => 'A@example.com' },
{ :EmailAddress => 'B@example.com' }
]}))
subject
end
end
end
describe '#delete_suppressions' do
let(:email_addresses) { nil }
let(:message_stream_id) { 'outbound' }
subject { api_client.delete_suppressions(message_stream_id, email_addresses) }
context '1 email address as string' do
let(:email_addresses) { 'A@example.com' }
specify do
expect(http_client).to receive(:post).
with('message-streams/outbound/suppressions/delete',
match_json({
:Suppressions => [
{ :EmailAddress => 'A@example.com' },
]}))
subject
end
end
context '1 email address as string & non-default stream' do
let(:email_addresses) { 'A@example.com' }
let(:message_stream_id) { 'xxxx' }
specify do
expect(http_client).to receive(:post).
with('message-streams/xxxx/suppressions/delete',
match_json({
:Suppressions => [
{ :EmailAddress => 'A@example.com' }
]}))
subject
end
end
context '1 email address as array of strings' do
let(:email_addresses) { ['A@example.com'] }
specify do
expect(http_client).to receive(:post).
with('message-streams/outbound/suppressions/delete',
match_json({
:Suppressions => [
{ :EmailAddress => 'A@example.com' }
]}))
subject
end
end
context 'many email addresses as array of strings' do
let(:email_addresses) { ['A@example.com', 'B@example.com'] }
specify do
expect(http_client).to receive(:post).
with('message-streams/outbound/suppressions/delete',
match_json({
:Suppressions => [
{ :EmailAddress => 'A@example.com' },
{ :EmailAddress => 'B@example.com' }
]}))
subject
end
end
end
describe '#dump_suppressions' do
let(:message_stream_id) { 'xxxx' }
subject { api_client.dump_suppressions(message_stream_id, :count => 123) }
before do
allow(http_client).to receive(:get).and_return({'TotalCount' => 0, 'Suppressions' => []})
end
specify do
expect(http_client).to receive(:get).
with('message-streams/xxxx/suppressions/dump', { :count => 123, :offset => 0 })
subject
end
end
end
postmark-1.22.0/spec/unit/postmark/account_api_client_spec.rb 0000644 0001751 0001751 00000060425 14123042137 024555 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe Postmark::AccountApiClient do
let(:api_token) { 'abcd-efgh' }
subject { Postmark::AccountApiClient}
it 'can be created with an API token' do
expect { subject.new(api_token) }.not_to raise_error
end
it 'can be created with an API token and options hash' do
expect { subject.new(api_token, :http_read_timeout => 5) }.not_to raise_error
end
context 'instance' do
subject { Postmark::AccountApiClient.new(api_token) }
it 'uses the auth header specific for Account API' do
auth_header = subject.http_client.auth_header_name
expect(auth_header).to eq('X-Postmark-Account-Token')
end
describe '#senders' do
let(:response) {
{
'TotalCount' => 10, 'SenderSignatures' => [{}, {}]
}
}
it 'is aliased as #signatures' do
expect(subject).to respond_to(:signatures)
expect(subject).to respond_to(:signatures).with(1).argument
end
it 'returns an enumerator' do
expect(subject.senders).to be_kind_of(Enumerable)
end
it 'lazily loads senders' do
allow(subject.http_client).to receive(:get).
with('senders', an_instance_of(Hash)).and_return(response)
subject.senders.take(1000)
end
end
describe '#get_senders' do
let(:response) {
{
"TotalCount" => 1,
"SenderSignatures" => [{
"Domain" => "example.com",
"EmailAddress" => "someone@example.com",
"ReplyToEmailAddress" => "info@example.com",
"Name" => "Example User",
"Confirmed" => true,
"ID" => 8139
}]
}
}
it 'is aliased as #get_signatures' do
expect(subject).to respond_to(:get_signatures).with(1).argument
end
it 'performs a GET request to /senders endpoint' do
allow(subject.http_client).to receive(:get).
with('senders', :offset => 0, :count => 30).
and_return(response)
subject.get_senders
end
it 'formats the keys of returned list of senders' do
allow(subject.http_client).to receive(:get).and_return(response)
keys = subject.get_senders.map { |s| s.keys }.flatten
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
it 'accepts offset and count options' do
allow(subject.http_client).to receive(:get).
with('senders', :offset => 10, :count => 42).
and_return(response)
subject.get_senders(:offset => 10, :count => 42)
end
end
describe '#get_senders_count' do
let(:response) { {'TotalCount' => 42} }
it 'is aliased as #get_signatures_count' do
expect(subject).to respond_to(:get_signatures_count)
expect(subject).to respond_to(:get_signatures_count).with(1).argument
end
it 'returns a total number of senders' do
allow(subject.http_client).to receive(:get).
with('senders', an_instance_of(Hash)).and_return(response)
expect(subject.get_senders_count).to eq(42)
end
end
describe '#get_sender' do
let(:response) {
{
"Domain" => "example.com",
"EmailAddress" => "someone@example.com",
"ReplyToEmailAddress" => "info@example.com",
"Name" => "Example User",
"Confirmed" => true,
"ID" => 8139
}
}
it 'is aliased as #get_signature' do
expect(subject).to respond_to(:get_signature).with(1).argument
end
it 'performs a GET request to /senders/:id endpoint' do
allow(subject.http_client).to receive(:get).with("senders/42").
and_return(response)
subject.get_sender(42)
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:get).and_return(response)
keys = subject.get_sender(42).keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#create_sender' do
let(:response) {
{
"Domain" => "example.com",
"EmailAddress" => "someone@example.com",
"ReplyToEmailAddress" => "info@example.com",
"Name" => "Example User",
"Confirmed" => true,
"ID" => 8139
}
}
it 'is aliased as #create_signature' do
expect(subject).to respond_to(:create_signature).with(1).argument
end
it 'performs a POST request to /senders endpoint' do
allow(subject.http_client).to receive(:post).
with("senders", an_instance_of(String)).and_return(response)
subject.create_sender(:name => 'Chris Nagele')
end
it 'converts the sender attributes names to camel case' do
allow(subject.http_client).to receive(:post).
with("senders", {'FooBar' => 'bar'}.to_json).and_return(response)
subject.create_sender(:foo_bar => 'bar')
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:post).and_return(response)
keys = subject.create_sender(:foo => 'bar').keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#update_sender' do
let(:response) {
{
"Domain" => "example.com",
"EmailAddress" => "someone@example.com",
"ReplyToEmailAddress" => "info@example.com",
"Name" => "Example User",
"Confirmed" => true,
"ID" => 8139
}
}
it 'is aliased as #update_signature' do
expect(subject).to respond_to(:update_signature).with(1).argument
expect(subject).to respond_to(:update_signature).with(2).arguments
end
it 'performs a PUT request to /senders/:id endpoint' do
allow(subject.http_client).to receive(:put).
with('senders/42', an_instance_of(String)).and_return(response)
subject.update_sender(42, :name => 'Chris Nagele')
end
it 'converts the sender attributes names to camel case' do
allow(subject.http_client).to receive(:put).
with('senders/42', {'FooBar' => 'bar'}.to_json).and_return(response)
subject.update_sender(42, :foo_bar => 'bar')
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:put).and_return(response)
keys = subject.update_sender(42, :foo => 'bar').keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#resend_sender_confirmation' do
let(:response) {
{
"ErrorCode" => 0,
"Message" => "Confirmation email for Sender Signature someone@example.com was re-sent."
}
}
it 'is aliased as #resend_signature_confirmation' do
expect(subject).to respond_to(:resend_signature_confirmation).
with(1).argument
end
it 'performs a POST request to /senders/:id/resend endpoint' do
allow(subject.http_client).to receive(:post).
with('senders/42/resend').and_return(response)
subject.resend_sender_confirmation(42)
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:post).and_return(response)
keys = subject.resend_sender_confirmation(42).keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#verified_sender_spf?' do
let(:response) { {"SPFVerified" => true} }
let(:false_response) { {"SPFVerified" => false} }
it 'is aliased as #verified_signature_spf?' do
expect(subject).to respond_to(:verified_signature_spf?).with(1).argument
end
it 'performs a POST request to /senders/:id/verifyspf endpoint' do
allow(subject.http_client).to receive(:post).
with('senders/42/verifyspf').and_return(response)
subject.verified_sender_spf?(42)
end
it 'returns false when SPFVerified field of the response is false' do
allow(subject.http_client).to receive(:post).and_return(false_response)
expect(subject.verified_sender_spf?(42)).to be false
end
it 'returns true when SPFVerified field of the response is true' do
allow(subject.http_client).to receive(:post).and_return(response)
expect(subject.verified_sender_spf?(42)).to be true
end
end
describe '#request_new_sender_dkim' do
let(:response) {
{
"Domain" => "example.com",
"EmailAddress" => "someone@example.com",
"ReplyToEmailAddress" => "info@example.com",
"Name" => "Example User",
"Confirmed" => true,
"ID" => 8139
}
}
it 'is aliased as #request_new_signature_dkim' do
expect(subject).to respond_to(:request_new_signature_dkim).
with(1).argument
end
it 'performs a POST request to /senders/:id/requestnewdkim endpoint' do
allow(subject.http_client).to receive(:post).
with('senders/42/requestnewdkim').and_return(response)
subject.request_new_sender_dkim(42)
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:post).and_return(response)
keys = subject.request_new_sender_dkim(42).keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#delete_sender' do
let(:response) {
{
"ErrorCode" => 0,
"Message" => "Signature someone@example.com removed."
}
}
it 'is aliased as #delete_signature' do
expect(subject).to respond_to(:delete_signature).with(1).argument
end
it 'performs a DELETE request to /senders/:id endpoint' do
allow(subject.http_client).to receive(:delete).
with('senders/42').and_return(response)
subject.delete_sender(42)
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:delete).and_return(response)
keys = subject.delete_sender(42).keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#domains' do
let(:response) {{'TotalCount' => 10, 'Domains' => [{}, {}]}}
it 'returns an enumerator' do
expect(subject.domains).to be_kind_of(Enumerable)
end
it 'lazily loads domains' do
allow(subject.http_client).to receive(:get).
with('domains', an_instance_of(Hash)).and_return(response)
subject.domains.take(1000)
end
end
describe '#get_domains' do
let(:response) {
{
"TotalCount" => 1,
"Domains" => [{
"Name" => "example.com",
"ID" => 8139
}]
}
}
it 'performs a GET request to /domains endpoint' do
allow(subject.http_client).to receive(:get).
with('domains', :offset => 0, :count => 30).
and_return(response)
subject.get_domains
end
it 'formats the keys of returned list of domains' do
allow(subject.http_client).to receive(:get).and_return(response)
keys = subject.get_domains.map { |s| s.keys }.flatten
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
it 'accepts offset and count options' do
allow(subject.http_client).to receive(:get).
with('domains', :offset => 10, :count => 42).
and_return(response)
subject.get_domains(:offset => 10, :count => 42)
end
end
describe '#get_domains_count' do
let(:response) { {'TotalCount' => 42} }
it 'returns a total number of domains' do
allow(subject.http_client).to receive(:get).
with('domains', an_instance_of(Hash)).and_return(response)
expect(subject.get_domains_count).to eq(42)
end
end
describe '#get_domain' do
let(:response) {
{
"Name" => "example.com",
"ID" => 8139
}
}
it 'performs a GET request to /domains/:id endpoint' do
allow(subject.http_client).to receive(:get).with("domains/42").
and_return(response)
subject.get_domain(42)
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:get).and_return(response)
keys = subject.get_domain(42).keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#create_domain' do
let(:response) {
{
"Name" => "example.com",
"ID" => 8139
}
}
it 'performs a POST request to /domains endpoint' do
allow(subject.http_client).to receive(:post).
with("domains", an_instance_of(String)).and_return(response)
subject.create_domain(:name => 'example.com')
end
it 'converts the domain attributes names to camel case' do
allow(subject.http_client).to receive(:post).
with("domains", {'FooBar' => 'bar'}.to_json).and_return(response)
subject.create_domain(:foo_bar => 'bar')
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:post).and_return(response)
keys = subject.create_domain(:foo => 'bar').keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#update_domain' do
let(:response) {
{
"Name" => "example.com",
"ReturnPathDomain" => "return.example.com",
"ID" => 8139
}
}
it 'performs a PUT request to /domains/:id endpoint' do
allow(subject.http_client).to receive(:put).
with('domains/42', an_instance_of(String)).and_return(response)
subject.update_domain(42, :return_path_domain => 'updated-return.example.com')
end
it 'converts the domain attributes names to camel case' do
allow(subject.http_client).to receive(:put).
with('domains/42', {'FooBar' => 'bar'}.to_json).and_return(response)
subject.update_domain(42, :foo_bar => 'bar')
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:put).and_return(response)
keys = subject.update_domain(42, :foo => 'bar').keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#verified_domain_spf?' do
let(:response) { {"SPFVerified" => true} }
let(:false_response) { {"SPFVerified" => false} }
it 'performs a POST request to /domains/:id/verifyspf endpoint' do
allow(subject.http_client).to receive(:post).
with('domains/42/verifyspf').and_return(response)
subject.verified_domain_spf?(42)
end
it 'returns false when SPFVerified field of the response is false' do
allow(subject.http_client).to receive(:post).and_return(false_response)
expect(subject.verified_domain_spf?(42)).to be false
end
it 'returns true when SPFVerified field of the response is true' do
allow(subject.http_client).to receive(:post).and_return(response)
expect(subject.verified_domain_spf?(42)).to be true
end
end
describe '#rotate_domain_dkim' do
let(:response) {
{
"Name" => "example.com",
"ID" => 8139
}
}
it 'performs a POST request to /domains/:id/rotatedkim endpoint' do
allow(subject.http_client).to receive(:post).
with('domains/42/rotatedkim').and_return(response)
subject.rotate_domain_dkim(42)
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:post).and_return(response)
keys = subject.rotate_domain_dkim(42).keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#delete_domain' do
let(:response) {
{
"ErrorCode" => 0,
"Message" => "Domain example.com removed."
}
}
it 'performs a DELETE request to /domains/:id endpoint' do
allow(subject.http_client).to receive(:delete).
with('domains/42').and_return(response)
subject.delete_domain(42)
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:delete).and_return(response)
keys = subject.delete_sender(42).keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#servers' do
let(:response) { {'TotalCount' => 10, 'Servers' => [{}, {}]} }
it 'returns an enumerator' do
expect(subject.servers).to be_kind_of(Enumerable)
end
it 'lazily loads servers' do
allow(subject.http_client).to receive(:get).
with('servers', an_instance_of(Hash)).and_return(response)
subject.servers.take(100)
end
end
describe '#get_servers' do
let(:response) {
{
'TotalCount' => 1,
'Servers' => [
{
"ID" => 11635,
"Name" => "Production01",
"ApiTokens" => [
"fe6ec0cf-ff06-787a-b5e9-e77a41c61ce3"
],
"ServerLink" => "https://postmarkapp.com/servers/11635/overview",
"Color" => "red",
"SmtpApiActivated" => true,
"RawEmailEnabled" => false,
"InboundAddress" => "7373de3ebd66acea228fjkdkf88dd7d5@inbound.postmarkapp.com",
"InboundHookUrl" => "http://inboundhook.example.com/inbound",
"BounceHookUrl" => "http://bouncehook.example.com/bounce",
"InboundDomain" => "",
"InboundHash" => "7373de3ebd66acea228fjkdkf88dd7d5"
}
]
}
}
it 'performs a GET request to /servers endpoint' do
allow(subject.http_client).to receive(:get).
with('servers', an_instance_of(Hash)).and_return(response)
subject.get_servers
end
it 'formats the keys of returned list of servers' do
allow(subject.http_client).to receive(:get).and_return(response)
keys = subject.get_servers.map { |s| s.keys }.flatten
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
it 'accepts offset and count options' do
allow(subject.http_client).to receive(:get).
with('servers', :offset => 30, :count => 50).
and_return(response)
subject.get_servers(:offset => 30, :count => 50)
end
end
describe '#get_server' do
let(:response) {
{
"ID" => 7438,
"Name" => "Staging Testing",
"ApiTokens" => [
"fe6ec0cf-ff06-44aa-jf88-e77a41c61ce3"
],
"ServerLink" => "https://postmarkapp.com/servers/7438/overview",
"Color" => "red",
"SmtpApiActivated" => true,
"RawEmailEnabled" => false,
"InboundAddress" => "7373de3ebd66acea22812731fb1dd7d5@inbound.postmarkapp.com",
"InboundHookUrl" => "",
"BounceHookUrl" => "",
"InboundDomain" => "",
"InboundHash" => "7373de3ebd66acea22812731fb1dd7d5"
}
}
it 'performs a GET request to /servers/:id endpoint' do
allow(subject.http_client).to receive(:get).
with('servers/42').and_return(response)
subject.get_server(42)
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:get).and_return(response)
keys = subject.get_server(42).keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#get_servers_count' do
let(:response) { {'TotalCount' => 42} }
it 'returns a total number of servers' do
allow(subject.http_client).to receive(:get).
with('servers', an_instance_of(Hash)).and_return(response)
expect(subject.get_servers_count).to eq(42)
end
end
describe '#create_server' do
let(:response) {
{
"Name" => "Staging Testing",
"Color" => "red",
"SmtpApiActivated" => true,
"RawEmailEnabled" => false,
"InboundHookUrl" => "http://hooks.example.com/inbound",
"BounceHookUrl" => "http://hooks.example.com/bounce",
"InboundDomain" => ""
}
}
it 'performs a POST request to /servers endpoint' do
allow(subject.http_client).to receive(:post).
with('servers', an_instance_of(String)).and_return(response)
subject.create_server(:foo => 'bar')
end
it 'converts the server attribute names to camel case' do
allow(subject.http_client).to receive(:post).
with('servers', {'FooBar' => 'foo_bar'}.to_json).
and_return(response)
subject.create_server(:foo_bar => 'foo_bar')
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:post).and_return(response)
keys = subject.create_server(:foo => 'bar').keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#update_server' do
let(:response) {
{
"ID" => 7450,
"Name" => "Production Testing",
"ApiTokens" => [
"fe6ec0cf-ff06-44aa-jf88-e77a41c61ce3"
],
"ServerLink" => "https://postmarkapp.com/servers/7438/overview",
"Color" => "blue",
"SmtpApiActivated" => false,
"RawEmailEnabled" => false,
"InboundAddress" => "7373de3ebd66acea22812731fb1dd7d5@inbound.postmarkapp.com",
"InboundHookUrl" => "http://hooks.example.com/inbound",
"BounceHookUrl" => "http://hooks.example.com/bounce",
"InboundDomain" => "",
"InboundHash" => "7373de3ebd66acea22812731fb1dd7d5"
}
}
it 'converts the server attribute names to camel case' do
allow(subject.http_client).to receive(:put).
with(an_instance_of(String), {'FooBar' => 'foo_bar'}.to_json).
and_return(response)
subject.update_server(42, :foo_bar => 'foo_bar')
end
it 'performs a PUT request to /servers/:id endpoint' do
allow(subject.http_client).to receive(:put).
with('servers/42', an_instance_of(String)).
and_return(response)
subject.update_server(42, :foo => 'bar')
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:put).and_return(response)
keys = subject.update_server(42, :foo => 'bar').keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#delete_server' do
let(:response) {
{
"ErrorCode" => "0",
"Message" => "Server Production Testing removed."
}
}
it 'performs a DELETE request to /servers/:id endpoint' do
allow(subject.http_client).to receive(:delete).
with('servers/42').and_return(response)
subject.delete_server(42)
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:delete).and_return(response)
keys = subject.delete_server(42).keys
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
describe '#push_templates' do
let(:response) {
{"TotalCount"=>5,
"Templates"=>
[{"Action"=>"Create", "TemplateId"=>nil, "Alias"=>"alias1", "Name"=>"Comment notification"},
{"Action"=>"Create", "TemplateId"=>nil, "Alias"=>"alias2", "Name"=>"Password reset"}]}
}
let(:request_data) {{:source_server_id => 1, :destination_server_id => 2, :perform_changes => false}}
it 'gets templates info and converts it to ruby format' do
allow(subject.http_client).to receive(:put).and_return(response)
templates = subject.push_templates({:source_server_id => 1, :destination_server_id => 2, :perform_changes => false} )
expect(templates.size).to eq(2)
expect(templates.first[:action]).to eq('Create')
expect(templates.first[:alias]).to eq('alias1')
end
it 'formats the keys of returned response' do
allow(subject.http_client).to receive(:put).and_return(response)
templates = subject.push_templates({:source_server_id => 1, :destination_server_id => 2, :perform_changes => false} )
keys = templates.map { |template| template.keys }.flatten
expect(keys.all? { |k| k.is_a?(Symbol) }).to be true
end
end
end
end
postmark-1.22.0/spec/support/ 0000755 0001751 0001751 00000000000 14123042137 016261 5 ustar vivekdeb vivekdeb postmark-1.22.0/spec/support/shared_examples.rb 0000644 0001751 0001751 00000004035 14123042137 021754 0 ustar vivekdeb vivekdeb shared_examples :mail do
it "set text body for plain message" do
expect(Postmark.send(:convert_message_to_options_hash, subject)['TextBody']).not_to be_nil
end
it "encode from properly when name is used" do
subject.from = "Sheldon Lee Cooper "
expect(subject).to be_serialized_to %q[{"Subject":"Hello!", "From":"Sheldon Lee Cooper ", "To":"lenard@bigbangtheory.com", "TextBody":"Hello Sheldon!"}]
end
it "encode reply to" do
subject.reply_to = ['a@a.com', 'b@b.com']
expect(subject).to be_serialized_to %q[{"Subject":"Hello!", "From":"sheldon@bigbangtheory.com", "ReplyTo":"a@a.com, b@b.com", "To":"lenard@bigbangtheory.com", "TextBody":"Hello Sheldon!"}]
end
it "encode tag" do
subject.tag = "invite"
expect(subject).to be_serialized_to %q[{"Subject":"Hello!", "From":"sheldon@bigbangtheory.com", "Tag":"invite", "To":"lenard@bigbangtheory.com", "TextBody":"Hello Sheldon!"}]
end
it "encode multiple recepients (TO)" do
subject.to = ['a@a.com', 'b@b.com']
expect(subject).to be_serialized_to %q[{"Subject":"Hello!", "From":"sheldon@bigbangtheory.com", "To":"a@a.com, b@b.com", "TextBody":"Hello Sheldon!"}]
end
it "encode multiple recepients (CC)" do
subject.cc = ['a@a.com', 'b@b.com']
expect(subject).to be_serialized_to %q[{"Cc":"a@a.com, b@b.com", "Subject":"Hello!", "From":"sheldon@bigbangtheory.com", "To":"lenard@bigbangtheory.com", "TextBody":"Hello Sheldon!"}]
end
it "encode multiple recepients (BCC)" do
subject.bcc = ['a@a.com', 'b@b.com']
expect(subject).to be_serialized_to %q[{"Bcc":"a@a.com, b@b.com", "Subject":"Hello!", "From":"sheldon@bigbangtheory.com", "To":"lenard@bigbangtheory.com", "TextBody":"Hello Sheldon!"}]
end
it "accept string as reply_to field" do
subject.reply_to = ['Anton Astashov ']
expect(subject).to be_serialized_to %q[{"From": "sheldon@bigbangtheory.com", "ReplyTo": "b@b.com", "To": "lenard@bigbangtheory.com", "Subject": "Hello!", "TextBody": "Hello Sheldon!"}]
end
end
postmark-1.22.0/spec/support/helpers.rb 0000644 0001751 0001751 00000000403 14123042137 020245 0 ustar vivekdeb vivekdeb module Postmark
module RSpecHelpers
def empty_gif_path
File.join(File.dirname(__FILE__), '..', 'data', 'empty.gif')
end
def encoded_empty_gif_data
Postmark::MessageHelper.encode_in_base64(File.read(empty_gif_path))
end
end
end postmark-1.22.0/spec/support/custom_matchers.rb 0000644 0001751 0001751 00000002005 14123042137 022003 0 ustar vivekdeb vivekdeb RSpec::Matchers.define :a_postmark_json do |string|
def postmark_key?(key)
key == ::Postmark::Inflector.to_postmark(key)
end
def postmark_object?(obj)
case obj
when Hash
return false unless obj.keys.all? { |k| postmark_key?(k) }
return false unless obj.values.all? { |v| postmark_object?(v) }
when Array
return false unless obj.all? { |v| postmark_object?(v) }
end
true
end
def postmark_json?(str)
return false unless str.is_a?(String)
json = Postmark::Json.decode(str)
postmark_object?(json)
rescue
false
end
match do |actual|
postmark_json?(actual)
end
end
RSpec::Matchers.define :json_representation_of do |x|
match { |actual| Postmark::Json.decode(actual) == x }
end
RSpec::Matchers.define :match_json do |x|
match { |actual| Postmark::Json.encode(x) == actual }
end
RSpec::Matchers.define :be_serialized_to do |json|
match do |mail_message|
Postmark.convert_message_to_options_hash(mail_message) == JSON.parse(json)
end
end
postmark-1.22.0/spec/spec_helper.rb 0000644 0001751 0001751 00000003311 14123042137 017361 0 ustar vivekdeb vivekdeb $LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'rubygems'
require 'bundler'
Bundler.setup(:development)
require 'mail'
require 'postmark'
require 'active_support'
require 'json'
require 'fakeweb'
require 'fakeweb_matcher'
require 'rspec'
require 'rspec/its'
require File.join(File.expand_path(File.dirname(__FILE__)), 'support', 'shared_examples.rb')
require File.join(File.expand_path(File.dirname(__FILE__)), 'support', 'custom_matchers.rb')
require File.join(File.expand_path(File.dirname(__FILE__)), 'support', 'helpers.rb')
if ENV['JSONGEM']
# `JSONGEM=Yajl rake spec`
Postmark.response_parser_class = ENV['JSONGEM'].to_sym
puts "Setting ResponseParser class to #{Postmark::ResponseParsers.const_get Postmark.response_parser_class}"
end
RSpec.configure do |config|
include Postmark::RSpecHelpers
config.expect_with(:rspec) { |c| c.syntax = :expect }
config.filter_run_excluding :skip_for_platform => lambda { |platform|
RUBY_PLATFORM.to_s =~ /^#{platform.to_s}/
}
config.filter_run_excluding :skip_ruby_version => lambda { |version|
versions = [*version]
versions.any? { |v| RUBY_VERSION.to_s =~ /^#{v.to_s}/ }
}
config.filter_run_excluding :exclusive_for_ruby_version => lambda { |version|
versions = [*version]
versions.all? { |v| !(RUBY_VERSION.to_s =~ /^#{v.to_s}/) }
}
config.before(:each) do
%w(api_client response_parser_class secure api_token proxy_host proxy_port
proxy_user proxy_pass host port path_prefix http_open_timeout
http_read_timeout max_retries).each do |var|
Postmark.instance_variable_set(:"@#{var}", nil)
end
Postmark.response_parser_class = nil
end
end
postmark-1.22.0/spec/integration/ 0000755 0001751 0001751 00000000000 14123042137 017070 5 ustar vivekdeb vivekdeb postmark-1.22.0/spec/integration/mail_delivery_method_spec.rb 0000644 0001751 0001751 00000005465 14123042137 024626 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe "Sending Mail::Messages with delivery_method Mail::Postmark" do
let(:postmark_message_id_format) { /\w{8}\-\w{4}-\w{4}-\w{4}-\w{12}/ }
let(:message) {
Mail.new do
from "sender@postmarkapp.com"
to "recipient@postmarkapp.com"
subject "Mail::Message object"
body "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
"eiusmod tempor incididunt ut labore et dolore magna aliqua."
delivery_method Mail::Postmark, :api_token => "POSTMARK_API_TEST",
:http_open_timeout => 15,
:http_read_timeout => 15
end
}
let(:tagged_message) { message.tap { |m| m.tag "postmark-gem" } }
let(:message_with_no_body) {
Mail.new do
from "sender@postmarkapp.com"
to "recipient@postmarkapp.com"
delivery_method Mail::Postmark, :api_token => "POSTMARK_API_TEST",
:http_open_timeout => 15,
:http_read_timeout => 15
end
}
let(:message_with_attachment) {
message.tap do |msg|
msg.attachments["test.gif"] = File.read(File.join(File.dirname(__FILE__), '..', 'data', 'empty.gif'))
end
}
let(:message_with_invalid_to) {
Mail.new do
from "sender@postmarkapp.com"
to "@postmarkapp.com"
delivery_method Mail::Postmark, :api_token => "POSTMARK_API_TEST",
:http_open_timeout => 15,
:http_read_timeout => 15
end
}
it 'delivers a plain text message' do
expect { message.deliver }.to change{message.delivered?}.to(true)
end
it 'updates a message object with X-PM-Message-Id' do
expect { message.deliver }.to change{message['X-PM-Message-Id'].to_s}.to(postmark_message_id_format)
end
it 'updates a message object with full postmark response' do
expect { message.deliver }.to change{message.postmark_response}.from(nil)
end
it 'delivers a tagged message' do
expect { tagged_message.deliver }.to change{message.delivered?}.to(true)
end
it 'delivers a message with attachment' do
expect { message_with_attachment.deliver }.to change{message_with_attachment.delivered?}.to(true)
end
context 'fails to deliver a message' do
it ' without body - raise error' do
expect { message_with_no_body.deliver! }.to raise_error(Postmark::InvalidMessageError)
end
it 'without body - do not deliver' do
expect(message_with_no_body).not_to be_delivered
end
it 'with invalid To address - raise error' do
expect { message_with_invalid_to.deliver! }.to raise_error(Postmark::InvalidMessageError)
end
it 'with invalid To address - do not deliver' do
expect(message_with_invalid_to).not_to be_delivered
end
end
end postmark-1.22.0/spec/integration/api_client_resources_spec.rb 0000644 0001751 0001751 00000003640 14123042137 024633 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe 'Accessing server resources using the API' do
let(:api_client) {Postmark::ApiClient.new(ENV['POSTMARK_API_KEY'], :http_open_timeout => 15)}
let(:recipient) {ENV['POSTMARK_CI_RECIPIENT']}
let(:message) {
{
:from => ENV['POSTMARK_CI_SENDER'],
:to => recipient,
:subject => "Mail::Message object",
:text_body => "Lorem ipsum dolor sit amet, consectetur adipisicing elit, " \
"sed do eiusmod tempor incididunt ut labore et dolore " \
"magna aliqua."
}
}
context 'Messages API' do
def with_retries(max_retries = 20, wait_seconds = 3)
yield
rescue => e
retries = retries ? retries + 1 : 1
if retries < max_retries
sleep wait_seconds
retry
else
raise e
end
end
it 'is possible to send a message and access its details via the Messages API' do
response = api_client.deliver(message)
message = with_retries {api_client.get_message(response[:message_id])}
expect(message[:recipients]).to include(recipient)
end
it 'is possible to send a message and dump it via the Messages API' do
response = api_client.deliver(message)
dump = with_retries {api_client.dump_message(response[:message_id])}
expect(dump[:body]).to include('Mail::Message object')
end
it 'is possible to send a message and find it via the Messages API' do
response = api_client.deliver(message)
expect {
with_retries {
messages = api_client.get_messages(:recipient => recipient,
:fromemail => message[:from],
:subject => message[:subject])
unless messages.map {|m| m[:message_id]}.include?(response[:message_id])
raise 'Message not found'
end
}
}.not_to raise_error
end
end
end
postmark-1.22.0/spec/integration/api_client_messages_spec.rb 0000644 0001751 0001751 00000010110 14123042137 024416 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe "Sending Mail::Messages with Postmark::ApiClient" do
let(:postmark_message_id_format) { /\w{8}\-\w{4}-\w{4}-\w{4}-\w{12}/ }
let(:api_client) { Postmark::ApiClient.new('POSTMARK_API_TEST', :http_open_timeout => 15, :http_read_timeout => 15) }
let(:message) {
Mail.new do
from "sender@postmarkapp.com"
to "recipient@postmarkapp.com"
subject "Mail::Message object"
body "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
"eiusmod tempor incididunt ut labore et dolore magna aliqua."
end
}
let(:message_with_no_body) {
Mail.new do
from "sender@postmarkapp.com"
to "recipient@postmarkapp.com"
end
}
let(:message_with_attachment) { message.tap { |msg| msg.attachments["test.gif"] = File.read(empty_gif_path) } }
let(:message_with_invalid_to) {
Mail.new do
from "sender@postmarkapp.com"
to "@postmarkapp.com"
end
}
let(:valid_messages) { [message, message.dup] }
let(:partially_valid_messages) { [message, message.dup, message_with_no_body] }
let(:invalid_messages) { [message_with_no_body, message_with_no_body.dup] }
context 'invalid API code' do
it "doesn't deliver messages" do
expect {
Postmark::ApiClient.new('INVALID').deliver_message(message) rescue Postmark::InvalidApiKeyError
}.to change{message.delivered?}.to(false)
end
end
context "single message" do
it 'plain text message' do
expect(api_client.deliver_message(message)).to have_key(:message_id)
end
it 'message with attachment' do
expect(api_client.deliver_message(message_with_attachment)).to have_key(:message_id)
end
it 'response Message-ID' do
expect(api_client.deliver_message(message)[:message_id]).to be =~ postmark_message_id_format
end
it 'response is Hash' do
expect(api_client.deliver_message(message)).to be_a Hash
end
it 'fails to deliver a message without body' do
expect { api_client.deliver_message(message_with_no_body) }.to raise_error(Postmark::InvalidMessageError)
end
it 'fails to deliver a message with invalid To address' do
expect { api_client.deliver_message(message_with_invalid_to) }.to raise_error(Postmark::InvalidMessageError)
end
end
context "batch message" do
it 'response - valid Mail::Message objects' do
expect { api_client.deliver_messages(valid_messages) }.
to change{valid_messages.all? { |m| m.delivered? }}.to true
end
it 'response - valid X-PM-Message-Ids' do
api_client.deliver_messages(valid_messages)
expect(valid_messages.all? { |m| m['X-PM-Message-Id'].to_s =~ postmark_message_id_format }).to be true
end
it 'response - valid response objects' do
api_client.deliver_messages(valid_messages)
expect(valid_messages.all? { |m| m.postmark_response["To"] == m.to[0] }).to be true
end
it 'response - message responses count' do
expect(api_client.deliver_messages(valid_messages).count).to eq valid_messages.count
end
context "custom max_batch_size" do
before do
api_client.max_batch_size = 1
end
it 'response - valid response objects' do
api_client.deliver_messages(valid_messages)
expect(valid_messages.all? { |m| m.postmark_response["To"] == m.to[0] }).to be true
end
it 'response - message responses count' do
expect(api_client.deliver_messages(valid_messages).count).to eq valid_messages.count
end
end
it 'partially delivers a batch of partially valid Mail::Message objects' do
expect { api_client.deliver_messages(partially_valid_messages) }.
to change{partially_valid_messages.select { |m| m.delivered? }.count}.to 2
end
it "doesn't deliver a batch of invalid Mail::Message objects" do
aggregate_failures do
expect { api_client.deliver_messages(invalid_messages) }.
to change{invalid_messages.all? { |m| m.delivered? == false }}.to true
expect(invalid_messages).to satisfy { |ms| ms.all? { |m| !!m.postmark_response }}
end
end
end
end postmark-1.22.0/spec/integration/api_client_hashes_spec.rb 0000644 0001751 0001751 00000005640 14123042137 024076 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe "Sending messages as Ruby hashes with Postmark::ApiClient" do
let(:message_id_format) {/<.+@.+>/}
let(:postmark_message_id_format) {/\w{8}\-\w{4}-\w{4}-\w{4}-\w{12}/}
let(:api_client) {Postmark::ApiClient.new('POSTMARK_API_TEST', :http_open_timeout => 15, :http_read_timeout => 15)}
let(:message) {
{
:from => "sender@postmarkapp.com",
:to => "recipient@postmarkapp.com",
:subject => "Mail::Message object",
:text_body => "Lorem ipsum dolor sit amet, consectetur adipisicing elit, " \
"sed do eiusmod tempor incididunt ut labore et dolore " \
"magna aliqua."
}
}
let(:message_with_no_body) {
{
:from => "sender@postmarkapp.com",
:to => "recipient@postmarkapp.com",
}
}
let(:message_with_attachment) {
message.tap do |m|
m[:attachments] = [File.open(empty_gif_path)]
end
}
let(:message_with_invalid_to) {{:from => "sender@postmarkapp.com", :to => "@postmarkapp.com"}}
let(:valid_messages) {[message, message.dup]}
let(:partially_valid_messages) {[message, message.dup, message_with_no_body]}
let(:invalid_messages) {[message_with_no_body, message_with_no_body.dup]}
context "single message" do
it 'plain text message' do
expect(api_client.deliver(message)).to have_key(:message_id)
end
it 'message with attachment' do
expect(api_client.deliver(message_with_attachment)).to have_key(:message_id)
end
it 'response Message-ID' do
expect(api_client.deliver(message)[:message_id]).to be =~ postmark_message_id_format
end
it 'response is Hash' do
expect(api_client.deliver(message)).to be_a Hash
end
it 'fails to deliver a message without body' do
expect {api_client.deliver(message_with_no_body)}.to raise_error(Postmark::InvalidMessageError)
end
it 'fails to deliver a message with invalid To address' do
expect {api_client.deliver(message_with_invalid_to)}.to raise_error(Postmark::InvalidMessageError)
end
end
context "batch message" do
it 'response messages count' do
expect(api_client.deliver_in_batches(valid_messages).count).to eq valid_messages.count
end
context "custom max_batch_size" do
before do
api_client.max_batch_size = 1
end
it 'response message count' do
expect(api_client.deliver_in_batches(valid_messages).count).to eq valid_messages.count
end
end
it 'partially delivers a batch of partially valid Mail::Message objects' do
response = api_client.deliver_in_batches(partially_valid_messages)
expect(response).to satisfy {|r| r.count {|mr| mr[:error_code].to_i.zero?} == 2}
end
it "doesn't deliver a batch of invalid Mail::Message objects" do
response = api_client.deliver_in_batches(invalid_messages)
expect(response).to satisfy {|r| r.all? {|mr| !!mr[:error_code]}}
end
end
end postmark-1.22.0/spec/integration/account_api_client_spec.rb 0000644 0001751 0001751 00000007213 14123042137 024255 0 ustar vivekdeb vivekdeb require 'spec_helper'
describe 'Account API client usage' do
subject { Postmark::AccountApiClient.new(ENV['POSTMARK_ACCOUNT_API_KEY'],
:http_open_timeout => 15,
:http_read_timeout => 15) }
let(:unique_token) { rand(36**32).to_s(36) }
let(:unique_from_email) { ENV['POSTMARK_CI_SENDER'].gsub(/(\+.+)?@/, "+#{unique_token}@") }
it 'manage senders' do
# create & count
new_sender = subject.create_sender(:name => 'Integration Test', :from_email => unique_from_email)
expect(subject.get_senders_count).to be > 0
# get
expect(subject.get_sender(new_sender[:id])[:id]).to eq(new_sender[:id])
# list
senders = subject.get_senders(:count => 50)
expect(senders.map { |s| s[:id] }).to include(new_sender[:id])
# collection
expect(subject.senders.map { |s| s[:id] }).to include(new_sender[:id])
# update
updated_sender = subject.update_sender(new_sender[:id], :name => 'New Name')
expect(updated_sender[:name]).to eq('New Name')
expect(updated_sender[:id]).to eq(new_sender[:id])
# spf
expect(subject.verified_sender_spf?(new_sender[:id])).to be true
# resend
expect { subject.resend_sender_confirmation(new_sender[:id]) }.not_to raise_error
# dkim
expect { subject.request_new_sender_dkim(new_sender[:id]) }.
to raise_error(Postmark::InvalidMessageError,
'This DKIM is already being renewed.')
# delete
expect { subject.delete_sender(new_sender[:id]) }.not_to raise_error
end
it 'manage domains' do
domain_name = "#{unique_token}-gem-integration.test"
return_path = "return.#{domain_name}"
updated_return_path = "updated-return.#{domain_name}"
# create & count
new_domain = subject.create_domain(:name => domain_name,
:return_path_domain => return_path)
expect(subject.get_domains_count).to be > 0
# get
expect(subject.get_domain(new_domain[:id])[:id]).to eq(new_domain[:id])
# list
domains = subject.get_domains(:count => 50)
expect(domains.map { |d| d[:id] }).to include(new_domain[:id])
# collection
expect(subject.domains.map { |d| d[:id] }).to include(new_domain[:id])
# update
updated_domain = subject.update_domain(new_domain[:id], :return_path_domain => updated_return_path)
expect(updated_domain[:return_path_domain]).to eq(updated_return_path)
expect(updated_domain[:id]).to eq(new_domain[:id])
# spf
expect(subject.verified_domain_spf?(new_domain[:id])).to be true
# dkim
expect { subject.rotate_domain_dkim(new_domain[:id]) }.
to raise_error(Postmark::InvalidMessageError,
'This DKIM is already being renewed.')
# delete
expect { subject.delete_domain(new_domain[:id]) }.not_to raise_error
end
it 'manage servers' do
# create & count
new_server = subject.create_server(:name => "server-#{unique_token}",
:color => 'red')
expect(subject.get_servers_count).to be > 0
# get
expect(subject.get_server(new_server[:id])[:id]).to eq(new_server[:id])
# list
servers = subject.get_servers(:count => 50)
expect(servers.map { |s| s[:id] }).to include(new_server[:id])
# collection
expect(subject.servers.map { |s| s[:id] }).to include(new_server[:id])
# update
updated_server = subject.update_server(new_server[:id], :color => 'blue')
expect(updated_server[:color]).to eq('blue')
expect(updated_server[:id]).to eq(new_server[:id])
# delete
expect { subject.delete_server(new_server[:id]) }.not_to raise_error
end
end
postmark-1.22.0/spec/data/ 0000755 0001751 0001751 00000000000 14123042137 015456 5 ustar vivekdeb vivekdeb postmark-1.22.0/spec/data/empty.gif 0000644 0001751 0001751 00000000053 14123042137 017301 0 ustar vivekdeb vivekdeb GIF89a !
, D ; postmark-1.22.0/postmark.png 0000644 0001751 0001751 00000006057 14123042137 016171 0 ustar vivekdeb vivekdeb PNG
IHDR SPLTE x # WL RG
gY -' }m ؼ д sd 70 u >6 sF= Ī ] GtRNS ȟA4^ּ!cƴtkVPJ=&ɁQ
DIDATxǒ@E_+K(s3䜳ëJih䝫=M_A8ʬms2pܳ~ q݃g[=r>;%pxBpFpv`d"KN
L쩟pTr3H-ϟ矫Z-]C%$NLv{~w/@K0B.,@Q٢a.k\'!Oj}s.R\YK@[ƾ:Hz|cXs^{dt-Yf