Version 2.1 #41

Merged
danieljsummers merged 123 commits from version-2.1 into main 2024-03-27 00:13:28 +00:00
4 changed files with 878 additions and 722 deletions
Showing only changes of commit 29167eca6c - Show all commits

View File

@ -4,87 +4,84 @@ open Expecto
open MyWebLog
/// Unit tests for the WebLog type
let webLogTests =
testList "WebLog" [
testList "ExtraPath" [
test "succeeds for blank URL base" {
Expect.equal WebLog.Empty.ExtraPath "" "Extra path should have been blank for blank URL base"
}
test "succeeds for domain root URL" {
Expect.equal
{ WebLog.Empty with UrlBase = "https://example.com" }.ExtraPath
""
"Extra path should have been blank for domain root"
}
test "succeeds for single subdirectory" {
Expect.equal
{ WebLog.Empty with UrlBase = "https://a.com/sub" }.ExtraPath
"/sub"
"Extra path incorrect for a single subdirectory"
}
test "succeeds for deeper nesting" {
Expect.equal
{ WebLog.Empty with UrlBase = "https://b.com/users/test/units" }.ExtraPath
"/users/test/units"
"Extra path incorrect for deeper nesting"
}
]
test "AbsoluteUrl succeeds" {
Expect.equal
({ WebLog.Empty with UrlBase = "https://my.site" }.AbsoluteUrl(Permalink "blog/page.html"))
"https://my.site/blog/page.html"
"Absolute URL is incorrect"
let webLogTests = testList "WebLog" [
testList "ExtraPath" [
test "succeeds for blank URL base" {
Expect.equal WebLog.Empty.ExtraPath "" "Extra path should have been blank for blank URL base"
}
test "succeeds for domain root URL" {
Expect.equal
{ WebLog.Empty with UrlBase = "https://example.com" }.ExtraPath
""
"Extra path should have been blank for domain root"
}
test "succeeds for single subdirectory" {
Expect.equal
{ WebLog.Empty with UrlBase = "https://a.com/sub" }.ExtraPath
"/sub"
"Extra path incorrect for a single subdirectory"
}
test "succeeds for deeper nesting" {
Expect.equal
{ WebLog.Empty with UrlBase = "https://b.com/users/test/units" }.ExtraPath
"/users/test/units"
"Extra path incorrect for deeper nesting"
}
testList "RelativeUrl" [
test "succeeds for domain root URL" {
Expect.equal
({ WebLog.Empty with UrlBase = "https://test.me" }.RelativeUrl(Permalink "about.htm"))
"/about.htm"
"Relative URL is incorrect for domain root site"
}
test "succeeds for domain non-root URL" {
Expect.equal
({ WebLog.Empty with UrlBase = "https://site.page/a/b/c" }.RelativeUrl(Permalink "x/y/z"))
"/a/b/c/x/y/z"
"Relative URL is incorrect for domain non-root site"
}
]
testList "LocalTime" [
test "succeeds when no time zone is set" {
Expect.equal
(WebLog.Empty.LocalTime(Noda.epoch))
(Noda.epoch.ToDateTimeUtc())
"Reference should be UTC when no time zone is specified"
}
test "succeeds when time zone is set" {
Expect.equal
({ WebLog.Empty with TimeZone = "Etc/GMT-1" }.LocalTime(Noda.epoch))
(Noda.epoch.ToDateTimeUtc().AddHours 1)
"The time should have been adjusted by one hour"
}
]
]
test "AbsoluteUrl succeeds" {
Expect.equal
({ WebLog.Empty with UrlBase = "https://my.site" }.AbsoluteUrl(Permalink "blog/page.html"))
"https://my.site/blog/page.html"
"Absolute URL is incorrect"
}
testList "RelativeUrl" [
test "succeeds for domain root URL" {
Expect.equal
({ WebLog.Empty with UrlBase = "https://test.me" }.RelativeUrl(Permalink "about.htm"))
"/about.htm"
"Relative URL is incorrect for domain root site"
}
test "succeeds for domain non-root URL" {
Expect.equal
({ WebLog.Empty with UrlBase = "https://site.page/a/b/c" }.RelativeUrl(Permalink "x/y/z"))
"/a/b/c/x/y/z"
"Relative URL is incorrect for domain non-root site"
}
]
testList "LocalTime" [
test "succeeds when no time zone is set" {
Expect.equal
(WebLog.Empty.LocalTime(Noda.epoch))
(Noda.epoch.ToDateTimeUtc())
"Reference should be UTC when no time zone is specified"
}
test "succeeds when time zone is set" {
Expect.equal
({ WebLog.Empty with TimeZone = "Etc/GMT-1" }.LocalTime(Noda.epoch))
(Noda.epoch.ToDateTimeUtc().AddHours 1)
"The time should have been adjusted by one hour"
}
]
]
/// Unit tests for the WebLogUser type
let webLogUserTests =
testList "WebLogUser" [
testList "DisplayName" [
test "succeeds when a preferred name is present" {
Expect.equal
{ WebLogUser.Empty with
FirstName = "Thomas"; PreferredName = "Tom"; LastName = "Tester" }.DisplayName
"Tom Tester"
"Display name incorrect when preferred name is present"
}
test "succeeds when a preferred name is absent" {
Expect.equal
{ WebLogUser.Empty with FirstName = "Test"; LastName = "Units" }.DisplayName
"Test Units"
"Display name incorrect when preferred name is absent"
}
]
let webLogUserTests = testList "WebLogUser" [
testList "DisplayName" [
test "succeeds when a preferred name is present" {
Expect.equal
{ WebLogUser.Empty with
FirstName = "Thomas"; PreferredName = "Tom"; LastName = "Tester" }.DisplayName
"Tom Tester"
"Display name incorrect when preferred name is present"
}
test "succeeds when a preferred name is absent" {
Expect.equal
{ WebLogUser.Empty with FirstName = "Test"; LastName = "Units" }.DisplayName
"Test Units"
"Display name incorrect when preferred name is absent"
}
]
]
/// All tests for the Domain.DataTypes file
let all =
testList "DataTypes" [ webLogTests; webLogUserTests ]
let all = testList "DataTypes" [ webLogTests; webLogUserTests ]

View File

@ -1,9 +1,8 @@
open Expecto
let allTests =
testList
"MyWebLog"
[ testList "Domain" [ SupportTypesTests.all; DataTypesTests.all; ViewModelsTests.all ] ]
let allTests = testList "MyWebLog" [
testList "Domain" [ SupportTypesTests.all; DataTypesTests.all; ViewModelsTests.all ]
]
[<EntryPoint>]
let main args = runTestsWithCLIArgs [] args allTests

View File

@ -6,427 +6,410 @@ open MyWebLog
open NodaTime
/// Tests for the NodaTime-wrapping module
let nodaTests =
testList "Noda" [
test "epoch succeeds" {
Expect.equal
(Noda.epoch.ToDateTimeUtc())
(DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc))
"The Unix epoch value is not correct"
}
test "toSecondsPrecision succeeds" {
let testDate = Instant.FromDateTimeUtc(DateTime(1970, 1, 1, 0, 0, 0, 444, DateTimeKind.Utc))
// testDate.
Expect.equal
((Noda.toSecondsPrecision testDate).ToDateTimeUtc())
(Noda.epoch.ToDateTimeUtc())
"Instant value was not rounded to seconds precision"
}
test "fromDateTime succeeds" {
let testDate = DateTime(1970, 1, 1, 0, 0, 0, 444, DateTimeKind.Utc)
Expect.equal (Noda.fromDateTime testDate) Noda.epoch "fromDateTime did not truncate to seconds"
}
]
let nodaTests = testList "Noda" [
test "epoch succeeds" {
Expect.equal
(Noda.epoch.ToDateTimeUtc())
(DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc))
"The Unix epoch value is not correct"
}
test "toSecondsPrecision succeeds" {
let testDate = Instant.FromDateTimeUtc(DateTime(1970, 1, 1, 0, 0, 0, 444, DateTimeKind.Utc))
// testDate.
Expect.equal
((Noda.toSecondsPrecision testDate).ToDateTimeUtc())
(Noda.epoch.ToDateTimeUtc())
"Instant value was not rounded to seconds precision"
}
test "fromDateTime succeeds" {
let testDate = DateTime(1970, 1, 1, 0, 0, 0, 444, DateTimeKind.Utc)
Expect.equal (Noda.fromDateTime testDate) Noda.epoch "fromDateTime did not truncate to seconds"
}
]
/// Tests for the AccessLevel type
let accessLevelTests =
testList "AccessLevel" [
testList "Parse" [
test "succeeds for \"Author\"" {
Expect.equal Author (AccessLevel.Parse "Author") "Author not parsed correctly"
}
test "succeeds for \"Editor\"" {
Expect.equal Editor (AccessLevel.Parse "Editor") "Editor not parsed correctly"
}
test "succeeds for \"WebLogAdmin\"" {
Expect.equal WebLogAdmin (AccessLevel.Parse "WebLogAdmin") "WebLogAdmin not parsed correctly"
}
test "succeeds for \"Administrator\"" {
Expect.equal Administrator (AccessLevel.Parse "Administrator") "Administrator not parsed correctly"
}
test "fails when given an unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (AccessLevel.Parse "Hacker")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "Author succeeds" {
Expect.equal (string Author) "Author" "Author string incorrect"
}
test "Editor succeeds" {
Expect.equal (string Editor) "Editor" "Editor string incorrect"
}
test "WebLogAdmin succeeds" {
Expect.equal (string WebLogAdmin) "WebLogAdmin" "WebLogAdmin string incorrect"
}
test "Administrator succeeds" {
Expect.equal (string Administrator) "Administrator" "Administrator string incorrect"
}
]
testList "HasAccess" [
test "Author has Author access" {
Expect.isTrue (Author.HasAccess Author) "Author should have Author access"
}
test "Author does not have Editor access" {
Expect.isFalse (Author.HasAccess Editor) "Author should not have Editor access"
}
test "Author does not have WebLogAdmin access" {
Expect.isFalse (Author.HasAccess WebLogAdmin) "Author should not have WebLogAdmin access"
}
test "Author does not have Administrator access" {
Expect.isFalse (Author.HasAccess Administrator) "Author should not have Administrator access"
}
test "Editor has Author access" {
Expect.isTrue (Editor.HasAccess Author) "Editor should have Author access"
}
test "Editor has Editor access" {
Expect.isTrue (Editor.HasAccess Editor) "Editor should have Editor access"
}
test "Editor does not have WebLogAdmin access" {
Expect.isFalse (Editor.HasAccess WebLogAdmin) "Editor should not have WebLogAdmin access"
}
test "Editor does not have Administrator access" {
Expect.isFalse (Editor.HasAccess Administrator) "Editor should not have Administrator access"
}
test "WebLogAdmin has Author access" {
Expect.isTrue (WebLogAdmin.HasAccess Author) "WebLogAdmin should have Author access"
}
test "WebLogAdmin has Editor access" {
Expect.isTrue (WebLogAdmin.HasAccess Editor) "WebLogAdmin should have Editor access"
}
test "WebLogAdmin has WebLogAdmin access" {
Expect.isTrue (WebLogAdmin.HasAccess WebLogAdmin) "WebLogAdmin should have WebLogAdmin access"
}
test "WebLogAdmin does not have Administrator access" {
Expect.isFalse (WebLogAdmin.HasAccess Administrator) "WebLogAdmin should not have Administrator access"
}
test "Administrator has Author access" {
Expect.isTrue (Administrator.HasAccess Author) "Administrator should have Author access"
}
test "Administrator has Editor access" {
Expect.isTrue (Administrator.HasAccess Editor) "Administrator should have Editor access"
}
test "Administrator has WebLogAdmin access" {
Expect.isTrue (Administrator.HasAccess WebLogAdmin) "Administrator should have WebLogAdmin access"
}
test "Administrator has Administrator access" {
Expect.isTrue (Administrator.HasAccess Administrator) "Administrator should have Administrator access"
}
]
]
/// Tests for the CommentStatus type
let commentStatusTests =
testList "CommentStatus" [
testList "Parse" [
test "succeeds for \"Approved\"" {
Expect.equal Approved (CommentStatus.Parse "Approved") "Approved not parsed correctly"
}
test "succeeds for \"Pending\"" {
Expect.equal Pending (CommentStatus.Parse "Pending") "Pending not parsed correctly"
}
test "succeeds for \"Spam\"" {
Expect.equal Spam (CommentStatus.Parse "Spam") "Spam not parsed correctly"
}
test "fails for unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (CommentStatus.Parse "Live")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "Approved succeeds" {
Expect.equal (string Approved) "Approved" "Approved string incorrect"
}
test "Pending succeeds" {
Expect.equal (string Pending) "Pending" "Pending string incorrect"
}
test "Spam succeeds" {
Expect.equal (string Spam) "Spam" "Spam string incorrect"
}
]
]
let explicitRatingTests =
testList "ExplicitRating" [
testList "Parse" [
test "succeeds for \"yes\"" {
Expect.equal Yes (ExplicitRating.Parse "yes") "\"yes\" not parsed correctly"
}
test "succeeds for \"no\"" {
Expect.equal No (ExplicitRating.Parse "no") "\"no\" not parsed correctly"
}
test "succeeds for \"clean\"" {
Expect.equal Clean (ExplicitRating.Parse "clean") "\"clean\" not parsed correctly"
}
test "fails for unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (ExplicitRating.Parse "maybe")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "Yes succeeds" {
Expect.equal (string Yes) "yes" "Yes string incorrect"
}
test "No succeeds" {
Expect.equal (string No) "no" "No string incorrect"
}
test "Clean succeeds" {
Expect.equal (string Clean) "clean" "Clean string incorrect"
}
]
]
/// Tests for the Episode type
let episodeTests =
testList "Episode" [
testList "FormatDuration" [
test "succeeds when no duration is specified" {
Expect.isNone (Episode.Empty.FormatDuration()) "A missing duration should have returned None"
}
test "succeeds when duration is specified" {
Expect.equal
({ Episode.Empty with
Duration = Some (Duration.FromMinutes 3L + Duration.FromSeconds 13L) }.FormatDuration())
(Some "0:03:13")
"Duration not formatted correctly"
}
test "succeeds when duration is > 10 hours" {
Expect.equal
({ Episode.Empty with Duration = Some (Duration.FromHours 11) }.FormatDuration())
(Some "11:00:00")
"Duration not formatted correctly"
}
]
]
/// Unit tests for the MarkupText type
let markupTextTests =
testList "MarkupText" [
testList "Parse" [
test "succeeds with HTML content" {
let txt = MarkupText.Parse "HTML: <p>howdy</p>"
match txt with
| Html it when it = "<p>howdy</p>" -> ()
| _ -> Expect.isTrue false $"Unexpected parse result for HTML: %A{txt}"
}
test "succeeds with Markdown content" {
let txt = MarkupText.Parse "Markdown: # A Title"
match txt with
| Markdown it when it = "# A Title" -> ()
| _ -> Expect.isTrue false $"Unexpected parse result for Markdown: %A{txt}"
}
test "fails with unexpected content" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (MarkupText.Parse "LaTEX: nope")) "Invalid value should have raised an exception"
}
]
testList "SourceType" [
test "succeeds for HTML" {
Expect.equal (MarkupText.Parse "HTML: something").SourceType "HTML" "HTML source type incorrect"
}
test "succeeds for Markdown" {
Expect.equal (MarkupText.Parse "Markdown: blah").SourceType "Markdown" "Markdown source type incorrect"
}
]
testList "Text" [
test "succeeds for HTML" {
Expect.equal (MarkupText.Parse "HTML: test").Text "test" "HTML text incorrect"
}
test "succeeds for Markdown" {
Expect.equal (MarkupText.Parse "Markdown: test!").Text "test!" "Markdown text incorrect"
}
]
testList "ToString" [
test "succeeds for HTML" {
Expect.equal
(string (MarkupText.Parse "HTML: <h1>HTML</h1>"))
"HTML: <h1>HTML</h1>"
"HTML string value incorrect"
}
test "succeeds for Markdown" {
Expect.equal
(string (MarkupText.Parse "Markdown: # Some Content"))
"Markdown: # Some Content"
"Markdown string value incorrect"
}
]
testList "AsHtml" [
test "succeeds for HTML" {
Expect.equal
((MarkupText.Parse "HTML: <h1>The Heading</h1>").AsHtml())
"<h1>The Heading</h1>"
"HTML value incorrect"
}
test "succeeds for Markdown" {
Expect.equal
((MarkupText.Parse "Markdown: *emphasis*").AsHtml())
"<p><em>emphasis</em></p>\n"
"Markdown HTML value incorrect"
}
]
]
/// Unit tests for the PodcastMedium type
let podcastMediumTests =
testList "PodcastMedium" [
testList "Parse" [
test "succeeds for \"podcast\"" {
Expect.equal (PodcastMedium.Parse "podcast") Podcast "\"podcast\" not parsed correctly"
}
test "succeeds for \"music\"" {
Expect.equal (PodcastMedium.Parse "music") Music "\"music\" not parsed correctly"
}
test "succeeds for \"video\"" {
Expect.equal (PodcastMedium.Parse "video") Video "\"video\" not parsed correctly"
}
test "succeeds for \"film\"" {
Expect.equal (PodcastMedium.Parse "film") Film "\"film\" not parsed correctly"
}
test "succeeds for \"audiobook\"" {
Expect.equal (PodcastMedium.Parse "audiobook") Audiobook "\"audiobook\" not parsed correctly"
}
test "succeeds for \"newsletter\"" {
Expect.equal (PodcastMedium.Parse "newsletter") Newsletter "\"newsletter\" not parsed correctly"
}
test "succeeds for \"blog\"" {
Expect.equal (PodcastMedium.Parse "blog") Blog "\"blog\" not parsed correctly"
}
test "fails for invalid type" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (PodcastMedium.Parse "laser")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "succeeds for Podcast" {
Expect.equal (string Podcast) "podcast" "Podcast string incorrect"
}
test "succeeds for Music" {
Expect.equal (string Music) "music" "Music string incorrect"
}
test "succeeds for Video" {
Expect.equal (string Video) "video" "Video string incorrect"
}
test "succeeds for Film" {
Expect.equal (string Film) "film" "Film string incorrect"
}
test "succeeds for Audiobook" {
Expect.equal (string Audiobook) "audiobook" "Audiobook string incorrect"
}
test "succeeds for Newsletter" {
Expect.equal (string Newsletter) "newsletter" "Newsletter string incorrect"
}
test "succeeds for Blog" {
Expect.equal (string Blog) "blog" "Blog string incorrect"
}
]
]
/// Unit tests for the PostStatus type
let postStatusTests =
testList "PostStatus" [
testList "Parse" [
test "succeeds for \"Draft\"" {
Expect.equal (PostStatus.Parse "Draft") Draft "\"Draft\" not parsed correctly"
}
test "succeeds for \"Published\"" {
Expect.equal (PostStatus.Parse "Published") Published "\"Published\" not parsed correctly"
}
test "fails for unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (PostStatus.Parse "Rescinded")) "Invalid value should have raised an exception"
}
]
]
/// Unit tests for the CustomFeedSource type
let customFeedSourceTests =
testList "CustomFeedSource" [
testList "Parse" [
test "succeeds for category feeds" {
Expect.equal
(CustomFeedSource.Parse "category:abc123")
(Category (CategoryId "abc123"))
"Category feed not parsed correctly"
}
test "succeeds for tag feeds" {
Expect.equal (CustomFeedSource.Parse "tag:turtles") (Tag "turtles") "Tag feed not parsed correctly"
}
test "fails for unknown type" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (CustomFeedSource.Parse "nasa:sat1"))
"Invalid value should have raised an exception"
}
]
testList "ToString" [
test "succeeds for category feed" {
Expect.equal
(string (CustomFeedSource.Parse "category:fish")) "category:fish" "Category feed string incorrect"
}
test "succeeds for tag feed" {
Expect.equal (string (CustomFeedSource.Parse "tag:rocks")) "tag:rocks" "Tag feed string incorrect"
}
]
]
/// Unit tests for the ThemeAssetId type
let themeAssetIdTests =
testList "ThemeAssetId" [
testList "Parse" [
test "succeeds with expected values" {
Expect.equal
(ThemeAssetId.Parse "test-theme/the-asset")
(ThemeAssetId ((ThemeId "test-theme"), "the-asset"))
"Theme asset ID not parsed correctly"
}
test "fails if no slash is present" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (ThemeAssetId.Parse "my-theme-asset"))
"Invalid value should have raised an exception"
}
]
test "ToString succeeds" {
Expect.equal
(string (ThemeAssetId ((ThemeId "howdy"), "pardner"))) "howdy/pardner" "Theme asset ID string incorrect"
let accessLevelTests = testList "AccessLevel" [
testList "Parse" [
test "succeeds for \"Author\"" {
Expect.equal Author (AccessLevel.Parse "Author") "Author not parsed correctly"
}
test "succeeds for \"Editor\"" {
Expect.equal Editor (AccessLevel.Parse "Editor") "Editor not parsed correctly"
}
test "succeeds for \"WebLogAdmin\"" {
Expect.equal WebLogAdmin (AccessLevel.Parse "WebLogAdmin") "WebLogAdmin not parsed correctly"
}
test "succeeds for \"Administrator\"" {
Expect.equal Administrator (AccessLevel.Parse "Administrator") "Administrator not parsed correctly"
}
test "fails when given an unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (AccessLevel.Parse "Hacker")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "Author succeeds" {
Expect.equal (string Author) "Author" "Author string incorrect"
}
test "Editor succeeds" {
Expect.equal (string Editor) "Editor" "Editor string incorrect"
}
test "WebLogAdmin succeeds" {
Expect.equal (string WebLogAdmin) "WebLogAdmin" "WebLogAdmin string incorrect"
}
test "Administrator succeeds" {
Expect.equal (string Administrator) "Administrator" "Administrator string incorrect"
}
]
testList "HasAccess" [
test "Author has Author access" {
Expect.isTrue (Author.HasAccess Author) "Author should have Author access"
}
test "Author does not have Editor access" {
Expect.isFalse (Author.HasAccess Editor) "Author should not have Editor access"
}
test "Author does not have WebLogAdmin access" {
Expect.isFalse (Author.HasAccess WebLogAdmin) "Author should not have WebLogAdmin access"
}
test "Author does not have Administrator access" {
Expect.isFalse (Author.HasAccess Administrator) "Author should not have Administrator access"
}
test "Editor has Author access" {
Expect.isTrue (Editor.HasAccess Author) "Editor should have Author access"
}
test "Editor has Editor access" {
Expect.isTrue (Editor.HasAccess Editor) "Editor should have Editor access"
}
test "Editor does not have WebLogAdmin access" {
Expect.isFalse (Editor.HasAccess WebLogAdmin) "Editor should not have WebLogAdmin access"
}
test "Editor does not have Administrator access" {
Expect.isFalse (Editor.HasAccess Administrator) "Editor should not have Administrator access"
}
test "WebLogAdmin has Author access" {
Expect.isTrue (WebLogAdmin.HasAccess Author) "WebLogAdmin should have Author access"
}
test "WebLogAdmin has Editor access" {
Expect.isTrue (WebLogAdmin.HasAccess Editor) "WebLogAdmin should have Editor access"
}
test "WebLogAdmin has WebLogAdmin access" {
Expect.isTrue (WebLogAdmin.HasAccess WebLogAdmin) "WebLogAdmin should have WebLogAdmin access"
}
test "WebLogAdmin does not have Administrator access" {
Expect.isFalse (WebLogAdmin.HasAccess Administrator) "WebLogAdmin should not have Administrator access"
}
test "Administrator has Author access" {
Expect.isTrue (Administrator.HasAccess Author) "Administrator should have Author access"
}
test "Administrator has Editor access" {
Expect.isTrue (Administrator.HasAccess Editor) "Administrator should have Editor access"
}
test "Administrator has WebLogAdmin access" {
Expect.isTrue (Administrator.HasAccess WebLogAdmin) "Administrator should have WebLogAdmin access"
}
test "Administrator has Administrator access" {
Expect.isTrue (Administrator.HasAccess Administrator) "Administrator should have Administrator access"
}
]
]
/// Tests for the CommentStatus type
let commentStatusTests = testList "CommentStatus" [
testList "Parse" [
test "succeeds for \"Approved\"" {
Expect.equal Approved (CommentStatus.Parse "Approved") "Approved not parsed correctly"
}
test "succeeds for \"Pending\"" {
Expect.equal Pending (CommentStatus.Parse "Pending") "Pending not parsed correctly"
}
test "succeeds for \"Spam\"" {
Expect.equal Spam (CommentStatus.Parse "Spam") "Spam not parsed correctly"
}
test "fails for unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (CommentStatus.Parse "Live")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "Approved succeeds" {
Expect.equal (string Approved) "Approved" "Approved string incorrect"
}
test "Pending succeeds" {
Expect.equal (string Pending) "Pending" "Pending string incorrect"
}
test "Spam succeeds" {
Expect.equal (string Spam) "Spam" "Spam string incorrect"
}
]
]
/// Tests for the ExplicitRating type
let explicitRatingTests = testList "ExplicitRating" [
testList "Parse" [
test "succeeds for \"yes\"" {
Expect.equal Yes (ExplicitRating.Parse "yes") "\"yes\" not parsed correctly"
}
test "succeeds for \"no\"" {
Expect.equal No (ExplicitRating.Parse "no") "\"no\" not parsed correctly"
}
test "succeeds for \"clean\"" {
Expect.equal Clean (ExplicitRating.Parse "clean") "\"clean\" not parsed correctly"
}
test "fails for unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (ExplicitRating.Parse "maybe")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "Yes succeeds" {
Expect.equal (string Yes) "yes" "Yes string incorrect"
}
test "No succeeds" {
Expect.equal (string No) "no" "No string incorrect"
}
test "Clean succeeds" {
Expect.equal (string Clean) "clean" "Clean string incorrect"
}
]
]
/// Tests for the Episode type
let episodeTests = testList "Episode" [
testList "FormatDuration" [
test "succeeds when no duration is specified" {
Expect.isNone (Episode.Empty.FormatDuration()) "A missing duration should have returned None"
}
test "succeeds when duration is specified" {
Expect.equal
({ Episode.Empty with
Duration = Some (Duration.FromMinutes 3L + Duration.FromSeconds 13L) }.FormatDuration())
(Some "0:03:13")
"Duration not formatted correctly"
}
test "succeeds when duration is > 10 hours" {
Expect.equal
({ Episode.Empty with Duration = Some (Duration.FromHours 11) }.FormatDuration())
(Some "11:00:00")
"Duration not formatted correctly"
}
]
]
/// Unit tests for the MarkupText type
let markupTextTests = testList "MarkupText" [
testList "Parse" [
test "succeeds with HTML content" {
let txt = MarkupText.Parse "HTML: <p>howdy</p>"
match txt with
| Html it when it = "<p>howdy</p>" -> ()
| _ -> Expect.isTrue false $"Unexpected parse result for HTML: %A{txt}"
}
test "succeeds with Markdown content" {
let txt = MarkupText.Parse "Markdown: # A Title"
match txt with
| Markdown it when it = "# A Title" -> ()
| _ -> Expect.isTrue false $"Unexpected parse result for Markdown: %A{txt}"
}
test "fails with unexpected content" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (MarkupText.Parse "LaTEX: nope")) "Invalid value should have raised an exception"
}
]
testList "SourceType" [
test "succeeds for HTML" {
Expect.equal (MarkupText.Parse "HTML: something").SourceType "HTML" "HTML source type incorrect"
}
test "succeeds for Markdown" {
Expect.equal (MarkupText.Parse "Markdown: blah").SourceType "Markdown" "Markdown source type incorrect"
}
]
testList "Text" [
test "succeeds for HTML" {
Expect.equal (MarkupText.Parse "HTML: test").Text "test" "HTML text incorrect"
}
test "succeeds for Markdown" {
Expect.equal (MarkupText.Parse "Markdown: test!").Text "test!" "Markdown text incorrect"
}
]
testList "ToString" [
test "succeeds for HTML" {
Expect.equal
(string (MarkupText.Parse "HTML: <h1>HTML</h1>")) "HTML: <h1>HTML</h1>" "HTML string value incorrect"
}
test "succeeds for Markdown" {
Expect.equal
(string (MarkupText.Parse "Markdown: # Some Content"))
"Markdown: # Some Content"
"Markdown string value incorrect"
}
]
testList "AsHtml" [
test "succeeds for HTML" {
Expect.equal
((MarkupText.Parse "HTML: <h1>The Heading</h1>").AsHtml()) "<h1>The Heading</h1>" "HTML value incorrect"
}
test "succeeds for Markdown" {
Expect.equal
((MarkupText.Parse "Markdown: *emphasis*").AsHtml())
"<p><em>emphasis</em></p>\n"
"Markdown HTML value incorrect"
}
]
]
/// Unit tests for the PodcastMedium type
let podcastMediumTests = testList "PodcastMedium" [
testList "Parse" [
test "succeeds for \"podcast\"" {
Expect.equal (PodcastMedium.Parse "podcast") Podcast "\"podcast\" not parsed correctly"
}
test "succeeds for \"music\"" {
Expect.equal (PodcastMedium.Parse "music") Music "\"music\" not parsed correctly"
}
test "succeeds for \"video\"" {
Expect.equal (PodcastMedium.Parse "video") Video "\"video\" not parsed correctly"
}
test "succeeds for \"film\"" {
Expect.equal (PodcastMedium.Parse "film") Film "\"film\" not parsed correctly"
}
test "succeeds for \"audiobook\"" {
Expect.equal (PodcastMedium.Parse "audiobook") Audiobook "\"audiobook\" not parsed correctly"
}
test "succeeds for \"newsletter\"" {
Expect.equal (PodcastMedium.Parse "newsletter") Newsletter "\"newsletter\" not parsed correctly"
}
test "succeeds for \"blog\"" {
Expect.equal (PodcastMedium.Parse "blog") Blog "\"blog\" not parsed correctly"
}
test "fails for invalid type" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (PodcastMedium.Parse "laser")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "succeeds for Podcast" {
Expect.equal (string Podcast) "podcast" "Podcast string incorrect"
}
test "succeeds for Music" {
Expect.equal (string Music) "music" "Music string incorrect"
}
test "succeeds for Video" {
Expect.equal (string Video) "video" "Video string incorrect"
}
test "succeeds for Film" {
Expect.equal (string Film) "film" "Film string incorrect"
}
test "succeeds for Audiobook" {
Expect.equal (string Audiobook) "audiobook" "Audiobook string incorrect"
}
test "succeeds for Newsletter" {
Expect.equal (string Newsletter) "newsletter" "Newsletter string incorrect"
}
test "succeeds for Blog" {
Expect.equal (string Blog) "blog" "Blog string incorrect"
}
]
]
/// Unit tests for the PostStatus type
let postStatusTests = testList "PostStatus" [
testList "Parse" [
test "succeeds for \"Draft\"" {
Expect.equal (PostStatus.Parse "Draft") Draft "\"Draft\" not parsed correctly"
}
test "succeeds for \"Published\"" {
Expect.equal (PostStatus.Parse "Published") Published "\"Published\" not parsed correctly"
}
test "fails for unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (PostStatus.Parse "Rescinded")) "Invalid value should have raised an exception"
}
]
]
/// Unit tests for the CustomFeedSource type
let customFeedSourceTests = testList "CustomFeedSource" [
testList "Parse" [
test "succeeds for category feeds" {
Expect.equal
(CustomFeedSource.Parse "category:abc123")
(Category (CategoryId "abc123"))
"Category feed not parsed correctly"
}
test "succeeds for tag feeds" {
Expect.equal (CustomFeedSource.Parse "tag:turtles") (Tag "turtles") "Tag feed not parsed correctly"
}
test "fails for unknown type" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (CustomFeedSource.Parse "nasa:sat1")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "succeeds for category feed" {
Expect.equal
(string (CustomFeedSource.Parse "category:fish")) "category:fish" "Category feed string incorrect"
}
test "succeeds for tag feed" {
Expect.equal (string (CustomFeedSource.Parse "tag:rocks")) "tag:rocks" "Tag feed string incorrect"
}
]
]
/// Unit tests for the ThemeAssetId type
let themeAssetIdTests = testList "ThemeAssetId" [
testList "Parse" [
test "succeeds with expected values" {
Expect.equal
(ThemeAssetId.Parse "test-theme/the-asset")
(ThemeAssetId ((ThemeId "test-theme"), "the-asset"))
"Theme asset ID not parsed correctly"
}
test "fails if no slash is present" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (ThemeAssetId.Parse "my-theme-asset")) "Invalid value should have raised an exception"
}
]
test "ToString succeeds" {
Expect.equal
(string (ThemeAssetId ((ThemeId "howdy"), "pardner"))) "howdy/pardner" "Theme asset ID string incorrect"
}
]
/// Unit tests for the UploadDestination type
let uploadDestinationTests =
testList "UploadDestination" [
testList "Parse" [
test "succeeds for \"Database\"" {
Expect.equal (UploadDestination.Parse "Database") Database "\"Database\" not parsed correctly"
}
test "succeeds for \"Disk\"" {
Expect.equal (UploadDestination.Parse "Disk") Disk "\"Disk\" not parsed correctly"
}
test "fails for unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (UploadDestination.Parse "Azure")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "succeeds for Database" {
Expect.equal (string Database) "Database" "Database string incorrect"
}
test "succeeds for Disk" {
Expect.equal (string Disk) "Disk" "Disk string incorrect"
}
]
let uploadDestinationTests = testList "UploadDestination" [
testList "Parse" [
test "succeeds for \"Database\"" {
Expect.equal (UploadDestination.Parse "Database") Database "\"Database\" not parsed correctly"
}
test "succeeds for \"Disk\"" {
Expect.equal (UploadDestination.Parse "Disk") Disk "\"Disk\" not parsed correctly"
}
test "fails for unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (UploadDestination.Parse "Azure")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "succeeds for Database" {
Expect.equal (string Database) "Database" "Database string incorrect"
}
test "succeeds for Disk" {
Expect.equal (string Disk) "Disk" "Disk string incorrect"
}
]
]
/// All tests for the Domain.SupportTypes file
let all =
testList
"SupportTypes"
[ nodaTests
accessLevelTests
commentStatusTests
explicitRatingTests
episodeTests
markupTextTests
podcastMediumTests
postStatusTests
customFeedSourceTests
themeAssetIdTests
uploadDestinationTests ]
let all = testList "SupportTypes" [
nodaTests
accessLevelTests
commentStatusTests
explicitRatingTests
episodeTests
markupTextTests
podcastMediumTests
postStatusTests
customFeedSourceTests
themeAssetIdTests
uploadDestinationTests
]

View File

@ -7,205 +7,195 @@ open MyWebLog.ViewModels
open NodaTime
/// Unit tests for the addBaseToRelativeUrls helper function
let addBaseToRelativeUrlsTests =
testList "PublicHelpers.addBaseToRelativeUrls" [
test "succeeds when there is no extra URL path" {
let testText = """<a href="/somewhere-else.html">Howdy></a>"""
let modified = addBaseToRelativeUrls "" testText
Expect.equal modified testText "The text should not have been modified"
}
test "succeeds with an extra URL path" {
let testText =
"""<a href="/my-link.htm"><img src="/pretty-picture.jpg"></a><a href="https://example.com>link</a>"""
let expected =
"""<a href="/a/b/my-link.htm"><img src="/a/b/pretty-picture.jpg"></a><a href="https://example.com>link</a>"""
Expect.equal (addBaseToRelativeUrls "/a/b" testText) expected "Relative URLs not modified correctly"
}
]
let addBaseToRelativeUrlsTests = testList "PublicHelpers.addBaseToRelativeUrls" [
test "succeeds when there is no extra URL path" {
let testText = """<a href="/somewhere-else.html">Howdy></a>"""
let modified = addBaseToRelativeUrls "" testText
Expect.equal modified testText "The text should not have been modified"
}
test "succeeds with an extra URL path" {
let testText =
"""<a href="/my-link.htm"><img src="/pretty-picture.jpg"></a><a href="https://example.com>link</a>"""
let expected =
"""<a href="/a/b/my-link.htm"><img src="/a/b/pretty-picture.jpg"></a><a href="https://example.com>link</a>"""
Expect.equal (addBaseToRelativeUrls "/a/b" testText) expected "Relative URLs not modified correctly"
}
]
/// Unit tests for the DisplayCustomFeed type
let displayCustomFeedTests =
testList "DisplayCustomFeed.FromFeed" [
test "succeeds for a feed for an existing category" {
let cats =
[| { DisplayCategory.Id = "abc"
Slug = "a-b-c"
Name = "My Lovely Category"
Description = None
ParentNames = [||]
PostCount = 3 } |]
let feed =
{ CustomFeed.Empty with
Id = CustomFeedId "test-feed"
Source = Category (CategoryId "abc")
Path = Permalink "test-feed.xml" }
let model = DisplayCustomFeed.FromFeed cats feed
Expect.equal model.Id "test-feed" "Id not filled properly"
Expect.equal model.Source "Category: My Lovely Category" "Source not filled properly"
Expect.equal model.Path "test-feed.xml" "Path not filled properly"
Expect.isFalse model.IsPodcast "IsPodcast not filled properly"
}
test "succeeds for a feed for a non-existing category" {
let feed =
{ CustomFeed.Empty with
Id = CustomFeedId "bad-feed"
Source = Category (CategoryId "xyz")
Path = Permalink "trouble.xml" }
let model = DisplayCustomFeed.FromFeed [||] feed
Expect.equal model.Id "bad-feed" "Id not filled properly"
Expect.equal model.Source "Category: --INVALID; DELETE THIS FEED--" "Source not filled properly"
Expect.equal model.Path "trouble.xml" "Path not filled properly"
Expect.isFalse model.IsPodcast "IsPodcast not filled properly"
}
test "succeeds for a feed for a tag" {
let feed =
{ Id = CustomFeedId "tag-feed"
Source = Tag "testing"
Path = Permalink "testing-posts.xml"
Podcast = Some PodcastOptions.Empty }
let model = DisplayCustomFeed.FromFeed [||] feed
Expect.equal model.Id "tag-feed" "Id not filled properly"
Expect.equal model.Source "Tag: testing" "Source not filled properly"
Expect.equal model.Path "testing-posts.xml" "Path not filled properly"
Expect.isTrue model.IsPodcast "IsPodcast not filled properly"
}
]
let displayCustomFeedTests = testList "DisplayCustomFeed.FromFeed" [
test "succeeds for a feed for an existing category" {
let cats =
[| { DisplayCategory.Id = "abc"
Slug = "a-b-c"
Name = "My Lovely Category"
Description = None
ParentNames = [||]
PostCount = 3 } |]
let feed =
{ CustomFeed.Empty with
Id = CustomFeedId "test-feed"
Source = Category (CategoryId "abc")
Path = Permalink "test-feed.xml" }
let model = DisplayCustomFeed.FromFeed cats feed
Expect.equal model.Id "test-feed" "Id not filled properly"
Expect.equal model.Source "Category: My Lovely Category" "Source not filled properly"
Expect.equal model.Path "test-feed.xml" "Path not filled properly"
Expect.isFalse model.IsPodcast "IsPodcast not filled properly"
}
test "succeeds for a feed for a non-existing category" {
let feed =
{ CustomFeed.Empty with
Id = CustomFeedId "bad-feed"
Source = Category (CategoryId "xyz")
Path = Permalink "trouble.xml" }
let model = DisplayCustomFeed.FromFeed [||] feed
Expect.equal model.Id "bad-feed" "Id not filled properly"
Expect.equal model.Source "Category: --INVALID; DELETE THIS FEED--" "Source not filled properly"
Expect.equal model.Path "trouble.xml" "Path not filled properly"
Expect.isFalse model.IsPodcast "IsPodcast not filled properly"
}
test "succeeds for a feed for a tag" {
let feed =
{ Id = CustomFeedId "tag-feed"
Source = Tag "testing"
Path = Permalink "testing-posts.xml"
Podcast = Some PodcastOptions.Empty }
let model = DisplayCustomFeed.FromFeed [||] feed
Expect.equal model.Id "tag-feed" "Id not filled properly"
Expect.equal model.Source "Tag: testing" "Source not filled properly"
Expect.equal model.Path "testing-posts.xml" "Path not filled properly"
Expect.isTrue model.IsPodcast "IsPodcast not filled properly"
}
]
/// Unit tests for the DisplayPage type
let displayPageTests =
testList "DisplayPage" [
let page =
{ Page.Empty with
Id = PageId "my-page"
AuthorId = WebLogUserId "jim"
Title = "A Fine Example"
Permalink = Permalink "about/a-fine-example.html"
PublishedOn = Noda.epoch
UpdatedOn = Noda.epoch + Duration.FromHours 1
Text = """<a href="/link.html">Click Me!</a>"""
Metadata = [ { Name = "unit"; Value = "test" } ] }
testList "FromPageMinimal" [
test "succeeds when page is default page" {
let webLog = { WebLog.Empty with TimeZone = "Etc/GMT-1"; DefaultPage = "my-page" }
let model = DisplayPage.FromPageMinimal webLog page
Expect.equal model.Id "my-page" "Id not filled properly"
Expect.equal model.AuthorId "jim" "AuthorId not filled properly"
Expect.equal model.Title "A Fine Example" "Title not filled properly"
Expect.equal model.Permalink "about/a-fine-example.html" "Permalink not filled properly"
Expect.equal
model.PublishedOn
((Noda.epoch + Duration.FromHours 1).ToDateTimeUtc())
"PublishedOn not filled properly"
Expect.equal
model.UpdatedOn
((Noda.epoch + Duration.FromHours 2).ToDateTimeUtc())
"UpdatedOn not filled properly"
Expect.isFalse model.IsInPageList "IsInPageList should not have been set"
Expect.isTrue model.IsDefault "IsDefault should have been set"
Expect.equal model.Text "" "Text should have been blank"
Expect.isEmpty model.Metadata "Metadata should have been empty"
}
test "succeeds when page is not the default page" {
let model = DisplayPage.FromPageMinimal { WebLog.Empty with DefaultPage = "posts" } page
Expect.isFalse model.IsDefault "IsDefault should not have been set"
}
]
testList "FromPage" [
test "succeeds when the web log is on the domain root" {
let webLog = { WebLog.Empty with TimeZone = "Etc/GMT-4"; UrlBase = "https://example.com" }
let model = DisplayPage.FromPage webLog page
Expect.equal model.Id "my-page" "Id not filled properly"
Expect.equal model.AuthorId "jim" "AuthorId not filled properly"
Expect.equal model.Title "A Fine Example" "Title not filled properly"
Expect.equal model.Permalink "about/a-fine-example.html" "Permalink not filled properly"
Expect.equal
model.PublishedOn
((Noda.epoch + Duration.FromHours 4).ToDateTimeUtc())
"PublishedOn not filled properly"
Expect.equal
model.UpdatedOn
((Noda.epoch + Duration.FromHours 5).ToDateTimeUtc())
"UpdatedOn not filled properly"
Expect.isFalse model.IsInPageList "IsInPageList should not have been set"
Expect.isFalse model.IsDefault "IsDefault should not have been set"
Expect.equal model.Text """<a href="/link.html">Click Me!</a>""" "Text not filled properly"
Expect.equal model.Metadata.Length 1 "Metadata not filled properly"
}
test "succeeds when the web log is not on the domain root" {
let model = DisplayPage.FromPage { WebLog.Empty with UrlBase = "https://example.com/a/b/c" } page
Expect.equal model.Text """<a href="/a/b/c/link.html">Click Me!</a>""" "Text not filled properly"
}
]
let displayPageTests = testList "DisplayPage" [
let page =
{ Page.Empty with
Id = PageId "my-page"
AuthorId = WebLogUserId "jim"
Title = "A Fine Example"
Permalink = Permalink "about/a-fine-example.html"
PublishedOn = Noda.epoch
UpdatedOn = Noda.epoch + Duration.FromHours 1
Text = """<a href="/link.html">Click Me!</a>"""
Metadata = [ { Name = "unit"; Value = "test" } ] }
testList "FromPageMinimal" [
test "succeeds when page is default page" {
let webLog = { WebLog.Empty with TimeZone = "Etc/GMT-1"; DefaultPage = "my-page" }
let model = DisplayPage.FromPageMinimal webLog page
Expect.equal model.Id "my-page" "Id not filled properly"
Expect.equal model.AuthorId "jim" "AuthorId not filled properly"
Expect.equal model.Title "A Fine Example" "Title not filled properly"
Expect.equal model.Permalink "about/a-fine-example.html" "Permalink not filled properly"
Expect.equal
model.PublishedOn
((Noda.epoch + Duration.FromHours 1).ToDateTimeUtc())
"PublishedOn not filled properly"
Expect.equal
model.UpdatedOn ((Noda.epoch + Duration.FromHours 2).ToDateTimeUtc()) "UpdatedOn not filled properly"
Expect.isFalse model.IsInPageList "IsInPageList should not have been set"
Expect.isTrue model.IsDefault "IsDefault should have been set"
Expect.equal model.Text "" "Text should have been blank"
Expect.isEmpty model.Metadata "Metadata should have been empty"
}
test "succeeds when page is not the default page" {
let model = DisplayPage.FromPageMinimal { WebLog.Empty with DefaultPage = "posts" } page
Expect.isFalse model.IsDefault "IsDefault should not have been set"
}
]
testList "FromPage" [
test "succeeds when the web log is on the domain root" {
let webLog = { WebLog.Empty with TimeZone = "Etc/GMT-4"; UrlBase = "https://example.com" }
let model = DisplayPage.FromPage webLog page
Expect.equal model.Id "my-page" "Id not filled properly"
Expect.equal model.AuthorId "jim" "AuthorId not filled properly"
Expect.equal model.Title "A Fine Example" "Title not filled properly"
Expect.equal model.Permalink "about/a-fine-example.html" "Permalink not filled properly"
Expect.equal
model.PublishedOn
((Noda.epoch + Duration.FromHours 4).ToDateTimeUtc())
"PublishedOn not filled properly"
Expect.equal
model.UpdatedOn
((Noda.epoch + Duration.FromHours 5).ToDateTimeUtc())
"UpdatedOn not filled properly"
Expect.isFalse model.IsInPageList "IsInPageList should not have been set"
Expect.isFalse model.IsDefault "IsDefault should not have been set"
Expect.equal model.Text """<a href="/link.html">Click Me!</a>""" "Text not filled properly"
Expect.equal model.Metadata.Length 1 "Metadata not filled properly"
}
test "succeeds when the web log is not on the domain root" {
let model = DisplayPage.FromPage { WebLog.Empty with UrlBase = "https://example.com/a/b/c" } page
Expect.equal model.Text """<a href="/a/b/c/link.html">Click Me!</a>""" "Text not filled properly"
}
]
]
/// Unit tests for the DisplayRevision type
let displayRevisionTests =
test "DisplayRevision.FromRevision succeeds" {
let model =
DisplayRevision.FromRevision
{ WebLog.Empty with TimeZone = "Etc/GMT+1" }
{ Text = Html "howdy"; AsOf = Noda.epoch }
Expect.equal model.AsOf (Noda.epoch.ToDateTimeUtc()) "AsOf not filled properly"
Expect.equal
model.AsOfLocal ((Noda.epoch - Duration.FromHours 1).ToDateTimeUtc()) "AsOfLocal not filled properly"
Expect.equal model.Format "HTML" "Format not filled properly"
}
let displayRevisionTests = test "DisplayRevision.FromRevision succeeds" {
let model =
DisplayRevision.FromRevision
{ WebLog.Empty with TimeZone = "Etc/GMT+1" }
{ Text = Html "howdy"; AsOf = Noda.epoch }
Expect.equal model.AsOf (Noda.epoch.ToDateTimeUtc()) "AsOf not filled properly"
Expect.equal model.AsOfLocal ((Noda.epoch - Duration.FromHours 1).ToDateTimeUtc()) "AsOfLocal not filled properly"
Expect.equal model.Format "HTML" "Format not filled properly"
}
open System.IO
/// Unit tests for the DisplayTheme type
let displayThemeTests =
testList "DisplayTheme.FromTheme" [
let theme =
{ Id = ThemeId "the-theme"
Name = "Test Theme"
Version = "v0.1.2"
Templates = [ ThemeTemplate.Empty; ThemeTemplate.Empty ] }
test "succeeds when theme is in use and not on disk" {
let model =
DisplayTheme.FromTheme
(fun it -> Expect.equal it (ThemeId "the-theme") "The theme ID not passed correctly"; true) theme
Expect.equal model.Id "the-theme" "Id not filled properly"
Expect.equal model.Name "Test Theme" "Name not filled properly"
Expect.equal model.Version "v0.1.2" "Version not filled properly"
Expect.equal model.TemplateCount 2 "TemplateCount not filled properly"
Expect.isTrue model.IsInUse "IsInUse should have been set"
Expect.isFalse model.IsOnDisk "IsOnDisk should not have been set"
}
test "succeeds when the theme is not in use as is on disk" {
let file = File.Create "another-theme.zip"
try
let model = DisplayTheme.FromTheme (fun _ -> false) { theme with Id = ThemeId "another" }
Expect.isFalse model.IsInUse "IsInUse should not have been set"
Expect.isTrue model.IsOnDisk "IsOnDisk should have been set"
finally
file.Close()
file.Dispose()
File.Delete "another-theme.zip"
}
]
let displayThemeTests = testList "DisplayTheme.FromTheme" [
let theme =
{ Id = ThemeId "the-theme"
Name = "Test Theme"
Version = "v0.1.2"
Templates = [ ThemeTemplate.Empty; ThemeTemplate.Empty ] }
test "succeeds when theme is in use and not on disk" {
let model =
DisplayTheme.FromTheme
(fun it -> Expect.equal it (ThemeId "the-theme") "The theme ID not passed correctly"; true) theme
Expect.equal model.Id "the-theme" "Id not filled properly"
Expect.equal model.Name "Test Theme" "Name not filled properly"
Expect.equal model.Version "v0.1.2" "Version not filled properly"
Expect.equal model.TemplateCount 2 "TemplateCount not filled properly"
Expect.isTrue model.IsInUse "IsInUse should have been set"
Expect.isFalse model.IsOnDisk "IsOnDisk should not have been set"
}
test "succeeds when the theme is not in use as is on disk" {
let file = File.Create "another-theme.zip"
try
let model = DisplayTheme.FromTheme (fun _ -> false) { theme with Id = ThemeId "another" }
Expect.isFalse model.IsInUse "IsInUse should not have been set"
Expect.isTrue model.IsOnDisk "IsOnDisk should have been set"
finally
file.Close()
file.Dispose()
File.Delete "another-theme.zip"
}
]
/// Unit tests for the DisplayUpload type
let displayUploadTests =
test "DisplayUpload.FromUpload succeeds" {
let upload =
{ Upload.Empty with
Id = UploadId "test-up"
Path = Permalink "2022/04/my-pic.jpg"
UpdatedOn = Noda.epoch }
let model = DisplayUpload.FromUpload { WebLog.Empty with TimeZone = "Etc/GMT-1" } Database upload
Expect.equal model.Id "test-up" "Id not filled properly"
Expect.equal model.Name "my-pic.jpg" "Name not filled properly"
Expect.equal model.Path "2022/04/" "Path not filled properly"
Expect.equal model.Source "Database" "Source not filled properly"
Expect.isSome model.UpdatedOn "There should have been an UpdatedOn value"
Expect.equal
model.UpdatedOn.Value ((Noda.epoch + Duration.FromHours 1).ToDateTimeUtc()) "UpdatedOn not filled properly"
}
let displayUploadTests = test "DisplayUpload.FromUpload succeeds" {
let upload =
{ Upload.Empty with
Id = UploadId "test-up"
Path = Permalink "2022/04/my-pic.jpg"
UpdatedOn = Noda.epoch }
let model = DisplayUpload.FromUpload { WebLog.Empty with TimeZone = "Etc/GMT-1" } Database upload
Expect.equal model.Id "test-up" "Id not filled properly"
Expect.equal model.Name "my-pic.jpg" "Name not filled properly"
Expect.equal model.Path "2022/04/" "Path not filled properly"
Expect.equal model.Source "Database" "Source not filled properly"
Expect.isSome model.UpdatedOn "There should have been an UpdatedOn value"
Expect.equal
model.UpdatedOn.Value ((Noda.epoch + Duration.FromHours 1).ToDateTimeUtc()) "UpdatedOn not filled properly"
}
/// Unit tests for the DisplayUser type
let displayUserTests =
testList "DisplayUser.FromUser" [
let displayUserTests = testList "DisplayUser.FromUser" [
let minimalUser =
{ WebLogUser.Empty with
Id = WebLogUserId "test-user"
@ -246,47 +236,234 @@ let displayUserTests =
]
/// Unit tests for the EditCategoryModel type
let editCategoryModelTests =
testList "EditCategoryModel" [
testList "FromCategory" [
let minimalCat = { Category.Empty with Id = CategoryId "test-cat"; Name = "test"; Slug = "test-slug" }
test "succeeds with minimal information" {
let model = EditCategoryModel.FromCategory minimalCat
Expect.equal model.CategoryId "test-cat" "CategoryId not filled properly"
Expect.equal model.Name "test" "Name not filled properly"
Expect.equal model.Slug "test-slug" "Slug not filled properly"
Expect.equal model.Description "" "Description not filled properly"
Expect.equal model.ParentId "" "ParentId not filled properly"
}
test "succeeds with complete information" {
let model =
EditCategoryModel.FromCategory
{ minimalCat with Description = Some "Testing"; ParentId = Some (CategoryId "parent") }
Expect.equal model.Description "Testing" "Description not filled properly"
Expect.equal model.ParentId "parent" "ParentId not filled properly"
}
]
testList "IsNew" [
test "succeeds for a new category" {
let model = EditCategoryModel.FromCategory { Category.Empty with Id = CategoryId "new" }
Expect.isTrue model.IsNew "Category should have been considered new"
}
test "succeeds for a non-new category" {
let model = EditCategoryModel.FromCategory Category.Empty
Expect.isFalse model.IsNew "Category should not have been considered new"
}
]
let editCategoryModelTests = testList "EditCategoryModel" [
testList "FromCategory" [
let minimalCat = { Category.Empty with Id = CategoryId "test-cat"; Name = "test"; Slug = "test-slug" }
test "succeeds with minimal information" {
let model = EditCategoryModel.FromCategory minimalCat
Expect.equal model.CategoryId "test-cat" "CategoryId not filled properly"
Expect.equal model.Name "test" "Name not filled properly"
Expect.equal model.Slug "test-slug" "Slug not filled properly"
Expect.equal model.Description "" "Description not filled properly"
Expect.equal model.ParentId "" "ParentId not filled properly"
}
test "succeeds with complete information" {
let model =
EditCategoryModel.FromCategory
{ minimalCat with Description = Some "Testing"; ParentId = Some (CategoryId "parent") }
Expect.equal model.Description "Testing" "Description not filled properly"
Expect.equal model.ParentId "parent" "ParentId not filled properly"
}
]
testList "IsNew" [
test "succeeds for a new category" {
let model = EditCategoryModel.FromCategory { Category.Empty with Id = CategoryId "new" }
Expect.isTrue model.IsNew "Category should have been considered new"
}
test "succeeds for a non-new category" {
let model = EditCategoryModel.FromCategory Category.Empty
Expect.isFalse model.IsNew "Category should not have been considered new"
}
]
]
/// All tests for the Domain namespace
let all =
testList
"ViewModels"
[ addBaseToRelativeUrlsTests
displayCustomFeedTests
displayPageTests
displayRevisionTests
displayThemeTests
displayUploadTests
displayUserTests
editCategoryModelTests ]
/// Unit tests for the EditCustomFeedModel type
let editCustomFeedModelTests = testList "EditCustomFeedModel" [
let minimalPodcast =
{ PodcastOptions.Empty with
Title = "My Minimal Podcast"
Summary = "As little as possible"
DisplayedAuthor = "The Tester"
Email = "thetester@example.com"
ImageUrl = Permalink "upload/my-image.png"
AppleCategory = "News"
Explicit = Clean }
// A GUID with all zeroes, ending in "a"
let aGuid =
let guidBytes = Guid.Empty.ToByteArray()
guidBytes[15] <- byte 10
Guid guidBytes
let fullPodcast =
{ minimalPodcast with
Subtitle = Some "A Podcast about Little"
ItemsInFeed = 17
AppleSubcategory = Some "Analysis"
DefaultMediaType = Some "video/mpeg4"
MediaBaseUrl = Some "a/b/c"
PodcastGuid = Some aGuid
FundingUrl = Some "https://pay.me"
FundingText = Some "Gimme Money!"
Medium = Some Newsletter }
testList "FromFeed" [
test "succeeds with no podcast" {
let model =
EditCustomFeedModel.FromFeed
{ Id = CustomFeedId "test-feed"
Source = Category (CategoryId "no-podcast")
Path = Permalink "no-podcast.xml"
Podcast = None }
Expect.equal model.Id "test-feed" "Id not filled properly"
Expect.equal model.SourceType "category" "SourceType not filled properly"
Expect.equal model.SourceValue "no-podcast" "SourceValue not filled properly"
Expect.equal model.Path "no-podcast.xml" "Path not filled properly"
Expect.isFalse model.IsPodcast "IsPodcast should not have been set"
Expect.equal model.Title "" "Title should be the default value"
Expect.equal model.Subtitle "" "Subtitle should be the default value"
Expect.equal model.ItemsInFeed 25 "ItemsInFeed should be the default value"
Expect.equal model.Summary "" "Summary should be the default value"
Expect.equal model.DisplayedAuthor "" "DisplayedAuthor should be the default value"
Expect.equal model.Email "" "Email should be the default value"
Expect.equal model.ImageUrl "" "ImageUrl should be the default value"
Expect.equal model.AppleCategory "" "AppleCategory should be the default value"
Expect.equal model.AppleSubcategory "" "AppleSubcategory should be the default value"
Expect.equal model.Explicit "no" "Explicit should be the default value"
Expect.equal model.DefaultMediaType "audio/mpeg" "DefaultMediaType should be the default value"
Expect.equal model.MediaBaseUrl "" "MediaBaseUrl should be the default value"
Expect.equal model.FundingUrl "" "FundingUrl should be the default value"
Expect.equal model.FundingText "" "FundingText should be the default value"
Expect.equal model.PodcastGuid "" "PodcastGuid should be the default value"
Expect.equal model.Medium "" "Medium should be the default value"
}
test "succeeds with minimal podcast" {
let model =
EditCustomFeedModel.FromFeed
{ Id = CustomFeedId "minimal-feed"
Source = Tag "min-podcast"
Path = Permalink "min-podcast.xml"
Podcast = Some minimalPodcast }
Expect.equal model.Id "minimal-feed" "Id not filled properly"
Expect.equal model.SourceType "tag" "SourceType not filled properly"
Expect.equal model.SourceValue "min-podcast" "SourceValue not filled properly"
Expect.equal model.Path "min-podcast.xml" "Path not filled properly"
Expect.isTrue model.IsPodcast "IsPodcast should have been set"
Expect.equal model.Title "My Minimal Podcast" "Title not filled properly"
Expect.equal model.Subtitle "" "Subtitle not filled properly (should be blank)"
Expect.equal model.ItemsInFeed 0 "ItemsInFeed not filled properly"
Expect.equal model.Summary "As little as possible" "Summary not filled properly"
Expect.equal model.DisplayedAuthor "The Tester" "DisplayedAuthor not filled properly"
Expect.equal model.Email "thetester@example.com" "Email not filled properly"
Expect.equal model.ImageUrl "upload/my-image.png" "ImageUrl not filled properly"
Expect.equal model.AppleCategory "News" "AppleCategory not filled properly"
Expect.equal model.AppleSubcategory "" "AppleSubcategory not filled properly (should be blank)"
Expect.equal model.Explicit "clean" "Explicit not filled properly"
Expect.equal model.DefaultMediaType "" "DefaultMediaType not filled properly (should be blank)"
Expect.equal model.MediaBaseUrl "" "MediaBaseUrl not filled properly (should be blank)"
Expect.equal model.FundingUrl "" "FundingUrl not filled properly (should be blank)"
Expect.equal model.FundingText "" "FundingText not filled properly (should be blank)"
Expect.equal model.PodcastGuid "" "PodcastGuid not filled properly (should be blank)"
Expect.equal model.Medium "" "Medium not filled properly (should be blank)"
}
test "succeeds with full podcast" {
let model =
EditCustomFeedModel.FromFeed
{ Id = CustomFeedId "full-feed"
Source = Tag "whole-enchilada"
Path = Permalink "full-podcast.xml"
Podcast = Some fullPodcast }
Expect.equal model.Id "full-feed" "Id not filled properly"
Expect.equal model.SourceType "tag" "SourceType not filled properly"
Expect.equal model.SourceValue "whole-enchilada" "SourceValue not filled properly"
Expect.equal model.Path "full-podcast.xml" "Path not filled properly"
Expect.isTrue model.IsPodcast "IsPodcast should have been set"
Expect.equal model.Title "My Minimal Podcast" "Title not filled properly"
Expect.equal model.Subtitle "A Podcast about Little" "Subtitle not filled properly"
Expect.equal model.ItemsInFeed 17 "ItemsInFeed not filled properly"
Expect.equal model.Summary "As little as possible" "Summary not filled properly"
Expect.equal model.DisplayedAuthor "The Tester" "DisplayedAuthor not filled properly"
Expect.equal model.Email "thetester@example.com" "Email not filled properly"
Expect.equal model.ImageUrl "upload/my-image.png" "ImageUrl not filled properly"
Expect.equal model.AppleCategory "News" "AppleCategory not filled properly"
Expect.equal model.AppleSubcategory "Analysis" "AppleSubcategory not filled properly"
Expect.equal model.Explicit "clean" "Explicit not filled properly"
Expect.equal model.DefaultMediaType "video/mpeg4" "DefaultMediaType not filled properly"
Expect.equal model.MediaBaseUrl "a/b/c" "MediaBaseUrl not filled properly"
Expect.equal model.FundingUrl "https://pay.me" "FundingUrl not filled properly"
Expect.equal model.FundingText "Gimme Money!" "FundingText not filled properly"
Expect.equal model.PodcastGuid "00000000-0000-0000-0000-00000000000a" "PodcastGuid not filled properly"
Expect.equal model.Medium "newsletter" "Medium not filled properly"
}
]
testList "UpdateFeed" [
test "succeeds with no podcast" {
let model =
{ EditCustomFeedModel.Empty with SourceType = "tag"; SourceValue = "no-audio"; Path = "no-podcast.xml" }
let feed =
model.UpdateFeed
{ CustomFeed.Empty with Id = CustomFeedId "no-podcast-feed"; Podcast = Some fullPodcast }
Expect.equal feed.Id (CustomFeedId "no-podcast-feed") "Id not filled properly"
Expect.equal feed.Source (Tag "no-audio") "Source not filled properly"
Expect.equal feed.Path (Permalink "no-podcast.xml") "Path not filled properly"
Expect.isNone feed.Podcast "Podcast not filled properly"
}
test "succeeds with minimal podcast" {
let model = EditCustomFeedModel.FromFeed { CustomFeed.Empty with Podcast = Some minimalPodcast }
let feed = model.UpdateFeed CustomFeed.Empty
Expect.equal feed.Source (Category (CategoryId "")) "Source not filled properly"
Expect.equal feed.Path (Permalink "") "Path not filled properly"
Expect.isSome feed.Podcast "Podcast should be present"
let podcast = feed.Podcast.Value
Expect.equal podcast.Title "My Minimal Podcast" "Podcast title not filled properly"
Expect.isNone podcast.Subtitle "Podcast subtitle not filled properly"
Expect.equal podcast.ItemsInFeed 0 "Podcast items in feed not filled properly"
Expect.equal podcast.Summary "As little as possible" "Podcast summary not filled properly"
Expect.equal podcast.DisplayedAuthor "The Tester" "Podcast author not filled properly"
Expect.equal podcast.Email "thetester@example.com" "Podcast email not filled properly"
Expect.equal podcast.Explicit Clean "Podcast explicit rating not filled properly"
Expect.equal podcast.AppleCategory "News" "Podcast Apple category not filled properly"
Expect.isNone podcast.AppleSubcategory "Podcast Apple subcategory not filled properly"
Expect.isNone podcast.DefaultMediaType "Podcast default media type not filled properly"
Expect.isNone podcast.MediaBaseUrl "Podcast media base URL not filled properly"
Expect.isNone podcast.PodcastGuid "Podcast GUID not filled properly"
Expect.isNone podcast.FundingUrl "Podcast funding URL not filled properly"
Expect.isNone podcast.FundingText "Podcast funding text not filled properly"
Expect.isNone podcast.Medium "Podcast medium not filled properly"
}
test "succeeds with full podcast" {
let model = EditCustomFeedModel.FromFeed { CustomFeed.Empty with Podcast = Some fullPodcast }
let feed = model.UpdateFeed CustomFeed.Empty
Expect.equal feed.Source (Category (CategoryId "")) "Source not filled properly"
Expect.equal feed.Path (Permalink "") "Path not filled properly"
Expect.isSome feed.Podcast "Podcast should be present"
let podcast = feed.Podcast.Value
Expect.equal podcast.Title "My Minimal Podcast" "Podcast title not filled properly"
Expect.equal podcast.Subtitle (Some "A Podcast about Little") "Podcast subtitle not filled properly"
Expect.equal podcast.ItemsInFeed 17 "Podcast items in feed not filled properly"
Expect.equal podcast.Summary "As little as possible" "Podcast summary not filled properly"
Expect.equal podcast.DisplayedAuthor "The Tester" "Podcast author not filled properly"
Expect.equal podcast.Email "thetester@example.com" "Podcast email not filled properly"
Expect.equal podcast.Explicit Clean "Podcast explicit rating not filled properly"
Expect.equal podcast.AppleCategory "News" "Podcast Apple category not filled properly"
Expect.equal podcast.AppleSubcategory (Some "Analysis") "Podcast Apple subcategory not filled properly"
Expect.equal podcast.DefaultMediaType (Some "video/mpeg4") "Podcast default media type not filled properly"
Expect.equal podcast.MediaBaseUrl (Some "a/b/c") "Podcast media base URL not filled properly"
Expect.equal podcast.PodcastGuid (Some aGuid) "Podcast GUID not filled properly"
Expect.equal podcast.FundingUrl (Some "https://pay.me") "Podcast funding URL not filled properly"
Expect.equal podcast.FundingText (Some "Gimme Money!") "Podcast funding text not filled properly"
Expect.equal podcast.Medium (Some Newsletter) "Podcast medium not filled properly"
}
]
]
/// Unit tests for the EditMyInfoModel type
let editMyInfoModelTests = test "EditMyInfoModel.FromUser succeeds" {
let model = EditMyInfoModel.FromUser { WebLogUser.Empty with FirstName = "A"; LastName = "B"; PreferredName = "C" }
Expect.equal model.FirstName "A" "FirstName not filled properly"
Expect.equal model.LastName "B" "LastName not filled properly"
Expect.equal model.PreferredName "C" "PreferredName not filled properly"
Expect.equal model.NewPassword "" "NewPassword not filled properly"
Expect.equal model.NewPasswordConfirm "" "NewPasswordConfirm not filled properly"
}
/// All tests in the Domain.ViewModels file
let all = testList "ViewModels" [
addBaseToRelativeUrlsTests
displayCustomFeedTests
displayPageTests
displayRevisionTests
displayThemeTests
displayUploadTests
displayUserTests
editCategoryModelTests
editCustomFeedModelTests
editMyInfoModelTests
]