Minor refactor, added another DU

caught up on some tests as well
This commit is contained in:
Daniel J. Summers 2019-03-16 23:08:46 -05:00
parent 50f8b56871
commit bce2d5dbcc
5 changed files with 118 additions and 21 deletions

View File

@ -14,11 +14,11 @@ module private Helpers =
/// Central place to append sort criteria for prayer request queries /// Central place to append sort criteria for prayer request queries
let reqSort sort (query : IQueryable<PrayerRequest>) = let reqSort sort (query : IQueryable<PrayerRequest>) =
match sort with match sort with
| "D" -> | SortByDate ->
query.OrderByDescending(fun pr -> pr.updatedDate) query.OrderByDescending(fun pr -> pr.updatedDate)
.ThenByDescending(fun pr -> pr.enteredDate) .ThenByDescending(fun pr -> pr.enteredDate)
.ThenBy(fun pr -> pr.requestor) .ThenBy(fun pr -> pr.requestor)
| _ -> | SortByRequestor ->
query.OrderBy(fun pr -> pr.requestor) query.OrderBy(fun pr -> pr.requestor)
.ThenByDescending(fun pr -> pr.updatedDate) .ThenByDescending(fun pr -> pr.updatedDate)
.ThenByDescending(fun pr -> pr.enteredDate) .ThenByDescending(fun pr -> pr.enteredDate)

View File

@ -54,31 +54,65 @@ with
| "L" -> LongDate | "L" -> LongDate
| _ -> invalidArg "code" (sprintf "Unknown code %s" code) | _ -> invalidArg "code" (sprintf "Unknown code %s" code)
/// Convert this DU case to a single-character string /// Convert this DU case to a single-character string
member this.toCode () = member this.code =
match this with match this with
| NoDisplay -> "N" | NoDisplay -> "N"
| ShortDate -> "S" | ShortDate -> "S"
| LongDate -> "L" | LongDate -> "L"
/// How requests should be sorted
type RequestSort =
/// Sort by date, then by requestor/subject
| SortByDate
/// Sort by requestor/subject, then by date
| SortByRequestor
with
/// Convert to a DU case from a single-character string
static member fromCode code =
match code with
| "D" -> SortByDate
| "R" -> SortByRequestor
| _ -> invalidArg "code" (sprintf "Unknown code %s" code)
/// Convert this DU case to a single-character string
member this.code =
match this with
| SortByDate -> "D"
| SortByRequestor -> "R"
module Converters = module Converters =
open Microsoft.EntityFrameworkCore.Storage.ValueConversion open Microsoft.EntityFrameworkCore.Storage.ValueConversion
open Microsoft.FSharp.Linq.RuntimeHelpers open Microsoft.FSharp.Linq.RuntimeHelpers
open System.Linq.Expressions open System.Linq.Expressions
let private fromDU = let private asOfFromDU =
<@ Func<AsOfDateDisplay, string>(fun (x : AsOfDateDisplay) -> x.toCode ()) @> <@ Func<AsOfDateDisplay, string>(fun (x : AsOfDateDisplay) -> x.code) @>
|> LeafExpressionConverter.QuotationToExpression |> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<AsOfDateDisplay, string>>> |> unbox<Expression<Func<AsOfDateDisplay, string>>>
let private toDU = let private asOfToDU =
<@ Func<string, AsOfDateDisplay>(AsOfDateDisplay.fromCode) @> <@ Func<string, AsOfDateDisplay>(AsOfDateDisplay.fromCode) @>
|> LeafExpressionConverter.QuotationToExpression |> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<string, AsOfDateDisplay>>> |> unbox<Expression<Func<string, AsOfDateDisplay>>>
let private sortFromDU =
<@ Func<RequestSort, string>(fun (x : RequestSort) -> x.code) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<RequestSort, string>>>
let private sortToDU =
<@ Func<string, RequestSort>(RequestSort.fromCode) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<string, RequestSort>>>
/// Conversion between a string and an AsOfDateDisplay DU value /// Conversion between a string and an AsOfDateDisplay DU value
type AsOfDateDisplayConverter () = type AsOfDateDisplayConverter () =
inherit ValueConverter<AsOfDateDisplay, string> (fromDU, toDU) inherit ValueConverter<AsOfDateDisplay, string> (asOfFromDU, asOfToDU)
/// Conversion between a string and a RequestSort DU value
type RequestSortConverter () =
inherit ValueConverter<RequestSort, string> (sortFromDU, sortToDU)
/// Statistics for churches /// Statistics for churches
@ -189,7 +223,7 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
/// The font size for the text on the prayer request list /// The font size for the text on the prayer request list
textFontSize : int textFontSize : int
/// The order in which the prayer requests are sorted /// The order in which the prayer requests are sorted
requestSort : string requestSort : RequestSort
/// The password used for "small group login" (view-only request list) /// The password used for "small group login" (view-only request list)
groupPassword : string groupPassword : string
/// The default e-mail type for this class /// The default e-mail type for this class
@ -219,7 +253,7 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
lineColor = "navy" lineColor = "navy"
headingFontSize = 16 headingFontSize = 16
textFontSize = 12 textFontSize = 12
requestSort = "D" requestSort = SortByDate
groupPassword = "" groupPassword = ""
defaultEmailType = EmailType.Html defaultEmailType = EmailType.Html
isPublic = false isPublic = false
@ -289,7 +323,7 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
.HasColumnName("RequestSort") .HasColumnName("RequestSort")
.IsRequired() .IsRequired()
.HasMaxLength(1) .HasMaxLength(1)
.HasDefaultValue "D" .HasDefaultValue SortByDate
|> ignore |> ignore
m.Property(fun e -> e.groupPassword) m.Property(fun e -> e.groupPassword)
.HasColumnName("GroupPassword") .HasColumnName("GroupPassword")
@ -323,6 +357,8 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
.HasDefaultValue NoDisplay .HasDefaultValue NoDisplay
|> ignore) |> ignore)
|> ignore |> ignore
mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("requestSort")
.SetValueConverter(Converters.RequestSortConverter ())
mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("asOfDateDisplay") mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("asOfDateDisplay")
.SetValueConverter(Converters.AsOfDateDisplayConverter ()) .SetValueConverter(Converters.AsOfDateDisplayConverter ())

View File

@ -5,6 +5,33 @@ open NodaTime.Testing
open NodaTime open NodaTime
open System 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"
}
]
[<Tests>] [<Tests>]
let churchTests = let churchTests =
testList "Church" [ testList "Church" [
@ -38,7 +65,7 @@ let listPreferencesTests =
Expect.equal mt.lineColor "navy" "The default heding line color should have been navy" 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.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.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.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.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.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.isFalse mt.isPublic "The isPublic flag should not have been set"
@ -130,6 +157,26 @@ let prayerRequestTests =
} }
] ]
[<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"
}
]
[<Tests>] [<Tests>]
let smallGroupTests = let smallGroupTests =
testList "SmallGroup" [ testList "SmallGroup" [

View File

@ -15,6 +15,18 @@ let countAll _ = true
module ReferenceListTests = module ReferenceListTests =
[<Tests>]
let asOfDateListTests =
testList "ReferenceList.asOfDateList" [
test "has all three options listed" {
let asOf = ReferenceList.asOfDateList _s
Expect.hasCountOf asOf 3u countAll "There should have been 3 as-of choices returned"
Expect.exists asOf (fun (x, _) -> x = NoDisplay.code) "The option for no display was not found"
Expect.exists asOf (fun (x, _) -> x = ShortDate.code) "The option for a short date was not found"
Expect.exists asOf (fun (x, _) -> x = LongDate.code) "The option for a full date was not found"
}
]
[<Tests>] [<Tests>]
let emailTypeListTests = let emailTypeListTests =
testList "ReferenceList.emailTypeList" [ testList "ReferenceList.emailTypeList" [
@ -248,7 +260,7 @@ let editPreferencesTests =
Expect.equal edit.expireDays prefs.daysToExpire "The expiration days were not filled correctly" 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.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.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.requestSort prefs.requestSort.code "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.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.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.defaultEmailType prefs.defaultEmailType "The default e-mail type was not filled correctly"
@ -572,7 +584,9 @@ let requestListTests =
let newList = let newList =
{ reqList with { reqList with
listGroup = listGroup =
{ reqList.listGroup with preferences = { reqList.listGroup.preferences with requestSort = "R" } } { reqList.listGroup with
preferences = { reqList.listGroup.preferences with requestSort = SortByRequestor }
}
} }
let reqs = newList.requestsInCategory RequestType.Current let reqs = newList.requestsInCategory RequestType.Current
Expect.hasCountOf reqs 2u countAll "There should have been two requests" Expect.hasCountOf reqs 2u countAll "There should have been two requests"

View File

@ -12,9 +12,9 @@ module ReferenceList =
/// A localized list of the AsOfDateDisplay DU cases /// A localized list of the AsOfDateDisplay DU cases
let asOfDateList (s : IStringLocalizer) = let asOfDateList (s : IStringLocalizer) =
[ NoDisplay.toCode (), s.["Do not display the “as of” date"] [ NoDisplay.code, s.["Do not display the “as of” date"]
ShortDate.toCode (), s.["Display a short “as of” date"] ShortDate.code, s.["Display a short “as of” date"]
LongDate.toCode (), s.["Display a full “as of” date"] LongDate.code, s.["Display a full “as of” date"]
] ]
/// A list of e-mail type options /// A list of e-mail type options
@ -289,7 +289,7 @@ with
{ expireDays = prefs.daysToExpire { expireDays = prefs.daysToExpire
daysToKeepNew = prefs.daysToKeepNew daysToKeepNew = prefs.daysToKeepNew
longTermUpdateWeeks = prefs.longTermUpdateWeeks longTermUpdateWeeks = prefs.longTermUpdateWeeks
requestSort = prefs.requestSort requestSort = prefs.requestSort.code
emailFromName = prefs.emailFromName emailFromName = prefs.emailFromName
emailFromAddress = prefs.emailFromAddress emailFromAddress = prefs.emailFromAddress
defaultEmailType = prefs.defaultEmailType defaultEmailType = prefs.defaultEmailType
@ -303,7 +303,7 @@ with
timeZone = prefs.timeZoneId timeZone = prefs.timeZoneId
groupPassword = Some prefs.groupPassword groupPassword = Some prefs.groupPassword
pageSize = prefs.pageSize pageSize = prefs.pageSize
asOfDate = prefs.asOfDateDisplay.toCode () asOfDate = prefs.asOfDateDisplay.code
listVisibility = listVisibility =
match true with match true with
| _ when prefs.isPublic -> RequestVisibility.``public`` | _ when prefs.isPublic -> RequestVisibility.``public``
@ -322,7 +322,7 @@ with
daysToExpire = this.expireDays daysToExpire = this.expireDays
daysToKeepNew = this.daysToKeepNew daysToKeepNew = this.daysToKeepNew
longTermUpdateWeeks = this.longTermUpdateWeeks longTermUpdateWeeks = this.longTermUpdateWeeks
requestSort = this.requestSort requestSort = RequestSort.fromCode this.requestSort
emailFromName = this.emailFromName emailFromName = this.emailFromName
emailFromAddress = this.emailFromAddress emailFromAddress = this.emailFromAddress
defaultEmailType = this.defaultEmailType defaultEmailType = this.defaultEmailType
@ -573,8 +573,8 @@ with
|> Seq.ofList |> Seq.ofList
|> Seq.filter (fun req -> req.requestType = cat) |> Seq.filter (fun req -> req.requestType = cat)
match this.listGroup.preferences.requestSort with match this.listGroup.preferences.requestSort with
| "D" -> reqs |> Seq.sortByDescending (fun req -> req.updatedDate) | SortByDate -> reqs |> Seq.sortByDescending (fun req -> req.updatedDate)
| _ -> reqs |> Seq.sortBy (fun req -> req.requestor) | SortByRequestor -> reqs |> Seq.sortBy (fun req -> req.requestor)
|> List.ofSeq |> List.ofSeq
/// Is this request new? /// Is this request new?
member this.isNew (req : PrayerRequest) = member this.isNew (req : PrayerRequest) =