diff --git a/README.md b/README.md index 7f06747..35a22c5 100644 --- a/README.md +++ b/README.md @@ -8,104 +8,123 @@ INSTALL Add a dependency for the plugin in `build.gradle`: -``` - +```groovy dependencies { - compile 'io.github.gpc:greenmail:5.0.0' + testImplementation 'io.github.gpc:greenmail:5.0.0' + } - ``` +If you need to type your `MimeMessages` you also need to depend on: +```groovy + testImplementation 'jakarta.mail:jakarta.mail-api:1.6.7' +``` USAGE ------- -Provides a wrapper around [GreenMail](http://www.icegreen.com/greenmail/) and provides a view that displays `sent` messages - useful for testing application in the `development` or `test` environments. - - -### Installation - - grails install-plugin greenmail - +Provides a wrapper around [GreenMail](https://greenmail-mail-test.github.io/greenmail/) and provides a view that displays `sent` messages - useful for testing application in the `development` or `test` environments. + + + +The plugin assumes that you have some sort of Java mail provider installed (for instance the Grails mail plugin). You need to define an SMTP port for the mock Greenmail SMTP server to start with. Using the Grails Mail plugin, this is as simple as defining the `grails.mail.port` property in `application.yml`, like this (see the first line in the `development` and `test` blocks): + +You can completely disable the plugin by using the config setting `grails.plugin.greenmail.disabled = true`. + +If you need to change the default listening port (3025) you can use the `grails.plugin.greenmail.ports.smtp` +configuration variable. + +#### Example configuration: + +```yaml +--- # Mail and GreenMail configurations +environments: + development: + grails: + mail: + port: 3025 # Use default GreenMail port + test: + grails: + plugin: + greenmail: + ports: + smtp: 2525 # Specify GreenMail port + mail: + port: "${grails.plugin.greenmail.ports.smtp}" + production: + grails: + plugin: + greenmail: + disabled: true # Will not run the GreenMail plugin + mail: # For your production SMTP server. See mail plugin for configuration options + server: smtp.example.com + port: 25 +``` -The plugin assumes that you have some sort of Java mail provider installed (for instance the Grails mail plugin). You need to define a SMTP port for the mock Greenmail SMTP server to start with. Using the Grails Mail plugin, this is as simple as defining the `grails.mail.port` property in `Config.groovy`, like this (see the first line in the `development` and `test` blocks): +### Usage in Integration Tests - environments { - production { - grails.serverURL = "http://www.changeme.com" - } - development { - grails.mail.port = com.icegreen.greenmail.util.ServerSetupTest.SMTP.port - grails.serverURL = "http://localhost:8080/${appName}" - } - test { - grails.mail.port = com.icegreen.greenmail.util.ServerSetupTest.SMTP.port - grails.serverURL = "http://localhost:8080/${appName}" - } - } +The plugin can be used to capture email messages during integration tests. For example: -You can also completely disable the plugin by using the config setting `grails.plugin.greenmail.disabled = true`. For example, to disable greenmail in production: +```groovy - environments { - production { - grails.plugin.greenmail.disabled=true - } - } +import com.icegreen.greenmail.util.GreenMailUtil +import grails.plugin.greenmail.GreenMail +import grails.plugins.mail.MailService +import grails.testing.mixin.integration.Integration +import spock.lang.Specification -If you need to change the default listening port (1025) you can use the `grails.plugin.greenmail.ports.smtp` configuration variable. For example: +import javax.mail.internet.MimeMessage - environments { - test { - grails.plugin.greenmail.ports.smtp = 2025 - } - } +@Integration +class GreenmailExampleSpec extends Specification { + MailService mailService + GreenMail greenMail + void cleanup() { + greenMail.deleteAllMessages() + } -### Usage in Integration Tests + void "send a test mail"() { + given: + Map mail = [message: 'hello world', from: 'from@piragua.com', to: 'to@piragua.com', subject: 'subject'] -The plugin can be used to capture email messages during integration tests. For example: + when: + mailService.sendMail { + to mail.to + from mail.from + subject mail.subject + body mail.message + } - import com.icegreen.greenmail.util.* + then: + greenMail.receivedMessages.length == 1 - class GreenmailTests extends GroovyTestCase { - def mailService - def greenMail + with(greenMail.receivedMessages[0]) { MimeMessage message -> + GreenMailUtil.getBody(message) == mail.message + GreenMailUtil.getAddressList(message.from) == mail.from + message.subject == mail.subject + } + } - void testSendMail() { - Map mail = [message:'hello world', from:'from@piragua.com', to:'to@piragua.com', subject:'subject'] +} +``` - mailService.sendMail { - to mail.to - from mail.from - subject mail.subject - body mail.message - } - - assertEquals(1, greenMail.getReceivedMessages().length) - - def message = greenMail.getReceivedMessages()[0] - - assertEquals(mail.message, GreenMailUtil.getBody(message)) - assertEquals(mail.from, GreenMailUtil.getAddressList(message.from)) - assertEquals(mail.subject, message.subject) - } +#### Test example - void tearDown() { - greenMail.deleteAllMessages() - } - } +The above code snippets can be found here: https://github.com/sbglasius/greenmail-example +### Additional methods -The plugin adds a `deleteAllMessages()` convenience method to the `greenMail` bean that deletes all received messages. +`grails.plugin.greenmail.GreenMail` extends from `com.icegreen.greenmail.util.GreenMail` and adds a few extra methods. See [GreenMail.groovy](src/main/groovy/grails/plugin/greenmail/GreenMail.groovy) for reference. ### Usage in running application -The plugin provides a controller and view to show messages that are `sent` from the application. Simply browse to http://localhost:8080/greenmail and it will show a list of messages sent. You can click on the `show` link to view the raw message. +The plugin provides a controller and view to show messages that are `sent` from the application. Simply browse to http://localhost:8080/greenmail, and it will show a list of messages sent. You can click on the `show` link to view the raw message. ### Roadmap This is a fully functional plugin, though there are some features that I think would be worth adding. Contributions and patches are welcome! -* Messages sent by the Grails Mail plugin have duplicate "TO:" fields in the raw message and in the address list, for instance if the recipient is spam@piragua.com, then that email address is listed twice when you retrieve the address list for RecipientType.TO (e.g. GreenMailUtil.getAddressList(message.getRecipients(javax.mail.Message.RecipientType.TO)) +* Messages sent by the Grails Mail plugin have duplicate _TO:_ fields in the raw message and in the address list, for instance if the recipient is _spam@piragua.com_, then that email address is listed twice when you retrieve the address list for `RecipientType.TO` (e.g. `GreenMailUtil.getAddressList(message.getRecipients(javax.mail.Message.RecipientType.TO))` * Ability to view HTML email messages as they appear in a mail client rather than as RAW message. diff --git a/build.gradle b/build.gradle index d4ff7ed..69ed8bc 100644 --- a/build.gradle +++ b/build.gradle @@ -40,9 +40,9 @@ dependencies { testImplementation "io.micronaut:micronaut-inject-groovy" testImplementation "org.grails:grails-web-testing-support" - implementation "com.icegreen:greenmail:2.0.0" - implementation 'jakarta.mail:jakarta.mail-api:2.0.1' - api "com.icegreen:greenmail:2.0.0" + implementation "com.icegreen:greenmail:1.6.14" + implementation 'jakarta.mail:jakarta.mail-api:1.6.7' + api "com.icegreen:greenmail:1.6.14" } bootRun { diff --git a/gradle.properties b/gradle.properties index 6b3260a..bf46416 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -version=5.0.0 +version=5.0.0-SNAPSHOT grailsVersion=5.2.5 grailsGradlePluginVersion=5.2.4 diff --git a/src/main/groovy/grails/plugin/greenmail/GreenMail.groovy b/src/main/groovy/grails/plugin/greenmail/GreenMail.groovy index 4d598f8..7039306 100644 --- a/src/main/groovy/grails/plugin/greenmail/GreenMail.groovy +++ b/src/main/groovy/grails/plugin/greenmail/GreenMail.groovy @@ -15,68 +15,56 @@ */ package grails.plugin.greenmail -import com.icegreen.greenmail.imap.ImapHostManagerImpl -import com.icegreen.greenmail.util.ServerSetup -import com.icegreen.greenmail.util.Service +import groovy.transform.CompileStatic +import groovy.transform.InheritConstructors import javax.mail.internet.MimeMessage /** - * GreenMail provides no easy way to delete all messages, this class - * provides deleteAllMessages() which does that. + * This class provides convenience methods added to the original GreenMail class */ +@InheritConstructors +@CompileStatic class GreenMail extends com.icegreen.greenmail.util.GreenMail { - GreenMail() { - super() - } + /** + * GreenMail supports removing all messages, but by a different method + */ + void deleteAllMessages() { + super.purgeEmailFromAllMailboxes() + } - GreenMail(ServerSetup config) { - super(config) - } + /** + * Counts messages + * @return message count + */ + int getMessagesCount() { + messages.size() + } - GreenMail(ServerSetup[] config) { - super(config) - } + /** + * Get list of messages (instead of Array) + * @return list + */ + Collection getMessages() { + receivedMessages as List + } - @Override - synchronized void start() { - ImapHostManagerImpl.getDeclaredField('store').accessible = true - super.start() - } + /** + * Get a specific message + * @param index + * @return specific message or null if not found + */ + MimeMessage getMessage(int index) { + return index < messagesCount ? messages[index] : null + } - @Override - synchronized void stop() { - super.stop() - } - - void deleteAllMessages() { - managers.imapHostManager.store.listMailboxes('*')*.deleteAllMessages() - } - - int getMessagesCount() { - getMessages().size() - } - - Collection getMessages() { - getReceivedMessages().toList() - } - - MimeMessage getMessage(int index) { - def messages = getMessages() - if (index < messages.size()) { - messages[index] - } else { - null - } - } - - MimeMessage getLatestMessage() { - def messages = getMessages() - if (messages) { - messages.last() - } else { - null - } - } -} \ No newline at end of file + /** + * Get latest message + * @return latest message or null if not found + */ + MimeMessage getLatestMessage() { + return messages ? messages.last() : null + } + +} diff --git a/src/main/groovy/grails/plugin/greenmail/GreenmailGrailsPlugin.groovy b/src/main/groovy/grails/plugin/greenmail/GreenmailGrailsPlugin.groovy index f41f2f7..b2482d2 100644 --- a/src/main/groovy/grails/plugin/greenmail/GreenmailGrailsPlugin.groovy +++ b/src/main/groovy/grails/plugin/greenmail/GreenmailGrailsPlugin.groovy @@ -45,8 +45,8 @@ class GreenmailGrailsPlugin extends Plugin { @Override Closure doWithSpring() { {-> if (greenMailEnabled) { - int smtpPort = config.getProperty("grails.plugin.greenmail.ports.smtp", Integer, ServerSetupTest.SMTP.port) - ServerSetup smtp = new ServerSetup(smtpPort, null, "smtp") + int smtpPort = config.getProperty("grails.plugin.greenmail.ports.smtp", Integer, ServerSetupTest.SMTP.port) + ServerSetup smtp = new ServerSetup(smtpPort, null, ServerSetup.PROTOCOL_SMTP) greenMail(GreenMail, [smtp] as ServerSetup[]) } else {