feat: add more tests
This commit is contained in:
		
							
								
								
									
										323
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,323 @@
 | 
				
			|||||||
 | 
					# Contributing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Thanks so much for wanting to help! We really appreciate it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Have an idea for a new feature?
 | 
				
			||||||
 | 
					* Want to add a new built-in theme?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Excellent! You've come to the right place.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. If you find a bug or wish to suggest a new feature, please create an issue first
 | 
				
			||||||
 | 
					2. Make sure your code & comment conventions are in-line with the project's style (execute gometalinter as in [.travis.yml](.travis.yml) file)
 | 
				
			||||||
 | 
					3. Make your commits and PRs as tiny as possible - one feature or bugfix at a time
 | 
				
			||||||
 | 
					4. Write detailed commit messages, in-line with the project's commit naming conventions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Theming Instructions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This file contains instructions on adding themes to Mailgen:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [Using a Custom Theme](#using-a-custom-theme)
 | 
				
			||||||
 | 
					* [Creating a Built-In Theme](#creating-a-built-in-theme)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> We use Golang templates under the hood to inject the e-mail body into themes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Using a Custom Theme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to supply your own **custom theme** for Hermes to use (but don't want it included with Mailgen):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Create a new struct implementing `Theme` interface ([hermes.go](hermes.go)). An real-life example is in [default.go](default.go)
 | 
				
			||||||
 | 
					2. Supply your new theme at hermes creation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type MyCustomTheme struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (dt *MyCustomTheme) Name() string {
 | 
				
			||||||
 | 
						return "mycustomthem"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (dt *MyCustomTheme) HTMLTemplate() string {
 | 
				
			||||||
 | 
					    // Get the template from a file (if you want to be able to change the template live without retstarting your application)
 | 
				
			||||||
 | 
					    // Or write the template by returning pure string here (if you want embbeded template and do not bother with external dependencies)
 | 
				
			||||||
 | 
					    return "<A go html template with wanted information>" 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (dt *Default) PlainTextTemplate() string {
 | 
				
			||||||
 | 
					    // Get the template from a file (if you want to be able to change the template live without retstarting your application)
 | 
				
			||||||
 | 
					    // Or write the template by returning pure string here (if you want embbeded template and do not bother with external dependencies)
 | 
				
			||||||
 | 
					    return "<A go plaintext template with wanter information>"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					h := hermes.Hermes{
 | 
				
			||||||
 | 
					    Theme: new(MyCustomTheme) // Set your fresh new theme here
 | 
				
			||||||
 | 
					    Product: hermes.Product{
 | 
				
			||||||
 | 
					        Name: "Hermes",
 | 
				
			||||||
 | 
					        Link: "https://example-hermes.com/",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ...
 | 
				
			||||||
 | 
					// Continue with the rest as usual, create your email and generate the content.
 | 
				
			||||||
 | 
					// ...
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. That's it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Creating a Built-In Theme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to create a new **built-in** Mailgen theme:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Fork the repository to your GitHub account and clone it to your computer
 | 
				
			||||||
 | 
					2. Create a new Go file named after your new theme
 | 
				
			||||||
 | 
					3. Copy content of [default.go](default.go) file in new file and make any necessary changes
 | 
				
			||||||
 | 
					6. Scroll down to the [injection snippets](#injection-snippets) and copy and paste each code snippet into the relevant area of your template markup
 | 
				
			||||||
 | 
					7. Test the theme by running the `examples/*.js` scripts (insert your theme name in each script) and observing the template output in `preview.html`
 | 
				
			||||||
 | 
					8. Take a screenshot of your theme portraying each example and place it in `screenshots/{theme}/{example}.png`
 | 
				
			||||||
 | 
					9. Add the theme name, credit, and screenshots to the `README.md` file's [Supported Themes](README.md#supported-themes) section (copy one of the existing themes' markup and modify it accordingly)
 | 
				
			||||||
 | 
					7. Submit a pull request with your changes and we'll let you know if anything's missing!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Thanks again for your contribution!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Injection Snippets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Product Branding Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following will inject either the product logo or name into the template.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<a href="<%- product.link %>" target="_blank">
 | 
				
			||||||
 | 
					    <% if (locals.product.logo) { %>
 | 
				
			||||||
 | 
					        <img src="<%- product.logo %>" class="email-logo" />
 | 
				
			||||||
 | 
					    <% } else { %>
 | 
				
			||||||
 | 
					        <%- product.name %>
 | 
				
			||||||
 | 
					    <% } %>
 | 
				
			||||||
 | 
					</a>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It's a good idea to add the following CSS declaration to set `max-height: 50px` for the logo:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```css
 | 
				
			||||||
 | 
					.email-logo {
 | 
				
			||||||
 | 
					    max-height: 50px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Title Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following will inject the e-mail title (Hi John Appleseed,) or a custom title provided by the user:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<%- title %>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Intro Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following will inject the intro text (string or array) into the e-mail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<% if (locals.intro) { %>
 | 
				
			||||||
 | 
					    <% intro.forEach(function (introItem) { -%>
 | 
				
			||||||
 | 
					        <p><%- introItem %></p>
 | 
				
			||||||
 | 
					    <% }) -%>
 | 
				
			||||||
 | 
					<% } %>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Dictionary Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following will inject a `<dl>` of key-value pairs into the e-mail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<!-- Dictionary -->
 | 
				
			||||||
 | 
					<% if (locals.dictionary) { %>
 | 
				
			||||||
 | 
					    <dl class="dictionary">
 | 
				
			||||||
 | 
					    <% for (item in dictionary) { -%>
 | 
				
			||||||
 | 
					        <dt><%- item.charAt(0).toUpperCase() + item.slice(1) %>:</dt>
 | 
				
			||||||
 | 
					        <dd><%- dictionary[item] %></dd>
 | 
				
			||||||
 | 
					    <% } -%>
 | 
				
			||||||
 | 
					    </dl>
 | 
				
			||||||
 | 
					<% } %>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It's a good idea to add this to the top of the template to improve the styling of the dictionary:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```css
 | 
				
			||||||
 | 
					/* Dictionary */
 | 
				
			||||||
 | 
					.dictionary {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    margin: 0 auto;
 | 
				
			||||||
 | 
					    padding: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.dictionary dt {
 | 
				
			||||||
 | 
					    clear: both;
 | 
				
			||||||
 | 
					    color: #000;
 | 
				
			||||||
 | 
					    font-weight: bold;
 | 
				
			||||||
 | 
					    margin-right: 4px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.dictionary dd {
 | 
				
			||||||
 | 
					    margin: 0 0 10px 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Table Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following will inject the table into the e-mail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<!-- Table -->
 | 
				
			||||||
 | 
					<% if (locals.table) { %>
 | 
				
			||||||
 | 
					<table class="data-table" width="100%" cellpadding="0" cellspacing="0">
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <% for (var column in table.data[0]) {%>
 | 
				
			||||||
 | 
					        <th
 | 
				
			||||||
 | 
					            <% if(locals.table.columns && locals.table.columns.customWidth && locals.table.columns.customWidth[column]) { %>
 | 
				
			||||||
 | 
					                width="<%= table.columns.customWidth[column] %>"
 | 
				
			||||||
 | 
					            <% } %>
 | 
				
			||||||
 | 
					            <% if(locals.table.columns && locals.table.columns.customAlignment && locals.table.columns.customAlignment[column]) { %>
 | 
				
			||||||
 | 
					                style="text-align:<%= table.columns.customAlignment[column] %>"
 | 
				
			||||||
 | 
					            <% } %>
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <p><%- column.charAt(0).toUpperCase() + column.slice(1) %></p>
 | 
				
			||||||
 | 
					        </th>
 | 
				
			||||||
 | 
					        <% } %>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <% for (var i in table.data) {%>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <% for (var column in table.data[i]) {%>
 | 
				
			||||||
 | 
					        <td
 | 
				
			||||||
 | 
					            <% if(locals.table.columns && locals.table.columns.customAlignment && locals.table.columns.customAlignment[column]) { %>
 | 
				
			||||||
 | 
					                style="text-align:<%= table.columns.customAlignment[column] %>"
 | 
				
			||||||
 | 
					            <% } %>
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <%- table.data[i][column] %>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					        <% } %>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <% } %>
 | 
				
			||||||
 | 
					</table>
 | 
				
			||||||
 | 
					<% } %>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It's a good idea to add this to the top of the template to improve the styling of the table:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```css
 | 
				
			||||||
 | 
					/* Table */
 | 
				
			||||||
 | 
					.data-wrapper {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					    padding: 35px 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.data-table {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.data-table th {
 | 
				
			||||||
 | 
					    text-align: left;
 | 
				
			||||||
 | 
					    padding: 0px 5px;
 | 
				
			||||||
 | 
					    padding-bottom: 8px;
 | 
				
			||||||
 | 
					    border-bottom: 1px solid #DEDEDE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.data-table th p {
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					    font-size: 12px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.data-table td {
 | 
				
			||||||
 | 
					    text-align: left;
 | 
				
			||||||
 | 
					    padding: 10px 5px;
 | 
				
			||||||
 | 
					    font-size: 15px;
 | 
				
			||||||
 | 
					    line-height: 18px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Action Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following will inject the action link (or button) into the e-mail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<!-- Action -->
 | 
				
			||||||
 | 
					<% if (locals.action) { %>
 | 
				
			||||||
 | 
					    <% action.forEach(function (actionItem) { -%>
 | 
				
			||||||
 | 
					        <p><%- actionItem.instructions %></p>
 | 
				
			||||||
 | 
					        <a href="<%- actionItem.button.link %>" style="color:<%- actionItem.button.color %>" target="_blank">
 | 
				
			||||||
 | 
					            <%- actionItem.button.text %>
 | 
				
			||||||
 | 
					        </a>
 | 
				
			||||||
 | 
					    <% }) -%>
 | 
				
			||||||
 | 
					<% } %>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It's a good idea to add this to the top of the template to specify a fallback color for the action buttons in case it wasn't provided by the user:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<%
 | 
				
			||||||
 | 
					if (locals.action) {
 | 
				
			||||||
 | 
					    // Make it possible to override action button color (specify fallback color if no color specified)
 | 
				
			||||||
 | 
					    locals.action.forEach(function(actionItem) {
 | 
				
			||||||
 | 
					        if (!actionItem.button.color) {
 | 
				
			||||||
 | 
					            actionItem.button.color = '#48CFAD';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					%>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Outro Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following will inject the outro text (string or array) into the e-mail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<% if (locals.outro) { %>
 | 
				
			||||||
 | 
					    <% outro.forEach(function (outroItem) { -%>
 | 
				
			||||||
 | 
					        <p><%- outroItem %></p>
 | 
				
			||||||
 | 
					    <% }) -%>
 | 
				
			||||||
 | 
					<% } %>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Signature Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following will inject the signature phrase (e.g. Yours truly) along with the product name into the e-mail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<%- signature %>,
 | 
				
			||||||
 | 
					<br />
 | 
				
			||||||
 | 
					<%- product.name %>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Copyright Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following will inject the copyright notice into the e-mail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<%- product.copyright %>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Go-To Action Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In order to support Gmail's [Go-To Actions](https://developers.google.com/gmail/markup/reference/go-to-action), add the following anywhere within the template:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<!-- Support for Gmail Go-To Actions -->
 | 
				
			||||||
 | 
					<% if (locals.goToAction) { %>
 | 
				
			||||||
 | 
					    <script type="application/ld+json">
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "@context": "http://schema.org",
 | 
				
			||||||
 | 
					        "@type": "EmailMessage",
 | 
				
			||||||
 | 
					        "potentialAction": {
 | 
				
			||||||
 | 
					            "@type": "ViewAction",
 | 
				
			||||||
 | 
					            "url": "<%- goToAction.link %>",
 | 
				
			||||||
 | 
					            "target": "<%- goToAction.link %>",
 | 
				
			||||||
 | 
					            "name": "<%- goToAction.text %>"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "description": "<%- goToAction.description %>"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    </script>
 | 
				
			||||||
 | 
					<% } %>
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Text Direction Injection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In order to support generating RTL e-mails, inject the `textDirection` variable into the `<body>` tag:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```html
 | 
				
			||||||
 | 
					<body dir="<%- textDirection %>">
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								README.md
									
									
									
									
									
								
							@ -2,6 +2,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[](https://travis-ci.org/matcornic/hermes)
 | 
					[](https://travis-ci.org/matcornic/hermes)
 | 
				
			||||||
[](https://goreportcard.com/report/github.com/matcornic/hermes)
 | 
					[](https://goreportcard.com/report/github.com/matcornic/hermes)
 | 
				
			||||||
 | 
					[](http://gocover.io/github.com/matcornic/hermes/)
 | 
				
			||||||
 | 
					[](https://godoc.org/github.com/matcornic/hermes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Hermes is the Go port of the great [mailgen](https://github.com/eladnava/mailgen) engine for Node.js. Check their work, it's awesome !
 | 
					Hermes is the Go port of the great [mailgen](https://github.com/eladnava/mailgen) engine for Node.js. Check their work, it's awesome !
 | 
				
			||||||
It's a package that generates clean, responsive HTML e-mails for sending transactional e-mails (welcome e-mail, reset password e-mails, receipt e-mails and so on).
 | 
					It's a package that generates clean, responsive HTML e-mails for sending transactional e-mails (welcome e-mail, reset password e-mails, receipt e-mails and so on).
 | 
				
			||||||
@ -257,17 +259,7 @@ email := hermes.Email{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Contributing
 | 
					## Contributing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Thanks so much for wanting to help! We really appreciate it.
 | 
					See [CONTRIBUTING.md](CONTRIBUTING.md)
 | 
				
			||||||
 | 
					 | 
				
			||||||
* Have an idea for a new feature?
 | 
					 | 
				
			||||||
* Want to add a new built-in theme?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Excellent! You've come to the right place.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. If you find a bug or wish to suggest a new feature, please create an issue first
 | 
					 | 
				
			||||||
2. Make sure your code & comment conventions are in-line with the project's style
 | 
					 | 
				
			||||||
3. Make your commits and PRs as tiny as possible - one feature or bugfix at a time
 | 
					 | 
				
			||||||
4. Write detailed commit messages, in-line with the project's commit naming conventions
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
## License
 | 
					## License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -379,7 +379,7 @@ func (dt *Default) HTMLTemplate() string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// PlainTextTemplate returns a Golang template that will generate an plain text email.
 | 
					// PlainTextTemplate returns a Golang template that will generate an plain text email.
 | 
				
			||||||
func (dt *Default) PlainTextTemplate() string {
 | 
					func (dt *Default) PlainTextTemplate() string {
 | 
				
			||||||
	return `{{.Email.Body.Greeting}} {{.Email.Body.Name}},
 | 
						return `{{if .Email.Body.Title }}{{ .Email.Body.Title }}{{ else }}{{ .Email.Body.Greeting }} {{ .Email.Body.Name }},{{ end }},
 | 
				
			||||||
{{ with .Email.Body.Intros }}{{ range $line := . }}{{ $line }}{{ end }}{{ end }}
 | 
					{{ with .Email.Body.Intros }}{{ range $line := . }}{{ $line }}{{ end }}{{ end }}
 | 
				
			||||||
{{ with .Email.Body.Dictionary }}{{ range $entry := . }}
 | 
					{{ with .Email.Body.Dictionary }}{{ range $entry := . }}
 | 
				
			||||||
{{ $entry.Key }}: {{ $entry.Value }}{{ end }}{{ end }}
 | 
					{{ $entry.Key }}: {{ $entry.Value }}{{ end }}{{ end }}
 | 
				
			||||||
@ -390,7 +390,7 @@ func (dt *Default) PlainTextTemplate() string {
 | 
				
			|||||||
{{ $line }}{{ end }}{{ end }}
 | 
					{{ $line }}{{ end }}{{ end }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{.Email.Body.Signature}},
 | 
					{{.Email.Body.Signature}},
 | 
				
			||||||
{{.Hermes.Product.Name}}
 | 
					{{.Hermes.Product.Name}} - {{.Hermes.Product.Link}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{.Hermes.Product.Copyright}}
 | 
					{{.Hermes.Product.Copyright}}
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										272
									
								
								hermes_test.go
									
									
									
									
									
								
							
							
						
						
									
										272
									
								
								hermes_test.go
									
									
									
									
									
								
							@ -5,13 +5,42 @@ import (
 | 
				
			|||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestHermes_ok(t *testing.T) {
 | 
					var testedThemes = []Theme{
 | 
				
			||||||
 | 
						// Insert your new theme here
 | 
				
			||||||
 | 
						new(Default),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Every theme should display the same information //
 | 
				
			||||||
 | 
					// Find below the tests to check that              //
 | 
				
			||||||
 | 
					/////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Implement this interface when creating a new example checking a common feature of all themes
 | 
				
			||||||
 | 
					type Example interface {
 | 
				
			||||||
 | 
						// Create the hermes example with data
 | 
				
			||||||
 | 
						// Represents the "Given" step in Given/When/Then Workflow
 | 
				
			||||||
 | 
						getExample() (h Hermes, email Email)
 | 
				
			||||||
 | 
						// Checks the content of the generated HTML email by asserting content presence or not
 | 
				
			||||||
 | 
						assertHTMLContent(t *testing.T, s string)
 | 
				
			||||||
 | 
						// Checks the content of the generated Plaintext email by asserting content presence or not
 | 
				
			||||||
 | 
						assertPlainTextContent(t *testing.T, s string)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Scenario
 | 
				
			||||||
 | 
					type SimpleExample struct {
 | 
				
			||||||
 | 
						theme Theme
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *SimpleExample) getExample() (Hermes, Email) {
 | 
				
			||||||
	h := Hermes{
 | 
						h := Hermes{
 | 
				
			||||||
 | 
							Theme: ed.theme,
 | 
				
			||||||
		Product: Product{
 | 
							Product: Product{
 | 
				
			||||||
			Name: "Hermes",
 | 
								Name:      "HermesName",
 | 
				
			||||||
			Link: "http://hermes.com",
 | 
								Link:      "http://hermes-link.com",
 | 
				
			||||||
 | 
								Copyright: "Copyright © Hermes-Test",
 | 
				
			||||||
 | 
								Logo:      "http://www.duchess-france.org/wp-content/uploads/2016/01/gopher.png",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							TextDirection: TDLeftToRight,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	email := Email{
 | 
						email := Email{
 | 
				
			||||||
@ -25,6 +54,29 @@ func TestHermes_ok(t *testing.T) {
 | 
				
			|||||||
				{"Lastname", "Snow"},
 | 
									{"Lastname", "Snow"},
 | 
				
			||||||
				{"Birthday", "01/01/283"},
 | 
									{"Birthday", "01/01/283"},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 | 
								Table: Table{
 | 
				
			||||||
 | 
									Data: [][]Entry{
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											{Key: "Item", Value: "Golang"},
 | 
				
			||||||
 | 
											{Key: "Description", Value: "Open source programming language that makes it easy to build simple, reliable, and efficient software"},
 | 
				
			||||||
 | 
											{Key: "Price", Value: "$10.99"},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											{Key: "Item", Value: "Hermes"},
 | 
				
			||||||
 | 
											{Key: "Description", Value: "Programmatically create beautiful e-mails using Golang."},
 | 
				
			||||||
 | 
											{Key: "Price", Value: "$1.99"},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Columns: Columns{
 | 
				
			||||||
 | 
										CustomWidth: map[string]string{
 | 
				
			||||||
 | 
											"Item":  "20%",
 | 
				
			||||||
 | 
											"Price": "15%",
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										CustomAlignement: map[string]string{
 | 
				
			||||||
 | 
											"Price": "right",
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
			Actions: []Action{
 | 
								Actions: []Action{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Instructions: "To get started with Hermes, please click here:",
 | 
										Instructions: "To get started with Hermes, please click here:",
 | 
				
			||||||
@ -40,21 +92,206 @@ func TestHermes_ok(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return h, email
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *SimpleExample) assertHTMLContent(t *testing.T, r string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Assert on product
 | 
				
			||||||
 | 
						assert.Contains(t, r, "HermesName", "Product: Should find the name of the product in email")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "http://hermes-link.com", "Product: Should find the link of the product in email")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Copyright © Hermes-Test", "Product: Should find the Copyright of the product in email")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "http://www.duchess-france.org/wp-content/uploads/2016/01/gopher.png", "Product: Should find the logo of the product in email")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Assert on email body
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Hi Jon Snow", "Name: Should find the name of the person")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Welcome to Hermes", "Intro: Should have intro")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Birthday", "Dictionary: Should have dictionary")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Open source programming language", "Table: Should have table with first row and first column")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Programmatically create beautiful e-mails using Golang", "Table: Should have table with second row and first column")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "$10.99", "Table: Should have table with first row and second column")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "$1.99", "Table: Should have table with second row and second column")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "started with Hermes", "Action: Should have instruction")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Confirm your account", "Action: Should have button of action")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "#22BC66", "Action: Button should have given color")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "https://hermes-example.com/confirm?token=d9729feb74992cc3482b350163a1a010", "Action: Button should have link")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Need help, or have questions", "Outro: Should have outro")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *SimpleExample) assertPlainTextContent(t *testing.T, r string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Assert on product
 | 
				
			||||||
 | 
						assert.Contains(t, r, "HermesName", "Product: Should find the name of the product in email")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "http://hermes-link.com", "Product: Should find the link of the product in email")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Copyright © Hermes-Test", "Product: Should find the Copyright of the product in email")
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "http://www.duchess-france.org/wp-content/uploads/2016/01/gopher.png", "Product: Should not find any logo in plain text")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Assert on email body
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Hi Jon Snow", "Name: Should find the name of the person")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Welcome to Hermes", "Intro: Should have intro")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Birthday", "Dictionary: Should have dictionary")
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "Open source programming language", "Table: Not possible to have table in plain text")
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "Programmatically create beautiful e-mails using Golang", "Table: Not possible to have table in plain text")
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "$10.99", "Table: Not possible to have table in plain text")
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "$1.99", "Table: Not possible to have table in plain text")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "started with Hermes", "Action: Should have instruction")
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "Confirm your account", "Action: Should not have button of action in plain text")
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "#22BC66", "Action: Button should not have color in plain text")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "https://hermes-example.com/confirm?token=d9729feb74992cc3482b350163a1a010", "Action: Even if button is not possible in plain text, it should have the link")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Need help, or have questions", "Outro: Should have outro")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type WithTitleInsteadOfNameExample struct {
 | 
				
			||||||
 | 
						theme Theme
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *WithTitleInsteadOfNameExample) getExample() (Hermes, Email) {
 | 
				
			||||||
 | 
						h := Hermes{
 | 
				
			||||||
 | 
							Theme: ed.theme,
 | 
				
			||||||
 | 
							Product: Product{
 | 
				
			||||||
 | 
								Name: "Hermes",
 | 
				
			||||||
 | 
								Link: "http://hermes.com",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						email := Email{
 | 
				
			||||||
 | 
							Body{
 | 
				
			||||||
 | 
								Name:  "Jon Snow",
 | 
				
			||||||
 | 
								Title: "A new e-mail",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return h, email
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *WithTitleInsteadOfNameExample) assertHTMLContent(t *testing.T, r string) {
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "Hi Jon Snow", "Name: should not find greetings from Jon Snow because title should be used")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "A new e-mail", "Title should be used instead of name")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *WithTitleInsteadOfNameExample) assertPlainTextContent(t *testing.T, r string) {
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "Hi Jon Snow", "Name: should not find greetings from Jon Snow because title should be used")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "A new e-mail", "Title shoud be used instead of name")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type WithGreetingDifferentThanDefault struct {
 | 
				
			||||||
 | 
						theme Theme
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *WithGreetingDifferentThanDefault) getExample() (Hermes, Email) {
 | 
				
			||||||
 | 
						h := Hermes{
 | 
				
			||||||
 | 
							Theme: ed.theme,
 | 
				
			||||||
 | 
							Product: Product{
 | 
				
			||||||
 | 
								Name: "Hermes",
 | 
				
			||||||
 | 
								Link: "http://hermes.com",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						email := Email{
 | 
				
			||||||
 | 
							Body{
 | 
				
			||||||
 | 
								Greeting: "Dear",
 | 
				
			||||||
 | 
								Name:     "Jon Snow",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return h, email
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *WithGreetingDifferentThanDefault) assertHTMLContent(t *testing.T, r string) {
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "Hi Jon Snow", "Should not find greetings with 'Hi' which is default")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Dear Jon Snow", "Should have greeting with Dear")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *WithGreetingDifferentThanDefault) assertPlainTextContent(t *testing.T, r string) {
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "Hi Jon Snow", "Should not find greetings with 'Hi' which is default")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Dear Jon Snow", "Should have greeting with Dear")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type WithSignatureDifferentThanDefault struct {
 | 
				
			||||||
 | 
						theme Theme
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *WithSignatureDifferentThanDefault) getExample() (Hermes, Email) {
 | 
				
			||||||
 | 
						h := Hermes{
 | 
				
			||||||
 | 
							Theme: ed.theme,
 | 
				
			||||||
 | 
							Product: Product{
 | 
				
			||||||
 | 
								Name: "Hermes",
 | 
				
			||||||
 | 
								Link: "http://hermes.com",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						email := Email{
 | 
				
			||||||
 | 
							Body{
 | 
				
			||||||
 | 
								Name:      "Jon Snow",
 | 
				
			||||||
 | 
								Signature: "Best regards",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return h, email
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *WithSignatureDifferentThanDefault) assertHTMLContent(t *testing.T, r string) {
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "Yours truly", "Should not find signature with 'Yours truly' which is default")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Best regards", "Should have greeting with Dear")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ed *WithSignatureDifferentThanDefault) assertPlainTextContent(t *testing.T, r string) {
 | 
				
			||||||
 | 
						assert.NotContains(t, r, "Yours truly", "Should not find signature with 'Yours truly' which is default")
 | 
				
			||||||
 | 
						assert.Contains(t, r, "Best regards", "Should have greeting with Dear")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Test all the themes for the features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestThemeSimple(t *testing.T) {
 | 
				
			||||||
 | 
						for _, theme := range testedThemes {
 | 
				
			||||||
 | 
							checkExample(t, &SimpleExample{theme})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestThemeWithTitleInsteadOfName(t *testing.T) {
 | 
				
			||||||
 | 
						for _, theme := range testedThemes {
 | 
				
			||||||
 | 
							checkExample(t, &WithTitleInsteadOfNameExample{theme})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestThemeWithGreetingDifferentThanDefault(t *testing.T) {
 | 
				
			||||||
 | 
						for _, theme := range testedThemes {
 | 
				
			||||||
 | 
							checkExample(t, &WithGreetingDifferentThanDefault{theme})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestThemeWithGreetingDiffrentThanDefault(t *testing.T) {
 | 
				
			||||||
 | 
						for _, theme := range testedThemes {
 | 
				
			||||||
 | 
							checkExample(t, &WithSignatureDifferentThanDefault{theme})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func checkExample(t *testing.T, ex Example) {
 | 
				
			||||||
 | 
						// Given an example
 | 
				
			||||||
 | 
						h, email := ex.getExample()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// When generating HTML template
 | 
				
			||||||
	r, err := h.GenerateHTML(email)
 | 
						r, err := h.GenerateHTML(email)
 | 
				
			||||||
	t.Log(r)
 | 
						t.Log(r)
 | 
				
			||||||
	assert.Nil(t, err)
 | 
						assert.Nil(t, err)
 | 
				
			||||||
	assert.NotEmpty(t, r)
 | 
						assert.NotEmpty(t, r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Then asserting HTML is OK
 | 
				
			||||||
 | 
						ex.assertHTMLContent(t, r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// When generating plain text template
 | 
				
			||||||
	r, err = h.GeneratePlainText(email)
 | 
						r, err = h.GeneratePlainText(email)
 | 
				
			||||||
	t.Log(r)
 | 
						t.Log(r)
 | 
				
			||||||
	assert.Nil(t, err)
 | 
						assert.Nil(t, err)
 | 
				
			||||||
	assert.NotEmpty(t, r)
 | 
						assert.NotEmpty(t, r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.Equal(t, h.Theme.Name(), "default")
 | 
						// Then asserting plain text is OK
 | 
				
			||||||
 | 
						ex.assertPlainTextContent(t, r)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestHermes_defaultTextDirection(t *testing.T) {
 | 
					////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Tests on default values for all themes //
 | 
				
			||||||
 | 
					// It does not check email content        //
 | 
				
			||||||
 | 
					////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestHermes_TextDirectionAsDefault(t *testing.T) {
 | 
				
			||||||
	h := Hermes{
 | 
						h := Hermes{
 | 
				
			||||||
		Product: Product{
 | 
							Product: Product{
 | 
				
			||||||
			Name: "Hermes",
 | 
								Name: "Hermes",
 | 
				
			||||||
@ -88,4 +325,29 @@ func TestHermes_defaultTextDirection(t *testing.T) {
 | 
				
			|||||||
	_, err := h.GenerateHTML(email)
 | 
						_, err := h.GenerateHTML(email)
 | 
				
			||||||
	assert.Nil(t, err)
 | 
						assert.Nil(t, err)
 | 
				
			||||||
	assert.Equal(t, h.TextDirection, TDLeftToRight)
 | 
						assert.Equal(t, h.TextDirection, TDLeftToRight)
 | 
				
			||||||
 | 
						assert.Equal(t, h.Theme.Name(), "default")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestHermes_Default(t *testing.T) {
 | 
				
			||||||
 | 
						h := Hermes{}
 | 
				
			||||||
 | 
						setDefaultHermesValues(&h)
 | 
				
			||||||
 | 
						email := Email{}
 | 
				
			||||||
 | 
						setDefaultEmailValues(&email)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.Equal(t, h.TextDirection, TDLeftToRight)
 | 
				
			||||||
 | 
						assert.Equal(t, h.Theme, new(Default))
 | 
				
			||||||
 | 
						assert.Equal(t, h.Product.Name, "Hermes")
 | 
				
			||||||
 | 
						assert.Equal(t, h.Product.Copyright, "Copyright © 2017 Hermes. All rights reserved.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.Empty(t, email.Body.Actions)
 | 
				
			||||||
 | 
						assert.Empty(t, email.Body.Dictionary)
 | 
				
			||||||
 | 
						assert.Empty(t, email.Body.Intros)
 | 
				
			||||||
 | 
						assert.Empty(t, email.Body.Outros)
 | 
				
			||||||
 | 
						assert.Empty(t, email.Body.Table.Data)
 | 
				
			||||||
 | 
						assert.Empty(t, email.Body.Table.Columns.CustomWidth)
 | 
				
			||||||
 | 
						assert.Empty(t, email.Body.Table.Columns.CustomAlignement)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.Equal(t, email.Body.Greeting, "Hi")
 | 
				
			||||||
 | 
						assert.Equal(t, email.Body.Signature, "Yours truly")
 | 
				
			||||||
 | 
						assert.Empty(t, email.Body.Title)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user