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"); }
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&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>"); }
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&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>"); }
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&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(); }
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(); }
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)); }