postmark 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d99b2b07a9b385d8373eb4f0f020806d4ead30fc
4
- data.tar.gz: 56f731c91f3d7a660e56c896d5666ee65c177ec1
3
+ metadata.gz: 17d7c0c5ea350fd8902efaa8e8334dff894fe215
4
+ data.tar.gz: 17f7871d1544d69b7cf16d75c4ba260048de182c
5
5
  SHA512:
6
- metadata.gz: 1e0545eb81715e7a0d436557498f4cb0c3196fed8964ca8e0bc51699d2e944faacbb269cd8bfc1be537564983b2932a789738d2a9a0ba4271d2487371c3de61c
7
- data.tar.gz: 6c5f27e71506ef94a7efb1f07bd14438f9f9403f9d1a209434dab722c3a96e57448e937d02f8da0f394596e4d3e800e2d5baf67cf2ec793e856ae7b364d8abf9
6
+ metadata.gz: 38df57ae61ce36c80870832444d017083e1bff043901823eb675384ae25df1366f420170abf41059a7601d7a6a2c7e26866a15abf8c5b98fa7fa30b7d8cbeeb8
7
+ data.tar.gz: 4dcacb79aec065cf65445da357f0b3e275911da17881291124dacd70b0bccacb1a3d69b4779f34f010692b7667710a0e0b6c8214a00af557b65d86746fc0a499
@@ -1,5 +1,9 @@
1
1
  = Changelog
2
2
 
3
+ == 1.6.0
4
+
5
+ * Add methods to access new templates API endpoints.
6
+
3
7
  == 1.5.0
4
8
 
5
9
  * Call API access strings tokens instead of keys. Keep backwards compatibility.
data/README.md CHANGED
@@ -160,6 +160,22 @@ client.deliver(from: 'sheldon@bigbangtheory.com',
160
160
  # => {:to=>"Leonard Hofstadter <leonard@bigbangtheory.com>, Penny <penny@bigbangtheory.com>", :submitted_at=>"2013-05-09T05:04:16.3247488-04:00", :message_id=>"d647c5d6-xxxx-466d-9411-557dcd5c2297", :error_code=>0, :message=>"OK"}
161
161
  ```
162
162
 
163
+ ## Sending a templated email
164
+
165
+ If you have a [template created](https://github.com/wildbit/postmark-gem/wiki/The-Templates-API-support) in Postmark you can send an email using that template.
166
+
167
+ ``` ruby
168
+ client.deliver_with_template(from: 'sheldon@bigbangtheory.com',
169
+ to: 'Penny <penny@bigbangtheory.com>',
170
+ template_id: 123,
171
+ template_model: {
172
+ name: 'Penny',
173
+ message: 'Bazinga!'
174
+ })
175
+
176
+ # => {:to=>"Penny <penny@bigbangtheory.com>", :submitted_at=>"2013-05-09T03:00:55.4454938-04:00", :message_id=>"34aed4b3-3a95-xxxx-bd1d-88064909cc93", :error_code=>0, :message=>"OK"}
177
+ ```
178
+
163
179
  ## Sending in batches
164
180
 
165
181
  While Postmark is focused on transactional email, we understand that developers
@@ -544,6 +560,10 @@ Postmark allows you to automatically scale your sending infrastructure with the
544
560
 
545
561
  If you ever need to access your messages or their metadata (i.e. open tracking info), [the Messages API](https://github.com/wildbit/postmark-gem/wiki/The-Messages-API-support) is a great place to start.
546
562
 
563
+ ## The Templates API Support
564
+
565
+ [The Templates API](https://github.com/wildbit/postmark-gem/wiki/The-Templates-API-support) can be used to fully manage your templates.
566
+
547
567
  ## ActiveModel-like Interface For Bounces
548
568
 
549
569
  To provide an interface similar to ActiveModel for bounces, the Postmark gem adds
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.0
1
+ 1.6.0
@@ -165,6 +165,62 @@ module Postmark
165
165
  format_response http_client.put("server", serialize(data))
166
166
  end
167
167
 
168
+ def get_templates(options = {})
169
+ load_batch('templates', 'Templates', options)
170
+ end
171
+
172
+ def templates(options = {})
173
+ find_each('templates', 'Templates', options)
174
+ end
175
+
176
+ def get_template(id)
177
+ format_response http_client.get("templates/#{id}")
178
+ end
179
+
180
+ def create_template(attributes = {})
181
+ data = serialize(HashHelper.to_postmark(attributes))
182
+
183
+ format_response http_client.post('templates', data)
184
+ end
185
+
186
+ def update_template(id, attributes = {})
187
+ data = serialize(HashHelper.to_postmark(attributes))
188
+
189
+ format_response http_client.put("templates/#{id}", data)
190
+ end
191
+
192
+ def delete_template(id)
193
+ format_response http_client.delete("templates/#{id}")
194
+ end
195
+
196
+ def validate_template(attributes = {})
197
+ data = serialize(HashHelper.to_postmark(attributes))
198
+ response = format_response(http_client.post('templates/validate', data))
199
+
200
+ response.each do |k, v|
201
+ next unless v.is_a?(Hash) && k != :suggested_template_model
202
+
203
+ response[k] = HashHelper.to_ruby(v)
204
+
205
+ if response[k].has_key?(:validation_errors)
206
+ ruby_hashes = response[k][:validation_errors].map do |err|
207
+ HashHelper.to_ruby(err)
208
+ end
209
+ response[k][:validation_errors] = ruby_hashes
210
+ end
211
+ end
212
+
213
+ response
214
+ end
215
+
216
+ def deliver_with_template(attributes = {})
217
+ data = serialize(MessageHelper.to_postmark(attributes))
218
+
219
+ with_retries do
220
+ format_response http_client.post('email/withTemplate', data)
221
+ end
222
+ end
223
+
168
224
  protected
169
225
 
170
226
  def in_batches(messages)
@@ -195,4 +251,4 @@ module Postmark
195
251
  end
196
252
 
197
253
  end
198
- end
254
+ end
@@ -1,3 +1,3 @@
1
1
  module Postmark
2
- VERSION = '1.5.0'
2
+ VERSION = '1.6.0'
3
3
  end
@@ -572,4 +572,259 @@ describe Postmark::ApiClient do
572
572
  end
573
573
  end
574
574
 
575
- end
575
+ describe '#get_templates' do
576
+ let(:http_client) { subject.http_client }
577
+ let(:response) do
578
+ {
579
+ 'TotalCount' => 31,
580
+ 'Templates' => [
581
+ {
582
+ 'Active' => true,
583
+ 'TemplateId' => 123,
584
+ 'Name' => 'ABC'
585
+ },
586
+ {
587
+ 'Active' => true,
588
+ 'TemplateId' => 456,
589
+ 'Name' => 'DEF'
590
+ }
591
+ ]
592
+ }
593
+ end
594
+
595
+ it 'gets templates info and converts it to ruby format' do
596
+ http_client.should_receive(:get).with('templates', :offset => 0, :count => 2).and_return(response)
597
+
598
+ count, templates = subject.get_templates(:count => 2)
599
+
600
+ expect(count).to eq(31)
601
+ expect(templates.first[:template_id]).to eq(123)
602
+ expect(templates.first[:name]).to eq('ABC')
603
+ end
604
+ end
605
+
606
+ describe '#templates' do
607
+ it 'returns an Enumerator' do
608
+ expect(subject.templates).to be_kind_of(Enumerable)
609
+ end
610
+
611
+ it 'requests data at /templates' do
612
+ allow(subject.http_client).to receive(:get).
613
+ with('templates', an_instance_of(Hash)).
614
+ and_return('TotalCount' => 1, 'Templates' => [{}])
615
+ expect(subject.templates.first(5).count).to eq(1)
616
+ end
617
+ end
618
+
619
+ describe '#get_template' do
620
+ let(:http_client) { subject.http_client }
621
+ let(:response) do
622
+ {
623
+ 'Name' => 'Template Name',
624
+ 'TemplateId' => 123,
625
+ 'Subject' => 'Subject',
626
+ 'HtmlBody' => 'Html',
627
+ 'TextBody' => 'Text',
628
+ 'AssociatedServerId' => 456,
629
+ 'Active' => true
630
+ }
631
+ end
632
+
633
+ it 'gets single template and converts it to ruby format' do
634
+ http_client.should_receive(:get).with('templates/123').and_return(response)
635
+
636
+ template = subject.get_template('123')
637
+
638
+ expect(template[:name]).to eq('Template Name')
639
+ expect(template[:template_id]).to eq(123)
640
+ expect(template[:html_body]).to eq('Html')
641
+ end
642
+ end
643
+
644
+ describe '#create_template' do
645
+ let(:http_client) { subject.http_client }
646
+ let(:response) do
647
+ {
648
+ 'TemplateId' => 123,
649
+ 'Name' => 'template name',
650
+ 'Active' => true
651
+ }
652
+ end
653
+
654
+ it 'performs a POST request to /templates with the given attributes' do
655
+ expected_json = { 'Name' => 'template name' }.to_json
656
+
657
+ http_client.should_receive(:post).with('templates', expected_json).and_return(response)
658
+
659
+ template = subject.create_template(:name => 'template name')
660
+
661
+ expect(template[:name]).to eq('template name')
662
+ expect(template[:template_id]).to eq(123)
663
+ end
664
+ end
665
+
666
+ describe '#update_template' do
667
+ let(:http_client) { subject.http_client }
668
+ let(:response) do
669
+ {
670
+ 'TemplateId' => 123,
671
+ 'Name' => 'template name',
672
+ 'Active' => true
673
+ }
674
+ end
675
+
676
+ it 'performs a PUT request to /templates with the given attributes' do
677
+ expected_json = { 'Name' => 'template name' }.to_json
678
+
679
+ http_client.should_receive(:put).with('templates/123', expected_json).and_return(response)
680
+
681
+ template = subject.update_template(123, :name => 'template name')
682
+
683
+ expect(template[:name]).to eq('template name')
684
+ expect(template[:template_id]).to eq(123)
685
+ end
686
+ end
687
+
688
+ describe '#delete_template' do
689
+ let(:http_client) { subject.http_client }
690
+ let(:response) do
691
+ {
692
+ 'ErrorCode' => 0,
693
+ 'Message' => 'Template 123 removed.'
694
+ }
695
+ end
696
+
697
+ it 'performs a DELETE request to /templates/:id' do
698
+ http_client.should_receive(:delete).with('templates/123').and_return(response)
699
+
700
+ resp = subject.delete_template(123)
701
+
702
+ expect(resp[:error_code]).to eq(0)
703
+ end
704
+ end
705
+
706
+ describe '#validate_template' do
707
+ let(:http_client) { subject.http_client }
708
+
709
+ context 'when template is valid' do
710
+ let(:response) do
711
+ {
712
+ 'AllContentIsValid' => true,
713
+ 'HtmlBody' => {
714
+ 'ContentIsValid' => true,
715
+ 'ValidationErrors' => [],
716
+ 'RenderedContent' => '<html><head></head><body>MyName_Value</body></html>'
717
+ },
718
+ 'TextBody' => {
719
+ 'ContentIsValid' => true,
720
+ 'ValidationErrors' => [],
721
+ 'RenderedContent' => 'MyName_Value'
722
+ },
723
+ 'Subject' => {
724
+ 'ContentIsValid' => true,
725
+ 'ValidationErrors' => [],
726
+ 'RenderedContent' => 'MyName_Value'
727
+ },
728
+ 'SuggestedTemplateModel' => {
729
+ 'MyName' => 'MyName_Value'
730
+ }
731
+ }
732
+ end
733
+
734
+ it 'performs a POST request and returns unmodified suggested template model' do
735
+ expected_template_json = {
736
+ 'HtmlBody' => '{{MyName}}',
737
+ 'TextBody' => '{{MyName}}',
738
+ 'Subject' => '{{MyName}}'
739
+ }.to_json
740
+
741
+ http_client.should_receive(:post).with('templates/validate', expected_template_json).and_return(response)
742
+
743
+ resp = subject.validate_template(:html_body => '{{MyName}}',
744
+ :text_body => '{{MyName}}',
745
+ :subject => '{{MyName}}')
746
+
747
+ expect(resp[:all_content_is_valid]).to be_true
748
+ expect(resp[:html_body][:content_is_valid]).to be_true
749
+ expect(resp[:html_body][:validation_errors]).to be_empty
750
+ expect(resp[:suggested_template_model]['MyName']).to eq('MyName_Value')
751
+ end
752
+ end
753
+
754
+ context 'when template is invalid' do
755
+ let(:response) do
756
+ {
757
+ 'AllContentIsValid' => false,
758
+ 'HtmlBody' => {
759
+ 'ContentIsValid' => false,
760
+ 'ValidationErrors' => [
761
+ {
762
+ 'Message' => 'The \'each\' block being opened requires a model path to be specified in the form \'{#each <name>}\'.',
763
+ 'Line' => 1,
764
+ 'CharacterPosition' => 1
765
+ }
766
+ ],
767
+ 'RenderedContent' => nil
768
+ },
769
+ 'TextBody' => {
770
+ 'ContentIsValid' => true,
771
+ 'ValidationErrors' => [],
772
+ 'RenderedContent' => 'MyName_Value'
773
+ },
774
+ 'Subject' => {
775
+ 'ContentIsValid' => true,
776
+ 'ValidationErrors' => [],
777
+ 'RenderedContent' => 'MyName_Value'
778
+ },
779
+ 'SuggestedTemplateModel' => nil
780
+ }
781
+ end
782
+
783
+ it 'performs a POST request and returns validation errors' do
784
+ expected_template_json = {
785
+ 'HtmlBody' => '{{#each}}',
786
+ 'TextBody' => '{{MyName}}',
787
+ 'Subject' => '{{MyName}}'
788
+ }.to_json
789
+
790
+ http_client.should_receive(:post).with('templates/validate', expected_template_json).and_return(response)
791
+
792
+ resp = subject.validate_template(:html_body => '{{#each}}',
793
+ :text_body => '{{MyName}}',
794
+ :subject => '{{MyName}}')
795
+
796
+ expect(resp[:all_content_is_valid]).to be_false
797
+ expect(resp[:text_body][:content_is_valid]).to be_true
798
+ expect(resp[:html_body][:content_is_valid]).to be_false
799
+ expect(resp[:html_body][:validation_errors].first[:character_position]).to eq(1)
800
+ 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 <name>}\'.')
801
+ end
802
+ end
803
+ end
804
+
805
+ describe "#deliver_with_template" do
806
+ let(:email) { Postmark::MessageHelper.to_postmark(message_hash) }
807
+ let(:email_json) { Postmark::Json.encode(email) }
808
+ let(:http_client) { subject.http_client }
809
+ let(:response) { {"MessageID" => 42} }
810
+
811
+ it 'converts message hash to Postmark format and posts it to /email/withTemplate' do
812
+ http_client.should_receive(:post).with('email/withTemplate', email_json) { response }
813
+ subject.deliver_with_template(message_hash)
814
+ end
815
+
816
+ it 'retries 3 times' do
817
+ 2.times do
818
+ http_client.should_receive(:post).and_raise(Postmark::InternalServerError)
819
+ end
820
+ http_client.should_receive(:post) { response }
821
+ expect { subject.deliver_with_template(message_hash) }.not_to raise_error
822
+ end
823
+
824
+ it 'converts response to ruby format' do
825
+ http_client.should_receive(:post).with('email/withTemplate', email_json) { response }
826
+ r = subject.deliver_with_template(message_hash)
827
+ r.should have_key(:message_id)
828
+ end
829
+ end
830
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postmark
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Petyo Ivanov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-01-05 00:00:00.000000000 Z
13
+ date: 2015-08-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  version: 1.3.7
142
142
  requirements: []
143
143
  rubyforge_project:
144
- rubygems_version: 2.2.2
144
+ rubygems_version: 2.4.5
145
145
  signing_key:
146
146
  specification_version: 4
147
147
  summary: Official Postmark API wrapper.