。
54 | * 必须设置.
55 | *
56 | * @param from 发件人地址
57 | * @return E
58 | */
59 | public E from(String from) {
60 | return addParameter("from", from);
61 | }
62 |
63 | /**
64 | * 发件人名称. 显示如: Support
65 | *
66 | * @param fromName 发件人名称
67 | * @return E
68 | */
69 | public E fromName(String fromName) {
70 | return addParameter("fromName", fromName);
71 | }
72 |
73 | /**
74 | * 标题. 不能为空
75 | *
76 | * @param subject 标题
77 | * @return E
78 | */
79 | public E subject(String subject) {
80 | return addParameter("subject", subject);
81 | }
82 |
83 | /**
84 | * 设置用户默认的回复邮件地址. 如果 replyTo 没有或者为空, 则默认的回复邮件地址为 from.
85 | *
86 | * @param replyTo 回复邮件地址
87 | * @return E
88 | */
89 | public E replyTo(String replyTo) {
90 | return addParameter("replyTo", replyTo);
91 | }
92 |
93 | /**
94 | * 收件人地址. 发送多个地址支持调用该方法多次或使用';'分隔, 如 denger@gmail.com;andy@gmail.com
95 | *
96 | * @param to 收件人地址
97 | * @return E
98 | */
99 | public E to(String to) {
100 | if (isNotBlank(to)) {
101 | to(to.split(";"));
102 | } else {
103 | addParameter("to", null);
104 | }
105 | return getThis();
106 | }
107 |
108 | /**
109 | * 收件人地址,批量设置。
110 | *
111 | * @param toAddrs 地址列表
112 | * @return E
113 | */
114 | public E to(String[] toAddrs) {
115 | return addParameters("to", toAddrs, ";");
116 | }
117 |
118 | protected String[] to() {
119 | return getParameters("to", ";");
120 | }
121 |
122 | /**
123 | * 本次发送所使用的标签ID. 此标签需要事先创建
124 | *
125 | * @param labelid 标签ID
126 | * @return E
127 | */
128 | public E labelId(int labelid) {
129 | return addParameter("labelId", labelid);
130 | }
131 |
132 | /**
133 | * 邮件头部信息. JSON 格式, 比如:{"header1": "value1", "header2": "value2"}
134 | *
135 | * @param headers 邮件头部信息
136 | * @return E
137 | */
138 | public E headers(String headers) {
139 | return addParameter("headers", headers);
140 | }
141 |
142 | /**
143 | * 不返回 emailId. 有多个收件人时, 会返回 emailId 的列表
144 | *
145 | * @return E
146 | */
147 | public E notRespEmailId() {
148 | return addParameter("respEmailId", false);
149 | }
150 |
151 | /**
152 | * 使用发送回执
153 | *
154 | * @return E
155 | */
156 | public E useNotification() {
157 | return addParameter("useNotification", true);
158 | }
159 |
160 | /**
161 | * 添加附件。附件名默认使用文件名
162 | *
163 | * @param attachments 附件列表
164 | * @return
165 | */
166 | public E attachments(File[] attachments) {
167 | for (File file : attachments) {
168 | addBinaryAttachment(file);
169 | }
170 | return getThis();
171 | }
172 |
173 | /**
174 | * 添加附件。附件名默认使用文件名
175 | *
176 | * @param attachment
177 | * @return
178 | */
179 | public E attachment(File attachment) {
180 | addBinaryAttachment(attachment);
181 | return getThis();
182 | }
183 |
184 | /**
185 | * 添加附件
186 | *
187 | * @param attachment 附件文件
188 | * @param name 附件名
189 | * @return E
190 | */
191 | public E attachment(File attachment, String name) {
192 | addBinaryAttachment(attachment, name);
193 | return getThis();
194 | }
195 |
196 | /**
197 | * 添加附件
198 | *
199 | * @param attachment 附件内容
200 | * @param name 附件名
201 | * @return E
202 | */
203 | public E attachment(byte[] attachment, String name) {
204 | attachments.put(name, attachment);
205 | return getThis();
206 | }
207 |
208 | /**
209 | * 获取附件列表。
210 | *
211 | * @return key: name, value: bytes
212 | */
213 | public Map attachments() {
214 | return attachments;
215 | }
216 |
217 | protected String attachmentsKey() {
218 | return "attachments";
219 | }
220 |
221 | protected boolean hasAttachment() {
222 | return attachments().size() > 0;
223 | }
224 |
225 | protected void addBinaryAttachment(File file) {
226 | addBinaryAttachment(file, file.getName());
227 | }
228 |
229 | protected void addBinaryAttachment(File file, String name) {
230 | try {
231 | if (file == null || !isNotBlank(name)) {
232 | throw new IllegalArgumentException(
233 | String.format("Attachment: [file: %s or name: %s illegal]", file, name));
234 | }
235 | attachments.put(name, IOUtils.read(file));
236 | } catch (IOException ioe) {
237 | throw new RuntimeException("Can't add attachment:" + file.getAbsolutePath(), ioe);
238 | }
239 | }
240 |
241 | protected E addParameters(String name, String[] values, String sep) {
242 | StringBuffer bufValue = new StringBuffer();
243 | if (values != null && values.length > 0) {
244 | String origValue = getParameter(name);
245 | if (isNotBlank(origValue)) {
246 | bufValue.append(origValue);
247 | }
248 | for (String value : values) {
249 | if (!isNotBlank(value)) {
250 | continue;
251 | }
252 | if (bufValue.length() > 0) bufValue.append(sep);
253 | bufValue.append(value);
254 | }
255 | }
256 | return addParameter(name, bufValue.toString());
257 | }
258 |
259 | protected E addParameter(String name, Object value) {
260 | String strValue = String.valueOf(value);
261 | if (value == null || !isNotBlank(strValue)) {
262 | parameters.remove(name);
263 | } else {
264 | parameters.put(name, String.valueOf(value));
265 | }
266 | return getThis();
267 | }
268 |
269 | protected String getParameter(String name) {
270 | return parameters.get(name);
271 | }
272 |
273 | protected String[] getParameters(String name, String sep) {
274 | String values = parameters.get(name);
275 | return isNotBlank(values) ? values.split(sep) : new String[0];
276 | }
277 |
278 | public final Map getParameters() {
279 | if (!isRewrite)
280 | rewriteParameters();
281 | isRewrite = true;
282 |
283 | return parameters;
284 | }
285 |
286 | private boolean isNotBlank(String value) {
287 | return value != null && value.trim().length() > 0;
288 | }
289 |
290 | protected void rewriteParameters() {
291 | }
292 |
293 | protected abstract E getThis();
294 |
295 | }
296 |
--------------------------------------------------------------------------------
/src/main/java/io/jstack/sendcloud4j/mail/GeneralEmail.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 | public class GeneralEmail extends Email {
4 |
5 | /**
6 | * 密送地址. 多个地址使用';'分隔
7 | *
8 | * @param bcc 密送地址
9 | * @return E
10 | */
11 | public GeneralEmail bcc(String bcc) {
12 | if (bcc != null && bcc.length() > 0) {
13 | return bcc(bcc.split(";"));
14 | } else {
15 | return addParameter("bcc", null);
16 | }
17 | }
18 |
19 | /**
20 | * 密送地址列表
21 | *
22 | * @param bccs 密送地址列表
23 | * @return E
24 | */
25 | public GeneralEmail bcc(String[] bccs) {
26 | return addParameters("bcc", bccs, ";");
27 | }
28 |
29 | /**
30 | * 抄送地址. 多个地址使用';'分隔
31 | *
32 | * @param cc 抄送地址
33 | * @return E
34 | */
35 | public GeneralEmail cc(String cc) {
36 | if (cc != null && cc.length() > 0) {
37 | cc(cc.split(";"));
38 | } else {
39 | return addParameter("cc", null);
40 | }
41 | return getThis();
42 | }
43 |
44 | /**
45 | * 抄送地址. 多个地址使用';'分隔
46 | *
47 | * @param ccs 抄送地址列表
48 | * @return E
49 | */
50 | public GeneralEmail cc(String[] ccs) {
51 | return addParameters("cc", ccs, ";");
52 | }
53 |
54 | /**
55 | * 邮件的内容. 邮件格式为 text/html
56 | *
57 | * @param html 邮件内容
58 | * @return E
59 | */
60 | public GeneralEmail html(String html) {
61 | return addParameter("html", html);
62 | }
63 |
64 | /**
65 | * 邮件的内容. 邮件格式为 text/plain
66 | *
67 | * @param plain 邮件内容
68 | * @return E
69 | */
70 | public GeneralEmail plain(String plain) {
71 | return addParameter("plain", plain);
72 | }
73 |
74 |
75 | @Override
76 | protected GeneralEmail getThis() {
77 | return this;
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/io/jstack/sendcloud4j/mail/MailWebApi.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 | import io.jstack.sendcloud4j.SendCloud;
4 | import org.apache.http.HttpEntity;
5 | import org.apache.http.HttpHost;
6 | import org.apache.http.client.fluent.Form;
7 | import org.apache.http.client.fluent.Request;
8 | import org.apache.http.entity.ContentType;
9 | import org.apache.http.entity.mime.HttpMultipartMode;
10 | import org.apache.http.entity.mime.MultipartEntityBuilder;
11 |
12 | import java.io.IOException;
13 | import java.nio.charset.Charset;
14 | import java.util.Map;
15 |
16 | /**
17 | * 邮件 API v2 实现。
18 | *
19 | * @author denger
20 | */
21 | public class MailWebApi {
22 |
23 | private SendCloud sendCloud;
24 |
25 |
26 | private static final int DEFAULT_CONNECT_TIMEOUT = 500;
27 | private static final int DEFAULT_SOCKET_TIMEOUT = 1000;
28 |
29 | private int connectTimeout;
30 | private int socketTimeout;
31 | private HttpHost proxy;
32 |
33 | private static Charset UTF_8 = Charset.forName("UTF-8");
34 |
35 | public static final ContentType TEXT_PLAIN = ContentType.create("text/plain", UTF_8);
36 |
37 |
38 | public static MailWebApi create(SendCloud sendCloud) {
39 | return new MailWebApi(sendCloud);
40 | }
41 |
42 | private MailWebApi(SendCloud sendCloud) {
43 | this.socketTimeout = DEFAULT_SOCKET_TIMEOUT;
44 | this.connectTimeout = DEFAULT_CONNECT_TIMEOUT;
45 | this.sendCloud = sendCloud;
46 | }
47 |
48 | public MailWebApi viaProxy(String proxy) {
49 | this.proxy = HttpHost.create(proxy);
50 | return this;
51 | }
52 |
53 | public MailWebApi viaProxy(HttpHost proxy) {
54 | this.proxy = proxy;
55 | return this;
56 | }
57 |
58 | public MailWebApi socketTimeout(int socketTimeout) {
59 | this.socketTimeout = socketTimeout;
60 | return this;
61 | }
62 | public MailWebApi connectTimeout(int connectTimeout) {
63 | this.connectTimeout = connectTimeout;
64 | return this;
65 | }
66 |
67 | public Result send(Email email) {
68 | try {
69 | String jsonResult = requestSend(getSendAPIURI(email), email);
70 | return new Result(jsonResult);
71 | } catch (IOException ioe) {
72 | return Result.createExceptionResult(email, ioe);
73 | }
74 | }
75 |
76 | protected String getSendAPIURI(Email email) {
77 | return String.format("%s/apiv2/mail/%s", SendCloud.API_DOMAIN,
78 | (isTemplate(email) ? "sendtemplate" : "send"));
79 | }
80 |
81 | private boolean isTemplate(Email email) {
82 | return (email instanceof TemplateEmail);
83 | }
84 |
85 | private String requestSend(String uri, Email email) throws IOException {
86 | Request request = Request.Post(uri)
87 | .connectTimeout(connectTimeout)
88 | .socketTimeout(socketTimeout);
89 | if (proxy != null) {
90 | request.viaProxy(proxy);
91 | }
92 | if (email.hasAttachment()) {
93 | request.body(getMultipartEmailHttpEntity(email));
94 | } else {
95 | request.bodyForm(convertFrom(email.getParameters()).build(), UTF_8);
96 | }
97 | return request.execute().returnContent().asString(UTF_8);
98 | }
99 |
100 | private HttpEntity getMultipartEmailHttpEntity(Email email) {
101 | MultipartEntityBuilder entityBuilder = createEntityBuilder();
102 |
103 | Map attachments = email.attachments();
104 | for (Map.Entry attachment : attachments.entrySet()) {
105 | entityBuilder.addBinaryBody(email.attachmentsKey(), attachment.getValue(),
106 | ContentType.MULTIPART_FORM_DATA, attachment.getKey());
107 | }
108 | addParametersToTextBody(entityBuilder, email.getParameters());
109 |
110 | return entityBuilder.build();
111 | }
112 |
113 | public MultipartEntityBuilder createEntityBuilder() {
114 | return MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE).setCharset(UTF_8);
115 | }
116 |
117 | private void addParametersToTextBody(MultipartEntityBuilder entityBuilder, Map parameters) {
118 | for (Map.Entry param : parameters.entrySet()) {
119 | entityBuilder.addTextBody(param.getKey(), param.getValue(), TEXT_PLAIN);
120 | }
121 | entityBuilder.addTextBody("apiUser", sendCloud.apiUser(), TEXT_PLAIN);
122 | entityBuilder.addTextBody("apiKey", sendCloud.apiKey(), TEXT_PLAIN);
123 | }
124 |
125 | private Form convertFrom(Map parameters) {
126 | Form form = Form.form();
127 | for (Map.Entry param : parameters.entrySet()) {
128 | form.add(param.getKey(), param.getValue());
129 | }
130 | form.add("apiUser", sendCloud.apiUser());
131 | form.add("apiKey", sendCloud.apiKey());
132 |
133 | return form;
134 | }
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/src/main/java/io/jstack/sendcloud4j/mail/Result.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 | import org.apache.http.conn.ConnectTimeoutException;
4 | import org.json.JSONObject;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.net.SocketTimeoutException;
9 |
10 | public class Result {
11 | private static Logger logger = LoggerFactory.getLogger(Result.class);
12 |
13 | private boolean success = false;
14 | private int statusCode;
15 | private String message;
16 |
17 | private String responseText;
18 |
19 | // fixme: 针对内部错误的处理方式待改进
20 | private static final int IO_EXCEPTION_CODE = 500;
21 | private static final int SOCKET_EXCEPTION_CODE = 501;
22 | private static final int CONNECT_EXCEPTION_CODE = 502;
23 |
24 | protected Result(String responseText) {
25 | this.responseText = responseText;
26 | parserResponseText(responseText);
27 | }
28 |
29 | protected static Result createExceptionResult(Email email, Throwable throwable) {
30 | logger.error("Send mail fail, request params: {}", email.getParameters(), throwable);
31 | return new Result(false, getIOErrorCode(throwable), throwable.getMessage());
32 | }
33 |
34 | private static int getIOErrorCode(Throwable throwable) {
35 | if (throwable instanceof SocketTimeoutException) {
36 | return SOCKET_EXCEPTION_CODE;
37 | } else if (throwable instanceof ConnectTimeoutException) {
38 | return CONNECT_EXCEPTION_CODE;
39 | }
40 | return IO_EXCEPTION_CODE;
41 | }
42 |
43 | protected Result(boolean success, int statusCode, String message) {
44 | this.success = success;
45 | this.statusCode = statusCode;
46 | this.message = message;
47 | }
48 |
49 | protected void parserResponseText(String responseJson) {
50 | JSONObject jsonObject = new JSONObject(responseJson);
51 | if (jsonObject.has("result")) {
52 | this.success = jsonObject.getBoolean("result");
53 | }
54 | if (jsonObject.has("message")) {
55 | this.message = jsonObject.getString("message");
56 | }
57 | if (jsonObject.has("statusCode")) {
58 | this.statusCode = jsonObject.getInt("statusCode");
59 | }
60 | }
61 |
62 | public int getStatusCode() {
63 | return statusCode;
64 | }
65 |
66 | public boolean isSuccess() {
67 | return success;
68 | }
69 |
70 | public String getMessage() {
71 | return message;
72 | }
73 |
74 | @Override
75 | public String toString() {
76 | return this.responseText;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/io/jstack/sendcloud4j/mail/Substitution.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 |
4 | import java.util.ArrayList;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | /**
10 | * 模块变量定义。
11 | *
12 | * @author denger
13 | */
14 | public class Substitution {
15 |
16 | public static Sub sub() {
17 | return new Sub();
18 | }
19 |
20 | public static SubGroup subGroup() {
21 | return new SubGroup();
22 | }
23 |
24 | public static class Sub {
25 |
26 | private Map sub = new HashMap();
27 |
28 | public Sub set(String name, String value) {
29 | String subName = "%" + name + "%";
30 | sub.put(subName, value);
31 | return this;
32 | }
33 |
34 | public String get(String name) {
35 | return sub.get("%" + name + "%");
36 | }
37 |
38 | protected Map get() {
39 | return sub;
40 | }
41 |
42 | private List getList(String value) {
43 | List vars = new ArrayList(1);
44 |
45 | vars.add(value);
46 | return vars;
47 | }
48 | }
49 |
50 | public static class SubGroup {
51 | private Map> subsMap = new HashMap>();
52 |
53 | private List subs = new ArrayList();
54 |
55 | protected List getSubs() {
56 | return subs;
57 | }
58 |
59 | public SubGroup add(Sub sub) {
60 | subs.add(sub);
61 |
62 | Map vars = sub.get();
63 | for (Map.Entry var : vars.entrySet()) {
64 | String subName = var.getKey();
65 |
66 | List values = subsMap.get(subName);
67 | if (values == null) {
68 | values = new ArrayList();
69 | }
70 | values.add(var.getValue());
71 |
72 | subsMap.put(subName, values);
73 | }
74 | return this;
75 | }
76 |
77 | public Map> toSubsMap() {
78 | return this.subsMap;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/io/jstack/sendcloud4j/mail/TemplateEmail.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 |
4 | import org.json.JSONObject;
5 |
6 | import java.util.ArrayList;
7 | import java.util.Arrays;
8 | import java.util.List;
9 |
10 | public class TemplateEmail extends Email {
11 |
12 | private boolean useAddressList = false;
13 |
14 | private Substitution.SubGroup subGroup;
15 |
16 | public TemplateEmail(String template) {
17 | addParameter("templateInvokeName", template);
18 | }
19 |
20 | public TemplateEmail substitutionVars(Substitution.Sub sub) {
21 | this.subGroup = Substitution.subGroup().add(sub);
22 | return getThis();
23 | }
24 |
25 | public TemplateEmail substitutionVars(Substitution.SubGroup subGroup) {
26 | this.subGroup = subGroup;
27 | return getThis();
28 | }
29 |
30 | public TemplateEmail useAddressList() {
31 | useAddressList = true;
32 | return addParameter("useAddressList", String.valueOf(useAddressList));
33 | }
34 |
35 | @Override
36 | protected TemplateEmail getThis() {
37 | return this;
38 | }
39 |
40 | @Override
41 | protected void rewriteParameters() {
42 | JSONObject ret = new JSONObject();
43 | if (subGroup == null) {
44 | subGroup = Substitution.subGroup();
45 | }
46 | ret.put("sub", subGroup.toSubsMap());
47 | List toAddrs = new ArrayList();
48 |
49 | if (!useAddressList) {
50 | toAddrs.addAll(Arrays.asList(to()));
51 | // 去除 to 参数
52 | to("");
53 | ret.put("to", toAddrs);
54 | addParameter("xsmtpapi", ret.toString());
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/io/jstack/sendcloud4j/util/IOUtils.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.util;
2 |
3 |
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 |
9 | public class IOUtils {
10 |
11 | public static byte[] read(File file) throws IOException {
12 | if (!file.isFile() || !file.exists()) {
13 | throw new IOException(file.getAbsolutePath() + " is not file or not exists!");
14 | }
15 |
16 | byte[] buffer = new byte[(int) file.length()];
17 | InputStream ios = null;
18 | try {
19 | ios = new FileInputStream(file);
20 | if (ios.read(buffer) == -1) {
21 | throw new IOException(
22 | "EOF reached while trying to read the whole file");
23 | }
24 | } finally {
25 | try {
26 | if (ios != null)
27 | ios.close();
28 | } catch (IOException e) {
29 | }
30 | }
31 | return buffer;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/java/io/jstack/sendcloud4j/mail/EmailTest.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 |
4 | import org.junit.Test;
5 |
6 | import java.io.File;
7 | import java.util.Map;
8 |
9 | import static org.junit.Assert.*;
10 |
11 | public class EmailTest {
12 |
13 | private Email email = new MockTestEmail();
14 |
15 | @Test
16 | public void testAddAndGetParameter() {
17 | String from = "jack@jstack.io";
18 | email.addParameter("from", from);
19 |
20 | assertEquals(email.getParameter("from"), from);
21 | assertEquals(email.getParameters().size(), 1);
22 | assertEquals(email.getParameters().get("from"), from);
23 | }
24 |
25 | @Test
26 | public void testMultipleRecipients() {
27 | email.to("denger@jstack.io");
28 | email.to("jack@jstack.io");
29 | email.to("andy@jstack.io");
30 | email.to("support@jstack.io");
31 | email.to("rak@jstack.io;hello@jstack.io");
32 |
33 | assertEquals(email.to().length, 6);
34 | }
35 |
36 | @Test
37 | public void testRemoveParameterIfSetValueEmptyOrNull() {
38 | email.from("denger@stack.io");
39 | email.from(null);
40 | assertNull(email.getParameter("from"));
41 |
42 | email.to("denger@jstack.io");
43 | email.to("");
44 | assertEquals(email.to().length, 0);
45 | }
46 |
47 | @Test
48 | public void testRewriteParameterWhenGetParameters() {
49 | email.addParameter("test", "hello");
50 | assertEquals(email.getParameters().get("test"), "hello world");
51 | }
52 |
53 | @Test
54 | public void testAddFileAttachments() {
55 | email.attachments(new File[]{new File("src/test/resouces/3byte_test.txt")});
56 | Map attachments = email.attachments();
57 |
58 | assertTrue(email.hasAttachment());
59 | assertEquals(attachments.size(), 1);
60 | assertTrue(attachments.containsKey("3byte_test.txt"));
61 | assertEquals(attachments.get("3byte_test.txt").length, 3);
62 | }
63 |
64 | @Test
65 | public void testAddBytesAttachments() {
66 | email.attachment(new byte[]{1,1}, "filename");
67 | Map attachments = email.attachments();
68 |
69 | assertTrue(email.hasAttachment());
70 | assertEquals(attachments.size(), 1);
71 | assertEquals(attachments.get("filename").length, 2);
72 | }
73 |
74 | class MockTestEmail extends Email {
75 |
76 | @Override
77 | protected MockTestEmail getThis() {
78 | return this;
79 | }
80 |
81 | @Override
82 | protected void rewriteParameters() {
83 | if (getParameter("test") != null) {
84 | addParameter("test", getParameter("test") + " world");
85 | }
86 | }
87 | }
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/src/test/java/io/jstack/sendcloud4j/mail/GeneralEmailTest.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class GeneralEmailTest {
8 |
9 | @Test
10 | public void testAddBccParameter() {
11 | GeneralEmail generalEmail = new GeneralEmail();
12 |
13 | generalEmail.bcc("jstack@jstack.io");
14 | generalEmail.bcc("denger@jstack.io;tc@jstack.io");
15 |
16 | assertEquals(generalEmail.getParameter("bcc"), "jstack@jstack.io;denger@jstack.io;tc@jstack.io");
17 | }
18 |
19 | @Test
20 | public void testAddCcParameter() {
21 | GeneralEmail generalEmail = new GeneralEmail();
22 |
23 | generalEmail.cc("jstack@jstack.io");
24 | generalEmail.cc("denger@jstack.io;tc@jstack.io");
25 |
26 | assertEquals(generalEmail.getParameter("cc"), "jstack@jstack.io;denger@jstack.io;tc@jstack.io");
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/test/java/io/jstack/sendcloud4j/mail/MailWebApiTest.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 | import io.jstack.sendcloud4j.SendCloud;
4 | import org.junit.Test;
5 |
6 | import static org.junit.Assert.assertEquals;
7 |
8 | public class MailWebApiTest {
9 |
10 | private String apiUser = "testApiUser";
11 | private String apiKey = "testApiKey";
12 |
13 | SendCloud sendCloud = SendCloud.createWebApi(apiUser, apiKey);
14 |
15 | @Test
16 | public void testGetSendTemplateAPIURI() {
17 | String uri = sendCloud.mail().getSendAPIURI(new TemplateEmail("tmmp"));
18 | assertEquals(uri, SendCloud.API_DOMAIN + "/apiv2/mail/sendtemplate");
19 | }
20 |
21 | @Test
22 | public void testGetSendAPIURI() {
23 | String uri = sendCloud.mail().getSendAPIURI(new GeneralEmail());
24 | assertEquals(uri, SendCloud.API_DOMAIN + "/apiv2/mail/send");
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/java/io/jstack/sendcloud4j/mail/ResultTest.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 | import org.apache.http.conn.ConnectTimeoutException;
4 | import org.junit.Test;
5 |
6 | import java.net.SocketTimeoutException;
7 |
8 | import static org.junit.Assert.*;
9 |
10 | public class ResultTest {
11 | private static String SUCCESS_MSG = "{\"result\":true,\"statusCode\":200,\"message\":\"请求成功\",\"info\":{\"emailIdList\":[\"xxxxx@s\"]}}";
12 |
13 | private static String BLANK_ERROR_MSG = "{\"result\":false,\"statusCode\":40863,\"message\":\"to中有不存在的地址列表. \",\"info\":{\"emailIdList\":[\"xxxxx@s\"]}}";
14 |
15 | private static String BLANK_MSG = "{}";
16 |
17 | @Test
18 | public void testFromSuccess() {
19 | Result result = new Result(SUCCESS_MSG);
20 |
21 | assertTrue(result.isSuccess());
22 | assertEquals(result.getStatusCode(), 200);
23 | assertEquals(result.getMessage(), "请求成功");
24 | }
25 |
26 | @Test
27 | public void testFromFail() {
28 | Result result = new Result(BLANK_ERROR_MSG);
29 | assertFalse(result.isSuccess());
30 | assertEquals(result.getStatusCode(), 40863);
31 | assertEquals(result.getMessage(), "to中有不存在的地址列表. ");
32 | }
33 |
34 | @Test
35 | public void testFromException() {
36 | Result result = Result.createExceptionResult(new GeneralEmail(), new NullPointerException("Nullexception"));
37 |
38 | assertFalse(result.isSuccess());
39 | assertEquals(result.getStatusCode(), 500);
40 | assertEquals(result.getMessage(), "Nullexception");
41 | }
42 |
43 | @Test
44 | public void testIOException() {
45 | Result result = Result.createExceptionResult(new GeneralEmail(), new SocketTimeoutException());
46 |
47 | assertFalse(result.isSuccess());
48 | assertEquals(result.getStatusCode(), 501);
49 |
50 | result = Result.createExceptionResult(new GeneralEmail(), new ConnectTimeoutException());
51 |
52 | assertFalse(result.isSuccess());
53 | assertEquals(result.getStatusCode(), 502);
54 | }
55 |
56 | @Test
57 | public void testFromBlankJson() {
58 | Result result = new Result(BLANK_MSG);
59 | assertFalse(result.isSuccess());
60 | assertEquals(result.getStatusCode(), 0);
61 | assertEquals(result.getMessage(), null);
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/test/java/io/jstack/sendcloud4j/mail/SubstitutionTest.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | public class SubstitutionTest {
8 |
9 | String varName = "name";
10 | String varAge = "age";
11 |
12 | @Test
13 | public void testSingleSub() {
14 | Substitution.Sub sub = Substitution.sub()
15 | .set(varName, "jack")
16 | .set(varAge, "19");
17 |
18 | assertEquals(sub.get(varName), "jack");
19 | assertEquals(sub.get(varAge), "19");
20 | }
21 |
22 | @Test
23 | public void testSubGroups() {
24 | Substitution.Sub subJack = Substitution.sub()
25 | .set(varName, "jack")
26 | .set(varAge, "18");
27 | Substitution.Sub subDenger = Substitution.sub()
28 | .set(varName, "denger")
29 | .set(varAge, "25");
30 |
31 | Substitution.SubGroup subGroups = Substitution.subGroup()
32 | .add(subJack)
33 | .add(subDenger);
34 |
35 | assertEquals(subGroups.toSubsMap()
36 | .get("%" + varName + "%")
37 | .get(0), subJack.get(varName));
38 | assertEquals(subGroups.toSubsMap()
39 | .get("%" + varName + "%")
40 | .get(1), subDenger.get(varName));
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/test/java/io/jstack/sendcloud4j/mail/TemplateEmailTest.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.mail;
2 |
3 |
4 | import org.junit.Test;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.util.Map;
9 |
10 | import static org.junit.Assert.assertEquals;
11 | import static org.junit.Assert.assertTrue;
12 |
13 | public class TemplateEmailTest {
14 | Logger logger = LoggerFactory.getLogger(TemplateEmailTest.class);
15 |
16 | private static final String NOT_USE_ADD_XSMTPAPI = "\"to\":[\"denger.it@gmail.com\"]";
17 |
18 | @Test
19 | public void testRewriteParametersWhenNotUseAddressList() {
20 | TemplateEmail templateEmail = new TemplateEmail("test_tmp")
21 | .to("denger.it@gmail.com")
22 | .substitutionVars(Substitution.sub().set("name", "Jack"));
23 |
24 | Map params = templateEmail.getParameters();
25 | logger.info("Not use address list: {}", params);
26 |
27 | assertEquals(params.get("to"), null);
28 | assertTrue(params.get("xsmtpapi").contains(NOT_USE_ADD_XSMTPAPI));
29 | }
30 |
31 | @Test
32 | public void testRewriteParametersWhenUseAddressList() {
33 | TemplateEmail templateEmail = new TemplateEmail("test_tmp")
34 | .to("denger.it@gmail.com")
35 | .useAddressList()
36 | .substitutionVars(Substitution.sub().set("name", "Jack"));
37 |
38 | Map params = templateEmail.getParameters();
39 | logger.info("used address list: {}", params);
40 |
41 | assertEquals(params.get("to"), "denger.it@gmail.com");
42 | assertEquals(params.get("xsmtpapi"), null);
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/io/jstack/sendcloud4j/util/IOUtilsTest.java:
--------------------------------------------------------------------------------
1 | package io.jstack.sendcloud4j.util;
2 |
3 |
4 | import org.junit.Test;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 |
9 | import static org.junit.Assert.*;
10 |
11 | public class IOUtilsTest {
12 |
13 | @Test
14 | public void testReadExistsFile() {
15 | byte[] bt = null;
16 | try {
17 | bt = IOUtils.read(new File("src/test/resouces/3byte_test.txt"));
18 | } catch (IOException ioe) {
19 | fail(ioe.getMessage());
20 | }
21 | assertNotNull(bt);
22 | assertEquals(bt.length, 3);
23 | }
24 |
25 | @Test(expected = IOException.class)
26 | public void testReadNotExistsFileThrowException() throws IOException {
27 | IOUtils.read(new File("src/test/resouces/not_exists_file.txt"));
28 | }
29 |
30 | @Test(expected = IOException.class)
31 | public void testReadEmptyFileThrowException() throws IOException {
32 | IOUtils.read(new File("src/test/resouces/empty.txt"));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/resouces/3byte_test.txt:
--------------------------------------------------------------------------------
1 | abc
--------------------------------------------------------------------------------
/src/test/resouces/empty_test.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/denger/sendcloud4j/4f09383bb2f941d29c1222af217c824926097e4d/src/test/resouces/empty_test.txt
--------------------------------------------------------------------------------
/src/test/resouces/log4j.properties:
--------------------------------------------------------------------------------
1 | # Root logger option
2 | log4j.rootLogger=DEBUG, stdout
3 |
4 | # Direct log messages to stdout
5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
6 | log4j.appender.stdout.Target=System.out
7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
9 |
10 |
--------------------------------------------------------------------------------