// http://jira.qos.ch/browse/LBCLASSIC-221
  @Test
  public void bufferShouldBeResetBetweenMessages() throws Exception {
    buildSMTPAppender(smtpServer.getSmtp().getPort(), SYNCHRONOUS);
    smtpAppender.setLayout(buildPatternLayout(lc, DEFAULT_PATTERN));
    smtpAppender.start();
    logger.addAppender(smtpAppender);
    String msg0 = "hello zero";
    logger.debug(msg0);
    logger.error("error zero");

    String msg1 = "hello one";
    logger.debug(msg1);
    logger.error("error one");

    waitUntilEmailIsSent();
    waitUntilEmailIsReceived(smtpServer, 2);

    MimeMessage[] mma = smtpServer.getReceivedMessages();
    assertNotNull(mma);
    assertEquals(2, mma.length);

    MimeMessage mm0 = mma[0];
    MimeMultipart content0 = (MimeMultipart) mm0.getContent();
    String body0 = GreenMailUtil.getBody(content0.getBodyPart(0));
    assertTrue(body0.contains(msg0));

    MimeMessage mm1 = mma[1];
    MimeMultipart content1 = (MimeMultipart) mm1.getContent();
    String body1 = GreenMailUtil.getBody(content1.getBodyPart(0));
    // second body should not contain content from first message
    assertFalse(body1.contains(msg0));
  }
  // http://jira.qos.ch/browse/LBCLASSIC-221
  @Test
  public void bufferShouldBeResetBetweenMessages() throws Exception {
    buildSMTPAppender("bufferShouldBeResetBetweenMessages", SYNCHRONOUS);
    smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
    smtpAppender.start();
    logger.addAppender(smtpAppender);
    String msg0 = "hello zero";
    logger.debug(msg0);
    logger.error("error zero");

    String msg1 = "hello one";
    logger.debug(msg1);
    logger.error("error one");

    Thread.yield();
    int oldCount = 0;
    int expectedEmailCount = oldCount + 2;
    waitForServerToReceiveEmails(expectedEmailCount);

    MimeMessage[] mma = greenMailServer.getReceivedMessages();
    assertNotNull(mma);
    assertEquals(expectedEmailCount, mma.length);

    MimeMessage mm0 = mma[oldCount];
    MimeMultipart content0 = (MimeMultipart) mm0.getContent();
    String body0 = GreenMailUtil.getBody(content0.getBodyPart(0));

    MimeMessage mm1 = mma[oldCount + 1];
    MimeMultipart content1 = (MimeMultipart) mm1.getContent();
    String body1 = GreenMailUtil.getBody(content1.getBodyPart(0));
    // second body should not contain content from first message
    assertFalse(body1.contains(msg0));
  }
 @Test
 public void testSmtpServerBasic() throws MessagingException {
   GreenMailUtil.sendTextEmailTest("*****@*****.**", "*****@*****.**", "subject", "body");
   MimeMessage[] emails = greenMail.getReceivedMessages();
   assertEquals(1, emails.length);
   assertEquals("subject", emails[0].getSubject());
   assertEquals("body", GreenMailUtil.getBody(emails[0]));
 }
 @Test
 public void testSmtpServerLeadingPeriods() throws MessagingException {
   String body = ". body with leading period";
   GreenMailUtil.sendTextEmailTest("*****@*****.**", "*****@*****.**", "subject", body);
   MimeMessage[] emails = greenMail.getReceivedMessages();
   assertEquals(1, emails.length);
   assertEquals("subject", emails[0].getSubject());
   assertEquals(body, GreenMailUtil.getBody(emails[0]));
 }
  private void assertMessage(MimeMessage message, BirthdayMessage expected)
      throws MessagingException {
    BirthdayMessage sent =
        new BirthdayMessage(
            GreenMailUtil.getAddressList(message.getFrom()),
            GreenMailUtil.getAddressList(message.getRecipients(Message.RecipientType.TO)),
            message.getSubject(),
            GreenMailUtil.getBody(message));

    assertThat("Message", sent, is(expected));
  }
  @Test
  public void testSmtpServerReceiveWithSetup() throws Throwable {
    assertEquals(0, greenMail.getReceivedMessages().length);

    String subject = GreenMailUtil.random();
    String body = GreenMailUtil.random();
    GreenMailUtil.sendTextEmailTest("*****@*****.**", "*****@*****.**", subject, body);
    greenMail.waitForIncomingEmail(1500, 1);
    MimeMessage[] emails = greenMail.getReceivedMessages();
    assertEquals(1, emails.length);
    assertEquals(subject, emails[0].getSubject());
    assertEquals(body, GreenMailUtil.getBody(emails[0]).trim());
  }
  @Test
  public void testWatchThisPageAndWholeSpace() throws Exception {
    // Clear the list of watched documents and spaces
    getUtil()
        .updateObject(
            "XWiki",
            this.profilePage.getUsername(),
            "XWiki.WatchListClass",
            0,
            "spaces",
            "",
            "documents",
            "");

    // Watch Test.TestWatchThisPage
    ViewPage page = getUtil().createPage("Test", "TestWatchThisPage", "TestWatchThisPage ui", null);
    page.watchDocument();

    // Watch TestWatchWholeSpace.Test1
    page = getUtil().createPage("TestWatchWholeSpace", "Test1", "TestWatchWholeSpace ui", null);
    page.watchSpace();

    // Verify that the watched page & space are present in the watchlist manager
    this.watchlistPage = WatchlistUserProfilePage.gotoPage(this.watchlistPage.getUsername());
    // TODO: use LiveTableElement instead but does not seems to work...
    // LiveTableElement watchlist = this.watchlistPage.getWatchList();
    // watchlist.waitUntilReady();
    this.watchlistPage.waitUntilElementIsVisible(
        By.xpath(
            "//tbody[@id='mywatchlist-display']/tr/td/a[@href='/xwiki/bin/view/Test/TestWatchThisPage']"));
    Assert.assertTrue(this.watchlistPage.isWatched("Test", "TestWatchThisPage"));
    Assert.assertTrue(this.watchlistPage.isWatched("TestWatchWholeSpace"));

    // Ensure that the watchlist notified is set to Daily since we're going to trigger that notifier
    // scheduler job
    WatchlistPreferencesEditPage watchlistPreferences = this.watchlistPage.editPreferences();
    watchlistPreferences.setNotifierDaily();
    watchlistPreferences.clickSaveAndContinue();

    // Switch to Admin user and go to the scheduler home page
    SchedulerHomePage schedulerHomePage = new SchedulerHomePage();
    getDriver().get(getUtil().getURLToLoginAsAdminAndGotoPage(schedulerHomePage.getURL()));
    getUtil().recacheSecretToken();

    // Trigger the notification for the Daily job
    schedulerHomePage.clickJobActionTrigger("WatchList daily notifier");

    // Wait for the email with a timeout
    Assert.assertTrue("Mail not received", this.greenMail.waitForIncomingEmail(70000, 1));

    // Verify email content
    String messageFromXWiki = GreenMailUtil.getBody(this.greenMail.getReceivedMessages()[0]);
    Assert.assertFalse(messageFromXWiki.contains("Exception"));
    Assert.assertTrue(messageFromXWiki.contains("TestWatchThisPage"));
    Assert.assertTrue(messageFromXWiki.contains("TestWatchWholeSpace"));
  }
  @Test
  public void testParseInlineContentDispostionHeaderMimePart() {
    MimeMessage message = GreenMailUtil.newMimeMessage(sampleEmail);

    SimpleMessageAttributes simpleMessageAttributes = new SimpleMessageAttributes();
    simpleMessageAttributes.parseMimePart(message);

    String bodyStructure = simpleMessageAttributes.getBodyStructure(true);
    Assertions.assertThat(bodyStructure).contains("(\"inline\" NIL)");
  }
  protected void assertRecoveredUserName(String expectedUserName) throws Exception {
    // Need 1 message
    waitForMail(1);

    MimeMessage[] msgs = server.getReceivedMessages();

    for (MimeMessage msg : msgs) {
      log.debug("Mail Title:\n" + GreenMailUtil.getHeaders(msg));
      log.debug("Mail Body:\n" + GreenMailUtil.getBody(msg));
    }

    String username = null;
    // Sample body: Your password has been reset. Your new password is: c1r6g4p8l7
    String body = GreenMailUtil.getBody(msgs[0]);

    int index = body.indexOf(" - \"");
    int usernameStartIndex = index + " - \"".length();
    if (index != -1) {
      username = body.substring(usernameStartIndex, body.indexOf('\"', usernameStartIndex)).trim();
    }

    Assert.assertEquals(username, expectedUserName);
  }
  @Test
  public void testCustomEvaluator() throws Exception {
    configure(
        smtpServer.getSmtp().getPort(),
        ClassicTestConstants.JORAN_INPUT_PREFIX + "smtp/customEvaluator.xml");

    logger.debug("hello");
    String msg2 = "world";
    logger.debug(msg2);
    logger.debug("invisible");
    waitUntilEmailIsSent();
    MimeMultipart mp = verify(smtpServer, this.getClass().getName() + " - " + msg2);
    String body = GreenMailUtil.getBody(mp.getBodyPart(0));
    assertEquals("helloworld", body);
  }
  // See also http://jira.qos.ch/browse/LOGBACK-734
  @Test
  public void callerDataShouldBeCorrectlySetWithAsyncronousSending() throws Exception {
    buildSMTPAppender(smtpServer.getSmtp().getPort(), ASYNCHRONOUS);
    smtpAppender.setLayout(buildPatternLayout(lc, DEFAULT_PATTERN));
    smtpAppender.setIncludeCallerData(true);
    smtpAppender.start();
    logger.addAppender(smtpAppender);
    logger.debug("hello");
    logger.error("an error", new Exception("an exception"));

    waitUntilEmailIsSent();
    MimeMultipart mp = verify(smtpServer, TEST_SUBJECT);
    String body = GreenMailUtil.getBody(mp.getBodyPart(0));
    assertTrue(body.contains("DEBUG " + this.getClass().getName() + " - hello"));
  }
  @Test
  public void asyncronousSmoke() throws Exception {
    buildSMTPAppender(smtpServer.getSmtp().getPort(), ASYNCHRONOUS);
    smtpAppender.setLayout(buildPatternLayout(lc, DEFAULT_PATTERN));
    smtpAppender.start();
    logger.addAppender(smtpAppender);
    logger.debug("hello");
    logger.error("an error", new Exception("an exception"));

    waitUntilEmailIsSent();
    MimeMultipart mp = verify(smtpServer, TEST_SUBJECT);
    String body = GreenMailUtil.getBody(mp.getBodyPart(0));
    assertTrue(body.startsWith(HEADER.trim()));
    assertTrue(body.endsWith(FOOTER.trim()));
  }
  @Test
  public void testLargeMessageBody() throws MessagingException, IOException {
    String to = "to@localhost";
    GreenMailUtil.sendMessageBody(
        to,
        "from@localhost",
        "Subject",
        createLargeByteArray(),
        "application/blubb",
        greenMail.getSmtp().getServerSetup());
    greenMail.waitForIncomingEmail(5000, 1);

    retrieveAndCheckBody(new Retriever(greenMail.getPop3()), to);
    retrieveAndCheckBody(new Retriever(greenMail.getImap()), to);
  }
  @Test
  public void testCustomBufferSize() throws Exception {
    configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "smtp/customBufferSize.xml");

    logger.debug("invisible1");
    logger.debug("invisible2");
    String msg = "hello";
    logger.error(msg);
    waitUntilEmailIsSent();
    MimeMultipart mp =
        verifyAndExtractMimeMultipart(
            "testCustomBufferSize " + this.getClass().getName() + " - " + msg);
    String body = GreenMailUtil.getBody(mp.getBodyPart(0));
    assertEquals(msg, body);
  }
  @Test
  public void testCustomEvaluator() throws Exception {
    configure(ClassicTestConstants.JORAN_INPUT_PREFIX + "smtp/customEvaluator.xml");

    logger.debug("test");
    String msg2 = "CustomEvaluator";
    logger.debug(msg2);
    logger.debug("invisible");
    waitUntilEmailIsSent();
    MimeMultipart mp =
        verifyAndExtractMimeMultipart(
            "testCustomEvaluator " + this.getClass().getName() + " - " + msg2);
    String body = GreenMailUtil.getBody(mp.getBodyPart(0));
    assertEquals("testCustomEvaluator", body);
  }
  @Test
  public void asynchronousSmoke() throws Exception {
    String subject = "asynchronousSmoke";
    buildSMTPAppender(subject, ASYNCHRONOUS);
    smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
    smtpAppender.start();
    logger.addAppender(smtpAppender);
    logger.debug("hello");
    logger.error("en error", new Exception("an exception"));

    waitUntilEmailIsSent();
    MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
    String body = GreenMailUtil.getBody(mp.getBodyPart(0));
    assertTrue(body.startsWith(HEADER.trim()));
    assertTrue(body.endsWith(FOOTER.trim()));
  }
  @Test
  public void testAccountService() throws Exception {
    // 1. Get captcha
    String captchaKey = accountService.generateCaptchaKey();
    accountService.generateCaptchaImage(captchaKey);
    String captchaValue = "12345";

    // 2. Submit sign up Request
    SignUpRequest signUpRequest = new SignUpRequest();
    signUpRequest.setCaptchaKey(captchaKey);
    signUpRequest.setCaptchaValue(captchaValue);
    signUpRequest.setId("juven");
    signUpRequest.setEmail("*****@*****.**");
    signUpRequest.setName("Juven Xu");
    signUpRequest.setPassword("admin123");
    signUpRequest.setConfirmPassword("admin123");
    signUpRequest.setActivateServiceUrl("http://localhost:8080/account/activate");
    accountService.signUp(signUpRequest);

    // 3. Read activation link
    greenMail.waitForIncomingEmail(2000, 1);
    Message[] msgs = greenMail.getReceivedMessages();
    assertEquals(1, msgs.length);
    assertEquals("Please Activate Your Account", msgs[0].getSubject());
    String activationLink = GreenMailUtil.getBody(msgs[0]).trim();

    // 3a. Try login but not activated
    try {
      accountService.login("juven", "admin123");
      fail("Disabled account shouldn't be able to log in.");
    } catch (AccountServiceException e) {
    }

    // 4. Activate account
    String activationCode = activationLink.substring(activationLink.lastIndexOf("=") + 1);
    accountService.activate(activationCode);

    // 5. Login with correct id and password
    accountService.login("juven", "admin123");

    // 5a. Login with incorrect password
    try {
      accountService.login("juven", "admin456");
      fail("Password is incorrect, shouldn't be able to login.");
    } catch (AccountServiceException e) {
    }
  }
  // See also http://jira.qos.ch/browse/LOGBACK-734
  @Test
  public void callerDataShouldBeCorrectlySetWithAsynchronousSending() throws Exception {
    String subject = "LOGBACK-734";
    buildSMTPAppender("LOGBACK-734", ASYNCHRONOUS);
    smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
    smtpAppender.setIncludeCallerData(true);
    smtpAppender.start();
    logger.addAppender(smtpAppender);
    logger.debug("LOGBACK-734");
    logger.error("callerData", new Exception("ShouldBeCorrectlySetWithAsynchronousSending"));

    waitUntilEmailIsSent();
    MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
    String body = GreenMailUtil.getBody(mp.getBodyPart(0));
    assertTrue(
        "actual [" + body + "]",
        body.contains("DEBUG " + this.getClass().getName() + " - LOGBACK-734"));
  }
  @Test
  public void LBCLASSIC_104() throws Exception {
    buildSMTPAppender(smtpServer.getSmtp().getPort(), SYNCHRONOUS);
    smtpAppender.setAsynchronousSending(false);
    smtpAppender.setLayout(buildPatternLayout(lc, DEFAULT_PATTERN));
    smtpAppender.start();
    logger.addAppender(smtpAppender);
    MDC.put("key", "val");
    logger.debug("hello");
    MDC.clear();
    logger.error("an error", new Exception("an exception"));

    MimeMultipart mp = verify(smtpServer, TEST_SUBJECT);
    String body = GreenMailUtil.getBody(mp.getBodyPart(0));
    assertTrue("missing HEADER in body", body.startsWith(HEADER.trim()));
    assertTrue("missing MDC in body", body.contains("key=val"));
    assertTrue("missing FOOTER in body", body.endsWith(FOOTER.trim()));
  }
  // lost MDC
  @Test
  public void LBCLASSIC_104() throws Exception {
    String subject = "LBCLASSIC_104";
    buildSMTPAppender(subject, SYNCHRONOUS);
    smtpAppender.setAsynchronousSending(false);
    smtpAppender.setLayout(buildPatternLayout(DEFAULT_PATTERN));
    smtpAppender.start();
    logger.addAppender(smtpAppender);
    MDC.put("key", "val");
    logger.debug("hello");
    MDC.clear();
    logger.error("en error", new Exception("test"));

    MimeMultipart mp = verifyAndExtractMimeMultipart(subject);
    String body = GreenMailUtil.getBody(mp.getBodyPart(0));
    assertTrue("missing HEADER in body", body.startsWith(HEADER.trim()));
    assertTrue("missing MDC in body", body.contains("key=val"));
    assertTrue("missing FOOTER in body", body.endsWith(FOOTER.trim()));
  }
  @Test
  public void testRestPassword() throws Exception {

    this.copyDefaultConfigToPlace();
    this.setupEmailConfig();

    NexusConfiguration nexusConfig = this.lookup(NexusConfiguration.class);
    nexusConfig.loadConfiguration(true);

    String username = "******";

    PlexusResource resetEmailPR = this.lookup(PlexusResource.class, "UserResetPlexusResource");

    Request request = new Request();
    Response response = new Response(request);
    request.getAttributes().put(UserResetPlexusResource.USER_ID_KEY, username);
    resetEmailPR.delete(null, request, response);

    // Need 1 message
    server.waitForIncomingEmail(5000, 1);

    MimeMessage[] msgs = server.getReceivedMessages();
    Assert.assertTrue("Expected email.", msgs != null && msgs.length > 0);
    MimeMessage msg = msgs[0];

    String password = null;
    // Sample body: Your password has been reset. Your new password is: c1r6g4p8l7
    String body = GreenMailUtil.getBody(msg);

    int index = body.indexOf("Your new password is: ");
    int passwordStartIndex = index + "Your new password is: ".length();
    if (index != -1) {
      password = body.substring(passwordStartIndex, body.indexOf('\n', passwordStartIndex)).trim();
    }

    Assert.assertNotNull(password);
  }
  @Test
  public void sendMimeMail() throws InterruptedException, MessagingException, IOException {
    mimeMailService.sendNotificationMail("calvin");

    greenMail.waitForIncomingEmail(2000, 1);
    MimeMessage[] messages = greenMail.getReceivedMessages();
    MimeMessage message = messages[messages.length - 1];

    assertEquals("*****@*****.**", message.getFrom()[0].toString());
    assertEquals("用户修改通知", message.getSubject());

    MimeMultipart mimeMultipart = (MimeMultipart) message.getContent();

    assertEquals(2, mimeMultipart.getCount());

    // Html格式的主邮件
    String mainPartText = getMainPartText(mimeMultipart.getBodyPart(0));
    System.out.println(mainPartText);
    assertTrue(mainPartText.contains("<h1>用户calvin被修改.</h1>"));

    // 附件
    assertEquals(
        "Hello,i am a attachment.", GreenMailUtil.getBody(mimeMultipart.getBodyPart(1)).trim());
  }
  @Test
  public void testSmtpServerReceiveMultipart() throws Exception {
    assertEquals(0, greenMail.getReceivedMessages().length);

    String subject = GreenMailUtil.random();
    String body = GreenMailUtil.random();
    GreenMailUtil.sendAttachmentEmail(
        "*****@*****.**",
        "*****@*****.**",
        subject,
        body,
        new byte[] {0, 1, 2},
        "image/gif",
        "testimage_filename",
        "testimage_description",
        ServerSetupTest.SMTP);
    greenMail.waitForIncomingEmail(1500, 1);
    Message[] emails = greenMail.getReceivedMessages();
    assertEquals(1, emails.length);
    assertEquals(subject, emails[0].getSubject());

    Object o = emails[0].getContent();
    assertTrue(o instanceof MimeMultipart);
    MimeMultipart mp = (MimeMultipart) o;
    assertEquals(2, mp.getCount());
    BodyPart bp;
    bp = mp.getBodyPart(0);
    assertEquals(body, GreenMailUtil.getBody(bp).trim());

    bp = mp.getBodyPart(1);
    assertEquals("AAEC", GreenMailUtil.getBody(bp).trim());

    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    GreenMailUtil.copyStream(bp.getInputStream(), bout);
    byte[] gif = bout.toByteArray();
    for (int i = 0; i < gif.length; i++) {
      assertEquals(i, gif[i]);
    }
  }
  @Test
  public void testParseContentLocationAndContentId() {
    String message =
        ""
            + "Return-Path: <*****@*****.**>\r\n"
            + "X-Sieve: CMU Sieve 2.2\r\n"
            + "Content-Class: urn:content-classes:message\r\n"
            + "Content-Type: multipart/related; type=\"multipart/alternative\"; boundary=\"----_=_NextPart_001_01CE6676.A2EDD0CD\"\r\n"
            + "X-MimeOLE: Produced By Microsoft Exchange V6.5\r\n"
            + "Subject: 5. une image\r\n"
            + "Date: Tue, 11 Jun 2013 09:38:16 +0200\r\n"
            + "Message-ID: <*****@*****.**>\r\n"
            + "X-MS-Has-Attach: yes\r\n"
            + "X-MS-TNEF-Correlator: \r\n"
            + "Thread-Topic: une image\r\n"
            + "Thread-Index: Ac5mdqELvr6tZ5cFTieh4HTfAw877Q==\r\n"
            + "From: TEST M. <*****@*****.**>\r\n"
            + "To: Sylvain <*****@*****.**>, Christophe <*****@*****.**>, Julien\r\n"
            + " <*****@*****.**>\r\n"
            + "X-OriginalArrivalTime: 11 Jun 2013 07:38:17.0046 (UTC)\r\n"
            + " FILETIME=[A331FF60:01CE6676]\r\n"
            + "X-Evolution-Source: 1371112195.13581.2@debian\r\n"
            + "MIME-Version: 1.0\r\n"
            + "\r\n"
            + "\r\n"
            + "------_=_NextPart_001_01CE6676.A2EDD0CD\r\n"
            + "Content-Type: multipart/alternative; boundary=\"----_=_NextPart_002_01CE6676.A2EDD0CD\"\r\n"
            + "\r\n"
            + "\r\n"
            + "------_=_NextPart_002_01CE6676.A2EDD0CD\r\n"
            + "Content-Type: text/plain; charset=\"us-ascii\"\r\n"
            + "Content-Transfer-Encoding: quoted-printable\r\n"
            + "\r\n"
            + "http=20\r\n"
            + "<http://kb.mozillazine.org/index.php?title=3DIMAP%3A_advanced_account_conf\r\n"
            + "iguration&diff=3D43408&oldid=3D42987>=20\r\n"
            + "\r\n"
            + "------_=_NextPart_002_01CE6676.A2EDD0CD\r\n"
            + "Content-Type: text/html; charset=\"us-ascii\"\r\n"
            + "Content-Transfer-Encoding: quoted-printable\r\n"
            + "\r\n"
            + "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><html><head>\r\n"
            + "<meta http-equiv=3D\"Content-Type\" content=3D\"text/html; charset=3Dus-ascii\"=\r\n"
            + ">\r\n"
            + "<meta name=3D\"GENERATOR\" content=3D\"MSHTML 8.00.6001.19298\"></head>\r\n"
            + "<body>\r\n"
            + "<div><font size=3D\"2\" face=3D\"Arial\"><a href=3D\"http://kb.mozillazine.org/i=\r\n"
            + "ndex.php?title=3DIMAP%3A_advanced_account_configuration&amp;diff=3D43408&am=\r\n"
            + "p;oldid=3D42987\">http<img border=3D\"0\" hspace=3D\"0\" alt=3D\"\" align=3D\"basel=\r\n"
            + "ine\" src=3D\"cid:555343607@11062013-0EC1\"></a></font></div></body></html>\r\n"
            + "\r\n"
            + "------_=_NextPart_002_01CE6676.A2EDD0CD--\r\n"
            + "\r\n"
            + "------_=_NextPart_001_01CE6676.A2EDD0CD\r\n"
            + "Content-Type: image/jpeg; name=\"TB_import.JPG\"\r\n"
            + "Content-Transfer-Encoding: base64\r\n"
            + "Content-ID: <555343607@11062013-0EC1>\r\n"
            + "Content-Description: TB_import.JPG\r\n"
            + "Content-Location: TB_import.JPG\r\n"
            + "\r\n"
            + "HBwgJ\r\n"
            + "------_=_NextPart_001_01CE6676.A2EDD0CD--\r\n"
            + "\r\n";

    MimeMessage mimeMessage = GreenMailUtil.newMimeMessage(message);

    SimpleMessageAttributes simpleMessageAttributes = new SimpleMessageAttributes();
    simpleMessageAttributes.parseMimePart(mimeMessage);

    String bodyStructure = simpleMessageAttributes.getBodyStructure(true);
    Assertions.assertThat(bodyStructure)
        .isEqualTo(
            "("
                + "("
                + "(\"TEXT\" \"PLAIN\" (\"charset\" \"us-ascii\") NIL NIL \"quoted-printable\" 125 3 NIL NIL NIL NIL)"
                + "(\"TEXT\" \"HTML\" (\"charset\" \"us-ascii\") NIL NIL \"quoted-printable\" 540 9 NIL NIL NIL NIL)"
                + " \"alternative\" (\"boundary\" \"----_=_NextPart_002_01CE6676.A2EDD0CD\") NIL NIL NIL)"
                + "(\"IMAGE\" \"JPEG\" (\"name\" \"TB_import.JPG\") "
                + "\"<555343607@11062013-0EC1>\" \"TB_import.JPG\" \"base64\" 5 NIL NIL NIL \"TB_import.JPG\") "
                + "\"related\" (\"type\" \"multipart/alternative\" \"boundary\" \"----_=_NextPart_001_01CE6676.A2EDD0CD\") NIL NIL NIL)");
  }