Skip to content

Commit 2309d2b

Browse files
author
Ashu Goel
committed
[template] add API for the preview template endpoint
1 parent 5f4a222 commit 2309d2b

File tree

5 files changed

+188
-0
lines changed

5 files changed

+188
-0
lines changed

lib/template.ex

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
defmodule SparkPost.Template do
2+
@moduledoc """
3+
The SparkPost Template API for working with templates. Use `SparkPost.Template.preview/2` to
4+
preview a template.
5+
6+
Check out the documentation for each function
7+
or use the [SparkPost API reference](https://developers.sparkpost.com/api/templates.html) for details.
8+
9+
Returned by `SparkPost.template.preview/2`.
10+
-from
11+
-email
12+
-name
13+
-subject
14+
-reply_to
15+
-text
16+
-html
17+
-headers
18+
"""
19+
20+
alias SparkPost.{Endpoint, Template}
21+
22+
@doc """
23+
Generate a preview of an existing template.
24+
25+
### Parameters
26+
- %SparkPost.Content.TemplateRef{} consisting of:
27+
- template_id: The string id of the template to retrieve a preview or.
28+
- use_draft_template: If true, previews the most recent draft template.
29+
If false, previews the most recent published template. If nil,
30+
previews the most recently template version period.
31+
- substitution_data: k,v map consisting of substituions. See the
32+
[SparkPost Substitutions Reference](https://developers.sparkpost.com/api/substitutions-reference.html)
33+
for more details.
34+
"""
35+
def preview(%SparkPost.Content.TemplateRef{} = template, substitution_data) do
36+
qs = if is_nil(template.use_draft_template) do
37+
""
38+
else
39+
"?draft=#{template.use_draft_template}"
40+
end
41+
body = %{substitution_data: substitution_data}
42+
:post
43+
|> Endpoint.request("/templates/#{template.template_id}/preview#{qs}", body)
44+
|> Endpoint.marshal_response(Template.ContentResponse)
45+
|> Template.ContentResponse.convert_from_field
46+
end
47+
end

lib/template/content_response.ex

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
defmodule SparkPost.Template.ContentResponse do
2+
@moduledoc """
3+
The content portion of a response generated when SparkPost receives a Template object.
4+
5+
See the [SparkPost Template Documentation](https://developers.sparkpost.com/api/templates.html#header-content-attributes)
6+
for more details.
7+
8+
## Fields
9+
- html: HTML content for the email's text/html MIME part
10+
- text: Text content for the email's text/plain MIME part
11+
- subject: Email subject line
12+
- from: a %SparkPost.Address{} object
13+
- reply_to: Email address used to compose the email's "Reply-To" header
14+
- headers: JSON object container headers other than "Subject", "From", "To" and "Reply-To"
15+
"""
16+
17+
defstruct html: nil,
18+
text: nil,
19+
subject: :required,
20+
from: :required,
21+
reply_to: nil,
22+
headers: nil
23+
24+
@doc """
25+
Convert a raw "from" field into a %SparkPost.Address{} object.
26+
"""
27+
def convert_from_field(%SparkPost.Endpoint.Error{} = response), do: response
28+
def convert_from_field(%__MODULE__{} = response) do
29+
%{response | from: SparkPost.Address.to_address(response.from)}
30+
end
31+
end

test/data/previewtemplate.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"results": {
3+
"from": {
4+
"email": "marketing@bounces.company.example",
5+
"name": "Example Company Marketing"
6+
},
7+
"subject": "Summer deals for Natalie",
8+
"reply_to": "Summer deals <summer_deals@company.example>",
9+
"text": "Check out these deals Natalie!",
10+
"html": "<b>Check out these deals Natalie!</b>",
11+
"headers": {
12+
"X-Customer-Campaign-ID": "Summer2014"
13+
}
14+
}
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"results": {
3+
"from": "marketing@bounces.company.example",
4+
"subject": "Summer deals for Natalie",
5+
"reply_to": "Summer deals <summer_deals@company.example>",
6+
"text": "Check out these deals Natalie!",
7+
"html": "<b>Check out these deals Natalie!</b>",
8+
"headers": {
9+
"X-Customer-Campaign-ID": "Summer2014"
10+
}
11+
}
12+
}

test/template_test.exs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
defmodule SparkPost.TemplateTest do
2+
use ExUnit.Case, async: false
3+
4+
alias SparkPost.Content.TemplateRef
5+
alias SparkPost.{Endpoint, MockServer, Template}
6+
alias SparkPost.Template.ContentResponse
7+
8+
import Mock
9+
10+
defmodule TestStruct do
11+
def basic_template do
12+
%TemplateRef{template_id: "TEMPLATE_ID", use_draft_template: nil}
13+
end
14+
15+
def template_with_draft do
16+
%TemplateRef{template_id: "TEMPLATE_ID", use_draft_template: true}
17+
end
18+
19+
def substitution_data do
20+
%{
21+
key1: "value1",
22+
key2: "value2"
23+
}
24+
end
25+
end
26+
27+
describe "preview tests" do
28+
test_with_mock "Template.preview succeeds with Template.ContentResponse",
29+
HTTPoison, [request: fn (method, url, body, headers, opts) ->
30+
assert method == :post
31+
# draft not set
32+
assert String.ends_with?(url, "preview")
33+
fun = MockServer.mk_http_resp(200, MockServer.get_json("previewtemplate"))
34+
fun.(method, url, body, headers, opts)
35+
end] do
36+
resp = Template.preview(TestStruct.basic_template(), TestStruct.substitution_data())
37+
assert %ContentResponse{} = resp
38+
end
39+
40+
test_with_mock "Template.preview succeeds with Template.ContentResponse and draft set",
41+
HTTPoison, [request: fn (method, url, body, headers, opts) ->
42+
assert method == :post
43+
assert String.ends_with?(url, "preview?draft=true")
44+
fun = MockServer.mk_http_resp(200, MockServer.get_json("previewtemplate"))
45+
fun.(method, url, body, headers, opts)
46+
end] do
47+
resp = Template.preview(TestStruct.template_with_draft(), TestStruct.substitution_data())
48+
assert %ContentResponse{} = resp
49+
end
50+
51+
test_with_mock "Template.preview fails with Endpoint.Error", HTTPoison,
52+
[request: MockServer.mk_fail] do
53+
resp = Template.preview(TestStruct.basic_template(), TestStruct.substitution_data())
54+
assert %Endpoint.Error{} = resp
55+
end
56+
57+
test_with_mock "Template.preview unmarshals complex from field correctly", HTTPoison,
58+
[request: fn (method, url, body, headers, opts) ->
59+
assert method == :post
60+
fun = MockServer.mk_http_resp(200, MockServer.get_json("previewtemplate"))
61+
fun.(method, url, body, headers, opts)
62+
end] do
63+
resp = Template.preview(TestStruct.basic_template(), TestStruct.substitution_data())
64+
assert %SparkPost.Address{
65+
name: "Example Company Marketing",
66+
"email": "marketing@bounces.company.example"
67+
} == resp.from
68+
end
69+
70+
test_with_mock "Template.preview unmarshals simple from field correctly", HTTPoison,
71+
[request: fn (method, url, body, headers, opts) ->
72+
assert method == :post
73+
fun = MockServer.mk_http_resp(200, MockServer.get_json("previewtemplate_simpleemail"))
74+
fun.(method, url, body, headers, opts)
75+
end] do
76+
resp = Template.preview(TestStruct.basic_template(), TestStruct.substitution_data())
77+
assert %SparkPost.Address{
78+
name: nil,
79+
"email": "marketing@bounces.company.example"
80+
} == resp.from
81+
end
82+
end
83+
end

0 commit comments

Comments
 (0)