Version 8 (#43)
* Use htmx for front end (#36) * Use short GUIDs in URLs and forms (#1) * Refresh theme (#38) * Use ASP.NET Core for log on/off (#39) * Fix date/time / time zone issues (#41) * Update help for v8 (#42) * Add FAKE build script (#37)
This commit was merged in pull request #43.
This commit is contained in:
@@ -7,356 +7,355 @@ open System
|
||||
|
||||
[<Tests>]
|
||||
let asOfDateDisplayTests =
|
||||
testList "AsOfDateDisplay" [
|
||||
test "NoDisplay code is correct" {
|
||||
Expect.equal NoDisplay.code "N" "The code for NoDisplay should have been \"N\""
|
||||
}
|
||||
test "ShortDate code is correct" {
|
||||
Expect.equal ShortDate.code "S" "The code for ShortDate should have been \"S\""
|
||||
}
|
||||
test "LongDate code is correct" {
|
||||
Expect.equal LongDate.code "L" "The code for LongDate should have been \"N\""
|
||||
}
|
||||
test "fromCode N should return NoDisplay" {
|
||||
Expect.equal (AsOfDateDisplay.fromCode "N") NoDisplay "\"N\" should have been converted to NoDisplay"
|
||||
}
|
||||
test "fromCode S should return ShortDate" {
|
||||
Expect.equal (AsOfDateDisplay.fromCode "S") ShortDate "\"S\" should have been converted to ShortDate"
|
||||
}
|
||||
test "fromCode L should return LongDate" {
|
||||
Expect.equal (AsOfDateDisplay.fromCode "L") LongDate "\"L\" should have been converted to LongDate"
|
||||
}
|
||||
test "fromCode X should raise" {
|
||||
Expect.throws (fun () -> AsOfDateDisplay.fromCode "X" |> ignore)
|
||||
"An unknown code should have raised an exception"
|
||||
}
|
||||
testList "AsOfDateDisplay" [
|
||||
test "NoDisplay code is correct" {
|
||||
Expect.equal (AsOfDateDisplay.toCode NoDisplay) "N" "The code for NoDisplay should have been \"N\""
|
||||
}
|
||||
test "ShortDate code is correct" {
|
||||
Expect.equal (AsOfDateDisplay.toCode ShortDate) "S" "The code for ShortDate should have been \"S\""
|
||||
}
|
||||
test "LongDate code is correct" {
|
||||
Expect.equal (AsOfDateDisplay.toCode LongDate) "L" "The code for LongDate should have been \"N\""
|
||||
}
|
||||
test "fromCode N should return NoDisplay" {
|
||||
Expect.equal (AsOfDateDisplay.fromCode "N") NoDisplay "\"N\" should have been converted to NoDisplay"
|
||||
}
|
||||
test "fromCode S should return ShortDate" {
|
||||
Expect.equal (AsOfDateDisplay.fromCode "S") ShortDate "\"S\" should have been converted to ShortDate"
|
||||
}
|
||||
test "fromCode L should return LongDate" {
|
||||
Expect.equal (AsOfDateDisplay.fromCode "L") LongDate "\"L\" should have been converted to LongDate"
|
||||
}
|
||||
test "fromCode X should raise" {
|
||||
Expect.throws (fun () -> AsOfDateDisplay.fromCode "X" |> ignore)
|
||||
"An unknown code should have raised an exception"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let churchTests =
|
||||
testList "Church" [
|
||||
test "empty is as expected" {
|
||||
let mt = Church.empty
|
||||
Expect.equal mt.churchId Guid.Empty "The church ID should have been an empty GUID"
|
||||
Expect.equal mt.name "" "The name should have been blank"
|
||||
Expect.equal mt.city "" "The city should have been blank"
|
||||
Expect.equal mt.st "" "The state should have been blank"
|
||||
Expect.isFalse mt.hasInterface "The church should not show that it has an interface"
|
||||
Expect.isNone mt.interfaceAddress "The interface address should not exist"
|
||||
Expect.isNotNull mt.smallGroups "The small groups navigation property should not be null"
|
||||
Expect.isEmpty mt.smallGroups "There should be no small groups for an empty church"
|
||||
}
|
||||
testList "Church" [
|
||||
test "empty is as expected" {
|
||||
let mt = Church.empty
|
||||
Expect.equal mt.Id.Value Guid.Empty "The church ID should have been an empty GUID"
|
||||
Expect.equal mt.Name "" "The name should have been blank"
|
||||
Expect.equal mt.City "" "The city should have been blank"
|
||||
Expect.equal mt.State "" "The state should have been blank"
|
||||
Expect.isFalse mt.HasVpsInterface "The church should not show that it has an interface"
|
||||
Expect.isNone mt.InterfaceAddress "The interface address should not exist"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let emailFormatTests =
|
||||
testList "EmailFormat" [
|
||||
test "HtmlFormat code is correct" {
|
||||
Expect.equal HtmlFormat.code "H" "The code for HtmlFormat should have been \"H\""
|
||||
}
|
||||
test "PlainTextFormat code is correct" {
|
||||
Expect.equal PlainTextFormat.code "P" "The code for PlainTextFormat should have been \"P\""
|
||||
}
|
||||
test "fromCode H should return HtmlFormat" {
|
||||
Expect.equal (EmailFormat.fromCode "H") HtmlFormat "\"H\" should have been converted to HtmlFormat"
|
||||
}
|
||||
test "fromCode P should return ShortDate" {
|
||||
Expect.equal (EmailFormat.fromCode "P") PlainTextFormat "\"P\" should have been converted to PlainTextFormat"
|
||||
}
|
||||
test "fromCode Z should raise" {
|
||||
Expect.throws (fun () -> EmailFormat.fromCode "Z" |> ignore) "An unknown code should have raised an exception"
|
||||
}
|
||||
testList "EmailFormat" [
|
||||
test "HtmlFormat code is correct" {
|
||||
Expect.equal (EmailFormat.toCode HtmlFormat) "H" "The code for HtmlFormat should have been \"H\""
|
||||
}
|
||||
test "PlainTextFormat code is correct" {
|
||||
Expect.equal (EmailFormat.toCode PlainTextFormat) "P" "The code for PlainTextFormat should have been \"P\""
|
||||
}
|
||||
test "fromCode H should return HtmlFormat" {
|
||||
Expect.equal (EmailFormat.fromCode "H") HtmlFormat "\"H\" should have been converted to HtmlFormat"
|
||||
}
|
||||
test "fromCode P should return ShortDate" {
|
||||
Expect.equal (EmailFormat.fromCode "P") PlainTextFormat
|
||||
"\"P\" should have been converted to PlainTextFormat"
|
||||
}
|
||||
test "fromCode Z should raise" {
|
||||
Expect.throws (fun () -> EmailFormat.fromCode "Z" |> ignore)
|
||||
"An unknown code should have raised an exception"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let expirationTests =
|
||||
testList "Expiration" [
|
||||
test "Automatic code is correct" {
|
||||
Expect.equal Automatic.code "A" "The code for Automatic should have been \"A\""
|
||||
}
|
||||
test "Manual code is correct" {
|
||||
Expect.equal Manual.code "M" "The code for Manual should have been \"M\""
|
||||
}
|
||||
test "Forced code is correct" {
|
||||
Expect.equal Forced.code "F" "The code for Forced should have been \"F\""
|
||||
}
|
||||
test "fromCode A should return Automatic" {
|
||||
Expect.equal (Expiration.fromCode "A") Automatic "\"A\" should have been converted to Automatic"
|
||||
}
|
||||
test "fromCode M should return Manual" {
|
||||
Expect.equal (Expiration.fromCode "M") Manual "\"M\" should have been converted to Manual"
|
||||
}
|
||||
test "fromCode F should return Forced" {
|
||||
Expect.equal (Expiration.fromCode "F") Forced "\"F\" should have been converted to Forced"
|
||||
}
|
||||
test "fromCode V should raise" {
|
||||
Expect.throws (fun () -> Expiration.fromCode "V" |> ignore) "An unknown code should have raised an exception"
|
||||
}
|
||||
testList "Expiration" [
|
||||
test "Automatic code is correct" {
|
||||
Expect.equal (Expiration.toCode Automatic) "A" "The code for Automatic should have been \"A\""
|
||||
}
|
||||
test "Manual code is correct" {
|
||||
Expect.equal (Expiration.toCode Manual) "M" "The code for Manual should have been \"M\""
|
||||
}
|
||||
test "Forced code is correct" {
|
||||
Expect.equal (Expiration.toCode Forced) "F" "The code for Forced should have been \"F\""
|
||||
}
|
||||
test "fromCode A should return Automatic" {
|
||||
Expect.equal (Expiration.fromCode "A") Automatic "\"A\" should have been converted to Automatic"
|
||||
}
|
||||
test "fromCode M should return Manual" {
|
||||
Expect.equal (Expiration.fromCode "M") Manual "\"M\" should have been converted to Manual"
|
||||
}
|
||||
test "fromCode F should return Forced" {
|
||||
Expect.equal (Expiration.fromCode "F") Forced "\"F\" should have been converted to Forced"
|
||||
}
|
||||
test "fromCode V should raise" {
|
||||
Expect.throws (fun () -> Expiration.fromCode "V" |> ignore)
|
||||
"An unknown code should have raised an exception"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let listPreferencesTests =
|
||||
testList "ListPreferences" [
|
||||
test "empty is as expected" {
|
||||
let mt = ListPreferences.empty
|
||||
Expect.equal mt.smallGroupId Guid.Empty "The small group ID should have been an empty GUID"
|
||||
Expect.equal mt.daysToExpire 14 "The default days to expire should have been 14"
|
||||
Expect.equal mt.daysToKeepNew 7 "The default days to keep new should have been 7"
|
||||
Expect.equal mt.longTermUpdateWeeks 4 "The default long term update weeks should have been 4"
|
||||
Expect.equal mt.emailFromName "PrayerTracker" "The default e-mail from name should have been PrayerTracker"
|
||||
Expect.equal mt.emailFromAddress "prayer@djs-consulting.com"
|
||||
"The default e-mail from address should have been prayer@djs-consulting.com"
|
||||
Expect.equal mt.listFonts "Century Gothic,Tahoma,Luxi Sans,sans-serif" "The default list fonts were incorrect"
|
||||
Expect.equal mt.headingColor "maroon" "The default heading text color should have been maroon"
|
||||
Expect.equal mt.lineColor "navy" "The default heding line color should have been navy"
|
||||
Expect.equal mt.headingFontSize 16 "The default heading font size should have been 16"
|
||||
Expect.equal mt.textFontSize 12 "The default text font size should have been 12"
|
||||
Expect.equal mt.requestSort SortByDate "The default request sort should have been by date"
|
||||
Expect.equal mt.groupPassword "" "The default group password should have been blank"
|
||||
Expect.equal mt.defaultEmailType HtmlFormat "The default e-mail type should have been HTML"
|
||||
Expect.isFalse mt.isPublic "The isPublic flag should not have been set"
|
||||
Expect.equal mt.timeZoneId "America/Denver" "The default time zone should have been America/Denver"
|
||||
Expect.equal mt.timeZone.timeZoneId "" "The default preferences should have included an empty time zone"
|
||||
Expect.equal mt.pageSize 100 "The default page size should have been 100"
|
||||
Expect.equal mt.asOfDateDisplay NoDisplay "The as-of date display should have been No Display"
|
||||
}
|
||||
testList "ListPreferences" [
|
||||
test "FontStack is correct for native fonts" {
|
||||
Expect.equal ListPreferences.empty.FontStack
|
||||
"""system-ui,-apple-system,"Segoe UI",Roboto,Ubuntu,"Liberation Sans",Cantarell,"Helvetica Neue",sans-serif"""
|
||||
"The expected native font stack was incorrect"
|
||||
}
|
||||
test "FontStack is correct for specific fonts" {
|
||||
Expect.equal { ListPreferences.empty with Fonts = "Arial,sans-serif" }.FontStack "Arial,sans-serif"
|
||||
"The specified fonts were not returned correctly"
|
||||
}
|
||||
test "empty is as expected" {
|
||||
let mt = ListPreferences.empty
|
||||
Expect.equal mt.SmallGroupId.Value Guid.Empty "The small group ID should have been an empty GUID"
|
||||
Expect.equal mt.DaysToExpire 14 "The default days to expire should have been 14"
|
||||
Expect.equal mt.DaysToKeepNew 7 "The default days to keep new should have been 7"
|
||||
Expect.equal mt.LongTermUpdateWeeks 4 "The default long term update weeks should have been 4"
|
||||
Expect.equal mt.EmailFromName "PrayerTracker" "The default e-mail from name should have been PrayerTracker"
|
||||
Expect.equal mt.EmailFromAddress "prayer@bitbadger.solutions"
|
||||
"The default e-mail from address should have been prayer@bitbadger.solutions"
|
||||
Expect.equal mt.Fonts "native" "The default list fonts were incorrect"
|
||||
Expect.equal mt.HeadingColor "maroon" "The default heading text color should have been maroon"
|
||||
Expect.equal mt.LineColor "navy" "The default heading line color should have been navy"
|
||||
Expect.equal mt.HeadingFontSize 16 "The default heading font size should have been 16"
|
||||
Expect.equal mt.TextFontSize 12 "The default text font size should have been 12"
|
||||
Expect.equal mt.RequestSort SortByDate "The default request sort should have been by date"
|
||||
Expect.equal mt.GroupPassword "" "The default group password should have been blank"
|
||||
Expect.equal mt.DefaultEmailType HtmlFormat "The default e-mail type should have been HTML"
|
||||
Expect.isFalse mt.IsPublic "The isPublic flag should not have been set"
|
||||
Expect.equal (TimeZoneId.toString mt.TimeZoneId) "America/Denver"
|
||||
"The default time zone should have been America/Denver"
|
||||
Expect.equal mt.PageSize 100 "The default page size should have been 100"
|
||||
Expect.equal mt.AsOfDateDisplay NoDisplay "The as-of date display should have been No Display"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let memberTests =
|
||||
testList "Member" [
|
||||
test "empty is as expected" {
|
||||
let mt = Member.empty
|
||||
Expect.equal mt.memberId Guid.Empty "The member ID should have been an empty GUID"
|
||||
Expect.equal mt.smallGroupId Guid.Empty "The small group ID should have been an empty GUID"
|
||||
Expect.equal mt.memberName "" "The member name should have been blank"
|
||||
Expect.equal mt.email "" "The member e-mail address should have been blank"
|
||||
Expect.isNone mt.format "The preferred e-mail format should not exist"
|
||||
Expect.equal mt.smallGroup.smallGroupId Guid.Empty "The small group should have been an empty one"
|
||||
}
|
||||
testList "Member" [
|
||||
test "empty is as expected" {
|
||||
let mt = Member.empty
|
||||
Expect.equal mt.Id.Value Guid.Empty "The member ID should have been an empty GUID"
|
||||
Expect.equal mt.SmallGroupId.Value Guid.Empty "The small group ID should have been an empty GUID"
|
||||
Expect.equal mt.Name "" "The member name should have been blank"
|
||||
Expect.equal mt.Email "" "The member e-mail address should have been blank"
|
||||
Expect.isNone mt.Format "The preferred e-mail format should not exist"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let prayerRequestTests =
|
||||
testList "PrayerRequest" [
|
||||
test "empty is as expected" {
|
||||
let mt = PrayerRequest.empty
|
||||
Expect.equal mt.prayerRequestId Guid.Empty "The request ID should have been an empty GUID"
|
||||
Expect.equal mt.requestType CurrentRequest "The request type should have been Current"
|
||||
Expect.equal mt.userId Guid.Empty "The user ID should have been an empty GUID"
|
||||
Expect.equal mt.smallGroupId Guid.Empty "The small group ID should have been an empty GUID"
|
||||
Expect.equal mt.enteredDate DateTime.MinValue "The entered date should have been the minimum"
|
||||
Expect.equal mt.updatedDate DateTime.MinValue "The updated date should have been the minimum"
|
||||
Expect.isNone mt.requestor "The requestor should not exist"
|
||||
Expect.equal mt.text "" "The request text should have been blank"
|
||||
Expect.isFalse mt.notifyChaplain "The notify chaplain flag should not have been set"
|
||||
Expect.equal mt.expiration Automatic "The expiration should have been Automatic"
|
||||
Expect.equal mt.user.userId Guid.Empty "The user should have been an empty one"
|
||||
Expect.equal mt.smallGroup.smallGroupId Guid.Empty "The small group should have been an empty one"
|
||||
}
|
||||
test "isExpired always returns false for expecting requests" {
|
||||
let req = { PrayerRequest.empty with requestType = Expecting }
|
||||
Expect.isFalse (req.isExpired DateTime.Now 0) "An expecting request should never be considered expired"
|
||||
}
|
||||
test "isExpired always returns false for manually-expired requests" {
|
||||
let req = { PrayerRequest.empty with updatedDate = DateTime.Now.AddMonths -1; expiration = Manual }
|
||||
Expect.isFalse (req.isExpired DateTime.Now 4) "A never-expired request should never be considered expired"
|
||||
}
|
||||
test "isExpired always returns false for long term/recurring requests" {
|
||||
let req = { PrayerRequest.empty with requestType = LongTermRequest }
|
||||
Expect.isFalse (req.isExpired DateTime.Now 0) "A recurring/long-term request should never be considered expired"
|
||||
}
|
||||
test "isExpired always returns true for force-expired requests" {
|
||||
let req = { PrayerRequest.empty with updatedDate = DateTime.Now; expiration = Forced }
|
||||
Expect.isTrue (req.isExpired DateTime.Now 5) "A force-expired request should always be considered expired"
|
||||
}
|
||||
test "isExpired returns false for non-expired requests" {
|
||||
let now = DateTime.Now
|
||||
let req = { PrayerRequest.empty with updatedDate = now.AddDays -5. }
|
||||
Expect.isFalse (req.isExpired now 7) "A request updated 5 days ago should not be considered expired"
|
||||
}
|
||||
test "isExpired returns true for expired requests" {
|
||||
let now = DateTime.Now
|
||||
let req = { PrayerRequest.empty with updatedDate = now.AddDays -8. }
|
||||
Expect.isTrue (req.isExpired now 7) "A request updated 8 days ago should be considered expired"
|
||||
}
|
||||
test "isExpired returns true for same-day expired requests" {
|
||||
let now = DateTime.Now
|
||||
let req = { PrayerRequest.empty with updatedDate = now.Date.AddDays(-7.).AddSeconds -1. }
|
||||
Expect.isTrue (req.isExpired now 7) "A request entered a second before midnight should be considered expired"
|
||||
}
|
||||
test "updateRequired returns false for expired requests" {
|
||||
let req = { PrayerRequest.empty with expiration = Forced }
|
||||
Expect.isFalse (req.updateRequired DateTime.Now 7 4) "An expired request should not require an update"
|
||||
}
|
||||
test "updateRequired returns false when an update is not required for an active request" {
|
||||
let now = DateTime.Now
|
||||
let req =
|
||||
{ PrayerRequest.empty with
|
||||
requestType = LongTermRequest
|
||||
updatedDate = now.AddDays -14.
|
||||
}
|
||||
Expect.isFalse (req.updateRequired now 7 4)
|
||||
"An active request updated 14 days ago should not require an update until 28 days"
|
||||
}
|
||||
test "updateRequired returns true when an update is required for an active request" {
|
||||
let now = DateTime.Now
|
||||
let req =
|
||||
{ PrayerRequest.empty with
|
||||
requestType = LongTermRequest
|
||||
updatedDate = now.AddDays -34.
|
||||
}
|
||||
Expect.isTrue (req.updateRequired now 7 4)
|
||||
"An active request updated 34 days ago should require an update (past 28 days)"
|
||||
}
|
||||
let instantNow = SystemClock.Instance.GetCurrentInstant
|
||||
let localDateNow () = (instantNow ()).InUtc().Date
|
||||
testList "PrayerRequest" [
|
||||
test "empty is as expected" {
|
||||
let mt = PrayerRequest.empty
|
||||
Expect.equal mt.Id.Value Guid.Empty "The request ID should have been an empty GUID"
|
||||
Expect.equal mt.RequestType CurrentRequest "The request type should have been Current"
|
||||
Expect.equal mt.UserId.Value Guid.Empty "The user ID should have been an empty GUID"
|
||||
Expect.equal mt.SmallGroupId.Value Guid.Empty "The small group ID should have been an empty GUID"
|
||||
Expect.equal mt.EnteredDate Instant.MinValue "The entered date should have been the minimum"
|
||||
Expect.equal mt.UpdatedDate Instant.MinValue "The updated date should have been the minimum"
|
||||
Expect.isNone mt.Requestor "The requestor should not exist"
|
||||
Expect.equal mt.Text "" "The request text should have been blank"
|
||||
Expect.isFalse mt.NotifyChaplain "The notify chaplain flag should not have been set"
|
||||
Expect.equal mt.Expiration Automatic "The expiration should have been Automatic"
|
||||
}
|
||||
test "isExpired always returns false for expecting requests" {
|
||||
PrayerRequest.isExpired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with RequestType = Expecting }
|
||||
|> Flip.Expect.isFalse "An expecting request should never be considered expired"
|
||||
}
|
||||
test "isExpired always returns false for manually-expired requests" {
|
||||
PrayerRequest.isExpired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with UpdatedDate = (instantNow ()) - Duration.FromDays 1; Expiration = Manual }
|
||||
|> Flip.Expect.isFalse "A never-expired request should never be considered expired"
|
||||
}
|
||||
test "isExpired always returns false for long term/recurring requests" {
|
||||
PrayerRequest.isExpired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with RequestType = LongTermRequest }
|
||||
|> Flip.Expect.isFalse "A recurring/long-term request should never be considered expired"
|
||||
}
|
||||
test "isExpired always returns true for force-expired requests" {
|
||||
PrayerRequest.isExpired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with UpdatedDate = (instantNow ()); Expiration = Forced }
|
||||
|> Flip.Expect.isTrue "A force-expired request should always be considered expired"
|
||||
}
|
||||
test "isExpired returns false for non-expired requests" {
|
||||
let now = instantNow ()
|
||||
PrayerRequest.isExpired (now.InUtc().Date) SmallGroup.empty
|
||||
{ PrayerRequest.empty with UpdatedDate = now - Duration.FromDays 5 }
|
||||
|> Flip.Expect.isFalse "A request updated 5 days ago should not be considered expired"
|
||||
}
|
||||
test "isExpired returns true for expired requests" {
|
||||
let now = instantNow ()
|
||||
PrayerRequest.isExpired (now.InUtc().Date) SmallGroup.empty
|
||||
{ PrayerRequest.empty with UpdatedDate = now - Duration.FromDays 15 }
|
||||
|> Flip.Expect.isTrue "A request updated 15 days ago should be considered expired"
|
||||
}
|
||||
test "isExpired returns true for same-day expired requests" {
|
||||
let now = instantNow ()
|
||||
PrayerRequest.isExpired (now.InUtc().Date) SmallGroup.empty
|
||||
{ PrayerRequest.empty with UpdatedDate = now - (Duration.FromDays 14) - (Duration.FromSeconds 1L) }
|
||||
|> Flip.Expect.isTrue "A request entered a second before midnight should be considered expired"
|
||||
}
|
||||
test "updateRequired returns false for expired requests" {
|
||||
PrayerRequest.updateRequired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with Expiration = Forced }
|
||||
|> Flip.Expect.isFalse "An expired request should not require an update"
|
||||
}
|
||||
test "updateRequired returns false when an update is not required for an active request" {
|
||||
let now = instantNow ()
|
||||
PrayerRequest.updateRequired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with RequestType = LongTermRequest; UpdatedDate = now - Duration.FromDays 14 }
|
||||
|> Flip.Expect.isFalse "An active request updated 14 days ago should not require an update until 28 days"
|
||||
}
|
||||
test "UpdateRequired returns true when an update is required for an active request" {
|
||||
let now = instantNow ()
|
||||
PrayerRequest.updateRequired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with RequestType = LongTermRequest; UpdatedDate = now - Duration.FromDays 34 }
|
||||
|> Flip.Expect.isTrue "An active request updated 34 days ago should require an update (past 28 days)"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let prayerRequestTypeTests =
|
||||
testList "PrayerRequestType" [
|
||||
test "CurrentRequest code is correct" {
|
||||
Expect.equal CurrentRequest.code "C" "The code for CurrentRequest should have been \"C\""
|
||||
}
|
||||
test "LongTermRequest code is correct" {
|
||||
Expect.equal LongTermRequest.code "L" "The code for LongTermRequest should have been \"L\""
|
||||
}
|
||||
test "PraiseReport code is correct" {
|
||||
Expect.equal PraiseReport.code "P" "The code for PraiseReport should have been \"P\""
|
||||
}
|
||||
test "Expecting code is correct" {
|
||||
Expect.equal Expecting.code "E" "The code for Expecting should have been \"E\""
|
||||
}
|
||||
test "Announcement code is correct" {
|
||||
Expect.equal Announcement.code "A" "The code for Announcement should have been \"A\""
|
||||
}
|
||||
test "fromCode C should return CurrentRequest" {
|
||||
Expect.equal (PrayerRequestType.fromCode "C") CurrentRequest
|
||||
"\"C\" should have been converted to CurrentRequest"
|
||||
}
|
||||
test "fromCode L should return LongTermRequest" {
|
||||
Expect.equal (PrayerRequestType.fromCode "L") LongTermRequest
|
||||
"\"L\" should have been converted to LongTermRequest"
|
||||
}
|
||||
test "fromCode P should return PraiseReport" {
|
||||
Expect.equal (PrayerRequestType.fromCode "P") PraiseReport "\"P\" should have been converted to PraiseReport"
|
||||
}
|
||||
test "fromCode E should return Expecting" {
|
||||
Expect.equal (PrayerRequestType.fromCode "E") Expecting "\"E\" should have been converted to Expecting"
|
||||
}
|
||||
test "fromCode A should return Announcement" {
|
||||
Expect.equal (PrayerRequestType.fromCode "A") Announcement "\"A\" should have been converted to Announcement"
|
||||
}
|
||||
test "fromCode R should raise" {
|
||||
Expect.throws (fun () -> PrayerRequestType.fromCode "R" |> ignore)
|
||||
"An unknown code should have raised an exception"
|
||||
}
|
||||
testList "PrayerRequestType" [
|
||||
test "CurrentRequest code is correct" {
|
||||
Expect.equal (PrayerRequestType.toCode CurrentRequest) "C"
|
||||
"The code for CurrentRequest should have been \"C\""
|
||||
}
|
||||
test "LongTermRequest code is correct" {
|
||||
Expect.equal (PrayerRequestType.toCode LongTermRequest) "L"
|
||||
"The code for LongTermRequest should have been \"L\""
|
||||
}
|
||||
test "PraiseReport code is correct" {
|
||||
Expect.equal (PrayerRequestType.toCode PraiseReport) "P" "The code for PraiseReport should have been \"P\""
|
||||
}
|
||||
test "Expecting code is correct" {
|
||||
Expect.equal (PrayerRequestType.toCode Expecting) "E" "The code for Expecting should have been \"E\""
|
||||
}
|
||||
test "Announcement code is correct" {
|
||||
Expect.equal (PrayerRequestType.toCode Announcement) "A" "The code for Announcement should have been \"A\""
|
||||
}
|
||||
test "fromCode C should return CurrentRequest" {
|
||||
Expect.equal (PrayerRequestType.fromCode "C") CurrentRequest
|
||||
"\"C\" should have been converted to CurrentRequest"
|
||||
}
|
||||
test "fromCode L should return LongTermRequest" {
|
||||
Expect.equal (PrayerRequestType.fromCode "L") LongTermRequest
|
||||
"\"L\" should have been converted to LongTermRequest"
|
||||
}
|
||||
test "fromCode P should return PraiseReport" {
|
||||
Expect.equal (PrayerRequestType.fromCode "P") PraiseReport
|
||||
"\"P\" should have been converted to PraiseReport"
|
||||
}
|
||||
test "fromCode E should return Expecting" {
|
||||
Expect.equal (PrayerRequestType.fromCode "E") Expecting "\"E\" should have been converted to Expecting"
|
||||
}
|
||||
test "fromCode A should return Announcement" {
|
||||
Expect.equal (PrayerRequestType.fromCode "A") Announcement
|
||||
"\"A\" should have been converted to Announcement"
|
||||
}
|
||||
test "fromCode R should raise" {
|
||||
Expect.throws (fun () -> PrayerRequestType.fromCode "R" |> ignore)
|
||||
"An unknown code should have raised an exception"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let requestSortTests =
|
||||
testList "RequestSort" [
|
||||
test "SortByDate code is correct" {
|
||||
Expect.equal SortByDate.code "D" "The code for SortByDate should have been \"D\""
|
||||
}
|
||||
test "SortByRequestor code is correct" {
|
||||
Expect.equal SortByRequestor.code "R" "The code for SortByRequestor should have been \"R\""
|
||||
}
|
||||
test "fromCode D should return SortByDate" {
|
||||
Expect.equal (RequestSort.fromCode "D") SortByDate "\"D\" should have been converted to SortByDate"
|
||||
}
|
||||
test "fromCode R should return SortByRequestor" {
|
||||
Expect.equal (RequestSort.fromCode "R") SortByRequestor "\"R\" should have been converted to SortByRequestor"
|
||||
}
|
||||
test "fromCode Q should raise" {
|
||||
Expect.throws (fun () -> RequestSort.fromCode "Q" |> ignore) "An unknown code should have raised an exception"
|
||||
}
|
||||
testList "RequestSort" [
|
||||
test "SortByDate code is correct" {
|
||||
Expect.equal (RequestSort.toCode SortByDate) "D" "The code for SortByDate should have been \"D\""
|
||||
}
|
||||
test "SortByRequestor code is correct" {
|
||||
Expect.equal (RequestSort.toCode SortByRequestor) "R" "The code for SortByRequestor should have been \"R\""
|
||||
}
|
||||
test "fromCode D should return SortByDate" {
|
||||
Expect.equal (RequestSort.fromCode "D") SortByDate "\"D\" should have been converted to SortByDate"
|
||||
}
|
||||
test "fromCode R should return SortByRequestor" {
|
||||
Expect.equal (RequestSort.fromCode "R") SortByRequestor
|
||||
"\"R\" should have been converted to SortByRequestor"
|
||||
}
|
||||
test "fromCode Q should raise" {
|
||||
Expect.throws (fun () -> RequestSort.fromCode "Q" |> ignore)
|
||||
"An unknown code should have raised an exception"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let smallGroupTests =
|
||||
testList "SmallGroup" [
|
||||
let now = DateTime (2017, 5, 12, 12, 15, 0, DateTimeKind.Utc)
|
||||
let withFakeClock f () =
|
||||
FakeClock (Instant.FromDateTimeUtc now) |> f
|
||||
yield test "empty is as expected" {
|
||||
let mt = SmallGroup.empty
|
||||
Expect.equal mt.smallGroupId Guid.Empty "The small group ID should have been an empty GUID"
|
||||
Expect.equal mt.churchId Guid.Empty "The church ID should have been an empty GUID"
|
||||
Expect.equal mt.name "" "The name should have been blank"
|
||||
Expect.equal mt.church.churchId Guid.Empty "The church should have been an empty one"
|
||||
Expect.isNotNull mt.members "The members navigation property should not be null"
|
||||
Expect.isEmpty mt.members "There should be no members for an empty small group"
|
||||
Expect.isNotNull mt.prayerRequests "The prayer requests navigation property should not be null"
|
||||
Expect.isEmpty mt.prayerRequests "There should be no prayer requests for an empty small group"
|
||||
Expect.isNotNull mt.users "The users navigation property should not be null"
|
||||
Expect.isEmpty mt.users "There should be no users for an empty small group"
|
||||
}
|
||||
yield! testFixture withFakeClock [
|
||||
"localTimeNow adjusts the time ahead of UTC",
|
||||
fun clock ->
|
||||
let grp = { SmallGroup.empty with preferences = { ListPreferences.empty with timeZoneId = "Europe/Berlin" } }
|
||||
Expect.isGreaterThan (grp.localTimeNow clock) now "UTC to Europe/Berlin should have added hours"
|
||||
"localTimeNow adjusts the time behind UTC",
|
||||
fun clock ->
|
||||
Expect.isLessThan (SmallGroup.empty.localTimeNow clock) now
|
||||
"UTC to America/Denver should have subtracted hours"
|
||||
"localTimeNow returns UTC when the time zone is invalid",
|
||||
fun clock ->
|
||||
let grp = { SmallGroup.empty with preferences = { ListPreferences.empty with timeZoneId = "garbage" } }
|
||||
Expect.equal (grp.localTimeNow clock) now "UTC should have been returned for an invalid time zone"
|
||||
]
|
||||
yield test "localTimeNow fails when clock is not passed" {
|
||||
Expect.throws (fun () -> (SmallGroup.empty.localTimeNow >> ignore) null)
|
||||
"Should have raised an exception for null clock"
|
||||
}
|
||||
yield test "localDateNow returns the date portion" {
|
||||
let now' = DateTime (2017, 5, 12, 1, 15, 0, DateTimeKind.Utc)
|
||||
let clock = FakeClock (Instant.FromDateTimeUtc now')
|
||||
Expect.isLessThan (SmallGroup.empty.localDateNow clock) now.Date "The date should have been a day earlier"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let timeZoneTests =
|
||||
testList "TimeZone" [
|
||||
test "empty is as expected" {
|
||||
let mt = TimeZone.empty
|
||||
Expect.equal mt.timeZoneId "" "The time zone ID should have been blank"
|
||||
Expect.equal mt.description "" "The description should have been blank"
|
||||
Expect.equal mt.sortOrder 0 "The sort order should have been zero"
|
||||
Expect.isFalse mt.isActive "The is-active flag should not have been set"
|
||||
}
|
||||
testList "SmallGroup" [
|
||||
let now = Instant.FromDateTimeUtc (DateTime (2017, 5, 12, 12, 15, 0, DateTimeKind.Utc))
|
||||
let withFakeClock f () =
|
||||
FakeClock now |> f
|
||||
yield test "empty is as expected" {
|
||||
let mt = SmallGroup.empty
|
||||
Expect.equal mt.Id.Value Guid.Empty "The small group ID should have been an empty GUID"
|
||||
Expect.equal mt.ChurchId.Value Guid.Empty "The church ID should have been an empty GUID"
|
||||
Expect.equal mt.Name "" "The name should have been blank"
|
||||
}
|
||||
yield! testFixture withFakeClock [
|
||||
"LocalTimeNow adjusts the time ahead of UTC",
|
||||
fun clock ->
|
||||
let grp =
|
||||
{ SmallGroup.empty with
|
||||
Preferences = { ListPreferences.empty with TimeZoneId = TimeZoneId "Europe/Berlin" }
|
||||
}
|
||||
Expect.isGreaterThan (SmallGroup.localTimeNow clock grp) (now.InUtc().LocalDateTime)
|
||||
"UTC to Europe/Berlin should have added hours"
|
||||
"LocalTimeNow adjusts the time behind UTC",
|
||||
fun clock ->
|
||||
Expect.isLessThan (SmallGroup.localTimeNow clock SmallGroup.empty) (now.InUtc().LocalDateTime)
|
||||
"UTC to America/Denver should have subtracted hours"
|
||||
"LocalTimeNow returns UTC when the time zone is invalid",
|
||||
fun clock ->
|
||||
let grp =
|
||||
{ SmallGroup.empty with
|
||||
Preferences = { ListPreferences.empty with TimeZoneId = TimeZoneId "garbage" }
|
||||
}
|
||||
Expect.equal (SmallGroup.localTimeNow clock grp) (now.InUtc().LocalDateTime)
|
||||
"UTC should have been returned for an invalid time zone"
|
||||
]
|
||||
yield test "localTimeNow fails when clock is not passed" {
|
||||
Expect.throws (fun () -> (SmallGroup.localTimeNow null SmallGroup.empty |> ignore))
|
||||
"Should have raised an exception for null clock"
|
||||
}
|
||||
yield test "LocalDateNow returns the date portion" {
|
||||
let clock = FakeClock (Instant.FromDateTimeUtc (DateTime (2017, 5, 12, 1, 15, 0, DateTimeKind.Utc)))
|
||||
Expect.isLessThan (SmallGroup.localDateNow clock SmallGroup.empty) (now.InUtc().Date)
|
||||
"The date should have been a day earlier"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let userTests =
|
||||
testList "User" [
|
||||
test "empty is as expected" {
|
||||
let mt = User.empty
|
||||
Expect.equal mt.userId Guid.Empty "The user ID should have been an empty GUID"
|
||||
Expect.equal mt.firstName "" "The first name should have been blank"
|
||||
Expect.equal mt.lastName "" "The last name should have been blank"
|
||||
Expect.equal mt.emailAddress "" "The e-mail address should have been blank"
|
||||
Expect.isFalse mt.isAdmin "The is admin flag should not have been set"
|
||||
Expect.equal mt.passwordHash "" "The password hash should have been blank"
|
||||
Expect.isNone mt.salt "The password salt should not exist"
|
||||
Expect.isNotNull mt.smallGroups "The small groups navigation property should not have been null"
|
||||
Expect.isEmpty mt.smallGroups "There should be no small groups for an empty user"
|
||||
}
|
||||
test "fullName concatenates first and last names" {
|
||||
let user = { User.empty with firstName = "Unit"; lastName = "Test" }
|
||||
Expect.equal user.fullName "Unit Test" "The full name should be the first and last, separated by a space"
|
||||
}
|
||||
testList "User" [
|
||||
test "empty is as expected" {
|
||||
let mt = User.empty
|
||||
Expect.equal mt.Id.Value Guid.Empty "The user ID should have been an empty GUID"
|
||||
Expect.equal mt.FirstName "" "The first name should have been blank"
|
||||
Expect.equal mt.LastName "" "The last name should have been blank"
|
||||
Expect.equal mt.Email "" "The e-mail address should have been blank"
|
||||
Expect.isFalse mt.IsAdmin "The is admin flag should not have been set"
|
||||
Expect.equal mt.PasswordHash "" "The password hash should have been blank"
|
||||
}
|
||||
test "Name concatenates first and last names" {
|
||||
let user = { User.empty with FirstName = "Unit"; LastName = "Test" }
|
||||
Expect.equal user.Name "Unit Test" "The full name should be the first and last, separated by a space"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let userSmallGroupTests =
|
||||
testList "UserSmallGroup" [
|
||||
test "empty is as expected" {
|
||||
let mt = UserSmallGroup.empty
|
||||
Expect.equal mt.userId Guid.Empty "The user ID should have been an empty GUID"
|
||||
Expect.equal mt.smallGroupId Guid.Empty "The small group ID should have been an empty GUID"
|
||||
Expect.equal mt.user.userId Guid.Empty "The user should have been an empty one"
|
||||
Expect.equal mt.smallGroup.smallGroupId Guid.Empty "The small group should have been an empty one"
|
||||
}
|
||||
testList "UserSmallGroup" [
|
||||
test "empty is as expected" {
|
||||
let mt = UserSmallGroup.empty
|
||||
Expect.equal mt.UserId.Value Guid.Empty "The user ID should have been an empty GUID"
|
||||
Expect.equal mt.SmallGroupId.Value Guid.Empty "The small group ID should have been an empty GUID"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user