public async void SendEmail()
        {
            var recipients = new List <string> {
                "*****@*****.**"
            };
            var report = new SolarAndUtilityReport(new DateInterval(new LocalDate(2017, 07, 17), new LocalDate(2017, 08, 16)), 100, 0, 2000);

            var expectedMessage = new MimeMessage
            {
                Subject = "expected message"
            };

            A.CallTo(() => reportFormatter.FormatReport(A <SolarAndUtilityReport> ._)).Returns(expectedMessage);

            await emailSender.SendEmail(report, recipients);

            CancellationToken cancellationToken = default;

            A.CallTo(() => smtpClient.ConnectAsync("aldaviva.com", 25, SecureSocketOptions.StartTls, cancellationToken))
            .MustHaveHappened()
            .Then(A.CallTo(() => smtpClient.AuthenticateAsync("user", "pass", cancellationToken)).MustHaveHappened())
            .Then(A.CallTo(() => smtpClient.SendAsync(A <MimeMessage> .That.Matches(message =>
                                                                                    message.Subject == "expected message"), cancellationToken, default)).MustHaveHappened())
            .Then(A.CallTo(() => smtpClient.DisconnectAsync(true, cancellationToken)).MustHaveHappened());
        }
        public async Task <int> sendSolarAndUtilityReport()
        {
            LOGGER.Info("Dad's Energy Reporter {0}", Assembly.GetExecutingAssembly().GetName().Version);

            LOGGER.Debug("Validating settings");
            try {
                validateSettings(settings);
            } catch (SettingsException) {
                return(1);
            }

            Instant mostRecentReportBillingDate = Instant.FromDateTimeUtc(settings.mostRecentReportBillingDate);

            if (haveSentReportTooRecently(mostRecentReportBillingDate))
            {
                LOGGER.Info(
                    "Report was already created and sent for billing cycle ending on {0}, which is too recent. Not checking again now.",
                    mostRecentReportBillingDate.InZone(DateTimeZoneProviders.Tzdb.GetSystemDefault()).Date);
                return(0);
            }

            try {
                LOGGER.Info("Logging in...");
                await logIn();

                LOGGER.Info("Logged in.");

                SolarAndUtilityReport report = await reportGenerator.generateReport();

                if (haveAlreadySentReport(mostRecentReportBillingDate, report))
                {
                    LOGGER.Info("Report has already been sent for billing cycle ending on {0}, not sending again.",
                                report.billingDate);
                    return(0);
                }

                LOGGER.Info("Sending email report");
                await emailSender.sendEmail(report, settings.reportRecipientEmails);

                settings.mostRecentReportBillingDate =
                    report.billingDate.AtStartOfDayInZone(reportTimeZone).ToInstant().ToDateTimeUtc();
                settings.save();
                return(0);
            } catch (Exception e) {
                LOGGER.Error(e, "Aborted report generation due to exception");
                return(1);
            } finally {
                LOGGER.Info("Logging out");
                Task.WaitAll(
                    ownerApiService.authentication.logOut(),
                    options.skipUtility ? Task.CompletedTask : orangeRocklandService.authentication.logOut());
                LOGGER.Info("Done");
            }
        }
        public MimeMessage formatReport(SolarAndUtilityReport report)
        {
            var viewModel = new ReportViewModel(report);

            return(new MimeMessage {
                Subject = formatSubject(report),
                Body = new BodyBuilder {
                    TextBody = formatBodyPlainText(viewModel),
                    HtmlBody = formatBodyHtml(viewModel)
                }.ToMessageBody()
            });
        }
        public void SendEmailFailure()
        {
            A.CallTo(() => smtpClient.ConnectAsync(A <string> ._, A <int> ._, A <SecureSocketOptions> ._, default))
            .ThrowsAsync(new IOException());

            var recipients = new List <string> {
                "*****@*****.**"
            };
            var report = new SolarAndUtilityReport(new DateInterval(new LocalDate(2017, 07, 17), new LocalDate(2017, 08, 16)), 100, 0, 2000);

            Func <Task> thrower = async() => await emailSender.SendEmail(report, recipients);

            thrower.Should().Throw <EmailException>().WithMessage("Failed to send email message");
        }
示例#5
0
        public void Zeroes()
        {
            var         report = new SolarAndUtilityReport(new DateInterval(new LocalDate(2017, 11, 1), new LocalDate(2017, 12, 2)), 0, 0, 2000);
            MimeMessage actual = reportFormatter.FormatReport(report);

            actual.Subject.Should().Be("Electricity Usage Report for 11/1–12/2");
            actual.TextBody.Should().Be(@"Generated by solar panels: 0 kWh
Purchased from O&R: 0 kWh for $20.00
---
Total energy consumed: 0 kWh");
            actual.HtmlBody.Should().Be(@"<table style=""border-collapse: collapse"">
    <tr><td><b>Generated by solar panels:</b></td><td style=""text-align: right"">0 kWh</td><td></td></tr>
    <tr><td><b>Purchased from O&amp;R:</b></td><td style=""text-align: right"">0 kWh</td><td> for $20.00</td></tr>
    <tr style=""border-top: 1px solid black""><td><b>Total energy consumed:</b></td><td style=""text-align: right"">0 kWh</td><td></td></tr>
</table>");
        }
示例#6
0
        public void SoldToOru()
        {
            var report = new SolarAndUtilityReport(new DateInterval(new LocalDate(2017, 07, 17), new LocalDate(2017, 08, 16)), 1400, -400,
                                                   20);
            MimeMessage actual = reportFormatter.FormatReport(report);

            actual.Subject.Should().Be("Electricity Usage Report for 7/17–8/16");
            actual.TextBody.Should().Be(@"Generated by solar panels: 1,400 kWh
Sold to O&R: 400 kWh
---
Total energy consumed: 1,000 kWh");
            actual.HtmlBody.Should().Be(@"<table style=""border-collapse: collapse"">
    <tr><td><b>Generated by solar panels:</b></td><td style=""text-align: right"">1,400 kWh</td><td></td></tr>
    <tr><td><b>Sold to O&amp;R:</b></td><td style=""text-align: right"">400 kWh</td><td></td></tr>
    <tr style=""border-top: 1px solid black""><td><b>Total energy consumed:</b></td><td style=""text-align: right"">1,000 kWh</td><td></td></tr>
</table>");
        }
示例#7
0
        public void PurchasedFromOru()
        {
            var report = new SolarAndUtilityReport(new DateInterval(new LocalDate(2017, 07, 17), new LocalDate(2017, 08, 16)), 1234.56789, 9999,
                                                   6780);
            MimeMessage actual = reportFormatter.FormatReport(report);

            actual.Subject.Should().Be("Electricity Usage Report for 7/17–8/16");
            actual.TextBody.Should().Be(@"Generated by solar panels: 1,235 kWh
Purchased from O&R: 9,999 kWh for $67.80
---
Total energy consumed: 11,234 kWh");
            actual.HtmlBody.Should().Be(@"<table style=""border-collapse: collapse"">
    <tr><td><b>Generated by solar panels:</b></td><td style=""text-align: right"">1,235 kWh</td><td></td></tr>
    <tr><td><b>Purchased from O&amp;R:</b></td><td style=""text-align: right"">9,999 kWh</td><td> for $67.80</td></tr>
    <tr style=""border-top: 1px solid black""><td><b>Total energy consumed:</b></td><td style=""text-align: right"">11,234 kWh</td><td></td></tr>
</table>");
        }
        public async void SkipsIfAlreadySentReport()
        {
            settings.MostRecentReportBillingDate = new LocalDate(2017, 08, 16).AtStartOfDayInZone(ZONE).ToInstant().ToDateTimeUtc();

            var report = new SolarAndUtilityReport(new DateInterval(new LocalDate(2017, 07, 17), new LocalDate(2017, 08, 16)), 100,
                                                   20, 3000);

            A.CallTo(() => reportGenerator.GenerateReport()).Returns(report);

            await energyReporter.SendSolarAndUtilityReport();

            A.CallTo(() => powerGuideAuthenticationService.GetAuthToken()).MustHaveHappened();
            A.CallTo(() => orangeRocklandAuthenticationService.GetAuthToken()).MustHaveHappened();
            A.CallTo(() => reportGenerator.GenerateReport()).MustHaveHappened();

            A.CallTo(() => emailSender.SendEmail(A <SolarAndUtilityReport> ._, A <IEnumerable <string> > ._)).MustNotHaveHappened();
        }
示例#9
0
        public async void GenerateReport()
        {
            var greenButtonData = new GreenButtonData
            {
                MeterReadings = new[]
                {
                    new GreenButtonData.MeterReading
                    {
                        CostCents       = 0,
                        BillingInterval = new DateInterval(new LocalDate(2017, 6, 15), new LocalDate(2017, 7, 17))
                    },
                    new GreenButtonData.MeterReading
                    {
                        CostCents       = 100,
                        BillingInterval = new DateInterval(new LocalDate(2017, 7, 17), new LocalDate(2017, 8, 16))
                    }
                }
            };

            A.CallTo(() => orangeRocklandService.GreenButton.FetchGreenButtonData()).Returns(greenButtonData);
            A.CallTo(() => orangeRocklandService.BillDocuments.FetchEnergyPurchasedOrSoldKWh(A <LocalDate> ._)).Returns(200);

            var measurement = new Measurement
            {
                GeneratedKilowattHours = 3000
            };

            A.CallTo(() => powerGuideService.Measurement.Measure(A <DateInterval> ._)).Returns(measurement);

            SolarAndUtilityReport report = await reportGenerator.GenerateReport();

            report.PowerGenerated.Should().Be(3000);
            report.PowerBoughtOrSold.Should().Be(200);
            report.PowerCostCents.Should().Be(100);
            report.BillingInterval.Start.Should().Be(new LocalDate(2017, 7, 17));
            report.BillingInterval.End.Should().Be(new LocalDate(2017, 8, 16));
            report.BillingDate.Should().Be(new LocalDate(2017, 8, 16));

            A.CallTo(() => orangeRocklandService.GreenButton.FetchGreenButtonData()).MustHaveHappened();
            A.CallTo(() =>
                     powerGuideService.Measurement.Measure(new DateInterval(new LocalDate(2017, 7, 17), new LocalDate(2017, 8, 16))))
            .MustHaveHappened();
        }
示例#10
0
        public async Task sendEmail(SolarAndUtilityReport report, IEnumerable <string> recipients)
        {
            MimeMessage message = reportFormatter.formatReport(report);

            message.From.Add(new MailboxAddress("Dad's Energy Reporter", settings.reportSenderEmail));
            message.To.AddRange(recipients.Select(recipient => new MailboxAddress(recipient)));

            try {
                await smtpClient.ConnectAsync(settings.smtpHost, settings.smtpPort, SecureSocketOptions.StartTls);

                await smtpClient.AuthenticateAsync(settings.smtpUsername, settings.smtpPassword);

                await smtpClient.SendAsync(message);

                await smtpClient.DisconnectAsync(true);
            } catch (IOException e) {
                throw new EmailException("Failed to send email message", e);
            }
        }
        public async void Normal()
        {
            var report = new SolarAndUtilityReport(new DateInterval(new LocalDate(2017, 07, 17), new LocalDate(2017, 08, 16)), 100,
                                                   2, 2000);

            A.CallTo(() => reportGenerator.GenerateReport()).Returns(report);

            await energyReporter.SendSolarAndUtilityReport();

            A.CallTo(() => powerGuideAuthenticationService.GetAuthToken()).MustHaveHappened();
            A.CallTo(() => orangeRocklandAuthenticationService.GetAuthToken()).MustHaveHappened();
            A.CallTo(() => reportGenerator.GenerateReport()).MustHaveHappened();
            A.CallTo(() =>
                     emailSender.SendEmail(report,
                                           A <IEnumerable <string> > .That.IsSameSequenceAs(new List <string> {
                "*****@*****.**"
            }))).MustHaveHappened();

            A.CallTo(() => powerGuideAuthenticationService.LogOut()).MustHaveHappened();
            A.CallTo(() => orangeRocklandAuthenticationService.LogOut()).MustHaveHappened();

            settings.MostRecentReportBillingDate.Should()
            .Be(report.BillingDate.AtStartOfDayInZone(ZONE).ToInstant().ToDateTimeUtc());
        }
 private static string formatSubject(SolarAndUtilityReport report)
 {
     return($"Electricity Usage Report for {shortDate(report.billingInterval.Start)}–" +
            shortDate(report.billingInterval.End));
 }
 public ReportViewModel(SolarAndUtilityReport report)
 {
     this.report = report;
 }
 internal bool haveAlreadySentReport(Instant mostRecentReportBillingDate, SolarAndUtilityReport report)
 {
     return(!(mostRecentReportBillingDate.InZone(reportTimeZone).Date < report.billingDate));
 }