public void Get_page_data_in_user_timezone() { Plug deki = Plug.New("http://mock/deki"); AutoMockPlug autoMock = MockPlug.Register(deki.Uri); PageChangeCache cache = new PageChangeCache(deki, (key, trigger) => { }); DateTime timestamp = DateTime.Parse("2009/02/01 10:10:00"); XUri pageUri = deki.Uri.At("pages", "10").With("redirects", "0"); XDoc pageResponse = new XDoc("page") .Elem("uri.ui", "http://foo.com/@api/deki/pages/10") .Elem("title", "foo") .Elem("path", "foo/bar"); XUri feedUri = deki.Uri .At("pages", "10", "feed") .With("redirects", "0") .With("format", "raw") .With("since", timestamp.Subtract(TimeSpan.FromSeconds(10)).ToString("yyyyMMddHHmmss")); XDoc changeResponse = new XDoc("table") .Start("change") .Elem("rc_summary", "Two edits") .Elem("rc_comment", "edit 1") .Elem("rc_comment", "edit 2") .Elem("rc_timestamp", "20090201101000") .End(); _log.Debug("first get"); autoMock.Expect("GET", pageUri, (XDoc)null, DreamMessage.Ok(pageResponse)); autoMock.Expect("GET", feedUri, (XDoc)null, DreamMessage.Ok(changeResponse)); PageChangeData data = Coroutine.Invoke(cache.GetPageData, (uint)10, "foo", timestamp, CultureInfo.InvariantCulture, "-09:00", new Result <PageChangeData>()).Wait(); Assert.IsTrue(autoMock.WaitAndVerify(TimeSpan.FromSeconds(10))); //string plainbody = "foo\r\n[ http://foo.com/@api/deki/pages/10 ]\r\n\r\n - edit 1 (Sun, 01 Feb 2009 01:10:00 -09:00)\r\n [ http://foo.com/@api/deki/pages/10?revision ]\r\n\r\n"; XDoc htmlBody = XDocFactory.From("<html><p><b><a href=\"http://foo.com/@api/deki/pages/10\">foo</a></b> ( Last edited by <a href=\"http://foo.com/User%3A\" /> )<br /><small><a href=\"http://foo.com/@api/deki/pages/10\">http://foo.com/@api/deki/pages/10</a></small><br /><small><a href=\"http://foo.com/index.php?title=Special%3APageAlerts&id=10\">Unsubscribe</a></small></p><p><ol><li>edit 1 ( <a href=\"http://foo.com/@api/deki/pages/10?revision\">Sun, 01 Feb 2009 01:10:00 -09:00</a> by <a href=\"http://foo.com/User%3A\" /> )</li></ol></p><br /></html>", MimeType.TEXT_XML); Assert.AreEqual(htmlBody.ToString(), data.HtmlBody.ToString()); }
private Yield SendEmail(DreamContext context, DreamMessage request, Result <DreamMessage> result) { var updateRecord = NotificationUpdateRecord.FromDocument(request.ToDocument()); _log.DebugFormat("trying to dispatch email to user {0} for wiki '{1}'", updateRecord.UserId, updateRecord.WikiId); var instance = GetInstanceInfo(updateRecord.WikiId); if (!instance.IsValid) { _log.WarnFormat("unable to get required data from site settings, cannot send email. Missing either ui/sitename or page-subscription/from-address "); result.Return(DreamMessage.Ok()); yield break; } var userInfo = instance.GetUserInfo(updateRecord.UserId); if (!userInfo.IsValid) { // need to refetch user info DreamMessage userMsg = null; yield return(_deki.At("users", updateRecord.UserId.ToString()) .With("apikey", _apikey) .WithCookieJar(Cookies) .WithHeader("X-Deki-Site", "id=" + updateRecord.WikiId) .Get(new Result <DreamMessage>()) .Set(x => userMsg = x)); if (!userMsg.IsSuccessful) { _log.DebugFormat("unable to fetch user {0}, skipping delivery: {1}", updateRecord.UserId, userMsg.Status); result.Return(DreamMessage.Ok()); yield break; } var userDoc = userMsg.ToDocument(); try { PopulateUser(userInfo, userDoc); } catch (UserException e) { _log.DebugFormat("unable to populate user {0}, skipping delivery: {1}", updateRecord.UserId, e.Message); result.Return(DreamMessage.Ok()); yield break; } } var culture = userInfo.Culture.GetNonNeutralCulture(instance.Culture); var subject = string.Format("[{0}] {1}", instance.Sitename, _resourceManager.GetString("Notification.Page.email-subject", culture, "Site Modified")); var emailAddress = (!instance.UseShortEmailAddress && !string.IsNullOrEmpty(userInfo.Username)) ? new MailAddress(userInfo.Email, userInfo.Username).ToString() : userInfo.Email; var email = new XDoc("email") .Attr("configuration", instance.WikiId) .Elem("to", emailAddress) .Elem("from", instance.EmailFromAddress) .Elem("subject", subject) .Start("pages"); var header = _resourceManager.GetString("Notification.Page.email-header", culture, "The following pages have changed:"); var plainBody = new StringBuilder(); plainBody.AppendFormat("{0}\r\n\r\n", header); var htmlBody = new XDoc("body") .Attr("html", true) .Elem("h2", header); foreach (Tuplet <uint, DateTime> record in updateRecord.Pages) { var pageId = record.Item1; email.Elem("pageid", pageId); PageChangeData data = null; var timezone = userInfo.Timezone.IfNullOrEmpty(instance.Timezone); yield return(Coroutine.Invoke(_cache.GetPageData, pageId, instance.WikiId, record.Item2, culture, timezone, new Result <PageChangeData>()).Set(x => data = x)); if (data == null) { _log.WarnFormat("Unable to fetch page change data for page {0}", pageId); continue; } htmlBody.AddAll(data.HtmlBody.Elements); plainBody.Append(data.PlainTextBody); } email.End(); if (!instance.EmailFormat.EqualsInvariantIgnoreCase("html")) { email.Elem("body", plainBody.ToString()); } if (!instance.EmailFormat.EqualsInvariantIgnoreCase("plaintext")) { email.Add(htmlBody); } _log.DebugFormat("dispatching email for user '{0}'", userInfo.Id); yield return(_emailer.WithCookieJar(Cookies).PostAsync(email).Catch()); result.Return(DreamMessage.Ok()); yield break; }