Import v7.1 files
This commit is contained in:
219
src/PrayerTracker.Tests/Data/EntitiesTests.fs
Normal file
219
src/PrayerTracker.Tests/Data/EntitiesTests.fs
Normal file
@@ -0,0 +1,219 @@
|
||||
module PrayerTracker.Entities.EntitiesTests
|
||||
|
||||
open Expecto
|
||||
open System
|
||||
open System.Linq
|
||||
open NodaTime.Testing
|
||||
open NodaTime
|
||||
|
||||
[<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"
|
||||
}
|
||||
]
|
||||
|
||||
[<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 "D" "The default request sort should have been D (date)"
|
||||
Expect.equal mt.groupPassword "" "The default group password should have been blank"
|
||||
Expect.equal mt.defaultEmailType EmailType.Html "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"
|
||||
}
|
||||
]
|
||||
|
||||
[<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"
|
||||
}
|
||||
]
|
||||
|
||||
[<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 RequestType.Current "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.doNotExpire "The do not expire flag should not have been set"
|
||||
Expect.isFalse mt.notifyChaplain "The notify chaplain flag should not have been set"
|
||||
Expect.isFalse mt.isManuallyExpired "The is manually expired flag should not have been set"
|
||||
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 = RequestType.Expecting }
|
||||
Expect.isFalse (req.isExpired DateTime.Now 0) "An expecting request should never be considered expired"
|
||||
}
|
||||
test "isExpired always returns false for never-expired requests" {
|
||||
let req = { PrayerRequest.empty with updatedDate = DateTime.Now.AddMonths -1; doNotExpire = true }
|
||||
Expect.isFalse (req.isExpired DateTime.Now 4) "A never-expired request should never be considered expired"
|
||||
}
|
||||
test "isExpired always returns false for recurring requests" {
|
||||
let req = { PrayerRequest.empty with requestType = RequestType.Recurring }
|
||||
Expect.isFalse (req.isExpired DateTime.Now 0) "A recurring/long-term request should never be considered expired"
|
||||
}
|
||||
test "isExpired always returns true for manually expired requests" {
|
||||
let req = { PrayerRequest.empty with updatedDate = DateTime.Now; isManuallyExpired = true }
|
||||
Expect.isTrue (req.isExpired DateTime.Now 5) "A manually expired request should always be considered expired"
|
||||
}
|
||||
test "isExpired returns false for non-expired requests" {
|
||||
let req = { PrayerRequest.empty with updatedDate = DateTime.Now.AddDays -5. }
|
||||
Expect.isFalse (req.isExpired DateTime.Now 7) "A request updated 5 days ago should not be considered expired"
|
||||
}
|
||||
test "isExpired returns true for expired requests" {
|
||||
let req = { PrayerRequest.empty with updatedDate = DateTime.Now.AddDays -8. }
|
||||
Expect.isTrue (req.isExpired DateTime.Now 7) "A request updated 8 days ago should be considered expired"
|
||||
}
|
||||
test "updateRequired returns false for expired requests" {
|
||||
let req = { PrayerRequest.empty with isManuallyExpired = true }
|
||||
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 req =
|
||||
{ PrayerRequest.empty with
|
||||
requestType = RequestType.Recurring
|
||||
updatedDate = DateTime.Now.AddDays -14.
|
||||
}
|
||||
Expect.isFalse (req.updateRequired DateTime.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 req =
|
||||
{ PrayerRequest.empty with
|
||||
requestType = RequestType.Recurring
|
||||
updatedDate = DateTime.Now.AddDays -34.
|
||||
}
|
||||
Expect.isTrue (req.updateRequired DateTime.Now 7 4)
|
||||
"An active request updated 34 days ago should require an update (past 28 days)"
|
||||
}
|
||||
]
|
||||
|
||||
[<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"
|
||||
}
|
||||
]
|
||||
|
||||
[<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"
|
||||
}
|
||||
]
|
||||
|
||||
[<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"
|
||||
}
|
||||
]
|
||||
33
src/PrayerTracker.Tests/PrayerTracker.Tests.fsproj
Normal file
33
src/PrayerTracker.Tests/PrayerTracker.Tests.fsproj
Normal file
@@ -0,0 +1,33 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="TestLocalization.fs" />
|
||||
<Compile Include="Data\EntitiesTests.fs" />
|
||||
<Compile Include="UI\UtilsTests.fs" />
|
||||
<Compile Include="UI\ViewModelsTests.fs" />
|
||||
<Compile Include="UI\CommonFunctionsTests.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Expecto" Version="8.4.2" />
|
||||
<PackageReference Include="Expecto.VisualStudio.TestAdapter" Version="10.0.0" />
|
||||
<PackageReference Include="NodaTime.Testing" Version="2.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PrayerTracker.Data\PrayerTracker.Data.fsproj" />
|
||||
<ProjectReference Include="..\PrayerTracker.UI\PrayerTracker.UI.fsproj" />
|
||||
<ProjectReference Include="..\PrayerTracker\PrayerTracker.fsproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="FSharp.Core" Version="4.5.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
5
src/PrayerTracker.Tests/Program.fs
Normal file
5
src/PrayerTracker.Tests/Program.fs
Normal file
@@ -0,0 +1,5 @@
|
||||
open Expecto
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv =
|
||||
runTestsInAssembly defaultConfig argv
|
||||
14
src/PrayerTracker.Tests/TestLocalization.fs
Normal file
14
src/PrayerTracker.Tests/TestLocalization.fs
Normal file
@@ -0,0 +1,14 @@
|
||||
module PrayerTracker.Tests.TestLocalization
|
||||
|
||||
open Microsoft.Extensions.Localization
|
||||
open Microsoft.Extensions.Logging.Abstractions
|
||||
open Microsoft.Extensions.Options
|
||||
open PrayerTracker
|
||||
|
||||
let _s =
|
||||
let asm = typeof<Common>.Assembly.GetName().Name
|
||||
let opts =
|
||||
{ new IOptions<LocalizationOptions> with
|
||||
member __.Value with get () = LocalizationOptions (ResourcesPath = "Resources")
|
||||
}
|
||||
ResourceManagerStringLocalizerFactory(opts, new NullLoggerFactory ()).Create("Common", asm)
|
||||
208
src/PrayerTracker.Tests/UI/CommonFunctionsTests.fs
Normal file
208
src/PrayerTracker.Tests/UI/CommonFunctionsTests.fs
Normal file
@@ -0,0 +1,208 @@
|
||||
module PrayerTracker.UI.CommonFunctionsTests
|
||||
|
||||
open Expecto
|
||||
open Giraffe.GiraffeViewEngine
|
||||
open Microsoft.AspNetCore.Mvc.Localization
|
||||
open Microsoft.Extensions.Localization
|
||||
open PrayerTracker.Tests.TestLocalization
|
||||
open PrayerTracker.Views
|
||||
open System.IO
|
||||
|
||||
|
||||
[<Tests>]
|
||||
let encLocTextTests =
|
||||
testList "encLocText" [
|
||||
test "succeeds" {
|
||||
let enc = encLocText (LocalizedString ("test", "test&")) |> renderHtmlNode
|
||||
Expect.equal enc "test&" "string not encoded correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let iconSizedTests =
|
||||
testList "iconSized" [
|
||||
test "succeeds" {
|
||||
let ico = iconSized 18 "tom-&-jerry" |> renderHtmlNode
|
||||
Expect.equal ico "<i class=\"material-icons md-18\">tom-&-jerry</i>" "icon HTML not correct"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let iconTests =
|
||||
testList "icon" [
|
||||
test "succeeds" {
|
||||
let ico = icon "bob-&-tom" |> renderHtmlNode
|
||||
Expect.equal ico "<i class=\"material-icons\">bob-&-tom</i>" "icon HTML not correct"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let namedColorListTests =
|
||||
testList "namedColorList" [
|
||||
test "succeeds with default values" {
|
||||
let expected =
|
||||
[ "<select name=\"the-name\">"
|
||||
"<option value=\"aqua\" style=\"background-color:aqua;color:black;\">aqua</option>"
|
||||
"<option value=\"black\" style=\"background-color:black;color:white;\">black</option>"
|
||||
"<option value=\"blue\" style=\"background-color:blue;color:white;\">blue</option>"
|
||||
"<option value=\"fuchsia\" style=\"background-color:fuchsia;color:black;\">fuchsia</option>"
|
||||
"<option value=\"gray\" style=\"background-color:gray;color:white;\">gray</option>"
|
||||
"<option value=\"green\" style=\"background-color:green;color:white;\">green</option>"
|
||||
"<option value=\"lime\" style=\"background-color:lime;color:black;\">lime</option>"
|
||||
"<option value=\"maroon\" style=\"background-color:maroon;color:white;\">maroon</option>"
|
||||
"<option value=\"navy\" style=\"background-color:navy;color:white;\">navy</option>"
|
||||
"<option value=\"olive\" style=\"background-color:olive;color:white;\">olive</option>"
|
||||
"<option value=\"purple\" style=\"background-color:purple;color:white;\">purple</option>"
|
||||
"<option value=\"red\" style=\"background-color:red;color:black;\">red</option>"
|
||||
"<option value=\"silver\" style=\"background-color:silver;color:black;\">silver</option>"
|
||||
"<option value=\"teal\" style=\"background-color:teal;color:white;\">teal</option>"
|
||||
"<option value=\"white\" style=\"background-color:white;color:black;\">white</option>"
|
||||
"<option value=\"yellow\" style=\"background-color:yellow;color:black;\">yellow</option>"
|
||||
"</select>"
|
||||
]
|
||||
|> String.concat ""
|
||||
let selectList = namedColorList "the-name" "" [] _s |> renderHtmlNode
|
||||
Expect.equal expected selectList "The default select list was not generated correctly"
|
||||
}
|
||||
test "succeeds with a selected value" {
|
||||
let selectList = namedColorList "the-name" "white" [] _s |> renderHtmlNode
|
||||
Expect.stringContains selectList " selected>white</option>" "Selected option not generated correctly"
|
||||
}
|
||||
test "succeeds with extra attributes" {
|
||||
let selectList = namedColorList "the-name" "" [ _id "myId" ] _s |> renderHtmlNode
|
||||
Expect.stringStarts selectList "<select name=\"the-name\" id=\"myId\">" "Attributes not included correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let radioTests =
|
||||
testList "radio" [
|
||||
test "succeeds when not selected" {
|
||||
let rad = radio "a-name" "anId" "test" "unit" |> renderHtmlNode
|
||||
Expect.equal rad "<input type=\"radio\" name=\"a-name\" id=\"anId\" value=\"test\">"
|
||||
"Unselected radio button not generated correctly"
|
||||
}
|
||||
test "succeeds when selected" {
|
||||
let rad = radio "a-name" "anId" "unit" "unit" |> renderHtmlNode
|
||||
Expect.equal rad "<input type=\"radio\" name=\"a-name\" id=\"anId\" value=\"unit\" checked>"
|
||||
"Selected radio button not generated correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let rawLocTextTests =
|
||||
testList "rawLocText" [
|
||||
test "succeeds" {
|
||||
use sw = new StringWriter ()
|
||||
let raw = rawLocText sw (LocalizedHtmlString ("test", "test&")) |> renderHtmlNode
|
||||
Expect.equal raw "test&" "string not written correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let selectDefaultTests =
|
||||
testList "selectDefault" [
|
||||
test "succeeds" {
|
||||
Expect.equal (selectDefault "a&b") "— a&b —" "Default selection not generated correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let selectListTests =
|
||||
testList "selectList" [
|
||||
test "succeeds with minimum options" {
|
||||
let theList = selectList "a-list" "" [] [] |> renderHtmlNode
|
||||
Expect.equal theList "<select name=\"a-list\" id=\"a-list\"></select>" "Empty select list not generated correctly"
|
||||
}
|
||||
test "succeeds with all options" {
|
||||
let theList =
|
||||
[ "tom", "Tom&"
|
||||
"bob", "Bob"
|
||||
"jan", "Jan"
|
||||
]
|
||||
|> selectList "the-list" "bob" [ _style "ugly" ]
|
||||
|> renderHtmlNode
|
||||
let expected =
|
||||
[ "<select name=\"the-list\" id=\"the-list\" style=\"ugly\">"
|
||||
"<option value=\"tom\">Tom&</option>"
|
||||
"<option value=\"bob\" selected>Bob</option>"
|
||||
"<option value=\"jan\">Jan</option>"
|
||||
"</select>"
|
||||
]
|
||||
|> String.concat ""
|
||||
Expect.equal theList expected "Filled select list not generated correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let spaceTests =
|
||||
testList "space" [
|
||||
test "succeeds" {
|
||||
Expect.equal (renderHtmlNode space) " " "space literal not correct"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
[<Tests>]
|
||||
let submitTests =
|
||||
testList "submit" [
|
||||
test "succeeds" {
|
||||
let btn = submit [ _class "slick" ] "file-ico" _s.["a&b"] |> renderHtmlNode
|
||||
Expect.equal
|
||||
btn
|
||||
"<button type=\"submit\" class=\"slick\"><i class=\"material-icons\">file-ico</i> a&b</button>"
|
||||
"Submit button not generated correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let tableSummaryTests =
|
||||
testList "tableSummary" [
|
||||
test "succeeds for no entries" {
|
||||
let sum = tableSummary 0 _s |> renderHtmlNode
|
||||
Expect.equal sum "<div class=\"pt-center-text\"><small>No Entries to Display</small></div>"
|
||||
"Summary for no items is incorrect"
|
||||
}
|
||||
test "succeeds for one entry" {
|
||||
let sum = tableSummary 1 _s |> renderHtmlNode
|
||||
Expect.equal sum "<div class=\"pt-center-text\"><small>Displaying 1 Entry</small></div>"
|
||||
"Summary for one item is incorrect"
|
||||
}
|
||||
test "succeeds for many entries" {
|
||||
let sum = tableSummary 5 _s |> renderHtmlNode
|
||||
Expect.equal sum "<div class=\"pt-center-text\"><small>Displaying 5 Entries</small></div>"
|
||||
"Summary for many items is incorrect"
|
||||
}
|
||||
]
|
||||
|
||||
module TimeZones =
|
||||
|
||||
open PrayerTracker.Views.CommonFunctions.TimeZones
|
||||
|
||||
[<Tests>]
|
||||
let nameTests =
|
||||
testList "TimeZones.name" [
|
||||
test "succeeds for US Eastern time" {
|
||||
Expect.equal (name "America/New_York" _s |> string) "Eastern" "US Eastern time zone not returned correctly"
|
||||
}
|
||||
test "succeeds for US Central time" {
|
||||
Expect.equal (name "America/Chicago" _s |> string) "Central" "US Central time zone not returned correctly"
|
||||
}
|
||||
test "succeeds for US Mountain time" {
|
||||
Expect.equal (name "America/Denver" _s |> string) "Mountain" "US Mountain time zone not returned correctly"
|
||||
}
|
||||
test "succeeds for US Mountain (AZ) time" {
|
||||
Expect.equal (name "America/Phoenix" _s |> string) "Mountain (Arizona)"
|
||||
"US Mountain (AZ) time zone not returned correctly"
|
||||
}
|
||||
test "succeeds for US Pacific time" {
|
||||
Expect.equal (name "America/Los_Angeles" _s |> string) "Pacific" "US Pacific time zone not returned correctly"
|
||||
}
|
||||
test "succeeds for Central European time" {
|
||||
Expect.equal (name "Europe/Berlin" _s |> string) "Central European"
|
||||
"Central European time zone not returned correctly"
|
||||
}
|
||||
test "fails for unexpected time zone" {
|
||||
Expect.equal (name "Wakanda" _s |> string) "Wakanda" "Unexpected time zone should have returned the original ID"
|
||||
}
|
||||
]
|
||||
129
src/PrayerTracker.Tests/UI/UtilsTests.fs
Normal file
129
src/PrayerTracker.Tests/UI/UtilsTests.fs
Normal file
@@ -0,0 +1,129 @@
|
||||
module PrayerTracker.UI.UtilsTests
|
||||
|
||||
open Expecto
|
||||
open PrayerTracker
|
||||
|
||||
[<Tests>]
|
||||
let ckEditorToTextTests =
|
||||
testList "ckEditorToText" [
|
||||
test "replaces newline/tab sequence with nothing" {
|
||||
Expect.equal (ckEditorToText "Here is some \n\ttext") "Here is some text"
|
||||
"Newline/tab sequence should have been removed"
|
||||
}
|
||||
test "replaces with a space" {
|
||||
Expect.equal (ckEditorToText "Test text") "Test text" " should have been replaced with a space"
|
||||
}
|
||||
test "replaces double space with one non-breaking space and one regular space" {
|
||||
Expect.equal (ckEditorToText "Test text") "Test  text"
|
||||
"double space should have been replaced with one non-breaking space and one regular space"
|
||||
}
|
||||
test "replaces paragraph break with two line breaks" {
|
||||
Expect.equal (ckEditorToText "some</p><p>text") "some<br><br>text"
|
||||
"paragraph break should have been replaced with two line breaks"
|
||||
}
|
||||
test "removes start and end paragraph tags" {
|
||||
Expect.equal (ckEditorToText "<p>something something</p>") "something something"
|
||||
"start/end paragraph tags should have been removed"
|
||||
}
|
||||
test "trims the result" {
|
||||
Expect.equal (ckEditorToText " abc ") "abc" "Should have trimmed the resulting text"
|
||||
}
|
||||
test "does all the replacements and removals at one time" {
|
||||
Expect.equal (ckEditorToText " <p>Paragraph 1\n\t line two</p><p>Paragraph 2 x</p>")
|
||||
"Paragraph 1 line two<br><br>Paragraph 2  x"
|
||||
"all replacements and removals were not made correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let htmlToPlainTextTests =
|
||||
testList "htmlToPlainText" [
|
||||
test "decodes HTML-encoded entities" {
|
||||
Expect.equal (htmlToPlainText "1 > 0") "1 > 0" "HTML-encoded entities should have been decoded"
|
||||
}
|
||||
test "trims the input HTML" {
|
||||
Expect.equal (htmlToPlainText " howdy ") "howdy" "HTML input string should have been trimmed"
|
||||
}
|
||||
test "replaces line breaks with new lines" {
|
||||
Expect.equal (htmlToPlainText "Lots<br>of<br />new<br>lines") "Lots\nof\nnew\nlines"
|
||||
"Break tags should have been converted to newline characters"
|
||||
}
|
||||
test "replaces non-breaking spaces with spaces" {
|
||||
Expect.equal (htmlToPlainText "Here is some more text") "Here is some more text"
|
||||
"Non-breaking spaces should have been replaced with spaces"
|
||||
}
|
||||
test "does all replacements at one time" {
|
||||
Expect.equal (htmlToPlainText " < <<br>test") "< <\ntest" "All replacements were not made correctly"
|
||||
}
|
||||
test "does not fail when passed null" {
|
||||
Expect.equal (htmlToPlainText null) "" "Should return an empty string for null input"
|
||||
}
|
||||
test "does not fail when passed an empty string" {
|
||||
Expect.equal (htmlToPlainText "") "" "Should return an empty string when given an empty string"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let replaceFirstTests =
|
||||
testList "replaceFirst" [
|
||||
test "replaces the first occurrence when it is found at the beginning of the string" {
|
||||
let testString = "unit unit unit"
|
||||
Expect.equal (replaceFirst "unit" "test" testString) "test unit unit"
|
||||
"First occurrence of a substring was not replaced properly at the beginning of the string"
|
||||
}
|
||||
test "replaces the first occurrence when it is found in the center of the string" {
|
||||
let testString = "test unit test"
|
||||
Expect.equal (replaceFirst "unit" "test" testString) "test test test"
|
||||
"First occurrence of a substring was not replaced properly when it is in the center of the string"
|
||||
}
|
||||
test "returns the original string if the replacement isn't found" {
|
||||
let testString = "unit tests"
|
||||
Expect.equal (replaceFirst "tested" "testing" testString) "unit tests"
|
||||
"String which did not have the target substring was not returned properly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let sndAsStringTests =
|
||||
testList "sndAsString" [
|
||||
test "converts the second item to a string" {
|
||||
Expect.equal (sndAsString ("a", 5)) "5" "The second part of the tuple should have been converted to a string"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let stripTagsTests =
|
||||
let testString = "<p class=\"testing\">Here is some text<br> <br />and some more</p>"
|
||||
testList "stripTags" [
|
||||
test "does nothing if all tags are allowed" {
|
||||
Expect.equal (stripTags [ "p"; "br" ] testString) testString
|
||||
"There should have been no replacements in the target string"
|
||||
}
|
||||
test "strips the start/end tag for non allowed tag" {
|
||||
Expect.equal (stripTags [ "br" ] testString) "Here is some text<br> <br />and some more"
|
||||
"There should have been no \"p\" tag, but all \"br\" tags, in the returned string"
|
||||
}
|
||||
test "strips void/self-closing tags" {
|
||||
Expect.equal (stripTags [] testString) "Here is some text and some more"
|
||||
"There should have been no tags; all void and self-closing tags should have been stripped"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let wordWrapTests =
|
||||
testList "wordWrap" [
|
||||
test "breaks where it is supposed to" {
|
||||
let testString = "The quick brown fox jumps over the lazy dog\nIt does!"
|
||||
Expect.equal (wordWrap 20 testString) "The quick brown fox\njumps over the lazy\ndog\nIt does!\n"
|
||||
"Line not broken correctly"
|
||||
}
|
||||
test "wraps long line without a space" {
|
||||
let testString = "Asamatteroffact, the dog does too"
|
||||
Expect.equal (wordWrap 10 testString) "Asamattero\nffact, the\ndog does\ntoo\n"
|
||||
"Longer line not broken correctly"
|
||||
}
|
||||
test "preserves blank lines" {
|
||||
let testString = "Here is\n\na string with blank lines"
|
||||
Expect.equal (wordWrap 80 testString) testString "Blank lines were not preserved"
|
||||
}
|
||||
]
|
||||
605
src/PrayerTracker.Tests/UI/ViewModelsTests.fs
Normal file
605
src/PrayerTracker.Tests/UI/ViewModelsTests.fs
Normal file
@@ -0,0 +1,605 @@
|
||||
module PrayerTracker.UI.ViewModelsTests
|
||||
|
||||
open Expecto
|
||||
open Microsoft.AspNetCore.Html
|
||||
open PrayerTracker.Entities
|
||||
open PrayerTracker.Tests.TestLocalization
|
||||
open PrayerTracker.Utils
|
||||
open PrayerTracker.ViewModels
|
||||
open System
|
||||
|
||||
|
||||
/// Filter function that filters nothing
|
||||
let countAll _ = true
|
||||
|
||||
|
||||
module ReferenceListTests =
|
||||
|
||||
[<Tests>]
|
||||
let emailTypeListTests =
|
||||
testList "ReferenceList.emailTypeList" [
|
||||
test "includes default type" {
|
||||
let typs = ReferenceList.emailTypeList EmailType.Html _s
|
||||
Expect.hasCountOf typs 3u countAll "There should have been 3 e-mail type options returned"
|
||||
let top = Seq.head typs
|
||||
Expect.equal (fst top) "" "The default option should have been blank"
|
||||
Expect.equal (snd top).Value "Group Default (HTML Format)" "The default option label was incorrect"
|
||||
let nxt = typs |> Seq.skip 1 |> Seq.head
|
||||
Expect.equal (fst nxt) EmailType.Html "The 2nd option should have been HTML"
|
||||
let lst = typs |> Seq.last
|
||||
Expect.equal (fst lst) EmailType.PlainText "The 3rd option should have been plain text"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let expirationListTests =
|
||||
testList "ReferenceList.expirationList" [
|
||||
test "excludes immediate expiration if not required" {
|
||||
let exps = ReferenceList.expirationList _s false
|
||||
Expect.hasCountOf exps 2u countAll "There should have been 2 expiration types returned"
|
||||
Expect.exists exps (fun exp -> fst exp = "N") "The option for normal expiration was not found"
|
||||
Expect.exists exps (fun exp -> fst exp = "Y") "The option for \"never expire\" was not found"
|
||||
}
|
||||
test "includes immediate expiration if required" {
|
||||
let exps = ReferenceList.expirationList _s true
|
||||
Expect.hasCountOf exps 3u countAll "There should have been 3 expiration types returned"
|
||||
Expect.exists exps (fun exp -> fst exp = "N") "The option for normal expiration was not found"
|
||||
Expect.exists exps (fun exp -> fst exp = "Y") "The option for \"never expire\" was not found"
|
||||
Expect.exists exps (fun exp -> fst exp = "X") "The option for \"expire immediately\" was not found"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let requestTypeListTests =
|
||||
testList "ReferenceList.requestTypeList" [
|
||||
let withList f () =
|
||||
(ReferenceList.requestTypeList >> f) _s
|
||||
yield! testFixture withList [
|
||||
yield "returns 5 types",
|
||||
fun typs -> Expect.hasCountOf typs 5u countAll "There should have been 5 request types returned"
|
||||
yield! [ RequestType.Current; RequestType.Recurring; RequestType.Praise; RequestType.Expecting;
|
||||
RequestType.Announcement
|
||||
]
|
||||
|> List.map (fun typ ->
|
||||
sprintf "contains \"%s\"" typ,
|
||||
fun typs ->
|
||||
Expect.isSome (typs |> List.tryFind (fun x -> fst x = typ))
|
||||
(sprintf "The \"%s\" option was not found" typ))
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
[<Tests>]
|
||||
let announcementTests =
|
||||
let empty = { sendToClass = "N"; text = "<p>unit testing</p>"; addToRequestList = None; requestType = None }
|
||||
testList "Announcement" [
|
||||
test "plainText strips HTML" {
|
||||
let ann = { empty with text = "<p>unit testing</p>" }
|
||||
Expect.equal (ann.plainText ()) "unit testing" "Plain text should have stripped HTML"
|
||||
}
|
||||
test "plainText wraps at 74 characters" {
|
||||
let ann = { empty with text = String.replicate 80 "x" }
|
||||
let txt = (ann.plainText ()).Split "\n"
|
||||
Expect.hasCountOf txt 3u countAll "There should have been two lines of plain text returned"
|
||||
Expect.stringHasLength txt.[0] 74 "The first line should have been wrapped at 74 characters"
|
||||
Expect.stringHasLength txt.[1] 6 "The second line should have had the remaining 6 characters"
|
||||
Expect.stringHasLength txt.[2] 0 "The third line should have been blank"
|
||||
}
|
||||
test "plainText wraps at 74 characters and strips HTML" {
|
||||
let ann = { empty with text = sprintf "<strong>%s</strong>" (String.replicate 80 "z") }
|
||||
let txt = ann.plainText ()
|
||||
Expect.stringStarts txt "zzz" "HTML should have been stripped from the front of the plain text"
|
||||
Expect.equal (txt.ToCharArray ()).[74] '\n' "The text should have been broken at 74 characters"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let appViewInfoTests =
|
||||
testList "AppViewInfo" [
|
||||
test "fresh is constructed properly" {
|
||||
let vi = AppViewInfo.fresh
|
||||
Expect.isEmpty vi.style "There should have been no styles set"
|
||||
Expect.isEmpty vi.script "There should have been no scripts set"
|
||||
Expect.equal vi.helpLink.Url HelpPage.None.Url "The help link should have been set to none"
|
||||
Expect.isEmpty vi.messages "There should have been no messages set"
|
||||
Expect.equal vi.version "" "The version should have been blank"
|
||||
Expect.isGreaterThan vi.requestStart DateTime.MinValue.Ticks "The request start time should have been set"
|
||||
Expect.isNone vi.user "There should not have been a user"
|
||||
Expect.isNone vi.group "There should not have been a small group"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let assignGroupsTests =
|
||||
testList "AssignGroups" [
|
||||
test "fromUser populates correctly" {
|
||||
let usr = { User.empty with userId = Guid.NewGuid (); firstName = "Alice"; lastName = "Bob" }
|
||||
let asg = AssignGroups.fromUser usr
|
||||
Expect.equal asg.userId usr.userId "The user ID was not filled correctly"
|
||||
Expect.equal asg.userName usr.fullName "The user name was not filled correctly"
|
||||
Expect.equal asg.smallGroups "" "The small group string was not filled correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let editChurchTests =
|
||||
testList "EditChurch" [
|
||||
test "fromChurch populates correctly when interface exists" {
|
||||
let church =
|
||||
{ Church.empty with
|
||||
churchId = Guid.NewGuid ()
|
||||
name = "Unit Test"
|
||||
city = "Testlandia"
|
||||
st = "UT"
|
||||
hasInterface = true
|
||||
interfaceAddress = Some "https://test-dem-units.test"
|
||||
}
|
||||
let edit = EditChurch.fromChurch church
|
||||
Expect.equal edit.churchId church.churchId "The church ID was not filled correctly"
|
||||
Expect.equal edit.name church.name "The church name was not filled correctly"
|
||||
Expect.equal edit.city church.city "The church's city was not filled correctly"
|
||||
Expect.equal edit.st church.st "The church's state was not filled correctly"
|
||||
Expect.isSome edit.hasInterface "The church should show that it has an interface"
|
||||
Expect.equal edit.hasInterface (Some true) "The hasInterface flag should be true"
|
||||
Expect.isSome edit.interfaceAddress "The interface address should exist"
|
||||
Expect.equal edit.interfaceAddress church.interfaceAddress "The interface address was not filled correctly"
|
||||
}
|
||||
test "fromChurch populates correctly when interface does not exist" {
|
||||
let edit =
|
||||
EditChurch.fromChurch
|
||||
{ Church.empty with
|
||||
churchId = Guid.NewGuid ()
|
||||
name = "Unit Test"
|
||||
city = "Testlandia"
|
||||
st = "UT"
|
||||
}
|
||||
Expect.isNone edit.hasInterface "The church should not show that it has an interface"
|
||||
Expect.isNone edit.interfaceAddress "The interface address should not exist"
|
||||
}
|
||||
test "empty is as expected" {
|
||||
let edit = EditChurch.empty
|
||||
Expect.equal edit.churchId Guid.Empty "The church ID should be the empty GUID"
|
||||
Expect.equal edit.name "" "The church name should be blank"
|
||||
Expect.equal edit.city "" "The church's city should be blank"
|
||||
Expect.equal edit.st "" "The church's state should be blank"
|
||||
Expect.isNone edit.hasInterface "The church should not show that it has an interface"
|
||||
Expect.isNone edit.interfaceAddress "The interface address should not exist"
|
||||
}
|
||||
test "isNew works on a new church" {
|
||||
Expect.isTrue (EditChurch.empty.isNew ()) "An empty GUID should be flagged as a new church"
|
||||
}
|
||||
test "isNew works on an existing church" {
|
||||
Expect.isFalse ({ EditChurch.empty with churchId = Guid.NewGuid () }.isNew ())
|
||||
"A non-empty GUID should not be flagged as a new church"
|
||||
}
|
||||
test "populateChurch works correctly when an interface exists" {
|
||||
let edit =
|
||||
{ EditChurch.empty with
|
||||
churchId = Guid.NewGuid ()
|
||||
name = "Test Baptist Church"
|
||||
city = "Testerville"
|
||||
st = "TE"
|
||||
hasInterface = Some true
|
||||
interfaceAddress = Some "https://test.units"
|
||||
}
|
||||
let church = edit.populateChurch Church.empty
|
||||
Expect.notEqual church.churchId edit.churchId "The church ID should not have been modified"
|
||||
Expect.equal church.name edit.name "The church name was not updated correctly"
|
||||
Expect.equal church.city edit.city "The church's city was not updated correctly"
|
||||
Expect.equal church.st edit.st "The church's state was not updated correctly"
|
||||
Expect.isTrue church.hasInterface "The church should show that it has an interface"
|
||||
Expect.isSome church.interfaceAddress "The interface address should exist"
|
||||
Expect.equal church.interfaceAddress edit.interfaceAddress "The interface address was not updated correctly"
|
||||
}
|
||||
test "populateChurch works correctly when an interface does not exist" {
|
||||
let church =
|
||||
{ EditChurch.empty with
|
||||
name = "Test Baptist Church"
|
||||
city = "Testerville"
|
||||
st = "TE"
|
||||
}.populateChurch Church.empty
|
||||
Expect.isFalse church.hasInterface "The church should show that it has an interface"
|
||||
Expect.isNone church.interfaceAddress "The interface address should exist"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let editMemberTests =
|
||||
testList "EditMember" [
|
||||
test "fromMember populates with group default format" {
|
||||
let mbr =
|
||||
{ Member.empty with
|
||||
memberId = Guid.NewGuid ()
|
||||
memberName = "Test Name"
|
||||
email = "test_units@example.com"
|
||||
}
|
||||
let edit = EditMember.fromMember mbr
|
||||
Expect.equal edit.memberId mbr.memberId "The member ID was not filled correctly"
|
||||
Expect.equal edit.memberName mbr.memberName "The member name was not filled correctly"
|
||||
Expect.equal edit.emailAddress mbr.email "The e-mail address was not filled correctly"
|
||||
Expect.equal edit.emailType "" "The e-mail type should have been blank for group default"
|
||||
}
|
||||
test "fromMember populates with specific format" {
|
||||
let edit = EditMember.fromMember { Member.empty with format = Some EmailType.Html }
|
||||
Expect.equal edit.emailType EmailType.Html "The e-mail type was not filled correctly"
|
||||
}
|
||||
test "empty is as expected" {
|
||||
let edit = EditMember.empty
|
||||
Expect.equal edit.memberId Guid.Empty "The member ID should have been an empty GUID"
|
||||
Expect.equal edit.memberName "" "The member name should have been blank"
|
||||
Expect.equal edit.emailAddress "" "The e-mail address should have been blank"
|
||||
Expect.equal edit.emailType "" "The e-mail type should have been blank"
|
||||
}
|
||||
test "isNew works for a new member" {
|
||||
Expect.isTrue (EditMember.empty.isNew ()) "An empty GUID should be flagged as a new member"
|
||||
}
|
||||
test "isNew works for an existing member" {
|
||||
Expect.isFalse ({ EditMember.empty with memberId = Guid.NewGuid () }.isNew ())
|
||||
"A non-empty GUID should not be flagged as a new member"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let editPreferencesTests =
|
||||
testList "EditPreferences" [
|
||||
test "fromPreferences succeeds for named colors and private list" {
|
||||
let prefs = ListPreferences.empty
|
||||
let edit = EditPreferences.fromPreferences prefs
|
||||
Expect.equal edit.expireDays prefs.daysToExpire "The expiration days were not filled correctly"
|
||||
Expect.equal edit.daysToKeepNew prefs.daysToKeepNew "The days to keep new were not filled correctly"
|
||||
Expect.equal edit.longTermUpdateWeeks prefs.longTermUpdateWeeks "The weeks for update were not filled correctly"
|
||||
Expect.equal edit.requestSort prefs.requestSort "The request sort was not filled correctly"
|
||||
Expect.equal edit.emailFromName prefs.emailFromName "The e-mail from name was not filled correctly"
|
||||
Expect.equal edit.emailFromAddress prefs.emailFromAddress "The e-mail from address was not filled correctly"
|
||||
Expect.equal edit.defaultEmailType prefs.defaultEmailType "The default e-mail type was not filled correctly"
|
||||
Expect.equal edit.headingLineType "Name" "The heading line color type was not derived correctly"
|
||||
Expect.equal edit.headingLineColor prefs.lineColor "The heading line color was not filled correctly"
|
||||
Expect.equal edit.headingTextType "Name" "The heading text color type was not derived correctly"
|
||||
Expect.equal edit.headingTextColor prefs.headingColor "The heading text color was not filled correctly"
|
||||
Expect.equal edit.listFonts prefs.listFonts "The list fonts were not filled correctly"
|
||||
Expect.equal edit.headingFontSize prefs.headingFontSize "The heading font size was not filled correctly"
|
||||
Expect.equal edit.listFontSize prefs.textFontSize "The list text font size was not filled correctly"
|
||||
Expect.equal edit.timeZone prefs.timeZoneId "The time zone was not filled correctly"
|
||||
Expect.isSome edit.groupPassword "The group password should have been set"
|
||||
Expect.equal edit.groupPassword (Some prefs.groupPassword) "The group password was not filled correctly"
|
||||
Expect.equal edit.listVisibility RequestVisibility.``private`` "The list visibility was not derived correctly"
|
||||
}
|
||||
test "fromPreferences succeeds for RGB line color and password-protected list" {
|
||||
let prefs = { ListPreferences.empty with lineColor = "#ff0000"; groupPassword = "pw" }
|
||||
let edit = EditPreferences.fromPreferences prefs
|
||||
Expect.equal edit.headingLineType "RGB" "The heading line color type was not derived correctly"
|
||||
Expect.equal edit.headingLineColor prefs.lineColor "The heading line color was not filled correctly"
|
||||
Expect.isSome edit.groupPassword "The group password should have been set"
|
||||
Expect.equal edit.groupPassword (Some prefs.groupPassword) "The group password was not filled correctly"
|
||||
Expect.equal edit.listVisibility RequestVisibility.passwordProtected
|
||||
"The list visibility was not derived correctly"
|
||||
}
|
||||
test "fromPreferences succeeds for RGB text color and public list" {
|
||||
let prefs = { ListPreferences.empty with headingColor = "#0000ff"; isPublic = true }
|
||||
let edit = EditPreferences.fromPreferences prefs
|
||||
Expect.equal edit.headingTextType "RGB" "The heading text color type was not derived correctly"
|
||||
Expect.equal edit.headingTextColor prefs.headingColor "The heading text color was not filled correctly"
|
||||
Expect.isSome edit.groupPassword "The group password should have been set"
|
||||
Expect.equal edit.groupPassword (Some "") "The group password was not filled correctly"
|
||||
Expect.equal edit.listVisibility RequestVisibility.``public`` "The list visibility was not derived correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let editRequestTests =
|
||||
testList "EditRequest" [
|
||||
test "empty is as expected" {
|
||||
let mt = EditRequest.empty
|
||||
Expect.equal mt.requestId Guid.Empty "The request ID should be an empty GUID"
|
||||
Expect.equal mt.requestType "" "The request type should have been blank"
|
||||
Expect.isNone mt.enteredDate "The entered date should have been None"
|
||||
Expect.isNone mt.skipDateUpdate "The \"skip date update\" flag should have been None"
|
||||
Expect.isNone mt.requestor "The requestor should have been None"
|
||||
Expect.equal mt.expiration "N" "The expiration should have been \"N\""
|
||||
Expect.equal mt.text "" "The text should have been blank"
|
||||
}
|
||||
test "fromRequest succeeds when a request has the do-not-expire flag set" {
|
||||
let req =
|
||||
{ PrayerRequest.empty with
|
||||
prayerRequestId = Guid.NewGuid ()
|
||||
requestType = RequestType.Current
|
||||
requestor = Some "Me"
|
||||
doNotExpire = true
|
||||
text = "the text"
|
||||
}
|
||||
let edit = EditRequest.fromRequest req
|
||||
Expect.equal edit.requestId req.prayerRequestId "The request ID was not filled correctly"
|
||||
Expect.equal edit.requestType req.requestType "The request type was not filled correctly"
|
||||
Expect.equal edit.requestor req.requestor "The requestor was not filled correctly"
|
||||
Expect.equal edit.expiration "Y" "The expiration should have been \"Y\" since the do-not-expire flag was set"
|
||||
Expect.equal edit.text req.text "The text was not filled correctly"
|
||||
}
|
||||
test "fromRequest succeeds when a request has the do-not-expire flag unset" {
|
||||
let req =
|
||||
{ PrayerRequest.empty with
|
||||
requestor = None
|
||||
doNotExpire = false
|
||||
}
|
||||
let edit = EditRequest.fromRequest req
|
||||
Expect.equal edit.requestor req.requestor "The requestor was not filled correctly"
|
||||
Expect.equal edit.expiration "N" "The expiration should have been \"N\" since the do-not-expire flag was not set"
|
||||
}
|
||||
test "isNew works for a new request" {
|
||||
Expect.isTrue (EditRequest.empty.isNew ()) "An empty GUID should be flagged as a new request"
|
||||
}
|
||||
test "isNew works for an existing request" {
|
||||
Expect.isFalse ({ EditRequest.empty with requestId = Guid.NewGuid () }.isNew ())
|
||||
"A non-empty GUID should not be flagged as a new request"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let editSmallGroupTests =
|
||||
testList "EditSmallGroup" [
|
||||
test "fromGroup succeeds" {
|
||||
let grp =
|
||||
{ SmallGroup.empty with
|
||||
smallGroupId = Guid.NewGuid ()
|
||||
name = "test group"
|
||||
churchId = Guid.NewGuid ()
|
||||
}
|
||||
let edit = EditSmallGroup.fromGroup grp
|
||||
Expect.equal edit.smallGroupId grp.smallGroupId "The small group ID was not filled correctly"
|
||||
Expect.equal edit.name grp.name "The name was not filled correctly"
|
||||
Expect.equal edit.churchId grp.churchId "The church ID was not filled correctly"
|
||||
}
|
||||
test "empty is as expected" {
|
||||
let mt = EditSmallGroup.empty
|
||||
Expect.equal mt.smallGroupId Guid.Empty "The small group ID should be an empty GUID"
|
||||
Expect.equal mt.name "" "The name should be blank"
|
||||
Expect.equal mt.churchId Guid.Empty "The church ID should be an empty GUID"
|
||||
}
|
||||
test "isNew works for a new small group" {
|
||||
Expect.isTrue (EditSmallGroup.empty.isNew ()) "An empty GUID should be flagged as a new small group"
|
||||
}
|
||||
test "isNew works for an existing small group" {
|
||||
Expect.isFalse ({ EditSmallGroup.empty with smallGroupId = Guid.NewGuid () }.isNew ())
|
||||
"A non-empty GUID should not be flagged as a new small group"
|
||||
}
|
||||
test "populateGroup succeeds" {
|
||||
let edit =
|
||||
{ EditSmallGroup.empty with
|
||||
name = "test name"
|
||||
churchId = Guid.NewGuid ()
|
||||
}
|
||||
let grp = edit.populateGroup SmallGroup.empty
|
||||
Expect.equal grp.name edit.name "The name was not populated correctly"
|
||||
Expect.equal grp.churchId edit.churchId "The church ID was not populated correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let editUserTests =
|
||||
testList "EditUser" [
|
||||
test "empty is as expected" {
|
||||
let mt = EditUser.empty
|
||||
Expect.equal mt.userId Guid.Empty "The user ID should be an empty GUID"
|
||||
Expect.equal mt.firstName "" "The first name should be blank"
|
||||
Expect.equal mt.lastName "" "The last name should be blank"
|
||||
Expect.equal mt.emailAddress "" "The e-mail address should be blank"
|
||||
Expect.equal mt.password "" "The password should be blank"
|
||||
Expect.equal mt.passwordConfirm "" "The confirmed password should be blank"
|
||||
Expect.isNone mt.isAdmin "The isAdmin flag should be None"
|
||||
}
|
||||
test "fromUser succeeds" {
|
||||
let usr =
|
||||
{ User.empty with
|
||||
userId = Guid.NewGuid ()
|
||||
firstName = "user"
|
||||
lastName = "test"
|
||||
emailAddress = "a@b.c"
|
||||
}
|
||||
let edit = EditUser.fromUser usr
|
||||
Expect.equal edit.userId usr.userId "The user ID was not filled correctly"
|
||||
Expect.equal edit.firstName usr.firstName "The first name was not filled correctly"
|
||||
Expect.equal edit.lastName usr.lastName "The last name was not filled correctly"
|
||||
Expect.equal edit.emailAddress usr.emailAddress "The e-mail address was not filled correctly"
|
||||
Expect.isNone edit.isAdmin "The isAdmin flag was not filled correctly"
|
||||
}
|
||||
test "isNew works for a new user" {
|
||||
Expect.isTrue (EditUser.empty.isNew ()) "An empty GUID should be flagged as a new user"
|
||||
}
|
||||
test "isNew works for an existing user" {
|
||||
Expect.isFalse ({ EditUser.empty with userId = Guid.NewGuid () }.isNew ())
|
||||
"A non-empty GUID should not be flagged as a new user"
|
||||
}
|
||||
test "populateUser succeeds" {
|
||||
let edit =
|
||||
{ EditUser.empty with
|
||||
firstName = "name"
|
||||
lastName = "eman"
|
||||
emailAddress = "n@m.e"
|
||||
isAdmin = Some true
|
||||
password = "testpw"
|
||||
}
|
||||
let hasher = fun x -> x + "+"
|
||||
let usr = edit.populateUser User.empty hasher
|
||||
Expect.equal usr.firstName edit.firstName "The first name was not populated correctly"
|
||||
Expect.equal usr.lastName edit.lastName "The last name was not populated correctly"
|
||||
Expect.equal usr.emailAddress edit.emailAddress "The e-mail address was not populated correctly"
|
||||
Expect.isTrue usr.isAdmin "The isAdmin flag was not populated correctly"
|
||||
Expect.equal usr.passwordHash (hasher edit.password) "The password hash was not populated correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let groupLogOnTests =
|
||||
testList "GroupLogOn" [
|
||||
test "empty is as expected" {
|
||||
let mt = GroupLogOn.empty
|
||||
Expect.equal mt.smallGroupId Guid.Empty "The small group ID should be an empty GUID"
|
||||
Expect.equal mt.password "" "The password should be blank"
|
||||
Expect.isNone mt.rememberMe "Remember Me should be None"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let requestListTests =
|
||||
testList "RequestList" [
|
||||
let withRequestList f () =
|
||||
{ requests = [
|
||||
{ PrayerRequest.empty with
|
||||
requestType = RequestType.Current
|
||||
requestor = Some "Zeb"
|
||||
text = "zyx"
|
||||
updatedDate = DateTime.Today
|
||||
}
|
||||
{ PrayerRequest.empty with
|
||||
requestType = RequestType.Current
|
||||
requestor = Some "Aaron"
|
||||
text = "abc"
|
||||
updatedDate = DateTime.Today - TimeSpan.FromDays 9.
|
||||
}
|
||||
{ PrayerRequest.empty with
|
||||
requestType = RequestType.Praise
|
||||
text = "nmo"
|
||||
updatedDate = DateTime.Today
|
||||
}
|
||||
]
|
||||
date = DateTime.Today
|
||||
listGroup = SmallGroup.empty
|
||||
showHeader = false
|
||||
recipients = []
|
||||
canEmail = false
|
||||
}
|
||||
|> f
|
||||
yield! testFixture withRequestList [
|
||||
"asHtml succeeds without header",
|
||||
fun reqList ->
|
||||
let htmlList = { reqList with listGroup = { reqList.listGroup with name = "Test HTML Group" } }
|
||||
let html = htmlList.asHtml _s
|
||||
Expect.equal -1 (html.IndexOf "Test HTML Group") "The small group name should not have existed (no header)"
|
||||
let curReqHeading =
|
||||
[ "<table style=\"font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif;page-break-inside:avoid;\">"
|
||||
"<tr>"
|
||||
"<td style=\"font-size:16pt;color:maroon;padding:3px 0;border-top:solid 3px navy;border-bottom:solid 3px navy;font-weight:bold;\">"
|
||||
" Current Requests </td></tr></table>"
|
||||
]
|
||||
|> String.concat ""
|
||||
Expect.stringContains html curReqHeading "Heading for category \"Current Requests\" not found"
|
||||
let curReqHtml =
|
||||
[ "<ul>"
|
||||
"<li style=\"list-style-type:circle;font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif;font-size:12pt;padding-bottom:.25em;\">"
|
||||
"<strong>Zeb</strong> — zyx</li>"
|
||||
"<li style=\"list-style-type:disc;font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif;font-size:12pt;padding-bottom:.25em;\">"
|
||||
"<strong>Aaron</strong> — abc</li></ul>"
|
||||
]
|
||||
|> String.concat ""
|
||||
Expect.stringContains html curReqHtml "Expected HTML for \"Current Requests\" requests not found"
|
||||
let praiseHeading =
|
||||
[ "<table style=\"font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif;page-break-inside:avoid;\">"
|
||||
"<tr>"
|
||||
"<td style=\"font-size:16pt;color:maroon;padding:3px 0;border-top:solid 3px navy;border-bottom:solid 3px navy;font-weight:bold;\">"
|
||||
" Praise Reports </td></tr></table>"
|
||||
]
|
||||
|> String.concat ""
|
||||
Expect.stringContains html praiseHeading "Heading for category \"Praise Reports\" not found"
|
||||
let praiseHtml =
|
||||
[ "<ul>"
|
||||
"<li style=\"list-style-type:circle;font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif;font-size:12pt;padding-bottom:.25em;\">"
|
||||
"nmo</li></ul>"
|
||||
]
|
||||
|> String.concat ""
|
||||
Expect.stringContains html praiseHtml "Expected HTML for \"Praise Reports\" requests not found"
|
||||
"asHtml succeeds with header",
|
||||
fun reqList ->
|
||||
let htmlList =
|
||||
{ reqList with
|
||||
listGroup = { reqList.listGroup with name = "Test HTML Group" }
|
||||
showHeader = true
|
||||
}
|
||||
let html = htmlList.asHtml _s
|
||||
let lstHeading =
|
||||
[ "<div style=\"text-align:center;font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif\">"
|
||||
"<span style=\"font-size:16pt;\"><strong>Prayer Requests</strong></span><br>"
|
||||
"<span style=\"font-size:12pt;\"><strong>Test HTML Group</strong><br>"
|
||||
htmlList.date.ToString "MMMM d, yyyy"
|
||||
"</span></div><br>"
|
||||
]
|
||||
|> String.concat ""
|
||||
Expect.stringContains html lstHeading "Expected HTML for the list heading not found"
|
||||
// spot check; without header test tests this exhaustively
|
||||
Expect.stringContains html "<strong>Zeb</strong> — zyx</li>" "Expected requests not found"
|
||||
"asText succeeds",
|
||||
fun reqList ->
|
||||
let textList = { reqList with listGroup = { reqList.listGroup with name = "Test Group" } }
|
||||
let text = textList.asText _s
|
||||
Expect.stringContains text (textList.listGroup.name + "\n") "Small group name not found"
|
||||
Expect.stringContains text "Prayer Requests\n" "List heading not found"
|
||||
Expect.stringContains text ((textList.date.ToString "MMMM d, yyyy") + "\n \n") "List date not found"
|
||||
Expect.stringContains text "--------------------\n CURRENT REQUESTS\n--------------------\n"
|
||||
"Heading for category \"Current Requests\" not found"
|
||||
Expect.stringContains text " + Zeb - zyx\n" "First request not found"
|
||||
Expect.stringContains text " - Aaron - abc\n \n" "Second request not found; should have been end of category"
|
||||
Expect.stringContains text "------------------\n PRAISE REPORTS\n------------------\n"
|
||||
"Heading for category \"Praise Reports\" not found"
|
||||
Expect.stringContains text " + nmo\n \n" "Last request not found"
|
||||
"isNew succeeds for both old and new requests",
|
||||
fun reqList ->
|
||||
let reqs = reqList.requestsInCategory RequestType.Current
|
||||
Expect.hasCountOf reqs 2u countAll "There should have been two requests"
|
||||
Expect.isTrue (reqList.isNew (List.head reqs)) "The first request should have been new"
|
||||
Expect.isFalse (reqList.isNew (List.last reqs)) "The second request should not have been new"
|
||||
"requestsInCategory succeeds when requests exist",
|
||||
fun reqList ->
|
||||
let reqs = reqList.requestsInCategory RequestType.Current
|
||||
Expect.hasCountOf reqs 2u countAll "There should have been two requests"
|
||||
let first = List.head reqs
|
||||
Expect.equal first.text "zyx" "The requests should be sorted by updated date descending"
|
||||
"requestsInCategory succeeds when requests do not exist",
|
||||
fun reqList ->
|
||||
Expect.isEmpty (reqList.requestsInCategory "ABC") "There should have been no category \"ABC\" requests"
|
||||
"requestsInCategory succeeds and sorts by requestor",
|
||||
fun reqList ->
|
||||
let newList =
|
||||
{ reqList with
|
||||
listGroup =
|
||||
{ reqList.listGroup with preferences = { reqList.listGroup.preferences with requestSort = "R" } }
|
||||
}
|
||||
let reqs = newList.requestsInCategory RequestType.Current
|
||||
Expect.hasCountOf reqs 2u countAll "There should have been two requests"
|
||||
let first = List.head reqs
|
||||
Expect.equal first.text "abc" "The requests should be sorted by requestor"
|
||||
]
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let userLogOnTests =
|
||||
testList "UserLogOn" [
|
||||
test "empty is as expected" {
|
||||
let mt = UserLogOn.empty
|
||||
Expect.equal mt.emailAddress "" "The e-mail address should be blank"
|
||||
Expect.equal mt.password "" "The password should be blank"
|
||||
Expect.equal mt.smallGroupId Guid.Empty "The small group ID should be an empty GUID"
|
||||
Expect.isNone mt.rememberMe "Remember Me should be None"
|
||||
Expect.isNone mt.redirectUrl "Redirect URL should be None"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let userMessageTests =
|
||||
testList "UserMessage" [
|
||||
test "Error is constructed properly" {
|
||||
let msg = UserMessage.Error
|
||||
Expect.equal msg.level "ERROR" "Incorrect message level"
|
||||
Expect.equal msg.text HtmlString.Empty "Text should have been blank"
|
||||
Expect.isNone msg.description "Description should have been None"
|
||||
}
|
||||
test "Warning is constructed properly" {
|
||||
let msg = UserMessage.Warning
|
||||
Expect.equal msg.level "WARNING" "Incorrect message level"
|
||||
Expect.equal msg.text HtmlString.Empty "Text should have been blank"
|
||||
Expect.isNone msg.description "Description should have been None"
|
||||
}
|
||||
test "Info is constructed properly" {
|
||||
let msg = UserMessage.Info
|
||||
Expect.equal msg.level "Info" "Incorrect message level"
|
||||
Expect.equal msg.text HtmlString.Empty "Text should have been blank"
|
||||
Expect.isNone msg.description "Description should have been None"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user