├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── buildconf └── checkstyle │ ├── checkstyle-suppressions.xml │ └── checkstyle.xml ├── pom.xml ├── pom_fullmock.xml └── src ├── main ├── java │ ├── com │ │ └── sun │ │ │ └── mail │ │ │ └── pop3 │ │ │ └── POP3MockFolder0.java │ └── de │ │ └── saly │ │ └── javamail │ │ └── mock2 │ │ ├── IMAPDefaultMockFolder.java │ │ ├── IMAPMockFolder.java │ │ ├── IMAPMockStore.java │ │ ├── IMAPSSLMockStore.java │ │ ├── MailboxFolder.java │ │ ├── MockMailbox.java │ │ ├── MockMessage.java │ │ ├── MockTransport.java │ │ ├── POP3MockFolder.java │ │ ├── POP3MockStore.java │ │ ├── POP3SSLMockStore.java │ │ └── Providers.java └── resources │ └── META-INF │ └── javamail.providers └── test ├── java └── de │ └── saly │ └── javamail │ └── mock2 │ └── test │ ├── AbstractTestCase.java │ ├── IMAPTestCase.java │ ├── MailboxFolderTestCase.java │ ├── Main.java │ ├── POP3TestCase.java │ ├── SMTPTestCase.java │ └── support │ └── MockTestException.java └── resources └── log4j.properties /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | 14 | /target 15 | .DS_Store 16 | *.sh 17 | .classpath 18 | .project 19 | .settings/ 20 | pom.inc 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - openjdk6 5 | - openjdk7 6 | - oraclejdk7 7 | - oraclejdk8 8 | 9 | notifications: 10 | email: 11 | recipients: 12 | - hendrikdev22@gmail.com 13 | on_success: always 14 | on_failure: always -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | javamail-mock2 2 | ============== 3 | 4 | Open source mock classes for mockup JavaMail (useful especially for unittest). Supports IMAP IDLE. 5 | 6 | [![Build Status](https://travis-ci.org/salyh/javamail-mock2.svg?branch=master)](https://travis-ci.org/salyh/javamail-mock2) 7 | 8 | E-Mail hendrikdev22@gmail.com

9 | Twitter @hendrikdev22 10 | 11 |

Features

12 | * Support imap, imaps, pop3, pop3s, smtp, smtps 13 | * Support for SMTP: Mock Transport.send() 14 | * Supported for POP3: 15 | * cast to POP3Folder 16 | * Folder.getUID(Message msg) 17 | * Supported for IMAP: 18 | * cast to IMAPFolder 19 | * cast to UIDFolder 20 | * IDLE 21 | * ID 22 | * Subfolders 23 | * Folder.getMessagesByUID(...) 24 | * delete/rename folders 25 | * append messages 26 | * Unsupported for the moment: 27 | * All IMAP extensions except IDLE and ID 28 | * casts to POP3Message/IMAPMessage 29 | * store listeners 30 | 31 | The library come in two flavors/modes 32 | * Normal (or halfmock): Allows also to connect to real IMAP/POP servers. Use this if you have mixed testing setups (mockend an real server). Require a little bit of setup. 33 | * Fullmock: Use this if you have mocked test only. Normally no setup required. 34 | 35 | See unittests for how to use the library. 36 | Maven site docu is here: [http://salyh.github.io/javamail-mock2/](http://salyh.github.io/javamail-mock2) 37 | 38 |

Usage: Normal (= Halfmock) mode

39 | * Include the javamail-mock2-halfmock-x.x.jar file in your unittest project (or use maven, see below) 40 | * Make sure every operation that should be mocked uses as protocol either mock_smtp, mock_imap or mock_pop3 (or mock_smtps, mock_imaps or mock_pop3s) 41 | * See unittest how to archive this 42 | * Create a mailbox and add folders/messages or use Transport.sendMail to put mails into your INBOX 43 | * Use the JavaMail API to retrieve mails via POP3 or IMAP or do whatever your application does 44 | 45 |

Usage: Fullmock mode

46 | * Include the javamail-mock2-fullmock-x.x.jar file in your unittest project (or use maven, see below) 47 | * Create a mailbox and add folders/messages or use Transport.sendMail to put mails into your INBOX 48 | * Use the JavaMail API to retrieve mails via POP3 or IMAP or do whatever your application does 49 | 50 |

Maven: Normal (= Halfmock)

51 | ```xml 52 | 53 | de.saly 54 | javamail-mock2-halfmock 55 | 0.5-beta4 56 | test 57 | 58 | ``` 59 | 60 |

Maven: Fullmock

61 | ```xml 62 | 63 | de.saly 64 | javamail-mock2-fullmock 65 | 0.5-beta4 66 | test 67 | 68 | ``` 69 | 70 |

Examples

71 | ```java 72 | 73 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 74 | final MailboxFolder mf = mb.getInbox(); 75 | 76 | final MimeMessage msg = new MimeMessage((Session) null); 77 | msg.setSubject("Test"); 78 | msg.setFrom("from@sender.com"); 79 | msg.setText("Some text here ..."); 80 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 81 | mf.add(msg); // 11 82 | mf.add(msg); // 12 83 | mf.add(msg); // 13 84 | 85 | Session session = Session.getInstance(new Properties()); 86 | final Store store = session.getStore("pop3s"); //or mock_pop3s for halfmock 87 | store.connect("hendrik@unknown.com", null); 88 | final Folder inbox = store.getFolder("INBOX"); 89 | inbox.open(Folder.READ_ONLY); 90 | Assert.assertEquals(3, inbox.getMessageCount()); 91 | Assert.assertNotNull(inbox.getMessage(1)); 92 | inbox.close(true); 93 | ``` 94 | 95 | For a real usage scenario look here: [Elasticsearch IMAP River](https://github.com/salyh/elasticsearch-river-imap) 96 | -------------------------------------------------------------------------------- /buildconf/checkstyle/checkstyle-suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /buildconf/checkstyle/checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 16 | 17 | 18 | 21 | 22 | 23 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | 3.1.0 8 | 9 | 10 | de.saly 11 | jar 12 | 13 | 14 | _halfmock_only 15 | github 16 | UTF-8 17 | 18 | 19 | 20 | javamail-mock2-halfmock 21 | 0.5-beta4 22 | Javamail Mock2 (Mode: halfmock) 23 | Open source mock classes for mock up JavaMail (Mode: halfmock) 24 | 25 | 26 | 27 | 2014 28 | https://github.com/salyh/javamail-mock2 29 | 30 | 31 | 32 | The Apache Software License, Version 2.0 33 | http://www.apache.org/licenses/LICENSE-2.0.txt 34 | repo 35 | 36 | 37 | 38 | 39 | https://github.com/salyh/javamail-mock2 40 | scm:git:git@github.com:salyh/javamail-mock2.git 41 | scm:git:git@github.com:salyh/javamail-mock2.git 42 | 43 | 44 | 45 | GitHub 46 | https://github.com/salyh/javamail-mock2/issues 47 | 48 | 49 | 50 | 51 | hendrikdev22@gmail.com 52 | Hendrik Saly 53 | https://github.com/salyh 54 | salyh 55 | 56 | 57 | 58 | 59 | 60 | sonatype-nexus-staging 61 | Nexus Release Repository 62 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 63 | 64 | 65 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | src/main/resources 77 | true 78 | 79 | **/* 80 | 81 | 82 | 83 | 84 | 85 | 86 | org.apache.maven.plugins 87 | maven-resources-plugin 88 | 2.6 89 | 90 | 91 | UTF-8 92 | 93 | 94 | 95 | maven-compiler-plugin 96 | 3.1 97 | 98 | 1.6 99 | 1.6 100 | UTF-8 101 | true 102 | true 103 | true 104 | 105 | 106 | 107 | 108 | maven-clean-plugin 109 | 2.5 110 | 111 | 112 | 113 | data 114 | 115 | 116 | 117 | 118 | 119 | 120 | org.apache.maven.plugins 121 | maven-surefire-plugin 122 | 2.17 123 | 124 | 125 | **/*Test*.java 126 | 127 | 128 | 129 | 130 | 131 | org.apache.maven.plugins 132 | maven-source-plugin 133 | 2.2.1 134 | 135 | 136 | attach-sources 137 | 138 | jar 139 | 140 | 141 | 142 | 143 | 144 | 145 | maven-assembly-plugin 146 | 2.4 147 | 148 | 149 | src 150 | bin 151 | 152 | 153 | 154 | 155 | 156 | maven-javadoc-plugin 157 | 2.9.1 158 | 159 | ${project.build.sourceEncoding} 160 | en 161 | true 162 | true 163 | 164 | 165 | 166 | package 167 | 168 | jar 169 | 170 | 171 | 172 | 173 | 174 | 175 | maven-site-plugin 176 | 3.3 177 | 178 | en 179 | UTF-8 180 | UTF-8 181 | 182 | 183 | 184 | com.github.github 185 | site-maven-plugin 186 | 0.9 187 | 188 | Building site for ${project.version} 189 | 190 | 191 | 192 | 193 | site 194 | 195 | site 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | com.sun.mail 205 | javax.mail 206 | 1.5.2 207 | 208 | 209 | activation 210 | javax.activation 211 | 212 | 213 | 214 | 215 | 216 | org.slf4j 217 | slf4j-api 218 | 1.7.7 219 | 220 | 221 | 222 | junit 223 | junit 224 | 4.11 225 | test 226 | 227 | 228 | 229 | org.slf4j 230 | slf4j-log4j12 231 | 1.7.7 232 | test 233 | 234 | 235 | 236 | 237 | 238 | 239 | org.apache.maven.plugins 240 | maven-project-info-reports-plugin 241 | 2.7 242 | 243 | 244 | 245 | maven-javadoc-plugin 246 | 2.9.1 247 | 248 | ${project.build.sourceEncoding} 249 | en 250 | true 251 | true 252 | 253 | 254 | 255 | 256 | maven-surefire-report-plugin 257 | 2.17 258 | 259 | 260 | 261 | org.apache.maven.plugins 262 | maven-jxr-plugin 263 | 2.4 264 | 265 | 266 | 267 | org.codehaus.mojo 268 | findbugs-maven-plugin 269 | 2.5.3 270 | 271 | 272 | 273 | org.apache.maven.plugins 274 | maven-checkstyle-plugin 275 | 2.12.1 276 | 277 | buildconf/checkstyle/checkstyle.xml 278 | buildconf/checkstyle/checkstyle-suppressions.xml 279 | 280 | 281 | 282 | 283 | checkstyle 284 | 285 | 286 | 287 | 288 | 289 | 290 | org.apache.maven.plugins 291 | maven-pmd-plugin 292 | 3.1 293 | 294 | 295 | 296 | 297 | 298 | 299 | release-sign-artifacts 300 | 301 | 302 | sign 303 | true 304 | 305 | 306 | 307 | 7903F81190910A83 308 | false 309 | 310 | 311 | 312 | 313 | org.apache.maven.plugins 314 | maven-gpg-plugin 315 | 1.5 316 | 317 | 318 | sign-artifacts 319 | verify 320 | 321 | sign 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | -------------------------------------------------------------------------------- /pom_fullmock.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | 3.1.0 8 | 9 | 10 | de.saly 11 | jar 12 | 13 | 14 | 15 | github 16 | UTF-8 17 | 18 | 19 | 20 | javamail-mock2-fullmock 21 | 0.5-beta4 22 | Javamail Mock2 (Mode: fullmock) 23 | Open source mock classes for mock up JavaMail (Mode: fullmock) 24 | 25 | 26 | 27 | 2014 28 | https://github.com/salyh/javamail-mock2 29 | 30 | 31 | 32 | The Apache Software License, Version 2.0 33 | http://www.apache.org/licenses/LICENSE-2.0.txt 34 | repo 35 | 36 | 37 | 38 | 39 | https://github.com/salyh/javamail-mock2 40 | scm:git:git@github.com:salyh/javamail-mock2.git 41 | scm:git:git@github.com:salyh/javamail-mock2.git 42 | 43 | 44 | 45 | GitHub 46 | https://github.com/salyh/javamail-mock2/issues 47 | 48 | 49 | 50 | 51 | hendrikdev22@gmail.com 52 | Hendrik Saly 53 | https://github.com/salyh 54 | salyh 55 | 56 | 57 | 58 | 59 | 60 | sonatype-nexus-staging 61 | Nexus Release Repository 62 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 63 | 64 | 65 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | src/main/resources 77 | true 78 | 79 | **/* 80 | 81 | 82 | 83 | 84 | 85 | 86 | org.apache.maven.plugins 87 | maven-resources-plugin 88 | 2.6 89 | 90 | 91 | UTF-8 92 | 93 | 94 | 95 | maven-compiler-plugin 96 | 3.1 97 | 98 | 1.6 99 | 1.6 100 | UTF-8 101 | true 102 | true 103 | true 104 | 105 | 106 | 107 | 108 | maven-clean-plugin 109 | 2.5 110 | 111 | 112 | 113 | data 114 | 115 | 116 | 117 | 118 | 119 | 120 | org.apache.maven.plugins 121 | maven-surefire-plugin 122 | 2.17 123 | 124 | 125 | **/*Test*.java 126 | 127 | 128 | 129 | 130 | 131 | org.apache.maven.plugins 132 | maven-source-plugin 133 | 2.2.1 134 | 135 | 136 | attach-sources 137 | 138 | jar 139 | 140 | 141 | 142 | 143 | 144 | 145 | maven-assembly-plugin 146 | 2.4 147 | 148 | 149 | src 150 | bin 151 | 152 | 153 | 154 | 155 | 156 | maven-javadoc-plugin 157 | 2.9.1 158 | 159 | ${project.build.sourceEncoding} 160 | en 161 | true 162 | true 163 | 164 | 165 | 166 | package 167 | 168 | jar 169 | 170 | 171 | 172 | 173 | 174 | 175 | maven-site-plugin 176 | 3.3 177 | 178 | en 179 | UTF-8 180 | UTF-8 181 | 182 | 183 | 184 | com.github.github 185 | site-maven-plugin 186 | 0.9 187 | 188 | Building site for ${project.version} 189 | 190 | 191 | 192 | 193 | site 194 | 195 | site 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | com.sun.mail 205 | javax.mail 206 | 1.5.2 207 | 208 | 209 | activation 210 | javax.activation 211 | 212 | 213 | 214 | 215 | 216 | org.slf4j 217 | slf4j-api 218 | 1.7.7 219 | 220 | 221 | 222 | junit 223 | junit 224 | 4.11 225 | test 226 | 227 | 228 | 229 | org.slf4j 230 | slf4j-log4j12 231 | 1.7.7 232 | test 233 | 234 | 235 | 236 | 237 | 238 | 239 | org.apache.maven.plugins 240 | maven-project-info-reports-plugin 241 | 2.7 242 | 243 | 244 | 245 | maven-javadoc-plugin 246 | 2.9.1 247 | 248 | ${project.build.sourceEncoding} 249 | en 250 | true 251 | true 252 | 253 | 254 | 255 | 256 | maven-surefire-report-plugin 257 | 2.17 258 | 259 | 260 | 261 | org.apache.maven.plugins 262 | maven-jxr-plugin 263 | 2.4 264 | 265 | 266 | 267 | org.codehaus.mojo 268 | findbugs-maven-plugin 269 | 2.5.3 270 | 271 | 272 | 273 | org.apache.maven.plugins 274 | maven-checkstyle-plugin 275 | 2.12.1 276 | 277 | buildconf/checkstyle/checkstyle.xml 278 | buildconf/checkstyle/checkstyle-suppressions.xml 279 | 280 | 281 | 282 | 283 | checkstyle 284 | 285 | 286 | 287 | 288 | 289 | 290 | org.apache.maven.plugins 291 | maven-pmd-plugin 292 | 3.1 293 | 294 | 295 | 296 | 297 | 298 | 299 | release-sign-artifacts 300 | 301 | 302 | sign 303 | true 304 | 305 | 306 | 307 | 7903F81190910A83 308 | false 309 | 310 | 311 | 312 | 313 | org.apache.maven.plugins 314 | maven-gpg-plugin 315 | 1.5 316 | 317 | 318 | sign-artifacts 319 | verify 320 | 321 | sign 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | -------------------------------------------------------------------------------- /src/main/java/com/sun/mail/pop3/POP3MockFolder0.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package com.sun.mail.pop3; 27 | 28 | import de.saly.javamail.mock2.POP3MockStore; 29 | 30 | /** 31 | * this class is needed currently because com.sun.mail.pop3.POP3Folder has a 32 | * constructor with default visibility 33 | * See https://kenai.com/bugzilla/show_bug.cgi?id=6379 34 | */ 35 | public class POP3MockFolder0 extends POP3Folder { 36 | 37 | // POP3 has only one Folder INBOX 38 | private static final String INBOX = "INBOX"; 39 | 40 | // make constructor visible for subclasses 41 | protected POP3MockFolder0(final POP3MockStore store) { 42 | super(store, INBOX); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/IMAPDefaultMockFolder.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import java.util.ArrayList; 29 | import java.util.List; 30 | 31 | import javax.mail.Folder; 32 | import javax.mail.MessagingException; 33 | 34 | import com.sun.mail.imap.DefaultFolder; 35 | 36 | public class IMAPDefaultMockFolder extends DefaultFolder { 37 | 38 | protected final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass()); 39 | private final MockMailbox mailbox; 40 | // private final IMAPMockFolder[] children; 41 | private final IMAPMockStore store; 42 | 43 | protected IMAPDefaultMockFolder(final IMAPMockStore store, final MockMailbox mailbox) { 44 | super(store); 45 | // this.children = children; 46 | this.mailbox = mailbox; 47 | this.store = store; 48 | logger.debug("Created"); 49 | } 50 | 51 | @Override 52 | public synchronized boolean create(final int type) throws MessagingException { 53 | return true; 54 | } 55 | 56 | @Override 57 | public synchronized boolean exists() throws MessagingException { 58 | return true; 59 | } 60 | 61 | @Override 62 | public Folder getFolder(final String name) throws MessagingException { 63 | 64 | logger.debug("getFolder(" + name + ") on " + getFullName()); 65 | 66 | if ("inbox".equalsIgnoreCase(name)) { 67 | return new IMAPMockFolder(store, mailbox.getInbox()); 68 | } 69 | 70 | return new IMAPMockFolder(store, mailbox.getRoot().getOrAddSubFolder(name)); 71 | 72 | } 73 | 74 | @Override 75 | public int getType() throws MessagingException { 76 | checkExists(); 77 | return HOLDS_FOLDERS; 78 | } 79 | 80 | @Override 81 | public Folder[] list(final String pattern) throws MessagingException { 82 | 83 | final List children = mailbox.getRoot().getChildren(); 84 | final List ret = new ArrayList(); 85 | 86 | for (final MailboxFolder mf : children) { 87 | if (mf.isExists()) { 88 | ret.add(new IMAPMockFolder(store, mf)); 89 | } 90 | } 91 | 92 | logger.debug("Folder (Defaultroot) list return " + ret); 93 | 94 | return ret.toArray(new Folder[ret.size()]); 95 | 96 | } 97 | 98 | @Override 99 | public synchronized Folder[] listSubscribed(final String pattern) throws MessagingException { 100 | return new Folder[0]; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/IMAPMockFolder.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import java.util.ArrayList; 29 | import java.util.List; 30 | import java.util.Map; 31 | import java.util.UUID; 32 | import java.util.concurrent.Semaphore; 33 | 34 | import javax.mail.FetchProfile; 35 | import javax.mail.Flags; 36 | import javax.mail.Flags.Flag; 37 | import javax.mail.Folder; 38 | import javax.mail.FolderClosedException; 39 | import javax.mail.FolderNotFoundException; 40 | import javax.mail.Message; 41 | import javax.mail.MessagingException; 42 | import javax.mail.Quota; 43 | import javax.mail.event.ConnectionEvent; 44 | import javax.mail.event.FolderEvent; 45 | import javax.mail.event.MailEvent; 46 | import javax.mail.event.MessageChangedEvent; 47 | import javax.mail.internet.MimeMessage; 48 | import javax.mail.search.SearchTerm; 49 | 50 | import com.sun.mail.iap.ProtocolException; 51 | import com.sun.mail.iap.Response; 52 | import com.sun.mail.imap.AppendUID; 53 | import com.sun.mail.imap.IMAPFolder; 54 | import com.sun.mail.imap.ResyncData; 55 | import com.sun.mail.imap.SortTerm; 56 | 57 | import de.saly.javamail.mock2.MailboxFolder.MailboxEventListener; 58 | 59 | public class IMAPMockFolder extends IMAPFolder implements MailboxEventListener { 60 | 61 | private static final int ABORTING = 2; // IDLE command aborting 62 | private static final int IDLE = 1; // IDLE command in effect 63 | private static final int RUNNING = 0; // not doing IDLE command 64 | private final Semaphore idleLock = new Semaphore(0, true); 65 | 66 | private int idleState = RUNNING; 67 | 68 | protected final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass()); 69 | 70 | private final MailboxFolder mailboxFolder; 71 | 72 | private final UUID objectId = UUID.randomUUID(); 73 | 74 | private volatile boolean opened = false; 75 | 76 | private int openMode; 77 | 78 | private final IMAPMockStore store; 79 | 80 | protected IMAPMockFolder(final IMAPMockStore store, final MailboxFolder mailboxFolder) { 81 | super("DUMMY_NAME_WHICH_MUST_NOT_BE_VISIBLE", MailboxFolder.SEPARATOR, store, false); 82 | this.mailboxFolder = mailboxFolder; 83 | this.mailboxFolder.addMailboxEventListener(this); 84 | this.store = store; 85 | logger.debug("Folder created " + objectId); 86 | } 87 | 88 | protected synchronized void abortIdle() { 89 | if (idleState == IDLE) { 90 | logger.trace("Abort idle"); 91 | 92 | if (logger.isTraceEnabled()) { 93 | try { 94 | throw new RuntimeException(); 95 | } catch (final Exception e) { 96 | logger.trace("TRACE stacktrace ", e); 97 | } 98 | 99 | } 100 | 101 | idleState = ABORTING; 102 | idleLock.release(); 103 | 104 | } 105 | } 106 | 107 | @Override 108 | public void appendMessages(final Message[] msgs) throws MessagingException { 109 | abortIdle(); 110 | checkExists(); 111 | // checkOpened(); 112 | // checkWriteMode(); 113 | for (final Message m : msgs) { 114 | mailboxFolder.add((MimeMessage) m); 115 | } 116 | 117 | logger.debug("Append " + msgs.length + " to " + getFullName()); 118 | } 119 | 120 | @Override 121 | public synchronized AppendUID[] appendUIDMessages(final Message[] msgs) throws MessagingException { 122 | abortIdle(); 123 | checkExists(); 124 | // checkOpened(); 125 | // checkWriteMode(); 126 | final AppendUID[] uids = new AppendUID[msgs.length]; 127 | int i = 0; 128 | for (final Message m : msgs) { 129 | final MockMessage mockMessage = (MockMessage) mailboxFolder.add((MimeMessage) m); 130 | uids[i++] = new AppendUID(mailboxFolder.getUidValidity(), mockMessage.getMockid()); 131 | } 132 | 133 | logger.debug("Append " + msgs.length + " to " + getFullName()); 134 | 135 | return uids; 136 | } 137 | 138 | @Override 139 | protected void checkClosed() { 140 | if (opened) { 141 | throw new IllegalStateException("This operation is not allowed on an open folder:" + getFullName() + " (" + objectId + ")"); 142 | } 143 | } 144 | 145 | @Override 146 | protected void checkExists() throws MessagingException { 147 | if (!exists()) { 148 | throw new FolderNotFoundException(this, getFullName() + " not found"); 149 | } 150 | } 151 | 152 | @Override 153 | protected void checkOpened() throws FolderClosedException { 154 | 155 | if (!opened) { 156 | 157 | throw new IllegalStateException("This operation is not allowed on a closed folder: " + getFullName() + " (" + objectId + ")"); 158 | 159 | } 160 | } 161 | 162 | protected void checkWriteMode() { 163 | if (openMode != Folder.READ_WRITE) { 164 | throw new IllegalStateException("Folder " + getFullName() + " is readonly" + " (" + objectId + ")"); 165 | } 166 | } 167 | 168 | @Override 169 | public synchronized void close(final boolean expunge) throws MessagingException { 170 | abortIdle(); 171 | checkOpened(); 172 | checkExists(); 173 | 174 | if (expunge) { 175 | expunge(); 176 | } 177 | 178 | opened = false; 179 | logger.debug("Folder " + getFullName() + " closed (" + objectId + ")"); 180 | notifyConnectionListeners(ConnectionEvent.CLOSED); 181 | } 182 | 183 | @Override 184 | public synchronized void copyMessages(final Message[] msgs, final Folder folder) throws MessagingException { 185 | abortIdle(); 186 | checkOpened(); 187 | checkExists(); 188 | if (msgs == null || folder == null || msgs.length == 0) { 189 | return; 190 | } 191 | 192 | if (!folder.exists()) { 193 | throw new FolderNotFoundException(folder.getFullName() + " does not exist", folder); 194 | } 195 | 196 | folder.appendMessages(msgs); 197 | } 198 | 199 | @Override 200 | public synchronized AppendUID[] copyUIDMessages(final Message[] msgs, final Folder folder) throws MessagingException { 201 | 202 | abortIdle(); 203 | checkExists(); 204 | checkOpened(); 205 | if (msgs == null || folder == null || msgs.length == 0) { 206 | return null; 207 | } 208 | 209 | final AppendUID[] uids = new AppendUID[msgs.length]; 210 | 211 | int i = 0; 212 | for (final Message m : msgs) { 213 | final MockMessage mockMessage = (MockMessage) mailboxFolder.add((MimeMessage) m); 214 | uids[i++] = new AppendUID(mailboxFolder.getUidValidity(), mockMessage.getMockid()); 215 | } 216 | 217 | logger.debug("Copied " + msgs.length + " to " + getFullName()); 218 | 219 | return uids; 220 | } 221 | 222 | @Override 223 | public synchronized boolean create(final int type) throws MessagingException { 224 | abortIdle(); 225 | if (exists()) { 226 | return true; 227 | } 228 | 229 | mailboxFolder.create(); 230 | notifyFolderListeners(FolderEvent.CREATED); 231 | return mailboxFolder.isExists(); 232 | 233 | // return mailboxFolder.reCreate().isExists(); 234 | 235 | } 236 | 237 | @Override 238 | public synchronized boolean delete(final boolean recurse) throws MessagingException { 239 | abortIdle(); 240 | checkExists(); 241 | checkClosed(); 242 | mailboxFolder.deleteFolder(recurse); 243 | notifyFolderListeners(FolderEvent.DELETED); 244 | return true; 245 | } 246 | 247 | @Override 248 | public synchronized Object doCommand(final ProtocolCommand cmd) throws MessagingException { 249 | throw new MessagingException( 250 | "no protocol for mock class - you should never see this exception. Please file a bugrfeport and include stacktrace"); 251 | 252 | } 253 | 254 | @Override 255 | public synchronized Object doCommandIgnoreFailure(final ProtocolCommand cmd) throws MessagingException { 256 | throw new MessagingException( 257 | "no protocol for mock class - you should never see this exception. Please file a bugrfeport and include stacktrace"); 258 | 259 | } 260 | 261 | @Override 262 | public synchronized Object doOptionalCommand(final String err, final ProtocolCommand cmd) throws MessagingException { 263 | throw new MessagingException("Optional command not supported: " + err); 264 | } 265 | 266 | @Override 267 | protected synchronized Object doProtocolCommand(final ProtocolCommand cmd) throws ProtocolException { 268 | 269 | throw new ProtocolException( 270 | "no protocol for mock class - you should never see this exception. Please file a bugrfeport and include stacktrace"); 271 | 272 | } 273 | 274 | @Override 275 | public synchronized boolean exists() throws MessagingException { 276 | abortIdle(); 277 | return mailboxFolder.isExists(); 278 | } 279 | 280 | @Override 281 | public synchronized Message[] expunge() throws MessagingException { 282 | abortIdle(); 283 | checkExists(); 284 | checkOpened(); 285 | checkWriteMode(); 286 | 287 | final Message[] removed = wrap(mailboxFolder.expunge()); 288 | 289 | if (removed.length > 0) { 290 | notifyMessageRemovedListeners(true, removed); 291 | } 292 | 293 | return removed; 294 | 295 | } 296 | 297 | @Override 298 | public synchronized Message[] expunge(final Message[] msgs) throws MessagingException { 299 | abortIdle(); 300 | checkExists(); 301 | checkOpened(); 302 | checkWriteMode(); 303 | final Message[] removed = wrap(mailboxFolder.expunge(msgs)); 304 | 305 | if (removed.length > 0) { 306 | notifyMessageRemovedListeners(true, removed); 307 | } 308 | 309 | return removed; 310 | 311 | } 312 | 313 | @Override 314 | public synchronized void fetch(final Message[] msgs, final FetchProfile fp) throws MessagingException { 315 | abortIdle(); 316 | // do nothing more 317 | } 318 | 319 | @Override 320 | public void folderCreated(final MailboxFolder mf) { 321 | // ignore 322 | 323 | } 324 | 325 | @Override 326 | public void folderDeleted(final MailboxFolder mf) { 327 | // ignore 328 | 329 | } 330 | 331 | @Override 332 | public void folderRenamed(final String from, final MailboxFolder to) { 333 | // ignore 334 | 335 | } 336 | 337 | @Override 338 | public synchronized void forceClose() throws MessagingException { 339 | close(false); 340 | } 341 | 342 | @Override 343 | public synchronized String[] getAttributes() throws MessagingException { 344 | checkExists(); 345 | // TODO \Marked \HasNoChildren ... 346 | return new String[0]; 347 | } 348 | 349 | @Override 350 | public synchronized int getDeletedMessageCount() throws MessagingException { 351 | abortIdle(); 352 | checkExists(); 353 | if (!opened) { 354 | return -1; 355 | } 356 | 357 | return mailboxFolder.getByFlags(new Flags(Flags.Flag.DELETED), false).length; 358 | } 359 | 360 | @Override 361 | public synchronized Folder getFolder(final String name) throws MessagingException { 362 | abortIdle(); 363 | // checkExists(); 364 | 365 | logger.debug("getFolder(" + name + ") on " + getFullName()); 366 | 367 | if ("inbox".equalsIgnoreCase(name)) { 368 | return new IMAPMockFolder(store, mailboxFolder.getMailbox().getInbox()); 369 | } 370 | 371 | return new IMAPMockFolder(store, mailboxFolder.getOrAddSubFolder(name)); 372 | 373 | } 374 | 375 | @Override 376 | public synchronized String getFullName() { 377 | 378 | return mailboxFolder.getFullName(); 379 | } 380 | 381 | @Override 382 | public synchronized long getHighestModSeq() throws MessagingException { 383 | throw new MessagingException("CONDSTORE not supported"); 384 | } 385 | 386 | @Override 387 | public Message getMessage(final int msgnum) throws MessagingException { 388 | abortIdle(); 389 | checkExists(); 390 | checkOpened(); 391 | return new MockMessage(mailboxFolder.getByMsgNum(msgnum), this); 392 | } 393 | 394 | @Override 395 | public synchronized Message getMessageByUID(final long uid) throws MessagingException { 396 | abortIdle(); 397 | checkExists(); 398 | checkOpened(); 399 | return new MockMessage(mailboxFolder.getById(uid), this); 400 | } 401 | 402 | @Override 403 | public int getMessageCount() throws MessagingException { 404 | abortIdle(); 405 | checkExists(); 406 | return mailboxFolder.getMessageCount(); 407 | } 408 | 409 | @Override 410 | public Message[] getMessages(final int low, final int high) throws MessagingException { 411 | abortIdle(); 412 | checkExists(); 413 | checkOpened(); 414 | final List messages = new ArrayList(); 415 | for (int i = low; i <= high; i++) { 416 | final Message m = mailboxFolder.getByMsgNum(i); 417 | messages.add(new MockMessage(m, this)); 418 | } 419 | return messages.toArray(new Message[messages.size()]); 420 | } 421 | 422 | @Override 423 | public synchronized Message[] getMessagesByUID(final long start, final long end) throws MessagingException { 424 | abortIdle(); 425 | checkExists(); 426 | checkOpened(); 427 | return wrap(mailboxFolder.getByIds(start, end)); 428 | 429 | } 430 | 431 | @Override 432 | public synchronized Message[] getMessagesByUID(final long[] uids) throws MessagingException { 433 | abortIdle(); 434 | checkExists(); 435 | checkOpened(); 436 | return wrap(mailboxFolder.getByIds(uids)); 437 | } 438 | 439 | @Override 440 | public synchronized Message[] getMessagesByUIDChangedSince(final long start, final long end, final long modseq) 441 | throws MessagingException { 442 | throw new MessagingException("CONDSTORE not supported"); 443 | } 444 | 445 | @Override 446 | public synchronized String getName() { 447 | 448 | return mailboxFolder.getName(); 449 | } 450 | 451 | @Override 452 | public int getNewMessageCount() throws MessagingException { 453 | abortIdle(); 454 | checkExists(); 455 | return mailboxFolder.getByFlags(new Flags(Flag.RECENT), true).length; // TODO 456 | // or 457 | // is 458 | // it 459 | // SEEN 460 | // false? 461 | } 462 | 463 | @Override 464 | public Folder getParent() throws MessagingException { 465 | checkExists(); 466 | if (mailboxFolder.getParent() == null) { 467 | throw new MessagingException("no parent, is already default root"); 468 | } 469 | 470 | return new IMAPMockFolder(store, mailboxFolder.getParent()); 471 | } 472 | 473 | @Override 474 | public Flags getPermanentFlags() { 475 | return null; 476 | } 477 | 478 | @Override 479 | public Quota[] getQuota() throws MessagingException { 480 | throw new MessagingException("QUOTA not supported"); 481 | } 482 | 483 | @Override 484 | public char getSeparator() throws MessagingException { 485 | abortIdle(); 486 | return MailboxFolder.SEPARATOR; 487 | } 488 | 489 | @Override 490 | public synchronized Message[] getSortedMessages(final SortTerm[] term) throws MessagingException { 491 | throw new MessagingException("SORT not supported"); 492 | } 493 | 494 | @Override 495 | public synchronized Message[] getSortedMessages(final SortTerm[] term, final SearchTerm sterm) throws MessagingException { 496 | throw new MessagingException("SORT not supported"); 497 | } 498 | 499 | @Override 500 | public int getType() throws MessagingException { 501 | // checkExists(); 502 | return mailboxFolder.isRoot() ? HOLDS_FOLDERS : HOLDS_MESSAGES | HOLDS_FOLDERS; 503 | } 504 | 505 | /* (non-Javadoc) 506 | * @see com.sun.mail.imap.IMAPFolder#getUID(javax.mail.Message) 507 | */ 508 | @Override 509 | public synchronized long getUID(final Message message) throws MessagingException { 510 | abortIdle(); 511 | return mailboxFolder.getUID(message); 512 | } 513 | 514 | /* (non-Javadoc) 515 | * @see com.sun.mail.imap.IMAPFolder#getUIDNext() 516 | */ 517 | @Override 518 | public synchronized long getUIDNext() throws MessagingException { 519 | abortIdle(); 520 | return mailboxFolder.getUniqueMessageId() + 10; // TODO +10 magic number 521 | } 522 | 523 | /* (non-Javadoc) 524 | * @see com.sun.mail.imap.IMAPFolder#getUIDValidity() 525 | */ 526 | @Override 527 | public synchronized long getUIDValidity() throws MessagingException { 528 | abortIdle(); 529 | return mailboxFolder.getUidValidity(); 530 | } 531 | 532 | @Override 533 | public synchronized int getUnreadMessageCount() throws MessagingException { 534 | abortIdle(); 535 | checkExists(); 536 | return mailboxFolder.getByFlags(new Flags(Flags.Flag.SEEN), false).length; 537 | } 538 | 539 | @Override 540 | public void handleResponse(final Response r) { 541 | throw new RuntimeException("not implemented/should not happen"); 542 | } 543 | 544 | @Override 545 | public boolean hasNewMessages() throws MessagingException { 546 | checkExists(); 547 | return getNewMessageCount() > 0; 548 | } 549 | 550 | @Override 551 | public Map id(final Map clientParams) throws MessagingException { 552 | return store.id(clientParams); 553 | } 554 | 555 | @Override 556 | public void idle(final boolean once) throws MessagingException { 557 | 558 | if (Thread.holdsLock(this)) { 559 | logger.error("Thread already hold folder lock, thats not supposed to be the case"); 560 | } 561 | 562 | synchronized (this) { // blocks until folder lock available 563 | checkOpened(); 564 | if (idleState == RUNNING) { 565 | 566 | idleState = IDLE; 567 | // this thread is now idle 568 | 569 | } else { 570 | // another thread must be currently idle 571 | logger.trace("Another thread is idle, return from idle()"); 572 | return; 573 | } 574 | } 575 | 576 | // give up folder lock 577 | 578 | logger.trace("Now idle ..."); 579 | try { 580 | 581 | while (idleState != ABORTING && opened && mailboxFolder.isExists()) { 582 | logger.trace("wait for folder actions"); 583 | idleLock.acquire(); // wait for folder actions, like new mails 584 | logger.trace("folder action happend"); 585 | 586 | if (once) { 587 | logger.trace("once =0 true, so return from idle()"); 588 | break; 589 | } 590 | } 591 | 592 | logger.trace("while loop end with idle state " + idleState); 593 | 594 | } catch (final InterruptedException e) { 595 | Thread.currentThread().interrupt(); 596 | // thread interrupted, set idleState to running and return 597 | } finally { 598 | logger.trace("set idle state to: running"); 599 | idleState = RUNNING; 600 | } 601 | 602 | logger.trace("return from idle()"); 603 | } 604 | 605 | @Override 606 | public boolean isOpen() { 607 | return opened; 608 | } 609 | 610 | @Override 611 | public synchronized boolean isSubscribed() { 612 | abortIdle(); 613 | return mailboxFolder.isSubscribed(); 614 | } 615 | 616 | @Override 617 | public Folder[] list(final String pattern) throws MessagingException { 618 | abortIdle(); 619 | checkExists(); 620 | // TODO evaluate pattern 621 | final List children = mailboxFolder.getChildren(); 622 | final List ret = new ArrayList(); 623 | 624 | for (final MailboxFolder mf : children) { 625 | if (mf.isExists()) { 626 | ret.add(new IMAPMockFolder(store, mf)); 627 | } 628 | } 629 | 630 | logger.debug("Folder (" + getFullName() + ") list return " + ret); 631 | 632 | return ret.toArray(new Folder[ret.size()]); 633 | 634 | } 635 | 636 | @Override 637 | public Folder[] listSubscribed(final String pattern) throws MessagingException { 638 | abortIdle(); 639 | checkExists(); 640 | // TODO evaluate pattern 641 | 642 | final List children = mailboxFolder.getChildren(); 643 | final List ret = new ArrayList(); 644 | 645 | for (final MailboxFolder mf : children) { 646 | if (mf.isExists() && mf.isSubscribed()) { 647 | ret.add(new IMAPMockFolder(store, mf)); 648 | } 649 | } 650 | 651 | logger.debug("Folder (" + getFullName() + ") list subscribed return " + ret); 652 | 653 | return ret.toArray(new Folder[ret.size()]); 654 | } 655 | 656 | @Override 657 | public void messageAdded(final MailboxFolder mf, final MockMessage msg) { 658 | notifyMessageAddedListeners(new Message[] { msg }); 659 | idleLock.release(); 660 | 661 | } 662 | 663 | @Override 664 | public void messageChanged(final MailboxFolder mf, final MockMessage msg, final boolean headerChanged, final boolean flagsChanged) { 665 | notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, msg); 666 | idleLock.release(); 667 | } 668 | 669 | @Override 670 | public void messageExpunged(final MailboxFolder mf, final MockMessage msg, final boolean removed) { 671 | idleLock.release(); 672 | 673 | } 674 | 675 | @Override 676 | public void open(final int mode) throws MessagingException { 677 | checkClosed(); 678 | checkExists(); 679 | opened = true; 680 | openMode = mode; 681 | logger.debug("Open folder " + getFullName() + " (" + objectId + ")"); 682 | notifyConnectionListeners(ConnectionEvent.OPENED); 683 | } 684 | 685 | @Override 686 | public synchronized List open(final int mode, final ResyncData rd) throws MessagingException { 687 | 688 | if (rd == null) { 689 | open(mode); 690 | return null; 691 | } 692 | 693 | throw new MessagingException("CONDSTORE and QRESYNC not supported"); 694 | 695 | } 696 | 697 | @Override 698 | public synchronized boolean renameTo(final Folder f) throws MessagingException { 699 | abortIdle(); 700 | checkClosed(); // insure that we are closed. 701 | checkExists(); 702 | if (f.getStore() != store) { 703 | throw new MessagingException("Can't rename across Stores"); 704 | } 705 | 706 | mailboxFolder.renameFolder(f.getName()); 707 | notifyFolderRenamedListeners(f); 708 | return true; 709 | } 710 | 711 | @Override 712 | public Message[] search(final SearchTerm term) throws MessagingException { 713 | abortIdle(); 714 | checkOpened(); 715 | return mailboxFolder.search(term, null); 716 | } 717 | 718 | @Override 719 | public Message[] search(final SearchTerm term, final Message[] msgs) throws MessagingException { 720 | abortIdle(); 721 | checkOpened(); 722 | return mailboxFolder.search(term, msgs); 723 | } 724 | 725 | @Override 726 | public synchronized void setFlags(final Message[] msgs, final Flags flag, final boolean value) throws MessagingException { 727 | abortIdle(); 728 | checkOpened(); 729 | 730 | for (final Message message : msgs) { 731 | 732 | final Message m = mailboxFolder.getById(((MockMessage) message).getMockid()); 733 | 734 | if (m != null) { 735 | m.setFlags(flag, value); 736 | } 737 | } 738 | 739 | } 740 | 741 | @Override 742 | public void setQuota(final Quota quota) throws MessagingException { 743 | throw new MessagingException("QUOTA not supported"); 744 | } 745 | 746 | @Override 747 | public synchronized void setSubscribed(final boolean subscribe) throws MessagingException { 748 | abortIdle(); 749 | mailboxFolder.setSubscribed(subscribe); 750 | } 751 | 752 | @Override 753 | public void uidInvalidated() { 754 | 755 | // ignore 756 | } 757 | 758 | private Message[] wrap(final Message[] msgs) throws MessagingException { 759 | final Message[] ret = new Message[msgs.length]; 760 | int i = 0; 761 | for (final Message message : msgs) { 762 | ret[i++] = new MockMessage(message, this); 763 | } 764 | return ret; 765 | } 766 | 767 | } 768 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/IMAPMockStore.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import java.util.Collections; 29 | import java.util.HashMap; 30 | import java.util.Map; 31 | import java.util.UUID; 32 | 33 | import javax.mail.Folder; 34 | import javax.mail.MessagingException; 35 | import javax.mail.Quota; 36 | import javax.mail.Session; 37 | import javax.mail.URLName; 38 | import javax.mail.event.ConnectionEvent; 39 | 40 | import com.sun.mail.imap.IMAPStore; 41 | 42 | public class IMAPMockStore extends IMAPStore { 43 | private boolean connected; 44 | protected final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass()); 45 | // private IMAPMockFolder folder; 46 | private MockMailbox mailbox; 47 | private final UUID objectId = UUID.randomUUID(); 48 | 49 | { 50 | logger.warn("IMAP Mock Store in use"); 51 | System.out.println("IMAP Mock Store in use"); 52 | } 53 | 54 | public IMAPMockStore(final Session session, final URLName urlname) { 55 | this(session, urlname, "imap", false); 56 | 57 | } 58 | 59 | public IMAPMockStore(final Session session, final URLName url, final String name, final boolean isSSL) { 60 | super(session, url, name, isSSL); 61 | 62 | logger.debug("Created " + objectId); 63 | } 64 | 65 | protected void checkConnected() throws MessagingException { 66 | if (!isConnected()) { 67 | throw new MessagingException("Not connected"); 68 | } 69 | } 70 | 71 | @Override 72 | public synchronized void close() throws MessagingException { 73 | this.connected = false; 74 | notifyConnectionListeners(ConnectionEvent.CLOSED); 75 | logger.debug("Closed " + objectId); 76 | } 77 | 78 | @Override 79 | public void connect() throws MessagingException { 80 | if (isConnected()) { 81 | throw new IllegalStateException("already connected"); 82 | } 83 | super.connect(url.getHost(), url.getPort(), url.getUsername(), url.getPassword()); 84 | } 85 | 86 | @Override 87 | public void connect(final String user, final String password) throws MessagingException { 88 | if (isConnected()) { 89 | throw new IllegalStateException("already connected"); 90 | } 91 | super.connect(url.getHost(), url.getPort(), user, password); 92 | } 93 | 94 | @Override 95 | public void connect(final String host, final String user, final String password) throws MessagingException { 96 | if (isConnected()) { 97 | throw new IllegalStateException("already connected"); 98 | } 99 | super.connect(host, url.getPort(), user, password); 100 | } 101 | 102 | @Override 103 | public Folder getDefaultFolder() throws MessagingException { 104 | checkConnected(); 105 | 106 | return new IMAPDefaultMockFolder(this, mailbox); 107 | } 108 | 109 | @Override 110 | public Folder getFolder(final String name) throws MessagingException { 111 | checkConnected(); 112 | logger.debug("getFolder(" + name + ")"); 113 | if ("inbox".equalsIgnoreCase(name)) { 114 | return new IMAPMockFolder(this, mailbox.getInbox()); 115 | } else { 116 | 117 | return new IMAPMockFolder(this, mailbox.getRoot().getOrAddSubFolder(name)); 118 | } 119 | } 120 | 121 | @Override 122 | public Folder getFolder(final URLName url) throws MessagingException { 123 | checkConnected(); 124 | return getFolder(url.getFile()); 125 | } 126 | 127 | @Override 128 | public Folder[] getPersonalNamespaces() throws MessagingException { 129 | return new Folder[] { getDefaultFolder() }; 130 | } 131 | 132 | @Override 133 | public synchronized Quota[] getQuota(final String root) throws MessagingException { 134 | throw new MessagingException("QUOTA not supported"); 135 | } 136 | 137 | // /------- 138 | 139 | Session getSession() { 140 | return session; 141 | } 142 | 143 | @Override 144 | public Folder[] getSharedNamespaces() throws MessagingException { 145 | return new Folder[0]; 146 | } 147 | 148 | @Override 149 | public Folder[] getUserNamespaces(final String user) { 150 | return new Folder[0]; 151 | } 152 | 153 | /* (non-Javadoc) 154 | * @see com.sun.mail.imap.IMAPStore#hasCapability(java.lang.String) 155 | */ 156 | @Override 157 | public synchronized boolean hasCapability(final String capability) throws MessagingException { 158 | return capability != null 159 | && (capability.toLowerCase().startsWith("IMAP4") || capability.toLowerCase().startsWith("IDLE") || capability.toLowerCase() 160 | .startsWith("ID")); 161 | } 162 | 163 | @Override 164 | public synchronized Map id(final Map clientParams) throws MessagingException { 165 | checkConnected(); 166 | final Map id = new HashMap(); 167 | 168 | id.put("name", "JavaMail Mock2"); 169 | id.put("vendor", "Hendrik Saly"); 170 | id.put("support-url", "https://github.com/salyh/javamail-mock2/issues"); 171 | 172 | return Collections.unmodifiableMap(id); 173 | 174 | } 175 | 176 | @Override 177 | public void idle() throws MessagingException { 178 | checkConnected(); 179 | 180 | try { 181 | Thread.sleep(1000); 182 | } catch (final InterruptedException e) { 183 | Thread.currentThread().interrupt(); 184 | return; 185 | } 186 | 187 | } 188 | 189 | @Override 190 | public boolean isConnected() { 191 | return this.connected; 192 | } 193 | 194 | @Override 195 | protected boolean protocolConnect(final String host, final int port, final String user, final String password) 196 | throws MessagingException { 197 | logger.debug("Connect to " + user + " (" + objectId + ")"); 198 | mailbox = MockMailbox.get(user); 199 | // folder = new IMAPMockFolder(this, mailbox.getInbox()); 200 | if (mailbox.getInbox().isSimulateError()) { 201 | throw new MessagingException("Simulated error connecting to mailbox of " + user); 202 | } 203 | 204 | this.connected = true; 205 | 206 | return true; 207 | } 208 | 209 | @Override 210 | public synchronized void setQuota(final Quota quota) throws MessagingException { 211 | 212 | throw new MessagingException("QUOTA not supported"); 213 | 214 | } 215 | 216 | } 217 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/IMAPSSLMockStore.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import javax.mail.Session; 29 | import javax.mail.URLName; 30 | 31 | public class IMAPSSLMockStore extends IMAPMockStore { 32 | 33 | public IMAPSSLMockStore(final Session session, final URLName urlname) { 34 | super(session, urlname, "imaps", true); 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/MailboxFolder.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import java.util.ArrayList; 29 | import java.util.Arrays; 30 | import java.util.Collections; 31 | import java.util.HashMap; 32 | import java.util.List; 33 | import java.util.Map; 34 | import java.util.TreeSet; 35 | 36 | import javax.mail.Flags; 37 | import javax.mail.Flags.Flag; 38 | import javax.mail.Message; 39 | import javax.mail.MessagingException; 40 | import javax.mail.UIDFolder; 41 | import javax.mail.internet.MimeMessage; 42 | import javax.mail.search.SearchTerm; 43 | 44 | public class MailboxFolder implements MockMessage.FlagChangeListener { 45 | 46 | public static interface MailboxEventListener { 47 | 48 | void folderCreated(MailboxFolder mf); 49 | 50 | void folderDeleted(MailboxFolder mf); 51 | 52 | void folderRenamed(String from, MailboxFolder to); 53 | 54 | void messageAdded(MailboxFolder mf, MockMessage msg); 55 | 56 | void messageChanged(MailboxFolder mf, MockMessage msg, boolean headerChanged, boolean flagsChanged); // TODO 57 | // header 58 | // change 59 | // can 60 | // not 61 | // happen 62 | // because 63 | // MockMessage 64 | // is 65 | // readonly? 66 | 67 | void messageExpunged(MailboxFolder mf, MockMessage msg, boolean removed); 68 | 69 | void uidInvalidated(); 70 | 71 | } 72 | 73 | public static final char SEPARATOR = '/'; 74 | private final List children = new ArrayList(); 75 | private boolean exists = true; 76 | protected final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass()); 77 | 78 | private final MockMailbox mailbox; 79 | 80 | private volatile List mailboxEventListeners = Collections.synchronizedList(new ArrayList()); 81 | 82 | private final Map messages = new HashMap(); 83 | private String name; 84 | private MailboxFolder parent; 85 | private boolean simulateError = false; 86 | private boolean subscribed; 87 | 88 | private long uidValidity = 50; 89 | 90 | private long uniqueMessageId = 10; 91 | 92 | protected MailboxFolder(final String name, final MockMailbox mb, final boolean exists) { 93 | super(); 94 | 95 | if (name == null) { 96 | this.name = ""; 97 | } else { 98 | this.name = name; 99 | } 100 | 101 | this.mailbox = mb; 102 | this.exists = exists; 103 | 104 | logger.debug("Created " + name + " (exists: " + exists + ")"); 105 | } 106 | 107 | public synchronized Message add(final MimeMessage e) throws MessagingException { 108 | checkExists(); 109 | 110 | uniqueMessageId++; 111 | 112 | final MockMessage mockMessage = new MockMessage(e, uniqueMessageId, this, this); 113 | 114 | mockMessage.setSpecialHeader("Message-ID", String.valueOf(uniqueMessageId)); 115 | mockMessage.setSpecialHeader("X-Mock-Folder", getFullName()); 116 | mockMessage.setFlags(new Flags(Flag.RECENT), true); 117 | // unread.add(e); 118 | 119 | messages.put(uniqueMessageId, mockMessage); 120 | 121 | for (final MailboxEventListener mailboxEventListener : mailboxEventListeners) { 122 | mailboxEventListener.messageAdded(this, mockMessage); 123 | } 124 | 125 | logger.debug("Message ID " + uniqueMessageId + " to " + getFullName() + " added for user " + mailbox.getAddress()); 126 | 127 | return mockMessage; 128 | } 129 | 130 | public synchronized void addMailboxEventListener(final MailboxEventListener l) { 131 | if (l != null) { 132 | mailboxEventListeners.add(l); 133 | } 134 | } 135 | 136 | protected MailboxFolder addSpecialSubFolder(final String name) { 137 | final MailboxFolder mbt = new MailboxFolder(name, mailbox, true); 138 | mbt.parent = this; 139 | children.add(mbt); 140 | return mbt; 141 | } 142 | 143 | protected void checkExists() { 144 | if (!exists) { 145 | throw new IllegalStateException("folder does not exist"); 146 | } 147 | } 148 | 149 | protected void checkFolderName(final String name) { 150 | checkFolderName(name, true); 151 | } 152 | 153 | protected void checkFolderName(final String name, final boolean checkSeparator) { 154 | // TODO regex for valid folder names? 155 | 156 | if (name == null || name.trim().equals("") || name.equalsIgnoreCase("inbox") || checkSeparator 157 | && name.contains(String.valueOf(SEPARATOR))) { 158 | throw new IllegalArgumentException("name '" + name + "' is not valid"); 159 | } 160 | } 161 | 162 | public synchronized MailboxFolder create() { 163 | if (isExists()) { 164 | throw new IllegalStateException("already exists"); 165 | } 166 | checkFolderName(this.name); 167 | 168 | exists = true; 169 | 170 | // TODO set parent and/or children to exists? 171 | 172 | if (parent != null && !parent.isExists()) { 173 | parent.create(); 174 | } 175 | 176 | /*children.clear(); 177 | 178 | if (parent != null) { 179 | parent.children.add(this); 180 | } 181 | 182 | if (mailboxEventListener != null) { 183 | mailboxEventListener.folderCreated(this); 184 | }*/ 185 | 186 | for (final MailboxEventListener mailboxEventListener : mailboxEventListeners) { 187 | mailboxEventListener.folderCreated(this); 188 | } 189 | 190 | logger.debug("Folder " + this.getFullName() + " created"); 191 | return this; 192 | 193 | } 194 | 195 | public synchronized void deleteFolder(final boolean recurse) { 196 | checkExists(); 197 | checkFolderName(this.name); 198 | 199 | if (isRoot()) { 200 | throw new IllegalArgumentException("root cannot be deleted"); 201 | } 202 | 203 | messages.clear(); 204 | // unread.clear(); 205 | 206 | if (recurse) { 207 | for (final MailboxFolder mf : getChildren()) { 208 | mf.deleteFolder(recurse); 209 | } 210 | } 211 | 212 | parent.children.remove(this); 213 | this.exists = false; 214 | 215 | for (final MailboxEventListener mailboxEventListener : mailboxEventListeners) { 216 | mailboxEventListener.folderDeleted(this); 217 | } 218 | logger.debug("Folder " + this.getFullName() + " deleted"); 219 | 220 | } 221 | 222 | @Override 223 | public boolean equals(final Object obj) { 224 | if (this == obj) { 225 | return true; 226 | } 227 | if (obj == null) { 228 | return false; 229 | } 230 | if (getClass() != obj.getClass()) { 231 | return false; 232 | } 233 | final MailboxFolder other = (MailboxFolder) obj; 234 | if (name == null) { 235 | if (other.name != null) { 236 | return false; 237 | } 238 | } else if (!name.equals(other.name)) { 239 | return false; 240 | } 241 | if (parent == null) { 242 | if (other.parent != null) { 243 | return false; 244 | } 245 | } else if (!parent.equals(other.parent)) { 246 | return false; 247 | } 248 | return true; 249 | } 250 | 251 | public synchronized Message[] expunge() throws MessagingException { 252 | checkExists(); 253 | final List expunged = new ArrayList(); 254 | for (final Message msg : getByFlags(new Flags(Flag.DELETED), true)) { 255 | 256 | expunged.add(messages.remove(((MockMessage) msg).getMockid())); 257 | ((MockMessage) msg).setExpunged(true); 258 | 259 | for (final MailboxEventListener mailboxEventListener : mailboxEventListeners) { 260 | mailboxEventListener.messageExpunged(this, (MockMessage) msg, true); 261 | } 262 | } 263 | 264 | logger.debug(expunged.size() + " messages expunged (deleted) from" + getFullName()); 265 | return expunged.toArray(new Message[expunged.size()]); 266 | 267 | } 268 | 269 | public synchronized Message[] expunge(final Message[] msgs) throws MessagingException { 270 | checkExists(); 271 | final List toExpunge = new ArrayList(); 272 | 273 | for (final Message msg : msgs) { 274 | toExpunge.add(((MockMessage) msg).getMockid()); 275 | } 276 | 277 | final List expunged = new ArrayList(); 278 | for (final Message msg : getByFlags(new Flags(Flag.DELETED), true)) { 279 | 280 | if (!toExpunge.contains(new Long(((MockMessage) msg).getMockid()))) { 281 | continue; 282 | } 283 | 284 | expunged.add(messages.remove(((MockMessage) msg).getMockid())); 285 | ((MockMessage) msg).setExpunged(true); 286 | 287 | for (final MailboxEventListener mailboxEventListener : mailboxEventListeners) { 288 | mailboxEventListener.messageExpunged(this, (MockMessage) msg, true); 289 | } 290 | } 291 | 292 | logger.debug(expunged.size() + " messages expunged (deleted) from " + getFullName()); 293 | return expunged.toArray(new Message[expunged.size()]); 294 | 295 | } 296 | 297 | public synchronized Message[] getByFlags(final Flags flags, final boolean mustSet /*final Folder folder*/) throws MessagingException { 298 | checkExists(); 299 | final List sms = new ArrayList(); 300 | int num = 0; 301 | 302 | for (final MockMessage mockMessage : new TreeSet(messages.values())) { 303 | 304 | if (mustSet && mockMessage.getFlags().contains(flags) || !mustSet && !mockMessage.getFlags().contains(flags)) { 305 | mockMessage.setMessageNumber(++num); 306 | // mockMessage.setFolder(folder); 307 | sms.add(mockMessage); 308 | } 309 | 310 | } 311 | logger.debug("getByFlags() for " + getFullName() + " returns " + sms.size()); 312 | return sms.toArray(new Message[sms.size()]); 313 | } 314 | 315 | public synchronized Message getById(final long id /*final Folder folder*/) { 316 | checkExists(); 317 | final Message m = messages.get(id); 318 | 319 | if (m == null) { 320 | 321 | logger.debug("No message with id " + id + ", return null"); 322 | return null; 323 | 324 | } 325 | 326 | // ((MockMessage) m).setFolder(folder); 327 | logger.debug("getById(" + id + ") for " + getFullName() + " returns successful"); 328 | 329 | return m; 330 | } 331 | 332 | // private List unread = new ArrayList(); 333 | 334 | public synchronized Message[] getByIds(final long start, final long end/* final Folder folder*/) { 335 | checkExists(); 336 | final List sms = new ArrayList(); 337 | int num = 0; 338 | 339 | MockMessage lastMsg = null; 340 | 341 | for (final MockMessage mockMessage : new TreeSet(messages.values())) { 342 | 343 | lastMsg = mockMessage; 344 | 345 | if (end == UIDFolder.LASTUID) { 346 | if (getMessageCount() != 1 && mockMessage.getMockid() < start) { // TODO 347 | // check? 348 | continue; 349 | } 350 | } else { 351 | if (mockMessage.getMockid() < start || mockMessage.getMockid() > end) { 352 | continue; 353 | } 354 | } 355 | 356 | mockMessage.setMessageNumber(++num); 357 | // mockMessage.setFolder(folder); 358 | sms.add(mockMessage); 359 | } 360 | 361 | if (end == UIDFolder.LASTUID && sms.size() == 0) { 362 | lastMsg.setMessageNumber(++num); 363 | // lastMsg.setFolder(folder); 364 | sms.add(lastMsg); 365 | } 366 | 367 | logger.debug("getByIds(" + start + "," + end + " for " + getFullName() + " returns " + sms.size()); 368 | return sms.toArray(new Message[sms.size()]); 369 | } 370 | 371 | public synchronized Message[] getByIds(final long[] id /*final Folder folder*/) { 372 | checkExists(); 373 | final List idlist = new ArrayList(); 374 | for (final long value : id) { 375 | idlist.add(value); 376 | } 377 | final List sms = new ArrayList(); 378 | int num = 0; 379 | 380 | for (final MockMessage mockMessage : new TreeSet(messages.values())) { 381 | 382 | if (!idlist.contains(mockMessage.getMockid())) { 383 | continue; 384 | } 385 | 386 | mockMessage.setMessageNumber(++num); 387 | // mockMessage.setFolder(folder); 388 | sms.add(mockMessage); 389 | } 390 | 391 | logger.debug("getByIds(" + Arrays.toString(id) + ") for " + getFullName() + " returns " + sms.size()); 392 | return sms.toArray(new Message[sms.size()]); 393 | } 394 | 395 | public synchronized Message getByMsgNum(final int msgnum/*, final Folder folder*/) { 396 | checkExists(); 397 | final List sms = new ArrayList(); 398 | 399 | int num = 0; 400 | 401 | for (final MockMessage mockMessage : new TreeSet(messages.values())) { 402 | 403 | mockMessage.setMessageNumber(++num); 404 | // mockMessage.setFolder(folder); 405 | sms.add(mockMessage); 406 | } 407 | 408 | logger.debug("getByMsgNum(" + msgnum + "), size is " + sms.size()); 409 | 410 | if (msgnum - 1 < 0 || msgnum > sms.size()) { 411 | throw new ArrayIndexOutOfBoundsException("message number (" + msgnum + ") out of bounds (" + sms.size() + ") for " 412 | + getFullName()); 413 | } 414 | 415 | final Message m = sms.get(msgnum - 1); 416 | return m; 417 | } 418 | 419 | /** 420 | * 421 | * @return Unmodifieable new list copy 422 | */ 423 | public synchronized List getChildren() { 424 | checkExists(); 425 | return Collections.unmodifiableList(new ArrayList(children)); 426 | } 427 | 428 | public synchronized String getFullName() { 429 | // checkExists(); 430 | if (isRoot()) { 431 | return ""; 432 | } 433 | 434 | return parent.isRoot() ? name : parent.getFullName() + SEPARATOR + name; 435 | 436 | } 437 | 438 | /** 439 | * @return the mailbox 440 | */ 441 | public MockMailbox getMailbox() { 442 | return mailbox; 443 | } 444 | 445 | public synchronized int getMessageCount() { 446 | checkExists(); 447 | logger.debug("getMessageCount() for " + getFullName() + " returns " + messages.size()); 448 | return messages.size(); 449 | } 450 | 451 | public synchronized Message[] getMessages(/*final Folder folder*/) { 452 | checkExists(); 453 | final List sms = new ArrayList(); 454 | int num = 0; 455 | 456 | for (final MockMessage mockMessage : new TreeSet(messages.values())) { 457 | 458 | mockMessage.setMessageNumber(++num); 459 | // mockMessage.setFolder(folder); 460 | sms.add(mockMessage); 461 | } 462 | logger.debug("getMessages() for " + getFullName() + " returns " + sms.size()); 463 | return sms.toArray(new Message[sms.size()]); 464 | } 465 | 466 | public String getName() { 467 | return name; 468 | } 469 | 470 | public MailboxFolder getOrAddSubFolder(final String name) throws MessagingException { 471 | // checkExists(); 472 | 473 | if (name == null || "".equals(name.trim())) { 474 | throw new MessagingException("cannot get or add root folder"); 475 | } 476 | 477 | logger.debug("getOrAddSubFolder(" + name + ") on " + getFullName()); 478 | 479 | final String[] path = name.split(String.valueOf(SEPARATOR)); 480 | 481 | MailboxFolder last = this; 482 | for (int i = 0; i < path.length; i++) { 483 | 484 | final String element = path[i]; 485 | 486 | if ("inbox".equalsIgnoreCase(element)) { 487 | last = mailbox.getInbox(); 488 | } else { 489 | checkFolderName(element); 490 | final MailboxFolder mbt = new MailboxFolder(element, mailbox, false); 491 | mbt.parent = last; 492 | 493 | int index = -1; 494 | if ((index = last.children.indexOf(mbt)) != -1) { 495 | 496 | final MailboxFolder tmp = last.children.get(index); 497 | if (tmp.isExists()) { 498 | last = tmp; 499 | continue; 500 | } 501 | } 502 | 503 | last.children.add(mbt); 504 | 505 | logger.debug("Subfolder " + mbt.getFullName() + " added"); 506 | last = mbt; 507 | } 508 | 509 | } 510 | 511 | return last; 512 | 513 | } 514 | 515 | public synchronized MailboxFolder getParent() { 516 | checkExists(); 517 | return parent; 518 | } 519 | 520 | public synchronized int getSizeInBytes() throws MessagingException { 521 | checkExists(); 522 | int size = 0; 523 | 524 | for (final MockMessage mockMessage : new TreeSet(messages.values())) { 525 | 526 | if (mockMessage.getSize() > 0) { 527 | size += mockMessage.getSize(); 528 | } 529 | 530 | } 531 | 532 | return size; 533 | } 534 | 535 | public synchronized long getUID(final Message msg) { 536 | checkExists(); 537 | return ((MockMessage) msg).getMockid(); 538 | } 539 | 540 | /** 541 | * @return the uidValidity 542 | */ 543 | public synchronized long getUidValidity() { 544 | checkExists(); 545 | return uidValidity; 546 | } 547 | 548 | /** 549 | * @return the uniqueMessageId 550 | */ 551 | protected long getUniqueMessageId() { 552 | return uniqueMessageId; 553 | } 554 | 555 | @Override 556 | public int hashCode() { 557 | final int prime = 31; 558 | int result = 1; 559 | result = prime * result + (name == null ? 0 : name.hashCode()); 560 | result = prime * result + (parent == null ? 0 : parent.hashCode()); 561 | return result; 562 | } 563 | 564 | public synchronized boolean hasMessages() { 565 | checkExists(); 566 | return messages.isEmpty(); 567 | } 568 | 569 | public synchronized void invalidateUid() { 570 | checkExists(); 571 | uidValidity += 10; 572 | 573 | for (final MailboxEventListener mailboxEventListener : mailboxEventListeners) { 574 | mailboxEventListener.uidInvalidated(); 575 | } 576 | logger.debug("UidValidity invalidated, new UidValidity is " + uidValidity); 577 | } 578 | 579 | /** 580 | * @return the exists 581 | */ 582 | public boolean isExists() { 583 | return exists; 584 | } 585 | 586 | public boolean isInbox() { 587 | return name != null && name.equalsIgnoreCase("inbox"); 588 | } 589 | 590 | public boolean isRoot() { 591 | return name == null || name.equals("") || parent == null; 592 | } 593 | 594 | /** 595 | * @return the simulateError 596 | */ 597 | public boolean isSimulateError() { 598 | return simulateError; 599 | } 600 | 601 | protected boolean isSubscribed() { 602 | return subscribed; 603 | } 604 | 605 | public synchronized void markMessageAsDeleted(final Message e) throws MessagingException { 606 | checkExists(); 607 | ((MockMessage) e).setFlag(Flag.DELETED, true); 608 | // if(mailboxEventListener!=null) 609 | // mailboxEventListener.messageRemoved(this, ((MockMessage)e), false); 610 | logger.debug("Mark message " + ((MockMessage) e).getMockid() + " as deleted (Flag DELETED set)"); 611 | } 612 | 613 | public synchronized void markMessageAsSeen(final Message e) throws MessagingException { 614 | checkExists(); 615 | ((MockMessage) e).setFlag(Flag.SEEN, true); 616 | // if(mailboxEventListener!=null) 617 | // mailboxEventListener.messageRemoved(this, ((MockMessage)e), false); 618 | logger.debug("Mark message " + ((MockMessage) e).getMockid() + " as seen (Flag SEEN set)"); 619 | } 620 | 621 | @Override 622 | public void onFlagChange(final MockMessage msg, final Flags flags, final boolean set) { 623 | 624 | for (final MailboxEventListener mailboxEventListener : mailboxEventListeners) { 625 | mailboxEventListener.messageChanged(this, msg, false, true); 626 | } 627 | 628 | logger.debug("Flags of message " + msg.getMockid() + " change"); 629 | 630 | if (messages.size() > 0 && messages.get(msg.getMockid()) != null) { 631 | try { 632 | if (set && messages.get(msg.getMockid()).getFlags().contains(flags)) { 633 | return; 634 | 635 | } 636 | 637 | if (set && !messages.get(msg.getMockid()).getFlags().contains(flags)) { 638 | messages.get(msg.getMockid()).setFlags(flags, set); 639 | 640 | } 641 | 642 | if (!set && messages.get(msg.getMockid()).getFlags().contains(flags)) { 643 | messages.get(msg.getMockid()).setFlags(flags, set); 644 | 645 | } 646 | 647 | if (!set && !messages.get(msg.getMockid()).getFlags().contains(flags)) { 648 | return; 649 | 650 | } 651 | } catch (final Exception e) { 652 | logger.error("Error while changing flags " + e.toString(), e); 653 | } 654 | } 655 | 656 | } 657 | 658 | public synchronized void removeMailboxEventListener(final MailboxEventListener l) { 659 | if (l != null) { 660 | mailboxEventListeners.remove(l); 661 | } 662 | } 663 | 664 | public synchronized void renameFolder(final String newName) { 665 | checkExists(); 666 | checkFolderName(this.name); 667 | checkFolderName(newName); 668 | final String tmpOldName = name; 669 | 670 | name = newName; 671 | 672 | for (final MailboxEventListener mailboxEventListener : mailboxEventListeners) { 673 | mailboxEventListener.folderRenamed(tmpOldName, this); 674 | } 675 | 676 | // TODO purge old folders, exists =false 677 | 678 | // TODO notify children? 679 | /*for (MailboxFolder mf: children) { 680 | renameFolder(mf.name); //do not really change name of children, just notify because parent changes 681 | }*/ 682 | 683 | logger.debug("Folder " + tmpOldName + " renamed to " + newName + newName + " - New Fullname is " + this.getFullName()); 684 | 685 | } 686 | 687 | public Message[] search(final SearchTerm term, final Message[] msgsToSearch) { 688 | final List sms = new ArrayList(); 689 | final List msgsToSearchL = new ArrayList(); 690 | 691 | if (msgsToSearch != null) { 692 | msgsToSearchL.addAll(Arrays.asList(msgsToSearch)); 693 | } 694 | 695 | for (final Message msg : getMessages()) { 696 | if (term != null && term.match(msg)) { 697 | 698 | if (msgsToSearch == null || msgsToSearchL.contains(msg)) { 699 | sms.add((MockMessage) msg); 700 | } 701 | } 702 | } 703 | return sms.toArray(new Message[sms.size()]); 704 | } 705 | 706 | /** 707 | * @param simulateError 708 | * the simulateError to set 709 | */ 710 | public void setSimulateError(final boolean simulateError) { 711 | this.simulateError = simulateError; 712 | } 713 | 714 | protected void setSubscribed(final boolean subscribed) { 715 | this.subscribed = subscribed; 716 | } 717 | } 718 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/MockMailbox.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import java.util.HashMap; 29 | import java.util.Map; 30 | 31 | import javax.mail.Address; 32 | import javax.mail.internet.AddressException; 33 | import javax.mail.internet.InternetAddress; 34 | 35 | public class MockMailbox { 36 | 37 | private static final Map mailboxes = new HashMap(); 38 | 39 | public synchronized static MockMailbox get(final Address a) { 40 | MockMailbox mb = mailboxes.get(a); 41 | if (mb == null) { 42 | mailboxes.put(a, mb = new MockMailbox(a)); 43 | } 44 | return mb; 45 | } 46 | 47 | public static MockMailbox get(final String address) throws AddressException { 48 | return get(new InternetAddress(address)); 49 | } 50 | 51 | public static void resetAll() { 52 | 53 | mailboxes.clear(); 54 | 55 | } 56 | 57 | private final Address address; 58 | private final MailboxFolder inbox; 59 | 60 | private final MailboxFolder root = new MailboxFolder("", this, true); 61 | 62 | private MockMailbox(final Address address) { 63 | super(); 64 | this.address = address; 65 | inbox = root.addSpecialSubFolder("INBOX"); 66 | } 67 | 68 | private MockMailbox(final String address) throws AddressException { 69 | this(new InternetAddress(address)); 70 | } 71 | 72 | /** 73 | * @return the address 74 | */ 75 | public Address getAddress() { 76 | return address; 77 | } 78 | 79 | public MailboxFolder getInbox() { 80 | return inbox; 81 | } 82 | 83 | public MailboxFolder getRoot() { 84 | return root; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/MockMessage.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import java.util.Date; 29 | 30 | import javax.activation.DataHandler; 31 | import javax.mail.Address; 32 | import javax.mail.Flags; 33 | import javax.mail.Folder; 34 | import javax.mail.IllegalWriteException; 35 | import javax.mail.Message; 36 | import javax.mail.MessagingException; 37 | import javax.mail.Multipart; 38 | import javax.mail.internet.MimeMessage; 39 | 40 | public class MockMessage extends MimeMessage implements Comparable { 41 | 42 | public static interface FlagChangeListener { 43 | void onFlagChange(MockMessage msg, Flags flags, boolean set); 44 | } 45 | 46 | private final FlagChangeListener flagChangeListener; 47 | private Folder folder; 48 | protected final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass()); 49 | private final MailboxFolder mbf; 50 | 51 | private final long mockid; 52 | 53 | protected MockMessage(final Message source, final Folder folder) throws MessagingException { 54 | this((MimeMessage) source, ((MockMessage) source).mockid, ((MockMessage) source).mbf, ((MockMessage) source).flagChangeListener); 55 | this.folder = folder; 56 | this.setMessageNumber(source.getMessageNumber()); 57 | } 58 | 59 | protected MockMessage(final MimeMessage source, final long mockid, final MailboxFolder mbf, final FlagChangeListener flagChangeListener) 60 | throws MessagingException { 61 | super(source); 62 | this.mockid = mockid; 63 | this.flagChangeListener = flagChangeListener; 64 | this.mbf = mbf; 65 | 66 | } 67 | 68 | /* (non-Javadoc) 69 | * @see javax.mail.internet.MimeMessage#addFrom(javax.mail.Address[]) 70 | */ 71 | @Override 72 | public void addFrom(final Address[] addresses) throws MessagingException { 73 | 74 | throw new IllegalWriteException("Mock messages are read-only"); 75 | } 76 | 77 | /* (non-Javadoc) 78 | * @see javax.mail.internet.MimeMessage#addHeader(java.lang.String, java.lang.String) 79 | */ 80 | @Override 81 | public void addHeader(final String name, final String value) throws MessagingException { 82 | throw new IllegalWriteException("Mock messages are read-only"); 83 | } 84 | 85 | /* (non-Javadoc) 86 | * @see javax.mail.internet.MimeMessage#addHeaderLine(java.lang.String) 87 | */ 88 | @Override 89 | public void addHeaderLine(final String line) throws MessagingException { 90 | throw new IllegalWriteException("Mock messages are read-only"); 91 | } 92 | 93 | /* (non-Javadoc) 94 | * @see javax.mail.Message#addRecipient(javax.mail.Message.RecipientType, javax.mail.Address) 95 | */ 96 | @Override 97 | public void addRecipient(final javax.mail.Message.RecipientType type, final Address address) throws MessagingException { 98 | throw new IllegalWriteException("Mock messages are read-only"); 99 | } 100 | 101 | /* (non-Javadoc) 102 | * @see javax.mail.internet.MimeMessage#addRecipients(javax.mail.Message.RecipientType, javax.mail.Address[]) 103 | */ 104 | @Override 105 | public void addRecipients(final javax.mail.Message.RecipientType type, final Address[] addresses) throws MessagingException { 106 | throw new IllegalWriteException("Mock messages are read-only"); 107 | } 108 | 109 | /* (non-Javadoc) 110 | * @see javax.mail.internet.MimeMessage#addRecipients(javax.mail.Message.RecipientType, java.lang.String) 111 | */ 112 | @Override 113 | public void addRecipients(final javax.mail.Message.RecipientType type, final String addresses) throws MessagingException { 114 | throw new IllegalWriteException("Mock messages are read-only"); 115 | } 116 | 117 | @Override 118 | public int compareTo(final MockMessage o) { 119 | 120 | return new Long(this.getMockid()).compareTo(new Long(o.getMockid())); 121 | } 122 | 123 | @Override 124 | public synchronized Folder getFolder() { 125 | if (folder == null) { 126 | throw new RuntimeException("wrong/unshaded mock message"); 127 | } else { 128 | return folder; 129 | } 130 | } 131 | 132 | // IllegalWriteException("Mock messages are read-only"); 133 | 134 | /** 135 | * @return the mockid 136 | */ 137 | public long getMockid() { 138 | return mockid; 139 | } 140 | 141 | /* (non-Javadoc) 142 | * @see javax.mail.internet.MimeMessage#removeHeader(java.lang.String) 143 | */ 144 | @Override 145 | public void removeHeader(final String name) throws MessagingException { 146 | throw new IllegalWriteException("Mock messages are read-only"); 147 | } 148 | 149 | /* (non-Javadoc) 150 | * @see javax.mail.internet.MimeMessage#saveChanges() 151 | */ 152 | @Override 153 | public void saveChanges() throws MessagingException { 154 | throw new IllegalWriteException("Mock messages are read-only"); 155 | } 156 | 157 | /* (non-Javadoc) 158 | * @see javax.mail.internet.MimeMessage#setContent(javax.mail.Multipart) 159 | */ 160 | @Override 161 | public void setContent(final Multipart mp) throws MessagingException { 162 | throw new IllegalWriteException("Mock messages are read-only"); 163 | } 164 | 165 | /* (non-Javadoc) 166 | * @see javax.mail.internet.MimeMessage#setContent(java.lang.Object, java.lang.String) 167 | */ 168 | @Override 169 | public void setContent(final Object o, final String type) throws MessagingException { 170 | throw new IllegalWriteException("Mock messages are read-only"); 171 | } 172 | 173 | /* (non-Javadoc) 174 | * @see javax.mail.internet.MimeMessage#setContentID(java.lang.String) 175 | */ 176 | @Override 177 | public void setContentID(final String cid) throws MessagingException { 178 | throw new IllegalWriteException("Mock messages are read-only"); 179 | } 180 | 181 | /* (non-Javadoc) 182 | * @see javax.mail.internet.MimeMessage#setContentLanguage(java.lang.String[]) 183 | */ 184 | @Override 185 | public void setContentLanguage(final String[] languages) throws MessagingException { 186 | throw new IllegalWriteException("Mock messages are read-only"); 187 | } 188 | 189 | /* (non-Javadoc) 190 | * @see javax.mail.internet.MimeMessage#setContentMD5(java.lang.String) 191 | */ 192 | @Override 193 | public void setContentMD5(final String md5) throws MessagingException { 194 | throw new IllegalWriteException("Mock messages are read-only"); 195 | } 196 | 197 | @Override 198 | public void setDataHandler(final DataHandler content) throws MessagingException { 199 | throw new IllegalWriteException("Mock messages are read-only"); 200 | } 201 | 202 | /* (non-Javadoc) 203 | * @see javax.mail.internet.MimeMessage#setDescription(java.lang.String) 204 | */ 205 | @Override 206 | public void setDescription(final String description) throws MessagingException { 207 | throw new IllegalWriteException("Mock messages are read-only"); 208 | } 209 | 210 | /* (non-Javadoc) 211 | * @see javax.mail.internet.MimeMessage#setDescription(java.lang.String, java.lang.String) 212 | */ 213 | @Override 214 | public void setDescription(final String description, final String charset) throws MessagingException { 215 | throw new IllegalWriteException("Mock messages are read-only"); 216 | } 217 | 218 | /* (non-Javadoc) 219 | * @see javax.mail.internet.MimeMessage#setDisposition(java.lang.String) 220 | */ 221 | @Override 222 | public void setDisposition(final String disposition) throws MessagingException { 223 | throw new IllegalWriteException("Mock messages are read-only"); 224 | } 225 | 226 | @Override 227 | protected void setExpunged(final boolean expunged) { 228 | 229 | super.setExpunged(expunged); 230 | } 231 | 232 | /* (non-Javadoc) 233 | * @see javax.mail.internet.MimeMessage#setFileName(java.lang.String) 234 | */ 235 | @Override 236 | public void setFileName(final String filename) throws MessagingException { 237 | throw new IllegalWriteException("Mock messages are read-only"); 238 | } 239 | 240 | /* (non-Javadoc) 241 | * @see javax.mail.internet.MimeMessage#setFlags(javax.mail.Flags, boolean) 242 | */ 243 | @Override 244 | public synchronized void setFlags(final Flags flag, final boolean set) throws MessagingException { 245 | 246 | super.setFlags(flag, set); 247 | 248 | if (flagChangeListener != null) { 249 | flagChangeListener.onFlagChange(this, flag, set); 250 | } 251 | 252 | } 253 | 254 | /* (non-Javadoc) 255 | * @see javax.mail.internet.MimeMessage#setFrom() 256 | */ 257 | @Override 258 | public void setFrom() throws MessagingException { 259 | throw new IllegalWriteException("Mock messages are read-only"); 260 | } 261 | 262 | /* (non-Javadoc) 263 | * @see javax.mail.internet.MimeMessage#setFrom(javax.mail.Address) 264 | */ 265 | @Override 266 | public void setFrom(final Address address) throws MessagingException { 267 | throw new IllegalWriteException("Mock messages are read-only"); 268 | } 269 | 270 | /* (non-Javadoc) 271 | * @see javax.mail.internet.MimeMessage#setFrom(java.lang.String) 272 | */ 273 | @Override 274 | public void setFrom(final String address) throws MessagingException { 275 | throw new IllegalWriteException("Mock messages are read-only"); 276 | } 277 | 278 | /* (non-Javadoc) 279 | * @see javax.mail.internet.MimeMessage#setHeader(java.lang.String, java.lang.String) 280 | */ 281 | @Override 282 | public void setHeader(final String name, final String value) throws MessagingException { 283 | throw new IllegalWriteException("Mock messages are read-only"); 284 | } 285 | 286 | @Override 287 | protected void setMessageNumber(final int msgnum) { 288 | 289 | super.setMessageNumber(msgnum); 290 | } 291 | 292 | /* (non-Javadoc) 293 | * @see javax.mail.Message#setRecipient(javax.mail.Message.RecipientType, javax.mail.Address) 294 | */ 295 | @Override 296 | public void setRecipient(final javax.mail.Message.RecipientType type, final Address address) throws MessagingException { 297 | throw new IllegalWriteException("Mock messages are read-only"); 298 | } 299 | 300 | /* (non-Javadoc) 301 | * @see javax.mail.internet.MimeMessage#setRecipients(javax.mail.Message.RecipientType, javax.mail.Address[]) 302 | */ 303 | @Override 304 | public void setRecipients(final javax.mail.Message.RecipientType type, final Address[] addresses) throws MessagingException { 305 | throw new IllegalWriteException("Mock messages are read-only"); 306 | } 307 | 308 | /* (non-Javadoc) 309 | * @see javax.mail.internet.MimeMessage#setRecipients(javax.mail.Message.RecipientType, java.lang.String) 310 | */ 311 | @Override 312 | public void setRecipients(final javax.mail.Message.RecipientType type, final String addresses) throws MessagingException { 313 | throw new IllegalWriteException("Mock messages are read-only"); 314 | } 315 | 316 | /* (non-Javadoc) 317 | * @see javax.mail.internet.MimeMessage#setReplyTo(javax.mail.Address[]) 318 | */ 319 | @Override 320 | public void setReplyTo(final Address[] addresses) throws MessagingException { 321 | throw new IllegalWriteException("Mock messages are read-only"); 322 | } 323 | 324 | /* (non-Javadoc) 325 | * @see javax.mail.internet.MimeMessage#setSender(javax.mail.Address) 326 | */ 327 | @Override 328 | public void setSender(final Address address) throws MessagingException { 329 | throw new IllegalWriteException("Mock messages are read-only"); 330 | } 331 | 332 | /* (non-Javadoc) 333 | * @see javax.mail.internet.MimeMessage#setSentDate(java.util.Date) 334 | */ 335 | @Override 336 | public void setSentDate(final Date d) throws MessagingException { 337 | throw new IllegalWriteException("Mock messages are read-only"); 338 | } 339 | 340 | void setSpecialHeader(final String name, final String value) throws MessagingException { 341 | super.addHeader(name, value); 342 | } 343 | 344 | /* (non-Javadoc) 345 | * @see javax.mail.internet.MimeMessage#setSubject(java.lang.String) 346 | */ 347 | @Override 348 | public void setSubject(final String subject) throws MessagingException { 349 | throw new IllegalWriteException("Mock messages are read-only"); 350 | } 351 | 352 | /* (non-Javadoc) 353 | * @see javax.mail.internet.MimeMessage#setSubject(java.lang.String, java.lang.String) 354 | */ 355 | @Override 356 | public void setSubject(final String subject, final String charset) throws MessagingException { 357 | throw new IllegalWriteException("Mock messages are read-only"); 358 | } 359 | 360 | /* (non-Javadoc) 361 | * @see javax.mail.internet.MimeMessage#setText(java.lang.String) 362 | */ 363 | @Override 364 | public void setText(final String text) throws MessagingException { 365 | throw new IllegalWriteException("Mock messages are read-only"); 366 | } 367 | 368 | /* (non-Javadoc) 369 | * @see javax.mail.internet.MimeMessage#setText(java.lang.String, java.lang.String) 370 | */ 371 | @Override 372 | public void setText(final String text, final String charset) throws MessagingException { 373 | throw new IllegalWriteException("Mock messages are read-only"); 374 | } 375 | 376 | /* (non-Javadoc) 377 | * @see javax.mail.internet.MimeMessage#setText(java.lang.String, java.lang.String, java.lang.String) 378 | */ 379 | @Override 380 | public void setText(final String text, final String charset, final String subtype) throws MessagingException { 381 | throw new IllegalWriteException("Mock messages are read-only"); 382 | } 383 | 384 | } 385 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/MockTransport.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import javax.mail.Address; 29 | import javax.mail.Message; 30 | import javax.mail.MessagingException; 31 | import javax.mail.Session; 32 | import javax.mail.Transport; 33 | import javax.mail.URLName; 34 | import javax.mail.event.ConnectionEvent; 35 | import javax.mail.event.TransportEvent; 36 | import javax.mail.internet.MimeMessage; 37 | 38 | public class MockTransport extends Transport { 39 | 40 | protected final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass()); 41 | 42 | { 43 | logger.warn("Mock Transport in use"); 44 | System.out.println("Mock Transport in use"); 45 | } 46 | 47 | public MockTransport(final Session session, final URLName urlname) { 48 | super(session, urlname); 49 | 50 | } 51 | 52 | @Override 53 | public void connect(final String host, final int port, final String user, final String password) throws MessagingException { 54 | 55 | if (isConnected()) { 56 | throw new IllegalStateException("already connected"); 57 | } 58 | 59 | setConnected(true); 60 | 61 | notifyConnectionListeners(ConnectionEvent.OPENED); 62 | } 63 | 64 | @Override 65 | public void sendMessage(final Message msg, final Address[] addresses) throws MessagingException { 66 | for (final Address a : addresses) { 67 | final MockMailbox mailbox = MockMailbox.get(a); 68 | if (mailbox.getInbox().isSimulateError()) { 69 | 70 | notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED, new Address[0], addresses, new Address[0], msg); 71 | 72 | throw new MessagingException("Simulated error sending message to " + a); 73 | 74 | } 75 | 76 | mailbox.getInbox().add(new MimeMessage((MimeMessage) msg)); 77 | notifyTransportListeners(TransportEvent.MESSAGE_DELIVERED, addresses, new Address[0], new Address[0], msg); 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/POP3MockFolder.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import java.io.IOException; 29 | import java.io.InputStream; 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | import java.util.UUID; 33 | 34 | import javax.mail.FetchProfile; 35 | import javax.mail.FolderClosedException; 36 | import javax.mail.Message; 37 | import javax.mail.MessagingException; 38 | import javax.mail.MethodNotSupportedException; 39 | import javax.mail.event.ConnectionEvent; 40 | import javax.mail.event.MessageChangedEvent; 41 | 42 | import com.sun.mail.pop3.POP3MockFolder0; 43 | 44 | import de.saly.javamail.mock2.MailboxFolder.MailboxEventListener; 45 | 46 | public class POP3MockFolder extends POP3MockFolder0 implements MailboxEventListener { 47 | protected final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass()); 48 | private final MailboxFolder mailboxFolder; 49 | private final UUID objectId = UUID.randomUUID(); 50 | private volatile boolean opened; 51 | 52 | { 53 | logger.warn("POP3 Mock Store in use"); 54 | System.out.println("POP3 Mock Store in use"); 55 | } 56 | 57 | protected POP3MockFolder(final POP3MockStore store, final MailboxFolder mailboxFolder) { 58 | super(store); 59 | this.mailboxFolder = mailboxFolder; 60 | this.mailboxFolder.addMailboxEventListener(this); 61 | } 62 | 63 | /* 64 | * TODO superclass ok? 65 | public Folder getParent(){ 66 | return null; 67 | } 68 | */ 69 | 70 | protected synchronized void checkClosed() { 71 | if (opened) { 72 | throw new IllegalStateException("This operation is not allowed on an open folder " + objectId); 73 | } 74 | } 75 | 76 | protected synchronized void checkOpened() throws FolderClosedException { 77 | 78 | if (!opened) { 79 | 80 | throw new IllegalStateException("This operation is not allowed on a closed folder " + objectId); 81 | 82 | } 83 | } 84 | 85 | @Override 86 | public synchronized void close(final boolean expunge) throws MessagingException { 87 | checkOpened(); 88 | 89 | if (expunge) { 90 | mailboxFolder.expunge(); 91 | 92 | } 93 | 94 | opened = false; 95 | 96 | logger.debug("Folder closed " + objectId); 97 | notifyConnectionListeners(ConnectionEvent.CLOSED); 98 | } 99 | 100 | @Override 101 | public void fetch(final Message[] msgs, final FetchProfile fp) throws MessagingException { 102 | // just do nothing 103 | } 104 | 105 | @Override 106 | public void folderCreated(final MailboxFolder mf) { 107 | // not valid for pop3 108 | 109 | } 110 | 111 | @Override 112 | public void folderDeleted(final MailboxFolder mf) { 113 | // not valid for pop3 114 | 115 | } 116 | 117 | @Override 118 | public void folderRenamed(final String from, final MailboxFolder to) { 119 | // not valid for pop3 120 | 121 | } 122 | 123 | @Override 124 | public synchronized Message getMessage(final int msgnum) throws MessagingException { 125 | checkOpened(); 126 | return new MockMessage(mailboxFolder.getByMsgNum(msgnum), this); 127 | } 128 | 129 | @Override 130 | public synchronized int getMessageCount() throws MessagingException { 131 | return mailboxFolder.getMessageCount(); 132 | } 133 | 134 | @Override 135 | public synchronized Message[] getMessages() throws MessagingException { 136 | checkOpened(); 137 | final List messages = new ArrayList(); 138 | for (int i = 1; i <= mailboxFolder.getMessageCount(); i++) { 139 | final Message m = mailboxFolder.getByMsgNum(i); 140 | messages.add(new MockMessage(m, this)); 141 | } 142 | return messages.toArray(new Message[messages.size()]); 143 | } 144 | 145 | @Override 146 | public synchronized Message[] getMessages(final int low, final int high) throws MessagingException { 147 | 148 | checkOpened(); 149 | final List messages = new ArrayList(); 150 | for (int i = low; i <= high; i++) { 151 | final Message m = mailboxFolder.getByMsgNum(i); 152 | messages.add(new MockMessage(m, this)); 153 | } 154 | return messages.toArray(new Message[messages.size()]); 155 | } 156 | 157 | @Override 158 | public synchronized Message[] getMessages(final int[] msgnums) throws MessagingException { 159 | checkOpened(); 160 | 161 | final List idlist = new ArrayList(); 162 | for (final int value : msgnums) { 163 | idlist.add(value); 164 | } 165 | 166 | final List messages = new ArrayList(); 167 | 168 | for (int i = 1; i <= mailboxFolder.getMessageCount(); i++) { 169 | 170 | if (!idlist.contains(new Integer(i))) { 171 | continue; 172 | } 173 | 174 | final Message m = mailboxFolder.getByMsgNum(i); 175 | messages.add(new MockMessage(m, this)); 176 | } 177 | return messages.toArray(new Message[messages.size()]); 178 | } 179 | 180 | @Override 181 | public synchronized int getSize() throws MessagingException { 182 | checkOpened(); 183 | return mailboxFolder.getSizeInBytes(); 184 | } 185 | 186 | @Override 187 | public synchronized int[] getSizes() throws MessagingException { 188 | checkOpened(); 189 | final int count = getMessageCount(); 190 | final int[] sizes = new int[count]; 191 | 192 | for (int i = 1; i <= count; i++) { 193 | sizes[i - 1] = getMessage(i).getSize(); 194 | } 195 | 196 | return sizes; 197 | 198 | } 199 | 200 | @Override 201 | public synchronized String getUID(final Message msg) throws MessagingException { 202 | checkOpened(); 203 | return String.valueOf(((MockMessage) msg).getMockid()); 204 | } 205 | 206 | @Override 207 | public boolean isOpen() { 208 | return opened; 209 | } 210 | 211 | @Override 212 | public InputStream listCommand() throws MessagingException, IOException { 213 | throw new MethodNotSupportedException(); 214 | } 215 | 216 | @Override 217 | public void messageAdded(final MailboxFolder mf, final MockMessage msg) { 218 | // ignore 219 | // TODO JavaMail impl seems to not fire a event here for pop3, so we 220 | // ignore it 221 | 222 | } 223 | 224 | @Override 225 | public void messageChanged(final MailboxFolder mf, final MockMessage msg, final boolean headerChanged, final boolean flagsChanged) { 226 | notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, msg); 227 | 228 | } 229 | 230 | @Override 231 | public void messageExpunged(final MailboxFolder mf, final MockMessage msg, final boolean removed) { 232 | // not valid for pop3 233 | 234 | } 235 | 236 | @Override 237 | public synchronized void open(final int mode) throws MessagingException { 238 | checkClosed(); 239 | opened = true; 240 | logger.debug("Open " + objectId); 241 | notifyConnectionListeners(ConnectionEvent.OPENED); 242 | } 243 | 244 | @Override 245 | public void uidInvalidated() { 246 | // not valid for pop3 247 | 248 | } 249 | 250 | } 251 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/POP3MockStore.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import java.util.HashMap; 29 | import java.util.Map; 30 | import java.util.UUID; 31 | 32 | import javax.mail.Folder; 33 | import javax.mail.MessagingException; 34 | import javax.mail.Session; 35 | import javax.mail.URLName; 36 | import javax.mail.event.ConnectionEvent; 37 | 38 | import com.sun.mail.pop3.POP3Store; 39 | 40 | public class POP3MockStore extends POP3Store { 41 | 42 | private volatile boolean connected; 43 | protected final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass()); 44 | private MockMailbox mailbox; 45 | private final UUID objectId = UUID.randomUUID(); 46 | 47 | public POP3MockStore(final Session session, final URLName urlname) { 48 | this(session, urlname, "pop3", false); 49 | 50 | } 51 | 52 | public POP3MockStore(final Session session, final URLName url, final String name, final boolean isSSL) { 53 | super(session, url, name, isSSL); 54 | 55 | logger.debug("Created " + objectId); 56 | } 57 | 58 | @SuppressWarnings("rawtypes") 59 | @Override 60 | public Map capabilities() throws MessagingException { 61 | 62 | return new HashMap(); 63 | } 64 | 65 | protected synchronized void checkConnected() throws MessagingException { 66 | if (!isConnected()) { 67 | throw new MessagingException("Not connected"); 68 | } 69 | } 70 | 71 | @Override 72 | public synchronized void close() throws MessagingException { 73 | connected = false; 74 | mailbox = null; 75 | notifyConnectionListeners(ConnectionEvent.CLOSED); 76 | logger.debug("Closed " + objectId); 77 | } 78 | 79 | @Override 80 | public synchronized void connect() throws MessagingException { 81 | if (isConnected()) { 82 | throw new IllegalStateException("already connected"); 83 | } 84 | super.connect(url.getHost(), url.getPort(), url.getUsername(), url.getPassword()); 85 | } 86 | 87 | @Override 88 | public synchronized void connect(final String user, final String password) throws MessagingException { 89 | if (isConnected()) { 90 | throw new IllegalStateException("already connected"); 91 | } 92 | super.connect(url.getHost(), url.getPort(), user, password); 93 | } 94 | 95 | @Override 96 | public synchronized void connect(final String host, final String user, final String password) throws MessagingException { 97 | if (isConnected()) { 98 | throw new IllegalStateException("already connected"); 99 | } 100 | super.connect(host, url.getPort(), user, password); 101 | } 102 | 103 | @Override 104 | public synchronized Folder getDefaultFolder() throws MessagingException { 105 | checkConnected(); 106 | return super.getDefaultFolder(); 107 | } 108 | 109 | @Override 110 | public synchronized Folder getFolder(final String name) throws MessagingException { 111 | checkConnected(); 112 | if ("inbox".equalsIgnoreCase(name)) { 113 | return new POP3MockFolder(this, mailbox.getInbox()); 114 | } 115 | 116 | return new POP3MockFolder(this, new MailboxFolder(name, mailbox, false)); 117 | 118 | } 119 | 120 | @Override 121 | public synchronized Folder getFolder(final URLName url) throws MessagingException { 122 | checkConnected(); 123 | return getFolder(url.getFile()); 124 | } 125 | 126 | synchronized Session getSession() { 127 | return session; 128 | } 129 | 130 | @Override 131 | public synchronized boolean isConnected() { 132 | return connected; 133 | } 134 | 135 | @Override 136 | protected synchronized boolean protocolConnect(final String host, final int port, final String user, final String password) 137 | throws MessagingException { 138 | logger.debug("Connect to " + user + " (" + objectId + ")"); 139 | mailbox = MockMailbox.get(user); 140 | // folder = new POP3MockFolder(this, mailbox.getInbox()); 141 | if (mailbox.getInbox().isSimulateError()) { 142 | throw new MessagingException("Simulated error connecting to mailbox of " + user); 143 | } 144 | this.connected = true; 145 | return true; 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/POP3SSLMockStore.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import javax.mail.Session; 29 | import javax.mail.URLName; 30 | 31 | public class POP3SSLMockStore extends POP3MockStore { 32 | 33 | public POP3SSLMockStore(final Session session, final URLName urlname) { 34 | super(session, urlname, "pop3s", true); 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/de/saly/javamail/mock2/Providers.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2; 27 | 28 | import javax.mail.Provider; 29 | 30 | public final class Providers { 31 | 32 | public static Provider getIMAPProvider(final String protocol, final boolean secure, final boolean mock) { 33 | if (mock) { 34 | return new Provider(Provider.Type.STORE, protocol, secure ? "de.saly.javamail.mock2.IMAPSSLMockStore" 35 | : "de.saly.javamail.mock2.IMAPMockStore", "JavaMail Mock2 provider", null); 36 | } 37 | 38 | return new Provider(Provider.Type.STORE, protocol, secure ? "com.sun.mail.imap.IMAPSSLStore" : "com.sun.mail.imap.IMAPStore", 39 | "Oracle", null); 40 | 41 | } 42 | 43 | public static Provider getPOP3Provider(final String protocol, final boolean secure, final boolean mock) { 44 | if (mock) { 45 | return new Provider(Provider.Type.STORE, protocol, secure ? "de.saly.javamail.mock2.POP3SSLMockStore" 46 | : "de.saly.javamail.mock2.POP3MockStore", "JavaMail Mock2 provider", null); 47 | } 48 | 49 | return new Provider(Provider.Type.STORE, protocol, secure ? "com.sun.mail.pop3.POP3SSLStore" : "com.sun.mail.pop3.POP3Store", 50 | "Oracle", null); 51 | 52 | } 53 | 54 | public static Provider getSMTPProvider(final String protocol, final boolean secure, final boolean mock) { 55 | if (mock) { 56 | return new Provider(Provider.Type.TRANSPORT, protocol, "de.saly.javamail.mock2.MockTransport", "JavaMail Mock2 provider", null); 57 | } 58 | 59 | return new Provider(Provider.Type.TRANSPORT, protocol, secure ? "com.sun.mail.smtp.SMTPSSLTransport" 60 | : "com.sun.mail.smtp.SMTPTransport", "Oracle", null); 61 | } 62 | 63 | private Providers() { 64 | // empty 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/javamail.providers: -------------------------------------------------------------------------------- 1 | protocol=mock_smtp; type=transport; class=de.saly.javamail.mock2.MockTransport; vendor=JavaMail Mock2 provider; 2 | protocol=mock_smtps; type=transport; class=de.saly.javamail.mock2.MockTransport; vendor=JavaMail Mock2 provider; 3 | protocol=mock_pop3; type=store; class=de.saly.javamail.mock2.POP3MockStore; vendor=JavaMail Mock2 provider; 4 | protocol=mock_imap; type=store; class=de.saly.javamail.mock2.IMAPMockStore; vendor=JavaMail Mock2 provider; 5 | protocol=mock_pop3s; type=store; class=de.saly.javamail.mock2.POP3SSLMockStore; vendor=JavaMail Mock2 provider; 6 | protocol=mock_imaps; type=store; class=de.saly.javamail.mock2.IMAPSSLMockStore; vendor=JavaMail Mock2 provider; 7 | #Override real providers 8 | protocol=smtp${mock.postfix}; type=transport; class=de.saly.javamail.mock2.MockTransport; vendor=JavaMail Mock2 provider; 9 | protocol=smtps${mock.postfix}; type=transport; class=de.saly.javamail.mock2.MockTransport; vendor=JavaMail Mock2 provider; 10 | protocol=pop3${mock.postfix}; type=store; class=de.saly.javamail.mock2.POP3MockStore; vendor=JavaMail Mock2 provider; 11 | protocol=imap${mock.postfix}; type=store; class=de.saly.javamail.mock2.IMAPMockStore; vendor=JavaMail Mock2 provider; 12 | protocol=pop3s${mock.postfix}; type=store; class=de.saly.javamail.mock2.POP3SSLMockStore; vendor=JavaMail Mock2 provider; 13 | protocol=imaps${mock.postfix}; type=store; class=de.saly.javamail.mock2.IMAPSSLMockStore; vendor=JavaMail Mock2 provider; 14 | -------------------------------------------------------------------------------- /src/test/java/de/saly/javamail/mock2/test/AbstractTestCase.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2.test; 27 | 28 | import java.util.Properties; 29 | 30 | import javax.mail.Session; 31 | 32 | import org.junit.After; 33 | import org.junit.Before; 34 | import org.junit.Rule; 35 | import org.junit.rules.TestName; 36 | 37 | import de.saly.javamail.mock2.MockMailbox; 38 | 39 | public abstract class AbstractTestCase { 40 | 41 | protected final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(this.getClass()); 42 | @Rule 43 | public TestName name = new TestName(); 44 | protected Session session = null; 45 | 46 | protected Properties getProperties() { 47 | final Properties props = new Properties(); 48 | return props; 49 | } 50 | 51 | @Before 52 | public void setUp() throws Exception { 53 | 54 | System.out.println("--------------------- SETUP " + name.getMethodName() + " -------------------------------------"); 55 | 56 | final Properties props = getProperties(); 57 | if (logger.isDebugEnabled()) { 58 | props.setProperty("mail.debug", "true"); 59 | } 60 | 61 | session = Session.getInstance(props); 62 | 63 | MockMailbox.resetAll(); 64 | 65 | } 66 | 67 | @After 68 | public void tearDown() throws Exception { 69 | 70 | System.out.println("--------------------- TEARDOWN " + name.getMethodName() + " -------------------------------------"); 71 | session = null; 72 | 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/test/java/de/saly/javamail/mock2/test/IMAPTestCase.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2.test; 27 | 28 | import java.util.Arrays; 29 | import java.util.Properties; 30 | 31 | import javax.mail.Flags.Flag; 32 | import javax.mail.Folder; 33 | import javax.mail.Message; 34 | import javax.mail.Message.RecipientType; 35 | import javax.mail.MessagingException; 36 | import javax.mail.Session; 37 | import javax.mail.Store; 38 | import javax.mail.UIDFolder; 39 | import javax.mail.event.MessageCountEvent; 40 | import javax.mail.event.MessageCountListener; 41 | import javax.mail.internet.InternetAddress; 42 | import javax.mail.internet.MimeMessage; 43 | 44 | import org.junit.Assert; 45 | import org.junit.Test; 46 | 47 | import com.sun.mail.imap.IMAPFolder; 48 | import com.sun.mail.imap.IMAPStore; 49 | 50 | import de.saly.javamail.mock2.MailboxFolder; 51 | import de.saly.javamail.mock2.MockMailbox; 52 | import de.saly.javamail.mock2.Providers; 53 | import de.saly.javamail.mock2.test.support.MockTestException; 54 | 55 | public class IMAPTestCase extends AbstractTestCase { 56 | 57 | private static class IdleMessageCountListener implements MessageCountListener { 58 | 59 | private int addedCount; 60 | private int removedCount; 61 | 62 | protected int getAddedCount() { 63 | return addedCount; 64 | } 65 | 66 | protected int getRemovedCount() { 67 | return removedCount; 68 | } 69 | 70 | @Override 71 | public void messagesAdded(final MessageCountEvent e) { 72 | addedCount++; 73 | 74 | } 75 | 76 | @Override 77 | public void messagesRemoved(final MessageCountEvent e) { 78 | removedCount++; 79 | 80 | } 81 | 82 | } 83 | 84 | private static class IdleThread extends Thread { 85 | private Exception exception; 86 | private final Folder folder; 87 | private int idleCount; 88 | 89 | public IdleThread(final Folder folder) { 90 | super(); 91 | this.folder = folder; 92 | } 93 | 94 | protected Exception getException() { 95 | return exception; 96 | } 97 | 98 | protected int getIdleCount() { 99 | return idleCount; 100 | } 101 | 102 | @Override 103 | public void run() { 104 | 105 | while (!Thread.interrupted()) { 106 | try { 107 | // System.out.println("enter idle"); 108 | ((IMAPFolder) folder).idle(); 109 | idleCount++; 110 | // System.out.println("leave idle"); 111 | } catch (final Exception e) { 112 | exception = e; 113 | } 114 | } 115 | 116 | // System.out.println("leave run()"); 117 | } 118 | } 119 | 120 | @Override 121 | protected Properties getProperties() { 122 | 123 | final Properties props = super.getProperties(); 124 | props.setProperty("mail.store.protocol", "mock_imaps"); 125 | return props; 126 | } 127 | 128 | @Test(expected = MockTestException.class) 129 | public void testACLUnsupported() throws Exception { 130 | 131 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 132 | final MailboxFolder mf = mb.getInbox(); 133 | 134 | final MimeMessage msg = new MimeMessage((Session) null); 135 | msg.setSubject("Test"); 136 | msg.setFrom("from@sender.com"); 137 | msg.setText("Some text here ..."); 138 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 139 | mf.add(msg); // 11 140 | mf.add(msg); // 12 141 | mf.add(msg); // 13 142 | mb.getRoot().getOrAddSubFolder("test").create().add(msg); 143 | 144 | final Store store = session.getStore("mock_imap"); 145 | store.connect("hendrik@unknown.com", null); 146 | final Folder defaultFolder = store.getDefaultFolder(); 147 | final Folder test = defaultFolder.getFolder("test"); 148 | 149 | final IMAPFolder testImap = (IMAPFolder) test; 150 | 151 | try { 152 | testImap.getACL(); 153 | } catch (final MessagingException e) { 154 | throw new MockTestException(e); 155 | } 156 | 157 | } 158 | 159 | @Test 160 | public void testAddMessages() throws Exception { 161 | 162 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 163 | final MailboxFolder mf = mb.getInbox(); 164 | 165 | final MimeMessage msg = new MimeMessage((Session) null); 166 | msg.setSubject("Test"); 167 | msg.setFrom("from@sender.com"); 168 | msg.setText("Some text here ..."); 169 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 170 | mf.add(msg); // 11 171 | mf.add(msg); // 12 172 | mf.add(msg); // 13 173 | 174 | final Store store = session.getStore(); 175 | store.connect("hendrik@unknown.com", null); 176 | final Folder inbox = store.getFolder("INBOX"); 177 | inbox.open(Folder.READ_WRITE); 178 | Assert.assertEquals(3, inbox.getMessageCount()); 179 | Assert.assertNotNull(inbox.getMessage(1)); 180 | 181 | inbox.close(true); 182 | 183 | Assert.assertEquals(3, inbox.getMessageCount()); 184 | 185 | inbox.open(Folder.READ_WRITE); 186 | inbox.getMessage(1).setFlag(Flag.DELETED, true); 187 | 188 | inbox.close(true); 189 | 190 | Assert.assertEquals(2, inbox.getMessageCount()); 191 | Assert.assertTrue(inbox instanceof UIDFolder); 192 | inbox.open(Folder.READ_WRITE); 193 | Assert.assertEquals(12L, ((UIDFolder) inbox).getUID(inbox.getMessage(1))); 194 | inbox.close(true); 195 | } 196 | 197 | @Test 198 | // (expected = MockTestException.class) 199 | public void testAppendFailMessage() throws Exception { 200 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 201 | final MailboxFolder mf = mb.getInbox(); 202 | 203 | final MimeMessage msg = new MimeMessage((Session) null); 204 | msg.setSubject("Test"); 205 | msg.setFrom("from@sender.com"); 206 | msg.setText("Some text here ..."); 207 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 208 | mf.add(msg); // 11 209 | mf.add(msg); // 12 210 | mf.add(msg); // 13 211 | mb.getRoot().getOrAddSubFolder("test").create().add(msg); 212 | 213 | final Store store = session.getStore(); 214 | store.connect("hendrik@unknown.com", null); 215 | final Folder defaultFolder = store.getDefaultFolder(); 216 | final Folder inbox = defaultFolder.getFolder("INBOX"); 217 | 218 | inbox.open(Folder.READ_ONLY); 219 | 220 | try { 221 | inbox.appendMessages(new MimeMessage[] { msg }); 222 | } catch (final IllegalStateException e) { 223 | // throw new MockTestException(e); 224 | } 225 | 226 | // Assert.fail("Exception expected before this point"); 227 | 228 | Assert.assertEquals(4, inbox.getMessageCount()); 229 | 230 | inbox.close(false); 231 | 232 | } 233 | 234 | @Test 235 | public void testAppendMessage() throws Exception { 236 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 237 | final MailboxFolder mf = mb.getInbox(); 238 | 239 | final MimeMessage msg = new MimeMessage((Session) null); 240 | msg.setSubject("Test"); 241 | msg.setFrom("from@sender.com"); 242 | msg.setText("Some text here ..."); 243 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 244 | mf.add(msg); // 11 245 | mf.add(msg); // 12 246 | mf.add(msg); // 13 247 | mb.getRoot().getOrAddSubFolder("test").create().add(msg); 248 | 249 | final Store store = session.getStore(Providers.getIMAPProvider("makes_no_difference_here", true, true)); 250 | store.connect("hendrik@unknown.com", null); 251 | final Folder defaultFolder = store.getDefaultFolder(); 252 | final Folder inbox = defaultFolder.getFolder("INBOX"); 253 | 254 | inbox.open(Folder.READ_WRITE); 255 | 256 | inbox.appendMessages(new MimeMessage[] { msg }); 257 | 258 | Assert.assertEquals(4, inbox.getMessageCount()); 259 | 260 | inbox.close(true); 261 | 262 | } 263 | 264 | @Test 265 | public void testDefaultFolder() throws Exception { 266 | 267 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 268 | final MailboxFolder mf = mb.getInbox(); 269 | 270 | final MimeMessage msg = new MimeMessage((Session) null); 271 | msg.setSubject("Test"); 272 | msg.setFrom("from@sender.com"); 273 | msg.setText("Some text here ..."); 274 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 275 | mf.add(msg); // 11 276 | mf.add(msg); // 12 277 | mf.add(msg); // 13 278 | mb.getRoot().getOrAddSubFolder("test").create().add(msg); 279 | 280 | final Store store = session.getStore("mock_imaps"); 281 | store.connect("hendrik@unknown.com", null); 282 | final Folder defaultFolder = store.getDefaultFolder(); 283 | final Folder inbox = defaultFolder.getFolder("INBOX"); 284 | 285 | inbox.open(Folder.READ_WRITE); 286 | 287 | Assert.assertEquals("[INBOX, test]", Arrays.toString(defaultFolder.list())); 288 | 289 | Assert.assertEquals(3, inbox.getMessageCount()); 290 | Assert.assertNotNull(inbox.getMessage(1)); 291 | 292 | inbox.close(true); 293 | 294 | Assert.assertEquals(3, inbox.getMessageCount()); 295 | 296 | inbox.open(Folder.READ_WRITE); 297 | inbox.getMessage(1).setFlag(Flag.DELETED, true); 298 | 299 | inbox.close(true); 300 | inbox.open(Folder.READ_WRITE); 301 | Assert.assertEquals(2, inbox.getMessageCount()); 302 | Assert.assertTrue(inbox instanceof UIDFolder); 303 | Assert.assertEquals(12L, ((UIDFolder) inbox).getUID(inbox.getMessage(1))); 304 | inbox.close(true); 305 | } 306 | 307 | @Test 308 | public void testIDLESupported() throws Exception { 309 | 310 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 311 | final MailboxFolder mf = mb.getInbox(); 312 | 313 | final MimeMessage msg = new MimeMessage((Session) null); 314 | msg.setSubject("Test"); 315 | msg.setFrom("from@sender.com"); 316 | msg.setText("Some text here ..."); 317 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 318 | mf.add(msg); // 11 319 | mf.add(msg); // 12 320 | mf.add(msg); // 13 321 | mb.getRoot().getOrAddSubFolder("test").create().add(msg); 322 | 323 | final Store store = session.getStore("mock_imap"); 324 | store.connect("hendrik@unknown.com", null); 325 | final Folder defaultFolder = store.getDefaultFolder(); 326 | final IMAPFolder test = (IMAPFolder) defaultFolder.getFolder("test"); 327 | 328 | final IdleMessageCountListener mcl = new IdleMessageCountListener(); 329 | test.addMessageCountListener(mcl); 330 | 331 | test.open(Folder.READ_WRITE); 332 | 333 | final IdleThread it = new IdleThread(test); 334 | it.start(); 335 | 336 | test.addMessages(new Message[] { msg }); 337 | test.addMessages(new Message[] { msg }); 338 | test.addMessages(new Message[] { msg }); 339 | 340 | Thread.sleep(500); 341 | 342 | it.interrupt(); 343 | it.join(); 344 | 345 | test.close(true); 346 | 347 | Assert.assertNull(it.getException()); 348 | Assert.assertEquals(3, mcl.getAddedCount()); 349 | Assert.assertEquals(0, mcl.getRemovedCount()); 350 | Assert.assertEquals(4, test.getMessageCount()); 351 | 352 | } 353 | 354 | @Test 355 | public void testNotOnlyInbox() throws Exception { 356 | 357 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 358 | final MailboxFolder mf = mb.getInbox(); 359 | 360 | final MimeMessage msg = new MimeMessage((Session) null); 361 | msg.setSubject("Test"); 362 | msg.setFrom("from@sender.com"); 363 | msg.setText("Some text here ..."); 364 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 365 | mf.add(msg); // 11 366 | mf.add(msg); // 12 367 | mf.add(msg); // 13 368 | mb.getRoot().getOrAddSubFolder("test").create().add(msg); 369 | 370 | final Store store = session.getStore("mock_imap"); 371 | store.connect("hendrik@unknown.com", null); 372 | final Folder defaultFolder = store.getDefaultFolder(); 373 | final Folder test = defaultFolder.getFolder("test"); 374 | 375 | Assert.assertNotNull(test); 376 | 377 | final Folder inbox = defaultFolder.getFolder("INBOX"); 378 | 379 | Assert.assertNotNull(inbox); 380 | 381 | } 382 | 383 | @Test(expected = MockTestException.class) 384 | public void testQUOTAUnsupported() throws Exception { 385 | 386 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 387 | final MailboxFolder mf = mb.getInbox(); 388 | 389 | final MimeMessage msg = new MimeMessage((Session) null); 390 | msg.setSubject("Test"); 391 | msg.setFrom("from@sender.com"); 392 | msg.setText("Some text here ..."); 393 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 394 | mf.add(msg); // 11 395 | mf.add(msg); // 12 396 | mf.add(msg); // 13 397 | mb.getRoot().getOrAddSubFolder("test").create().add(msg); 398 | 399 | final Store store = session.getStore("mock_imap"); 400 | store.connect("hendrik@unknown.com", null); 401 | final Folder defaultFolder = store.getDefaultFolder(); 402 | final Folder test = defaultFolder.getFolder("test"); 403 | 404 | final IMAPStore imapStore = (IMAPStore) store; 405 | 406 | try { 407 | imapStore.getQuota(""); 408 | } catch (final MessagingException e) { 409 | throw new MockTestException(e); 410 | } 411 | 412 | } 413 | 414 | @Test 415 | public void testRenameWithSubfolder() throws Exception { 416 | 417 | // final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 418 | 419 | final MimeMessage msg = new MimeMessage((Session) null); 420 | msg.setSubject("Test"); 421 | msg.setFrom("from@sender.com"); 422 | msg.setText("Some text here ..."); 423 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 424 | 425 | final Store store = session.getStore("mock_imap"); 426 | store.connect("hendrik@unknown.com", null); 427 | final Folder root = store.getDefaultFolder(); 428 | final Folder level1 = root.getFolder("LEVEL1"); 429 | level1.create(Folder.HOLDS_FOLDERS | Folder.HOLDS_MESSAGES); 430 | final Folder level2 = level1.getFolder("LEVEL2"); 431 | level2.create(Folder.HOLDS_FOLDERS | Folder.HOLDS_MESSAGES); 432 | level1.appendMessages(new Message[] { msg, msg }); 433 | level2.appendMessages(new Message[] { msg }); 434 | 435 | Assert.assertTrue(level1.exists()); 436 | Assert.assertEquals("LEVEL1", level1.getFullName()); 437 | Assert.assertEquals("LEVEL1", level1.getName()); 438 | Assert.assertEquals(2, level1.getMessageCount()); 439 | 440 | Assert.assertTrue(level2.exists()); 441 | Assert.assertEquals("LEVEL1/LEVEL2", level2.getFullName()); 442 | Assert.assertEquals("LEVEL2", level2.getName()); 443 | Assert.assertEquals(1, level2.getMessageCount()); 444 | Assert.assertEquals(2, root.list().length); 445 | 446 | // getFolder creates a store 447 | level1.renameTo(store.getFolder("LEVEL-1R")); 448 | 449 | // TODO really need a create? 450 | Assert.assertTrue(!store.getFolder("LEVEL1").exists()); 451 | 452 | Assert.assertTrue(level1.exists()); 453 | Assert.assertEquals("LEVEL-1R", level1.getFullName()); 454 | Assert.assertEquals("LEVEL-1R", level1.getName()); 455 | Assert.assertEquals(2, level1.getMessageCount()); 456 | 457 | Assert.assertTrue(level2.exists()); 458 | Assert.assertEquals("LEVEL-1R/LEVEL2", level2.getFullName()); 459 | Assert.assertEquals("LEVEL2", level2.getName()); 460 | Assert.assertEquals(1, level2.getMessageCount()); 461 | 462 | Assert.assertEquals(2, root.list().length); 463 | } 464 | 465 | } 466 | -------------------------------------------------------------------------------- /src/test/java/de/saly/javamail/mock2/test/MailboxFolderTestCase.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2.test; 27 | 28 | import javax.mail.IllegalWriteException; 29 | import javax.mail.Message.RecipientType; 30 | import javax.mail.Session; 31 | import javax.mail.internet.InternetAddress; 32 | import javax.mail.internet.MimeMessage; 33 | 34 | import org.junit.Assert; 35 | import org.junit.Test; 36 | 37 | import de.saly.javamail.mock2.MailboxFolder; 38 | import de.saly.javamail.mock2.MockMailbox; 39 | import de.saly.javamail.mock2.test.support.MockTestException; 40 | 41 | public class MailboxFolderTestCase extends AbstractTestCase { 42 | 43 | @Test 44 | public void testAddFolder() throws Exception { 45 | 46 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); // TODO 47 | // spam 48 | // protection, 49 | // dont 50 | // use 51 | // real 52 | // email 53 | final MailboxFolder mf = mb.getInbox(); 54 | final MailboxFolder archive2013 = mf.getOrAddSubFolder("Archive").getOrAddSubFolder("2013").create(); 55 | Assert.assertEquals("INBOX/Archive/2013", archive2013.getFullName()); 56 | Assert.assertEquals(1, mf.getChildren().size()); 57 | Assert.assertEquals(1, mf.getChildren().get(0).getChildren().size()); 58 | } 59 | 60 | @Test 61 | public void testAddMessages() throws Exception { 62 | 63 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 64 | final MailboxFolder mf = mb.getInbox(); 65 | 66 | final MimeMessage msg = new MimeMessage((Session) null); 67 | msg.setSubject("Test"); 68 | msg.setFrom("from@sender.com"); 69 | msg.setText("Some text here ..."); 70 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 71 | mf.add(msg); 72 | 73 | Assert.assertEquals(1, mf.getMessageCount()); 74 | Assert.assertNotNull(mf.getByMsgNum(1)); 75 | Assert.assertEquals(msg.getSubject(), mf.getByMsgNum(1).getSubject()); 76 | 77 | mf.add(msg); 78 | mf.add(msg); 79 | Assert.assertEquals(3, mf.getMessageCount()); 80 | Assert.assertNotNull(mf.getByMsgNum(3)); 81 | Assert.assertEquals(msg.getSubject(), mf.getByMsgNum(3).getSubject()); 82 | 83 | } 84 | 85 | @Test 86 | public void testDeleteFolder() throws Exception { 87 | 88 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 89 | final MailboxFolder mf = mb.getInbox(); 90 | final MailboxFolder archive2013 = mf.getOrAddSubFolder("Archive").getOrAddSubFolder("2013").create(); 91 | archive2013.deleteFolder(true); 92 | Assert.assertEquals(1, mf.getChildren().size()); 93 | Assert.assertEquals(0, mf.getChildren().get(0).getChildren().size()); 94 | } 95 | 96 | @Test 97 | public void testInitialize() throws Exception { 98 | 99 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 100 | Assert.assertNotNull(mb.getInbox()); 101 | Assert.assertNotNull(mb.getRoot()); 102 | 103 | Assert.assertEquals("INBOX", mb.getInbox().getFullName()); 104 | Assert.assertEquals("INBOX", mb.getInbox().getName()); 105 | 106 | Assert.assertEquals("", mb.getRoot().getFullName()); 107 | Assert.assertEquals("", mb.getRoot().getName()); 108 | 109 | Assert.assertEquals(1, mb.getRoot().getChildren().size()); 110 | Assert.assertEquals(0, mb.getInbox().getChildren().size()); 111 | Assert.assertEquals(0, mb.getInbox().getMessageCount()); 112 | } 113 | 114 | @Test(expected = MockTestException.class) 115 | public void testMockMessagesReadonly() throws Exception { 116 | 117 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 118 | final MailboxFolder mf = mb.getInbox(); 119 | 120 | final MimeMessage msg = new MimeMessage((Session) null); 121 | msg.setSubject("Test"); 122 | msg.setFrom("from@sender.com"); 123 | msg.setText("Some text here ..."); 124 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 125 | mf.add(msg); 126 | 127 | try { 128 | mf.getByMsgNum(1).setHeader("test", "test"); 129 | } catch (final IllegalWriteException e) { 130 | throw new MockTestException(e); 131 | } 132 | 133 | } 134 | 135 | @Test 136 | public void testRenameFolder() throws Exception { 137 | 138 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 139 | final MailboxFolder mf = mb.getInbox(); 140 | final MailboxFolder archive = mf.getOrAddSubFolder("Archive"); 141 | final MailboxFolder archive2013 = archive.getOrAddSubFolder("2013").create(); 142 | archive.renameFolder("dummy"); 143 | Assert.assertEquals("INBOX/dummy/2013", archive2013.getFullName()); 144 | } 145 | 146 | @Test 147 | public void testUIDMessages() throws Exception { 148 | 149 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 150 | final MailboxFolder mf = mb.getInbox(); 151 | 152 | final MimeMessage msg = new MimeMessage((Session) null); 153 | msg.setSubject("Test"); 154 | msg.setFrom("from@sender.com"); 155 | msg.setText("Some text here ..."); 156 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 157 | mf.add(msg); 158 | mf.add(msg); 159 | mf.add(msg); 160 | 161 | Assert.assertTrue(mf.getUID(mf.getByMsgNum(3)) > 0); 162 | Assert.assertNotNull(mf.getById(mf.getUID(mf.getByMsgNum(3)))); 163 | 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /src/test/java/de/saly/javamail/mock2/test/Main.java: -------------------------------------------------------------------------------- 1 | package de.saly.javamail.mock2.test; 2 | 3 | import java.util.Properties; 4 | 5 | import javax.mail.Folder; 6 | import javax.mail.Message; 7 | import javax.mail.Message.RecipientType; 8 | import javax.mail.Session; 9 | import javax.mail.Store; 10 | import javax.mail.event.MessageCountEvent; 11 | import javax.mail.event.MessageCountListener; 12 | import javax.mail.internet.InternetAddress; 13 | import javax.mail.internet.MimeMessage; 14 | 15 | import com.sun.mail.imap.IMAPFolder; 16 | 17 | import de.saly.javamail.mock2.MailboxFolder; 18 | import de.saly.javamail.mock2.MockMailbox; 19 | 20 | public class Main { 21 | 22 | private static class IdleMessageCountListener implements MessageCountListener { 23 | 24 | private int addedCount; 25 | private int removedCount; 26 | 27 | protected int getAddedCount() { 28 | return addedCount; 29 | } 30 | 31 | protected int getRemovedCount() { 32 | return removedCount; 33 | } 34 | 35 | @Override 36 | public void messagesAdded(final MessageCountEvent e) { 37 | addedCount++; 38 | 39 | } 40 | 41 | @Override 42 | public void messagesRemoved(final MessageCountEvent e) { 43 | removedCount++; 44 | 45 | } 46 | 47 | } 48 | 49 | private static class IdleThread extends Thread { 50 | private Exception exception; 51 | private final Folder folder; 52 | private int idleCount; 53 | 54 | public IdleThread(final Folder folder) { 55 | super(); 56 | this.folder = folder; 57 | } 58 | 59 | protected Exception getException() { 60 | return exception; 61 | } 62 | 63 | protected int getIdleCount() { 64 | return idleCount; 65 | } 66 | 67 | @Override 68 | public void run() { 69 | 70 | while (!Thread.interrupted()) { 71 | try { 72 | // System.out.println("enter idle"); 73 | ((IMAPFolder) folder).idle(); 74 | idleCount++; 75 | // System.out.println("leave idle"); 76 | Thread.sleep(500); 77 | } catch (final Exception e) { 78 | exception = e; 79 | } 80 | } 81 | 82 | // System.out.println("leave run()"); 83 | } 84 | } 85 | 86 | protected static Properties getProperties() { 87 | 88 | final Properties props = new Properties(); 89 | props.setProperty("mail.store.protocol", "mock_imaps"); 90 | return props; 91 | } 92 | 93 | public static void main(final String[] args) throws Exception { 94 | 95 | final Session session = Session.getInstance(getProperties()); 96 | 97 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 98 | final MailboxFolder mf = mb.getInbox(); 99 | 100 | final MimeMessage msg = new MimeMessage((Session) null); 101 | msg.setSubject("Test"); 102 | msg.setFrom("from@sender.com"); 103 | msg.setText("Some text here ..."); 104 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 105 | mf.add(msg); // 11 106 | mf.add(msg); // 12 107 | mf.add(msg); // 13 108 | mb.getRoot().getOrAddSubFolder("test").create().add(msg); 109 | 110 | final Store store = session.getStore("mock_imap"); 111 | store.connect("hendrik@unknown.com", null); 112 | final Folder defaultFolder = store.getDefaultFolder(); 113 | final IMAPFolder test = (IMAPFolder) defaultFolder.getFolder("test"); 114 | 115 | final IdleMessageCountListener mcl = new IdleMessageCountListener(); 116 | test.addMessageCountListener(mcl); 117 | 118 | test.open(Folder.READ_WRITE); 119 | 120 | final IdleThread it = new IdleThread(test); 121 | it.start(); 122 | 123 | final IdleThread it2 = new IdleThread(test); 124 | it2.start(); 125 | 126 | test.addMessages(new Message[] { msg }); 127 | test.addMessages(new Message[] { msg }); 128 | test.addMessages(new Message[] { msg }); 129 | 130 | // test.close(true); 131 | 132 | System.out.println(it.getException()); 133 | System.out.println(mcl.getAddedCount()); 134 | System.out.println(mcl.getRemovedCount()); 135 | System.out.println(test.getMessageCount()); 136 | System.out.println(it.getIdleCount()); 137 | 138 | // System.exit(1); 139 | 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /src/test/java/de/saly/javamail/mock2/test/POP3TestCase.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2.test; 27 | 28 | import java.util.Arrays; 29 | import java.util.Properties; 30 | 31 | import javax.mail.Flags.Flag; 32 | import javax.mail.Folder; 33 | import javax.mail.Message.RecipientType; 34 | import javax.mail.MessagingException; 35 | import javax.mail.Session; 36 | import javax.mail.Store; 37 | import javax.mail.internet.InternetAddress; 38 | import javax.mail.internet.MimeMessage; 39 | 40 | import org.junit.Assert; 41 | import org.junit.Test; 42 | 43 | import com.sun.mail.pop3.POP3Folder; 44 | 45 | import de.saly.javamail.mock2.MailboxFolder; 46 | import de.saly.javamail.mock2.MockMailbox; 47 | import de.saly.javamail.mock2.Providers; 48 | import de.saly.javamail.mock2.test.support.MockTestException; 49 | 50 | public class POP3TestCase extends AbstractTestCase { 51 | 52 | @Override 53 | protected Properties getProperties() { 54 | 55 | final Properties props = super.getProperties(); 56 | props.setProperty("mail.store.protocol", "mock_pop3s"); 57 | return props; 58 | } 59 | 60 | @Test 61 | public void testAddMessages() throws Exception { 62 | 63 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 64 | final MailboxFolder mf = mb.getInbox(); 65 | 66 | final MimeMessage msg = new MimeMessage((Session) null); 67 | msg.setSubject("Test"); 68 | msg.setFrom("from@sender.com"); 69 | msg.setText("Some text here ..."); 70 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 71 | mf.add(msg); // 11 72 | mf.add(msg); // 12 73 | mf.add(msg); // 13 74 | 75 | final Store store = session.getStore(); 76 | store.connect("hendrik@unknown.com", null); 77 | final Folder inbox = store.getFolder("INBOX"); 78 | inbox.open(Folder.READ_ONLY); 79 | Assert.assertEquals(3, inbox.getMessageCount()); 80 | Assert.assertNotNull(inbox.getMessage(1)); 81 | 82 | inbox.close(true); 83 | 84 | Assert.assertEquals(3, inbox.getMessageCount()); 85 | 86 | inbox.open(Folder.READ_ONLY); 87 | inbox.getMessage(1).setFlag(Flag.DELETED, true); 88 | 89 | inbox.close(true); 90 | inbox.open(Folder.READ_ONLY); 91 | Assert.assertEquals(2, inbox.getMessageCount()); 92 | Assert.assertTrue(inbox instanceof POP3Folder); 93 | Assert.assertEquals("12", ((POP3Folder) inbox).getUID(inbox.getMessage(1))); 94 | inbox.close(true); 95 | } 96 | 97 | @Test 98 | public void testDefaultFolder() throws Exception { 99 | 100 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 101 | final MailboxFolder mf = mb.getInbox(); 102 | 103 | final MimeMessage msg = new MimeMessage((Session) null); 104 | msg.setSubject("Test"); 105 | msg.setFrom("from@sender.com"); 106 | msg.setText("Some text here ..."); 107 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 108 | mf.add(msg); // 11 109 | mf.add(msg); // 12 110 | mf.add(msg); // 13 111 | mb.getRoot().getOrAddSubFolder("test").create().add(msg); 112 | 113 | final Store store = session.getStore("mock_pop3"); 114 | store.connect("hendrik@unknown.com", null); 115 | final Folder defaultFolder = store.getDefaultFolder(); 116 | final Folder inbox = defaultFolder.getFolder("INBOX"); 117 | 118 | inbox.open(Folder.READ_WRITE); 119 | 120 | Assert.assertEquals("[INBOX]", Arrays.toString(defaultFolder.list())); 121 | 122 | Assert.assertEquals(3, inbox.getMessageCount()); 123 | Assert.assertNotNull(inbox.getMessage(1)); 124 | 125 | inbox.close(true); 126 | 127 | Assert.assertEquals(3, inbox.getMessageCount()); 128 | 129 | inbox.open(Folder.READ_ONLY); 130 | inbox.getMessage(1).setFlag(Flag.DELETED, true); 131 | 132 | inbox.close(true); 133 | inbox.open(Folder.READ_WRITE); 134 | Assert.assertEquals(2, inbox.getMessageCount()); 135 | Assert.assertTrue(inbox instanceof POP3Folder); 136 | Assert.assertEquals("12", ((POP3Folder) inbox).getUID(inbox.getMessage(1))); 137 | inbox.close(true); 138 | } 139 | 140 | @Test(expected = MockTestException.class) 141 | public void testOnlyInbox() throws Exception { 142 | 143 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 144 | final MailboxFolder mf = mb.getInbox(); 145 | 146 | final MimeMessage msg = new MimeMessage((Session) null); 147 | msg.setSubject("Test"); 148 | msg.setFrom("from@sender.com"); 149 | msg.setText("Some text here ..."); 150 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 151 | mf.add(msg); // 11 152 | mf.add(msg); // 12 153 | mf.add(msg); // 13 154 | mb.getRoot().getOrAddSubFolder("test").create().add(msg); 155 | 156 | final Store store = session.getStore(Providers.getPOP3Provider("makes_no_differernce", false, true)); 157 | store.connect("hendrik@unknown.com", null); 158 | final Folder defaultFolder = store.getDefaultFolder(); 159 | 160 | try { 161 | defaultFolder.getFolder("test"); 162 | } catch (final MessagingException e) { 163 | throw new MockTestException(e); 164 | } 165 | 166 | } 167 | 168 | } 169 | -------------------------------------------------------------------------------- /src/test/java/de/saly/javamail/mock2/test/SMTPTestCase.java: -------------------------------------------------------------------------------- 1 | /*********************************************************************************************************************** 2 | * 3 | * JavaMail Mock2 Provider - open source mock classes for mock up JavaMail 4 | * ======================================================================= 5 | * 6 | * Copyright (C) 2014 by Hendrik Saly (http://saly.de) 7 | * 8 | * Based on ideas from Kohsuke Kawaguchi's Mock-javamail (https://java.net/projects/mock-javamail) 9 | * 10 | *********************************************************************************************************************** 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 13 | * the License. You may obtain a copy of the License at 14 | * 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | * 17 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 18 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 19 | * specific language governing permissions and limitations under the License. 20 | * 21 | *********************************************************************************************************************** 22 | * 23 | * $Id:$ 24 | * 25 | **********************************************************************************************************************/ 26 | package de.saly.javamail.mock2.test; 27 | 28 | import java.util.Properties; 29 | 30 | import javax.mail.Address; 31 | import javax.mail.Folder; 32 | import javax.mail.Message.RecipientType; 33 | import javax.mail.MessagingException; 34 | import javax.mail.Session; 35 | import javax.mail.Store; 36 | import javax.mail.Transport; 37 | import javax.mail.internet.InternetAddress; 38 | import javax.mail.internet.MimeMessage; 39 | 40 | import org.junit.Assert; 41 | import org.junit.FixMethodOrder; 42 | import org.junit.Test; 43 | import org.junit.runners.MethodSorters; 44 | 45 | import de.saly.javamail.mock2.MockMailbox; 46 | import de.saly.javamail.mock2.Providers; 47 | import de.saly.javamail.mock2.test.support.MockTestException; 48 | 49 | @FixMethodOrder(MethodSorters.NAME_ASCENDING) 50 | public class SMTPTestCase extends AbstractTestCase { 51 | 52 | @Override 53 | protected Properties getProperties() { 54 | 55 | final Properties props = super.getProperties(); 56 | props.setProperty("mail.transport.protocol.rfc822", "mock_smtp"); 57 | return props; 58 | } 59 | 60 | @Test(expected = MockTestException.class) 61 | public void test1SendMessageFailure() throws Exception { 62 | 63 | final MockMailbox mb = MockMailbox.get("hendrik@unknown.com"); 64 | mb.getInbox().setSimulateError(true); 65 | 66 | final MimeMessage msg = new MimeMessage(session); 67 | msg.setSubject("Test"); 68 | msg.setFrom("from@sender.com"); 69 | msg.setText("Some text here ..."); 70 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 71 | try { 72 | Transport.send(msg); 73 | } catch (final com.sun.mail.util.MailConnectException e) { 74 | throw e; 75 | } catch (final MessagingException e) { 76 | throw new MockTestException(e); 77 | } 78 | } 79 | 80 | @Test 81 | public void test2SendMessage2() throws Exception { 82 | 83 | final Transport transport = session.getTransport(Providers.getSMTPProvider("makes_no_difference_here", true, true)); 84 | 85 | final MimeMessage msg = new MimeMessage((Session) null); 86 | msg.setSubject("Test 1"); 87 | msg.setFrom("from@sender.com"); 88 | msg.setText("Some text here ..."); 89 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 90 | transport.sendMessage(msg, new Address[] { new InternetAddress("hendrik@unknown.com") }); 91 | 92 | final Store store = session.getStore("mock_pop3"); 93 | store.connect("hendrik@unknown.com", null); 94 | final Folder inbox = store.getFolder("INBOX"); 95 | inbox.open(Folder.READ_ONLY); 96 | Assert.assertEquals(1, inbox.getMessageCount()); 97 | Assert.assertNotNull(inbox.getMessage(1)); 98 | Assert.assertEquals("Test 1", inbox.getMessage(1).getSubject()); 99 | inbox.close(false); 100 | 101 | } 102 | 103 | @Test 104 | public void test3SendMessage() throws Exception { 105 | 106 | Session.getDefaultInstance(getProperties()); 107 | 108 | final MimeMessage msg = new MimeMessage((Session) null); 109 | msg.setSubject("Test 1"); 110 | msg.setFrom("from@sender.com"); 111 | msg.setText("Some text here ..."); 112 | msg.setRecipient(RecipientType.TO, new InternetAddress("hendrik@unknown.com")); 113 | Transport.send(msg); 114 | 115 | final Store store = session.getStore("mock_pop3"); 116 | store.connect("hendrik@unknown.com", null); 117 | final Folder inbox = store.getFolder("INBOX"); 118 | inbox.open(Folder.READ_ONLY); 119 | Assert.assertEquals(1, inbox.getMessageCount()); 120 | Assert.assertNotNull(inbox.getMessage(1)); 121 | Assert.assertEquals("Test 1", inbox.getMessage(1).getSubject()); 122 | inbox.close(false); 123 | 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/test/java/de/saly/javamail/mock2/test/support/MockTestException.java: -------------------------------------------------------------------------------- 1 | package de.saly.javamail.mock2.test.support; 2 | 3 | public final class MockTestException extends Exception { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 1L; 9 | 10 | public MockTestException() { 11 | // TODO Auto-generated constructor stub 12 | } 13 | 14 | public MockTestException(final String message) { 15 | super(message); 16 | // TODO Auto-generated constructor stub 17 | } 18 | 19 | public MockTestException(final String message, final Throwable cause) { 20 | super(message, cause); 21 | // TODO Auto-generated constructor stub 22 | } 23 | 24 | public MockTestException(final Throwable cause) { 25 | super(cause); 26 | // TODO Auto-generated constructor stub 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=ERROR, out 2 | 3 | log4j.logger.de.saly.javamail.mock2=ALL 4 | 5 | log4j.appender.out=org.apache.log4j.ConsoleAppender 6 | log4j.appender.out.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.out.layout.conversionPattern=[%d{HH:mm:ss,SSS}][%-5p][%c{1}][%t] %m%n --------------------------------------------------------------------------------