diff --git a/src/MyWebLog.Domain/SupportTypes.fs b/src/MyWebLog.Domain/SupportTypes.fs
index c424dad..3d78e61 100644
--- a/src/MyWebLog.Domain/SupportTypes.fs
+++ b/src/MyWebLog.Domain/SupportTypes.fs
@@ -660,7 +660,10 @@ type ThemeAssetId =
/// Convert a string into a theme asset ID
static member Parse(it : string) =
let themeIdx = it.IndexOf "/"
- ThemeAssetId(ThemeId it[..(themeIdx - 1)], it[(themeIdx + 1)..])
+ if themeIdx < 0 then
+ invalidArg "id" $"Invalid format; expected [theme_id]/[asset_id] (received {it})"
+ else
+ ThemeAssetId(ThemeId it[..(themeIdx - 1)], it[(themeIdx + 1)..])
/// Convert a theme asset ID into a path string
override this.ToString() =
diff --git a/src/MyWebLog.Tests/Domain.fs b/src/MyWebLog.Tests/Domain.fs
index b97a0e4..afdef76 100644
--- a/src/MyWebLog.Tests/Domain.fs
+++ b/src/MyWebLog.Tests/Domain.fs
@@ -176,6 +176,245 @@ let explicitRatingTests =
]
]
+/// 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") Database "\"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 namespace
let all =
testList
@@ -183,4 +422,11 @@ let all =
[ nodaTests
accessLevelTests
commentStatusTests
- explicitRatingTests ]
+ explicitRatingTests
+ episodeTests
+ markupTextTests
+ podcastMediumTests
+ postStatusTests
+ customFeedSourceTests
+ themeAssetIdTests
+ uploadDestinationTests ]