From 29167eca6c74d05b77ec35bda2fa074c9eff9acf Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Wed, 10 Jan 2024 22:11:48 -0500 Subject: [PATCH] Add podcast/user edit model tests - Reformat test lists to save an indent --- src/MyWebLog.Tests/DataTypesTests.fs | 151 +++-- src/MyWebLog.Tests/Program.fs | 7 +- src/MyWebLog.Tests/SupportTypesTests.fs | 813 ++++++++++++------------ src/MyWebLog.Tests/ViewModelsTests.fs | 629 +++++++++++------- 4 files changed, 878 insertions(+), 722 deletions(-) diff --git a/src/MyWebLog.Tests/DataTypesTests.fs b/src/MyWebLog.Tests/DataTypesTests.fs index 0a5f904..8d04321 100644 --- a/src/MyWebLog.Tests/DataTypesTests.fs +++ b/src/MyWebLog.Tests/DataTypesTests.fs @@ -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 ] diff --git a/src/MyWebLog.Tests/Program.fs b/src/MyWebLog.Tests/Program.fs index e7d56ba..5755a72 100644 --- a/src/MyWebLog.Tests/Program.fs +++ b/src/MyWebLog.Tests/Program.fs @@ -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 ] +] [] let main args = runTestsWithCLIArgs [] args allTests diff --git a/src/MyWebLog.Tests/SupportTypesTests.fs b/src/MyWebLog.Tests/SupportTypesTests.fs index 09c1fc4..b68494b 100644 --- a/src/MyWebLog.Tests/SupportTypesTests.fs +++ b/src/MyWebLog.Tests/SupportTypesTests.fs @@ -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 - (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 - (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 - (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:

howdy

" - match txt with - | Html it when it = "

howdy

" -> () - | _ -> 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 - (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:

HTML

")) - "HTML:

HTML

" - "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:

The Heading

").AsHtml()) - "

The Heading

" - "HTML value incorrect" - } - test "succeeds for Markdown" { - Expect.equal - ((MarkupText.Parse "Markdown: *emphasis*").AsHtml()) - "

emphasis

\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 - (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 - (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 - (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 - (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 + (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 + (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 + (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:

howdy

" + match txt with + | Html it when it = "

howdy

" -> () + | _ -> 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 + (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:

HTML

")) "HTML:

HTML

" "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:

The Heading

").AsHtml()) "

The Heading

" "HTML value incorrect" + } + test "succeeds for Markdown" { + Expect.equal + ((MarkupText.Parse "Markdown: *emphasis*").AsHtml()) + "

emphasis

\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 + (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 + (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 + (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 + (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 - (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 + (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 +] diff --git a/src/MyWebLog.Tests/ViewModelsTests.fs b/src/MyWebLog.Tests/ViewModelsTests.fs index bddae3c..e5c48fd 100644 --- a/src/MyWebLog.Tests/ViewModelsTests.fs +++ b/src/MyWebLog.Tests/ViewModelsTests.fs @@ -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 = """Howdy>""" - let modified = addBaseToRelativeUrls "" testText - Expect.equal modified testText "The text should not have been modified" - } - test "succeeds with an extra URL path" { - let testText = - """Howdy>""" + let modified = addBaseToRelativeUrls "" testText + Expect.equal modified testText "The text should not have been modified" + } + test "succeeds with an extra URL path" { + let testText = + """Click Me!""" - 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 """Click Me!""" "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 """Click Me!""" "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 = """Click Me!""" + 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 """Click Me!""" "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 """Click Me!""" "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 +]