<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 <NAME>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.gazbert.bxbot.core.mail;

import static junit.framework.TestCase.assertNotNull;
import static org.easymock.EasyMock.expect;

import com.gazbert.bxbot.domain.emailalerts.EmailAlertsConfig;
import com.gazbert.bxbot.domain.emailalerts.SmtpConfig;
import com.gazbert.bxbot.services.EmailAlertsConfigService;
import javax.mail.Message;
import javax.mail.Transport;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

/**
 * Test the Email Alerter behaves as expected.
 *
 * @author gazbert
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest({Transport.class})
@PowerMockIgnore({
    "javax.crypto.*",
    "javax.management.*",
    "com.sun.org.apache.xerces.*",
    "javax.xml.parsers.*",
    "org.xml.sax.*",
    "org.w3c.dom.*"
})
public class TestEmailAlerter {

  private static final String EMAIL_SUBJECT = "CRITICAL Alert message from BX-bot";
  private static final String EMAIL_MSG = "The exchange has blown up!";

  private static final String SMTP_HOST = "smtp.gmail.com";
  private static final int SMTP_TLS_PORT = 587;
  private static final String ACCOUNT_USERNAME = "<EMAIL>";
  private static final String ACCOUNT_PASSWORD = "<PASSWORD>";
  private static final String FROM_ADDRESS = "<EMAIL>";
  private static final String TO_ADDRESS = "<EMAIL>";

  private EmailAlertsConfigService emailAlertsConfigService;

  @Before
  public void setup() {
    emailAlertsConfigService = PowerMock.createMock(EmailAlertsConfigService.class);
  }

  @Test
  public void testEmailAlerterInitialisedSuccessfully() {
    expect(emailAlertsConfigService.getEmailAlertsConfig())
        .andReturn(someEmailAlertsConfigWithAlertsEnabledAndSmtpConfig());
    PowerMock.replayAll();

    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    assertNotNull(emailAlerter);

    PowerMock.verifyAll();
  }

  @Test
  public void testEmailAlerterInitialisedSuccessfullyWhenAlertsDisabledAndNoSmtpConfigSupplied() {
    expect(emailAlertsConfigService.getEmailAlertsConfig())
        .andReturn(someEmailAlertsConfigWithAlertsDisabledAndNoSmtpConfig());
    PowerMock.replayAll();

    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    assertNotNull(emailAlerter);

    PowerMock.verifyAll();
  }

  @Test(expected = IllegalStateException.class)
  public void testEmailAlerterInitialisationFailsWhenAlertsEnabledButNoSmtpConfigSupplied() {
    expect(emailAlertsConfigService.getEmailAlertsConfig())
        .andReturn(someEmailAlertsConfigWithAlertsEnabledAndNoSmtpConfig());
    PowerMock.replayAll();

    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    assertNotNull(emailAlerter);

    PowerMock.verifyAll();
  }

  /*
   * Can safely run this test without 'real' credentials.
   * Crude use of mocks to test behaviour.
   * It does not send anything down the wire.
   */
  @Test
  public void testEmailAlerterSendsMailSuccessfullyUsingMockTransport() throws Exception {
    expect(emailAlertsConfigService.getEmailAlertsConfig())
        .andReturn(someEmailAlertsConfigWithAlertsEnabledAndSmtpConfig());

    PowerMock.mockStatic(Transport.class);
    Transport.send(EasyMock.anyObject(Message.class));

    PowerMock.replayAll();

    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    emailAlerter.sendMessage(EMAIL_SUBJECT, EMAIL_MSG);

    PowerMock.verifyAll();
  }

  /**
   * Requires real credentials to run test. Will actually send email out. Good for testing that
   * you're all setup before deployment.
   *
   * <ol>
   *   <li>Uncomment @Test.
   *   <li>Change the [project-root]/config/email-alerts.xml to use your account SMTP settings.
   *   <li>Comment out @RunWith(PowerMockRunner.class) and @PrepareForTest(Transport.class) at top
   *       of class - they mess with the SSLContext and the test will fail - no time to debug why
   *       but related to: https://code.google.com/p/powermock/issues/detail?id=288
   *   <li>Run this test on its own.
   * </ol>
   */
  // @Test
  public void testEmailAlerterReallySendsMailSuccessfully() {
    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    emailAlerter.sendMessage(EMAIL_SUBJECT, EMAIL_MSG);

    // expect to send message - check your inbox!
  }

  // ------------------------------------------------------------------------
  // Private utils
  // ------------------------------------------------------------------------

  private static EmailAlertsConfig someEmailAlertsConfigWithAlertsEnabledAndSmtpConfig() {
    final SmtpConfig smtpConfig =
        new SmtpConfig(
            SMTP_HOST, SMTP_TLS_PORT, ACCOUNT_USERNAME, ACCOUNT_PASSWORD, FROM_ADDRESS, TO_ADDRESS);

    final EmailAlertsConfig emailAlertsConfig = new EmailAlertsConfig();
    emailAlertsConfig.setEnabled(true);
    emailAlertsConfig.setSmtpConfig(smtpConfig);
    return emailAlertsConfig;
  }

  private static EmailAlertsConfig someEmailAlertsConfigWithAlertsDisabledAndNoSmtpConfig() {
    final EmailAlertsConfig emailAlertsConfig = new EmailAlertsConfig();
    emailAlertsConfig.setEnabled(false);
    return emailAlertsConfig;
  }

  private static EmailAlertsConfig someEmailAlertsConfigWithAlertsEnabledAndNoSmtpConfig() {
    final EmailAlertsConfig emailAlertsConfig = new EmailAlertsConfig();
    emailAlertsConfig.setEnabled(true);
    return emailAlertsConfig;
  }
}<commit_msg>#106 : Increased Email Alerter test coverage<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 <NAME>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.gazbert.bxbot.core.mail;

import static junit.framework.TestCase.assertNotNull;
import static org.easymock.EasyMock.expect;

import com.gazbert.bxbot.domain.emailalerts.EmailAlertsConfig;
import com.gazbert.bxbot.domain.emailalerts.SmtpConfig;
import com.gazbert.bxbot.services.EmailAlertsConfigService;
import javax.mail.Message;
import javax.mail.Transport;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

/**
 * Test the Email Alerter behaves as expected.
 *
 * @author gazbert
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest({Transport.class})
@PowerMockIgnore({
    "javax.crypto.*",
    "javax.management.*",
    "com.sun.org.apache.xerces.*",
    "javax.xml.parsers.*",
    "org.xml.sax.*",
    "org.w3c.dom.*"
})
public class TestEmailAlerter {

  private static final String EMAIL_SUBJECT = "CRITICAL Alert message from BX-bot";
  private static final String EMAIL_MSG = "The exchange has blown up!";

  private static final String SMTP_HOST = "smtp.gmail.com";
  private static final int SMTP_TLS_PORT = 587;
  private static final String ACCOUNT_USERNAME = "<EMAIL>";
  private static final String ACCOUNT_PASSWORD = "<PASSWORD>";
  private static final String FROM_ADDRESS = "<EMAIL>";
  private static final String TO_ADDRESS = "<EMAIL>";

  private EmailAlertsConfigService emailAlertsConfigService;

  @Before
  public void setup() {
    emailAlertsConfigService = PowerMock.createMock(EmailAlertsConfigService.class);
  }

  @Test
  public void testEmailAlerterInitialisedSuccessfully() {
    expect(emailAlertsConfigService.getEmailAlertsConfig())
        .andReturn(someEmailAlertsConfigWithAlertsEnabledAndSmtpConfig());
    PowerMock.replayAll();

    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    assertNotNull(emailAlerter);

    PowerMock.verifyAll();
  }

  @Test
  public void testEmailAlerterInitialisedSuccessfullyWhenAlertsDisabledAndNoSmtpConfigSupplied() {
    expect(emailAlertsConfigService.getEmailAlertsConfig())
        .andReturn(someEmailAlertsConfigWithAlertsDisabledAndNoSmtpConfig());
    PowerMock.replayAll();

    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    assertNotNull(emailAlerter);

    PowerMock.verifyAll();
  }

  @Test
  public void testEmailAlerterInitialisedSuccessfullyWhenAlertsDisabledAndSmtpConfigSupplied() {
    expect(emailAlertsConfigService.getEmailAlertsConfig())
        .andReturn(someEmailAlertsConfigWithAlertsDisabledAndSmtpConfig());
    PowerMock.replayAll();

    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    assertNotNull(emailAlerter);

    PowerMock.verifyAll();
  }

  @Test(expected = IllegalStateException.class)
  public void testEmailAlerterInitialisationFailsWhenAlertsEnabledButNoSmtpConfigSupplied() {
    expect(emailAlertsConfigService.getEmailAlertsConfig())
        .andReturn(someEmailAlertsConfigWithAlertsEnabledAndNoSmtpConfig());
    PowerMock.replayAll();

    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    assertNotNull(emailAlerter);

    PowerMock.verifyAll();
  }

  /*
   * Can safely run this test without 'real' credentials.
   * Crude use of mocks to test behaviour.
   * It does not send anything down the wire.
   */
  @Test
  public void testEmailAlerterSendsMailSuccessfullyUsingMockTransport() throws Exception {
    expect(emailAlertsConfigService.getEmailAlertsConfig())
        .andReturn(someEmailAlertsConfigWithAlertsEnabledAndSmtpConfig());

    PowerMock.mockStatic(Transport.class);
    Transport.send(EasyMock.anyObject(Message.class));

    PowerMock.replayAll();

    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    emailAlerter.sendMessage(EMAIL_SUBJECT, EMAIL_MSG);

    PowerMock.verifyAll();
  }

  /**
   * Requires real credentials to run test. Will actually send email out. Good for testing that
   * you're all setup before deployment.
   *
   * <ol>
   *   <li>Uncomment @Test.
   *   <li>Change the [project-root]/config/email-alerts.xml to use your account SMTP settings.
   *   <li>Comment out @RunWith(PowerMockRunner.class) and @PrepareForTest(Transport.class) at top
   *       of class - they mess with the SSLContext and the test will fail - no time to debug why
   *       but related to: https://code.google.com/p/powermock/issues/detail?id=288
   *   <li>Run this test on its own.
   * </ol>
   */
  // @Test
  public void testEmailAlerterReallySendsMailSuccessfully() {
    final EmailAlerter emailAlerter = new EmailAlerter(emailAlertsConfigService);
    emailAlerter.sendMessage(EMAIL_SUBJECT, EMAIL_MSG);

    // expect to send message - check your inbox!
  }

  // ------------------------------------------------------------------------
  // Private utils
  // ------------------------------------------------------------------------

  private static EmailAlertsConfig someEmailAlertsConfigWithAlertsEnabledAndSmtpConfig() {
    final SmtpConfig smtpConfig =
        new SmtpConfig(
            SMTP_HOST, SMTP_TLS_PORT, ACCOUNT_USERNAME, ACCOUNT_PASSWORD, FROM_ADDRESS, TO_ADDRESS);

    final EmailAlertsConfig emailAlertsConfig = new EmailAlertsConfig();
    emailAlertsConfig.setEnabled(true);
    emailAlertsConfig.setSmtpConfig(smtpConfig);
    return emailAlertsConfig;
  }

  private static EmailAlertsConfig someEmailAlertsConfigWithAlertsDisabledAndNoSmtpConfig() {
    final EmailAlertsConfig emailAlertsConfig = new EmailAlertsConfig();
    emailAlertsConfig.setEnabled(false);
    return emailAlertsConfig;
  }

  private static EmailAlertsConfig someEmailAlertsConfigWithAlertsEnabledAndNoSmtpConfig() {
    final EmailAlertsConfig emailAlertsConfig = new EmailAlertsConfig();
    emailAlertsConfig.setEnabled(true);
    return emailAlertsConfig;
  }

  private static EmailAlertsConfig someEmailAlertsConfigWithAlertsDisabledAndSmtpConfig() {
    final SmtpConfig smtpConfig =
        new SmtpConfig(
            SMTP_HOST, SMTP_TLS_PORT, ACCOUNT_USERNAME, ACCOUNT_PASSWORD, FROM_ADDRESS, TO_ADDRESS);

    final EmailAlertsConfig emailAlertsConfig = new EmailAlertsConfig();
    emailAlertsConfig.setEnabled(false);
    emailAlertsConfig.setSmtpConfig(smtpConfig);
    return emailAlertsConfig;
  }
}
{'fraction_non_alphanumeric': 0.10021920811070009, 'fraction_numerical': 0.0018495684340320592, 'mean_word_length': 4.215791354055019, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5630816', 'n_tokens_mistral': 4289, 'n_tokens_neox': 4152, 'n_words': 1065}