Finish view model tests

This commit is contained in:
Daniel J. Summers 2024-01-20 11:56:40 -05:00
parent da5918b154
commit d50056cd66
4 changed files with 288 additions and 174 deletions

View File

@ -26,14 +26,13 @@ type Category = {
} with
/// An empty category
static member Empty = {
Id = CategoryId.Empty
static member Empty =
{ Id = CategoryId.Empty
WebLogId = WebLogId.Empty
Name = ""
Slug = ""
Description = None
ParentId = None
}
ParentId = None }
/// A comment on a post
@ -68,8 +67,8 @@ type Comment = {
} with
/// An empty comment
static member Empty = {
Id = CommentId.Empty
static member Empty =
{ Id = CommentId.Empty
PostId = PostId.Empty
InReplyToId = None
Name = ""
@ -77,8 +76,7 @@ type Comment = {
Url = None
Status = Pending
PostedOn = Noda.epoch
Text = ""
}
Text = "" }
/// A page (text not associated with a date/time)
@ -125,8 +123,8 @@ type Page = {
} with
/// An empty page
static member Empty = {
Id = PageId.Empty
static member Empty =
{ Id = PageId.Empty
WebLogId = WebLogId.Empty
AuthorId = WebLogUserId.Empty
Title = ""
@ -138,8 +136,7 @@ type Page = {
Text = ""
Metadata = []
PriorPermalinks = []
Revisions = []
}
Revisions = [] }
/// A web log post
@ -195,8 +192,8 @@ type Post = {
} with
/// An empty post
static member Empty = {
Id = PostId.Empty
static member Empty =
{ Id = PostId.Empty
WebLogId = WebLogId.Empty
AuthorId = WebLogUserId.Empty
Status = Draft
@ -211,8 +208,7 @@ type Post = {
Episode = None
Metadata = []
PriorPermalinks = []
Revisions = []
}
Revisions = [] }
/// A mapping between a tag and its URL value, used to translate restricted characters (ex. "#1" -> "number-1")
@ -232,12 +228,8 @@ type TagMap = {
} with
/// An empty tag mapping
static member Empty = {
Id = TagMapId.Empty
WebLogId = WebLogId.Empty
Tag = ""
UrlValue = ""
}
static member Empty =
{ Id = TagMapId.Empty; WebLogId = WebLogId.Empty; Tag = ""; UrlValue = "" }
/// A theme
@ -257,12 +249,8 @@ type Theme = {
} with
/// An empty theme
static member Empty = {
Id = ThemeId.Empty
Name = ""
Version = ""
Templates = []
}
static member Empty =
{ Id = ThemeId.Empty; Name = ""; Version = ""; Templates = [] }
/// A theme asset (a file served as part of a theme, at /themes/[theme]/[asset-path])
@ -279,11 +267,8 @@ type ThemeAsset = {
} with
/// An empty theme asset
static member Empty = {
Id = ThemeAssetId.Empty
UpdatedOn = Noda.epoch
Data = [||]
}
static member Empty =
{ Id = ThemeAssetId.Empty; UpdatedOn = Noda.epoch; Data = [||] }
/// An uploaded file
@ -306,13 +291,8 @@ type Upload = {
} with
/// An empty upload
static member Empty = {
Id = UploadId.Empty
WebLogId = WebLogId.Empty
Path = Permalink.Empty
UpdatedOn = Noda.epoch
Data = [||]
}
static member Empty =
{ Id = UploadId.Empty; WebLogId = WebLogId.Empty; Path = Permalink.Empty; UpdatedOn = Noda.epoch; Data = [||] }
open Newtonsoft.Json
@ -361,8 +341,8 @@ type WebLog = {
} with
/// An empty web log
static member Empty = {
Id = WebLogId.Empty
static member Empty =
{ Id = WebLogId.Empty
Name = ""
Slug = ""
Subtitle = None
@ -374,8 +354,7 @@ type WebLog = {
Rss = RssOptions.Empty
AutoHtmx = false
Uploads = Database
RedirectRules = []
}
RedirectRules = [] }
/// Any extra path where this web log is hosted (blank if web log is hosted at the root of the domain)
[<JsonIgnore>]
@ -441,8 +420,8 @@ type WebLogUser = {
} with
/// An empty web log user
static member Empty = {
Id = WebLogUserId.Empty
static member Empty =
{ Id = WebLogUserId.Empty
WebLogId = WebLogId.Empty
Email = ""
FirstName = ""
@ -452,8 +431,7 @@ type WebLogUser = {
Url = None
AccessLevel = Author
CreatedOn = Noda.epoch
LastSeenOn = None
}
LastSeenOn = None }
/// Get the user's displayed name
[<JsonIgnore>]

View File

@ -256,8 +256,8 @@ type Episode = {
} with
/// An empty episode
static member Empty = {
Media = ""
static member Empty =
{ Media = ""
Length = 0L
Duration = None
MediaType = None
@ -275,8 +275,7 @@ type Episode = {
SeasonNumber = None
SeasonDescription = None
EpisodeNumber = None
EpisodeDescription = None
}
EpisodeDescription = None }
/// Format a duration for an episode
member this.FormatDuration() =
@ -460,11 +459,8 @@ type RedirectRule = {
} with
/// An empty redirect rule
static member Empty = {
From = ""
To = ""
IsRegex = false
}
static member Empty =
{ From = ""; To = ""; IsRegex = false }
/// An identifier for a custom feed
@ -557,8 +553,8 @@ type PodcastOptions = {
} with
/// A default set of podcast options
static member Empty = {
Title = ""
static member Empty =
{ Title = ""
Subtitle = None
ItemsInFeed = 0
Summary = ""
@ -573,8 +569,7 @@ type PodcastOptions = {
PodcastGuid = None
FundingUrl = None
FundingText = None
Medium = None
}
Medium = None }
/// A custom feed
@ -594,12 +589,11 @@ type CustomFeed = {
} with
/// An empty custom feed
static member Empty = {
Id = CustomFeedId.Empty
static member Empty =
{ Id = CustomFeedId.Empty
Source = Category CategoryId.Empty
Path = Permalink.Empty
Podcast = None
}
Podcast = None }
/// Really Simple Syndication (RSS) options for this web log
@ -628,15 +622,14 @@ type RssOptions = {
} with
/// An empty set of RSS options
static member Empty = {
IsFeedEnabled = true
static member Empty =
{ IsFeedEnabled = true
FeedName = "feed.xml"
ItemsInFeed = None
IsCategoryEnabled = true
IsTagEnabled = true
Copyright = None
CustomFeeds = []
}
CustomFeeds = [] }
/// An identifier for a tag mapping

View File

@ -1146,8 +1146,8 @@ type SettingsModel = {
} with
/// Create a settings model from a web log
static member FromWebLog(webLog: WebLog) = {
Name = webLog.Name
static member FromWebLog(webLog: WebLog) =
{ Name = webLog.Name
Slug = webLog.Slug
Subtitle = defaultArg webLog.Subtitle ""
DefaultPage = webLog.DefaultPage
@ -1155,8 +1155,7 @@ type SettingsModel = {
TimeZone = webLog.TimeZone
ThemeId = string webLog.ThemeId
AutoHtmx = webLog.AutoHtmx
Uploads = string webLog.Uploads
}
Uploads = string webLog.Uploads }
/// Update a web log with settings from the form
member this.Update(webLog: WebLog) =

View File

@ -1074,6 +1074,147 @@ let manageRevisionsModelTests = testList "ManageRevisionsModel" [
}
]
/// Unit tests for the PostListItem type
let postListItemTests = testList "PostListItem" [
testList "FromPost" [
test "succeeds for a draft post" {
let post =
{ Post.Empty with
Id = PostId "draft-post"
AuthorId = WebLogUserId "myself"
Title = "Not Ready for Prime Time"
Permalink = Permalink "2021/draft.html"
UpdatedOn = Noda.epoch + Duration.FromHours 8
Text = "<h1>WIP</h1>" }
let model = PostListItem.FromPost { WebLog.Empty with TimeZone = "Etc/GMT-1" } post
Expect.equal model.Id "draft-post" "Id not filled properly"
Expect.equal model.AuthorId "myself" "AuthorId not filled properly"
Expect.equal model.Status "Draft" "Status not filled properly"
Expect.equal model.Title "Not Ready for Prime Time" "Title not filled properly"
Expect.equal model.Permalink "2021/draft.html" "Permalink not filled properly"
Expect.isFalse model.PublishedOn.HasValue "PublishedOn should not have had a value"
Expect.equal
model.UpdatedOn ((Noda.epoch + Duration.FromHours 9).ToDateTimeUtc()) "UpdatedOn not filled properly"
Expect.equal model.Text "<h1>WIP</h1>" "Text not filled properly"
Expect.isEmpty model.CategoryIds "There should have been no category IDs"
Expect.isEmpty model.Tags "There should have been no tags"
Expect.isNone model.Episode "There should not have been an episode"
Expect.isEmpty model.Metadata "There should have been no metadata"
}
test "succeeds for a published post in a non-root domain" {
let post =
{ Post.Empty with
Id = PostId "full-post"
AuthorId = WebLogUserId "me"
Status = Published
Title = "Finished Product"
Permalink = Permalink "2021/post.html"
PublishedOn = Some (Noda.epoch + Duration.FromHours 12)
UpdatedOn = Noda.epoch + Duration.FromHours 13
Text = """<a href="/other-post.html">Click</a>"""
CategoryIds = [ CategoryId "z"; CategoryId "y" ]
Tags = [ "test"; "unit" ]
Episode = Some { Episode.Empty with Media = "test.mp3" }
Metadata = [ { Name = "MyMeta"; Value = "MyValue" } ] }
let model =
PostListItem.FromPost { WebLog.Empty with UrlBase = "https://u.t/w"; TimeZone = "Etc/GMT+1" } post
Expect.equal model.Id "full-post" "Id not filled properly"
Expect.equal model.AuthorId "me" "AuthorId not filled properly"
Expect.equal model.Status "Published" "Status not filled properly"
Expect.equal model.Title "Finished Product" "Title not filled properly"
Expect.equal model.Permalink "2021/post.html" "Permalink not filled properly"
Expect.isTrue model.PublishedOn.HasValue "PublishedOn should not have had a value"
Expect.equal
model.PublishedOn.Value
((Noda.epoch + Duration.FromHours 11).ToDateTimeUtc())
"PublishedOn not filled properly"
Expect.equal
model.UpdatedOn ((Noda.epoch + Duration.FromHours 12).ToDateTimeUtc()) "UpdatedOn not filled properly"
Expect.equal model.Text """<a href="/w/other-post.html">Click</a>""" "Text not filled properly"
Expect.equal model.CategoryIds [ "z"; "y" ] "CategoryIds not filled properly"
Expect.equal model.Tags [ "test"; "unit" ] "Tags not filled properly"
Expect.isSome model.Episode "There should have been an episode"
Expect.equal model.Episode.Value.Media "test.mp3" "Episode not filled properly"
Expect.equal model.Metadata.Length 1 "There should have been 1 metadata item"
Expect.equal model.Metadata[0].Name "MyMeta" "Metadata not filled properly"
}
]
]
/// Unit tests for the SettingModel type
let settingsModelTests = testList "SettingsModel" [
testList "FromWebLog" [
test "succeeds with no subtitle" {
let model =
SettingsModel.FromWebLog
{ WebLog.Empty with
Name = "The Web Log"
Slug = "the-web-log"
DefaultPage = "this-one"
PostsPerPage = 18
TimeZone = "America/Denver"
ThemeId = ThemeId "my-theme"
AutoHtmx = true }
Expect.equal model.Name "The Web Log" "Name not filled properly"
Expect.equal model.Slug "the-web-log" "Slug not filled properly"
Expect.equal model.Subtitle "" "Subtitle not filled properly"
Expect.equal model.DefaultPage "this-one" "DefaultPage not filled properly"
Expect.equal model.PostsPerPage 18 "PostsPerPage not filled properly"
Expect.equal model.TimeZone "America/Denver" "TimeZone not filled properly"
Expect.equal model.ThemeId "my-theme" "ThemeId not filled properly"
Expect.isTrue model.AutoHtmx "AutoHtmx should have been set"
Expect.equal model.Uploads "Database" "Uploads not filled properly"
}
test "succeeds with a subtitle" {
let model = SettingsModel.FromWebLog { WebLog.Empty with Subtitle = Some "sub here!" }
Expect.equal model.Subtitle "sub here!" "Subtitle not filled properly"
}
]
testList "Update" [
test "succeeds with no subtitle" {
let webLog =
{ Name = "Interesting"
Slug = "some-stuff"
Subtitle = ""
DefaultPage = "that-one"
PostsPerPage = 8
TimeZone = "America/Chicago"
ThemeId = "test-theme"
AutoHtmx = true
Uploads = "Disk" }.Update WebLog.Empty
Expect.equal webLog.Name "Interesting" "Name not filled properly"
Expect.equal webLog.Slug "some-stuff" "Slug not filled properly"
Expect.isNone webLog.Subtitle "Subtitle should not have had a value"
Expect.equal webLog.DefaultPage "that-one" "DefaultPage not filled properly"
Expect.equal webLog.PostsPerPage 8 "PostsPerPage not filled properly"
Expect.equal webLog.TimeZone "America/Chicago" "TimeZone not filled properly"
Expect.equal webLog.ThemeId (ThemeId "test-theme") "ThemeId not filled properly"
Expect.isTrue webLog.AutoHtmx "AutoHtmx should have been set"
Expect.equal webLog.Uploads Disk "Uploads not filled properly"
}
test "succeeds with a subtitle" {
let webLog = { SettingsModel.FromWebLog WebLog.Empty with Subtitle = "Sub" }.Update WebLog.Empty
Expect.equal webLog.Subtitle (Some "Sub") "Subtitle should have had a value"
}
]
]
/// Unit tests for the UserMessage type
let userMessageTests = testList "UserMessage" [
test "Success succeeds" {
Expect.equal UserMessage.Success.Level "success" "Level incorrect"
}
test "Info succeeds" {
Expect.equal UserMessage.Info.Level "primary" "Level incorrect"
}
test "Warning succeeds" {
Expect.equal UserMessage.Warning.Level "warning" "Level incorrect"
}
test "Error succeeds" {
Expect.equal UserMessage.Error.Level "danger" "Level incorrect"
}
]
/// All tests in the Domain.ViewModels file
let all = testList "ViewModels" [
addBaseToRelativeUrlsTests
@ -1094,4 +1235,7 @@ let all = testList "ViewModels" [
editUserModelTests
managePermalinksModelTests
manageRevisionsModelTests
postListItemTests
settingsModelTests
userMessageTests
]