From b1a0c207fbf1b2f57028e1abc0bc02a6eebf712d Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Sat, 3 Feb 2024 14:01:13 -0500 Subject: [PATCH] Add theme tests - Add flags to isolate data impl tests - Make most non-tests private - Add SQLite tests missed in initial development --- .../Postgres/PostgresThemeData.fs | 4 +- src/MyWebLog.Data/RethinkDbData.fs | 64 +++++---- src/MyWebLog.Data/SQLite/SQLitePageData.fs | 8 +- src/MyWebLog.Tests/Data/CategoryDataTests.fs | 2 +- src/MyWebLog.Tests/Data/PageDataTests.fs | 8 +- src/MyWebLog.Tests/Data/PostDataTests.fs | 24 ++-- src/MyWebLog.Tests/Data/PostgresDataTests.fs | 47 +++++++ src/MyWebLog.Tests/Data/RethinkDbDataTests.fs | 47 +++++++ src/MyWebLog.Tests/Data/SQLiteDataTests.fs | 81 ++++++++++++ src/MyWebLog.Tests/Data/TagMapDataTests.fs | 6 +- src/MyWebLog.Tests/Data/ThemeDataTests.fs | 121 ++++++++++++++++++ src/MyWebLog.Tests/MyWebLog.Tests.fsproj | 1 + src/MyWebLog.Tests/Program.fs | 24 +++- 13 files changed, 373 insertions(+), 64 deletions(-) create mode 100644 src/MyWebLog.Tests/Data/ThemeDataTests.fs diff --git a/src/MyWebLog.Data/Postgres/PostgresThemeData.fs b/src/MyWebLog.Data/Postgres/PostgresThemeData.fs index bb7d67d..1f4d089 100644 --- a/src/MyWebLog.Data/Postgres/PostgresThemeData.fs +++ b/src/MyWebLog.Data/Postgres/PostgresThemeData.fs @@ -18,7 +18,9 @@ type PostgresThemeData(log: ILogger) = let all () = log.LogTrace "Theme.all" Custom.list - $"{Query.selectFromTable Table.Theme} WHERE data ->> '{nameof Theme.Empty.Id}' <> 'admin' ORDER BY id" + $"{Query.selectFromTable Table.Theme} + WHERE data ->> '{nameof Theme.Empty.Id}' <> 'admin' + ORDER BY data ->> '{nameof Theme.Empty.Id}'" [] withoutTemplateText diff --git a/src/MyWebLog.Data/RethinkDbData.fs b/src/MyWebLog.Data/RethinkDbData.fs index fe46841..295f830 100644 --- a/src/MyWebLog.Data/RethinkDbData.fs +++ b/src/MyWebLog.Data/RethinkDbData.fs @@ -101,7 +101,7 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger 0UL } - member _.FindById pageId webLogId = backgroundTask { - let! page = - rethink { - withTable Table.Page - getAll [ pageId ] - without [ nameof Page.Empty.PriorPermalinks; nameof Page.Empty.Revisions ] - result; withRetryDefault - } - |> tryFirst <| conn - return - page - |> Option.filter (fun pg -> pg.WebLogId = webLogId) - |> Option.map (fun pg -> { pg with Revisions = []; PriorPermalinks = [] }) - } + member _.FindById pageId webLogId = + rethink { + withTable Table.Page + getAll [ pageId ] + filter (nameof Page.Empty.WebLogId) webLogId + merge (r.HashMap(nameof Page.Empty.PriorPermalinks, [||]) + .With(nameof Page.Empty.Revisions, [||])) + result; withRetryDefault + } + |> tryFirst <| conn member _.FindByPermalink permalink webLogId = rethink { @@ -590,20 +586,16 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger 0UL } - member _.FindById postId webLogId = backgroundTask { - let! post = - rethink { - withTable Table.Post - getAll [ postId ] - without [ nameof Post.Empty.PriorPermalinks; nameof Post.Empty.Revisions ] - result; withRetryDefault - } - |> tryFirst <| conn - return - post - |> Option.filter (fun p -> p.WebLogId = webLogId) - |> Option.map (fun p -> { p with Revisions = []; PriorPermalinks = [] }) - } + member _.FindById postId webLogId = + rethink { + withTable Table.Post + getAll [ postId ] + filter (nameof Post.Empty.WebLogId) webLogId + merge (r.HashMap(nameof Post.Empty.PriorPermalinks, [||]) + .With(nameof Post.Empty.Revisions, [||])) + result; withRetryDefault + } + |> tryFirst <| conn member _.FindByPermalink permalink webLogId = rethink { @@ -848,12 +840,14 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger { - withTable Table.Theme - get themeId - merge withoutTemplateText - resultOption; withRetryOptionDefault conn - } + member _.FindByIdWithoutText themeId = + rethink { + withTable Table.Theme + getAll [ themeId ] + merge withoutTemplateText + result; withRetryDefault + } + |> tryFirst <| conn member this.Delete themeId = backgroundTask { match! this.FindByIdWithoutText themeId with diff --git a/src/MyWebLog.Data/SQLite/SQLitePageData.fs b/src/MyWebLog.Data/SQLite/SQLitePageData.fs index e2561fc..17af376 100644 --- a/src/MyWebLog.Data/SQLite/SQLitePageData.fs +++ b/src/MyWebLog.Data/SQLite/SQLitePageData.fs @@ -29,6 +29,10 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) = return { page with Revisions = revisions } } + /// Create a page with no prior permalinks + let pageWithoutLinks rdr = + { fromData rdr with PriorPermalinks = [] } + /// Update a page's revisions let updatePageRevisions (pageId: PageId) oldRevs newRevs = log.LogTrace "Page.updatePageRevisions" @@ -102,7 +106,7 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) = conn.customSingle $"""{Document.Query.selectByWebLog Table.Page} AND {Query.whereByField linkParam "@link"}""" (addFieldParam "@link" linkParam [ webLogParam webLogId ]) - (fun rdr -> { fromData rdr with PriorPermalinks = [] }) + pageWithoutLinks /// Find the current permalink within a set of potential prior permalinks for the given web log let findCurrentPermalink (permalinks: Permalink list) webLogId = @@ -138,7 +142,7 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) = conn.customList $"{Document.Query.selectByWebLog Table.Page} ORDER BY LOWER({titleField}) LIMIT @pageSize OFFSET @toSkip" [ webLogParam webLogId; SqliteParameter("@pageSize", 26); SqliteParameter("@toSkip", (pageNbr - 1) * 25) ] - fromData + (fun rdr -> { pageWithoutLinks rdr with Metadata = [] }) /// Update a page let update (page: Page) = backgroundTask { diff --git a/src/MyWebLog.Tests/Data/CategoryDataTests.fs b/src/MyWebLog.Tests/Data/CategoryDataTests.fs index b1233cd..d09fafe 100644 --- a/src/MyWebLog.Tests/Data/CategoryDataTests.fs +++ b/src/MyWebLog.Tests/Data/CategoryDataTests.fs @@ -11,7 +11,7 @@ open MyWebLog.Data let rootId = WebLogId "uSitJEuD3UyzWC9jgOHc8g" /// The ID of the Favorites category -let favoritesId = CategoryId "S5JflPsJ9EG7gA2LD4m92A" +let private favoritesId = CategoryId "S5JflPsJ9EG7gA2LD4m92A" let ``Add succeeds`` (data: IData) = task { let category = diff --git a/src/MyWebLog.Tests/Data/PageDataTests.fs b/src/MyWebLog.Tests/Data/PageDataTests.fs index 8a2a95d..b8e5370 100644 --- a/src/MyWebLog.Tests/Data/PageDataTests.fs +++ b/src/MyWebLog.Tests/Data/PageDataTests.fs @@ -10,16 +10,16 @@ open MyWebLog.Data open NodaTime /// The ID of the root web log -let rootId = WebLogId "uSitJEuD3UyzWC9jgOHc8g" +let private rootId = CategoryDataTests.rootId /// The ID of the "A cool page" page -let coolPageId = PageId "hgc_BLEZ50SoAWLuPNISvA" +let private coolPageId = PageId "hgc_BLEZ50SoAWLuPNISvA" /// The published and updated time of the "A cool page" page -let coolPagePublished = Instant.FromDateTimeOffset(DateTimeOffset.Parse "2024-01-20T22:14:28Z") +let private coolPagePublished = Instant.FromDateTimeOffset(DateTimeOffset.Parse "2024-01-20T22:14:28Z") /// The ID of the "Yet Another Page" page -let otherPageId = PageId "KouRjvSmm0Wz6TMD8xf67A" +let private otherPageId = PageId "KouRjvSmm0Wz6TMD8xf67A" let ``Add succeeds`` (data: IData) = task { let page = diff --git a/src/MyWebLog.Tests/Data/PostDataTests.fs b/src/MyWebLog.Tests/Data/PostDataTests.fs index ecf63c8..416327d 100644 --- a/src/MyWebLog.Tests/Data/PostDataTests.fs +++ b/src/MyWebLog.Tests/Data/PostDataTests.fs @@ -10,41 +10,41 @@ open MyWebLog.Data open NodaTime /// The ID of the root web log -let rootId = WebLogId "uSitJEuD3UyzWC9jgOHc8g" +let private rootId = CategoryDataTests.rootId /// The ID of podcast episode 1 -let episode1 = PostId "osxMfWGlAkyugUbJ1-xD1g" +let private episode1 = PostId "osxMfWGlAkyugUbJ1-xD1g" /// The published instant for episode 1 -let episode1Published = Instant.FromDateTimeOffset(DateTimeOffset.Parse "2024-01-20T22:24:01Z") +let private episode1Published = Instant.FromDateTimeOffset(DateTimeOffset.Parse "2024-01-20T22:24:01Z") /// The ID of podcast episode 2 -let episode2 = PostId "l4_Eh4aFO06SqqJjOymNzA" +let private episode2 = PostId "l4_Eh4aFO06SqqJjOymNzA" /// The ID of "Something May Happen" post -let something = PostId "QweKbWQiOkqqrjEdgP9wwg" +let private something = PostId "QweKbWQiOkqqrjEdgP9wwg" /// The published instant for "Something May Happen" post -let somethingPublished = Instant.FromDateTimeOffset(DateTimeOffset.Parse "2024-01-20T22:32:59Z") +let private somethingPublished = Instant.FromDateTimeOffset(DateTimeOffset.Parse "2024-01-20T22:32:59Z") /// The ID of "An Incomplete Thought" post -let incomplete = PostId "VweKbWQiOkqqrjEdgP9wwg" +let private incomplete = PostId "VweKbWQiOkqqrjEdgP9wwg" /// The ID of "Test Post 1" post -let testPost1 = PostId "RCsCU2puYEmkpzotoi8p4g" +let private testPost1 = PostId "RCsCU2puYEmkpzotoi8p4g" /// The published instant for "Test Post 1" post -let testPost1Published = Instant.FromDateTimeOffset(DateTimeOffset.Parse "2024-01-20T22:17:29Z") +let private testPost1Published = Instant.FromDateTimeOffset(DateTimeOffset.Parse "2024-01-20T22:17:29Z") /// The category IDs for "Spitball" (parent) and "Moonshot" -let testCatIds = [ CategoryId "jw6N69YtTEWVHAO33jHU-w"; CategoryId "ScVpyu1e7UiP7bDdge3ZEw" ] +let private testCatIds = [ CategoryId "jw6N69YtTEWVHAO33jHU-w"; CategoryId "ScVpyu1e7UiP7bDdge3ZEw" ] /// Ensure that a list of posts has text for each post -let ensureHasText (posts: Post list) = +let private ensureHasText (posts: Post list) = for post in posts do Expect.isNotEmpty post.Text $"Text should not be blank (post ID {post.Id})" /// Ensure that a list of posts has no revisions or prior permalinks -let ensureEmpty posts = +let private ensureEmpty posts = for post in posts do Expect.isEmpty post.Revisions $"There should have been no revisions (post ID {post.Id})" Expect.isEmpty post.PriorPermalinks $"There should have been no prior permalinks (post ID {post.Id})" diff --git a/src/MyWebLog.Tests/Data/PostgresDataTests.fs b/src/MyWebLog.Tests/Data/PostgresDataTests.fs index a248033..6297a8c 100644 --- a/src/MyWebLog.Tests/Data/PostgresDataTests.fs +++ b/src/MyWebLog.Tests/Data/PostgresDataTests.fs @@ -416,6 +416,52 @@ let tagMapTests = testList "TagMap" [ ] ] +let themeTests = testList "Theme" [ + testTask "All succeeds" { + do! ThemeDataTests.``All succeeds`` (mkData ()) + } + testList "Exists" [ + testTask "succeeds when the theme exists" { + do! ThemeDataTests.``Exists succeeds when the theme exists`` (mkData ()) + } + testTask "succeeds when the theme does not exist" { + do! ThemeDataTests.``Exists succeeds when the theme does not exist`` (mkData ()) + } + ] + testList "FindById" [ + testTask "succeeds when the theme exists" { + do! ThemeDataTests.``FindById succeeds when the theme exists`` (mkData ()) + } + testTask "succeeds when the theme does not exist" { + do! ThemeDataTests.``FindById succeeds when the theme does not exist`` (mkData ()) + } + ] + testList "FindByIdWithoutText" [ + testTask "succeeds when the theme exists" { + do! ThemeDataTests.``FindByIdWithoutText succeeds when the theme exists`` (mkData ()) + } + testTask "succeeds when the theme does not exist" { + do! ThemeDataTests.``FindByIdWithoutText succeeds when the theme does not exist`` (mkData ()) + } + ] + testList "Save" [ + testTask "succeeds when adding a theme" { + do! ThemeDataTests.``Save succeeds when adding a theme`` (mkData ()) + } + testTask "succeeds when updating a theme" { + do! ThemeDataTests.``Save succeeds when updating a theme`` (mkData ()) + } + ] + testList "Delete" [ + testTask "succeeds when a theme is deleted" { + do! ThemeDataTests.``Delete succeeds when a theme is deleted`` (mkData ()) + } + testTask "succeeds when a theme is not deleted" { + do! ThemeDataTests.``Delete succeeds when a theme is not deleted`` (mkData ()) + } + ] +] + /// Drop the throwaway PostgreSQL database let environmentCleanUp = test "Clean Up" { if db.IsSome then db.Value.Dispose() @@ -429,5 +475,6 @@ let all = pageTests postTests tagMapTests + themeTests environmentCleanUp ] |> testSequenced diff --git a/src/MyWebLog.Tests/Data/RethinkDbDataTests.fs b/src/MyWebLog.Tests/Data/RethinkDbDataTests.fs index 81de83a..e4d7001 100644 --- a/src/MyWebLog.Tests/Data/RethinkDbDataTests.fs +++ b/src/MyWebLog.Tests/Data/RethinkDbDataTests.fs @@ -416,6 +416,52 @@ let tagMapTests = testList "TagMap" [ ] ] +let themeTests = testList "Theme" [ + testTask "All succeeds" { + do! ThemeDataTests.``All succeeds`` data.Value + } + testList "Exists" [ + testTask "succeeds when the theme exists" { + do! ThemeDataTests.``Exists succeeds when the theme exists`` data.Value + } + testTask "succeeds when the theme does not exist" { + do! ThemeDataTests.``Exists succeeds when the theme does not exist`` data.Value + } + ] + testList "FindById" [ + testTask "succeeds when the theme exists" { + do! ThemeDataTests.``FindById succeeds when the theme exists`` data.Value + } + testTask "succeeds when the theme does not exist" { + do! ThemeDataTests.``FindById succeeds when the theme does not exist`` data.Value + } + ] + testList "FindByIdWithoutText" [ + testTask "succeeds when the theme exists" { + do! ThemeDataTests.``FindByIdWithoutText succeeds when the theme exists`` data.Value + } + testTask "succeeds when the theme does not exist" { + do! ThemeDataTests.``FindByIdWithoutText succeeds when the theme does not exist`` data.Value + } + ] + testList "Save" [ + testTask "succeeds when adding a theme" { + do! ThemeDataTests.``Save succeeds when adding a theme`` data.Value + } + testTask "succeeds when updating a theme" { + do! ThemeDataTests.``Save succeeds when updating a theme`` data.Value + } + ] + testList "Delete" [ + testTask "succeeds when a theme is deleted" { + do! ThemeDataTests.``Delete succeeds when a theme is deleted`` data.Value + } + testTask "succeeds when a theme is not deleted" { + do! ThemeDataTests.``Delete succeeds when a theme is not deleted`` data.Value + } + ] +] + /// Drop the throwaway RethinkDB database let environmentCleanUp = testTask "Clean Up" { do! disposeData () @@ -429,5 +475,6 @@ let all = pageTests postTests tagMapTests + themeTests environmentCleanUp ] |> testSequenced diff --git a/src/MyWebLog.Tests/Data/SQLiteDataTests.fs b/src/MyWebLog.Tests/Data/SQLiteDataTests.fs index ca18077..2410c91 100644 --- a/src/MyWebLog.Tests/Data/SQLiteDataTests.fs +++ b/src/MyWebLog.Tests/Data/SQLiteDataTests.fs @@ -269,6 +269,18 @@ let pageTests = testList "Page" [ finally dispose data } ] + testList "FindPageOfPages" [ + testTask "succeeds when pages are found" { + let data = mkData () + try do! PageDataTests.``FindPageOfPages succeeds when pages are found`` data + finally dispose data + } + testTask "succeeds when a pages are not found" { + let data = mkData () + try do! PageDataTests.``FindPageOfPages succeeds when pages are not found`` data + finally dispose data + } + ] testList "Update" [ testTask "succeeds when the page exists" { let data = mkData () @@ -603,6 +615,74 @@ let tagMapTests = testList "TagMap" [ ] ] +let themeTests = testList "Theme" [ + testTask "All succeeds" { + let data = mkData () + try do! ThemeDataTests.``All succeeds`` data + finally dispose data + } + testList "Exists" [ + testTask "succeeds when the theme exists" { + let data = mkData () + try do! ThemeDataTests.``Exists succeeds when the theme exists`` data + finally dispose data + } + testTask "succeeds when the theme does not exist" { + let data = mkData () + try do! ThemeDataTests.``Exists succeeds when the theme does not exist`` data + finally dispose data + } + ] + testList "FindById" [ + testTask "succeeds when the theme exists" { + let data = mkData () + try do! ThemeDataTests.``FindById succeeds when the theme exists`` data + finally dispose data + } + testTask "succeeds when the theme does not exist" { + let data = mkData () + try do! ThemeDataTests.``FindById succeeds when the theme does not exist`` data + finally dispose data + } + ] + testList "FindByIdWithoutText" [ + testTask "succeeds when the theme exists" { + let data = mkData () + try do! ThemeDataTests.``FindByIdWithoutText succeeds when the theme exists`` data + finally dispose data + } + testTask "succeeds when the theme does not exist" { + let data = mkData () + try do! ThemeDataTests.``FindByIdWithoutText succeeds when the theme does not exist`` data + finally dispose data + } + ] + testList "Save" [ + testTask "succeeds when adding a theme" { + let data = mkData () + try do! ThemeDataTests.``Save succeeds when adding a theme`` data + finally dispose data + } + testTask "succeeds when updating a theme" { + let data = mkData () + try do! ThemeDataTests.``Save succeeds when updating a theme`` data + finally dispose data + } + ] + testList "Delete" [ + testTask "succeeds when a theme is deleted" { + let data = mkData () + try do! ThemeDataTests.``Delete succeeds when a theme is deleted`` data + finally dispose data + } + testTask "succeeds when a theme is not deleted" { + let data = mkData () + try do! ThemeDataTests.``Delete succeeds when a theme is not deleted`` data + finally dispose data + } + ] +] + /// Delete the SQLite database let environmentCleanUp = test "Clean Up" { File.Delete dbName @@ -617,5 +697,6 @@ let all = pageTests postTests tagMapTests + themeTests environmentCleanUp ] |> testSequenced diff --git a/src/MyWebLog.Tests/Data/TagMapDataTests.fs b/src/MyWebLog.Tests/Data/TagMapDataTests.fs index f393fa8..d075b22 100644 --- a/src/MyWebLog.Tests/Data/TagMapDataTests.fs +++ b/src/MyWebLog.Tests/Data/TagMapDataTests.fs @@ -8,13 +8,13 @@ open MyWebLog open MyWebLog.Data /// The ID of the root web log -let rootId = CategoryDataTests.rootId +let private rootId = CategoryDataTests.rootId /// The ID of the f# tag -let fSharpId = TagMapId "Icm027noqE-rPHKZA98vAw" +let private fSharpId = TagMapId "Icm027noqE-rPHKZA98vAw" /// The ID of the ghoti tag -let fishId = TagMapId "GdryXh-S0kGsNBs2RIacGA" +let private fishId = TagMapId "GdryXh-S0kGsNBs2RIacGA" let ``FindById succeeds when a tag mapping is found`` (data: IData) = task { let! tagMap = data.TagMap.FindById fSharpId rootId diff --git a/src/MyWebLog.Tests/Data/ThemeDataTests.fs b/src/MyWebLog.Tests/Data/ThemeDataTests.fs new file mode 100644 index 0000000..dd4228c --- /dev/null +++ b/src/MyWebLog.Tests/Data/ThemeDataTests.fs @@ -0,0 +1,121 @@ +/// +/// Integration tests for implementations +/// +module ThemeDataTests + +open Expecto +open MyWebLog +open MyWebLog.Data + +/// The ID of the default theme (restored from root-weblog.json) +let private defaultId = ThemeId "default" + +/// Ensure that theme templates do not have any text +let private ensureNoText theme = + for template in theme.Templates do + Expect.equal template.Text "" $"Text for template {template.Name} should have been blank" + +let ``All succeeds`` (data: IData) = task { + let! themes = data.Theme.All() + Expect.hasLength themes 1 "There should have been one theme returned" + Expect.equal themes[0].Id defaultId "ID was incorrect" + Expect.equal themes[0].Name "myWebLog Default Theme" "Name was incorrect" + Expect.equal themes[0].Version "2.1.0" "Version was incorrect" + ensureNoText themes[0] +} + +let ``Exists succeeds when the theme exists`` (data: IData) = task { + let! exists = data.Theme.Exists defaultId + Expect.isTrue exists "The \"default\" theme should have existed" +} + +let ``Exists succeeds when the theme does not exist`` (data: IData) = task { + let! exists = data.Theme.Exists (ThemeId "fancy") + Expect.isFalse exists "The \"fancy\" theme should not have existed" +} + +let ``FindById succeeds when the theme exists`` (data: IData) = task { + let! theme = data.Theme.FindById defaultId + Expect.isSome theme "The theme should have been found" + let it = theme.Value + Expect.equal it.Id defaultId "ID was incorrect" + Expect.equal it.Name "myWebLog Default Theme" "Name was incorrect" + Expect.equal it.Version "2.1.0" "Version was incorrect" + for template in it.Templates do + Expect.isNotEmpty template.Text $"Text for template {template.Name} should not have been blank" +} + +let ``FindById succeeds when the theme does not exist`` (data: IData) = task { + let! theme = data.Theme.FindById (ThemeId "missing") + Expect.isNone theme "There should not have been a theme found" +} + +let ``FindByIdWithoutText succeeds when the theme exists`` (data: IData) = task { + let! theme = data.Theme.FindByIdWithoutText defaultId + Expect.isSome theme "The theme should have been found" + let it = theme.Value + Expect.equal it.Id defaultId "ID was incorrect" + ensureNoText it +} + +let ``FindByIdWithoutText succeeds when the theme does not exist`` (data: IData) = task { + let! theme = data.Theme.FindByIdWithoutText (ThemeId "ornate") + Expect.isNone theme "There should not have been a theme found" +} + +let ``Save succeeds when adding a theme`` (data: IData) = task { + let themeId = ThemeId "test-theme" + do! data.Theme.Save + { Id = themeId + Name = "Test Theme" + Version = "evergreen" + Templates = + [ { Name = "index"; Text = "

{{ values_here }}

" } + { Name = "single-post"; Text = "

{{ the_post }}" } ] } + let! saved = data.Theme.FindById themeId + Expect.isSome saved "There should have been a theme returned" + let it = saved.Value + Expect.equal it.Id themeId "ID was incorrect" + Expect.equal it.Name "Test Theme" "Name was incorrect" + Expect.equal it.Version "evergreen" "Version was incorrect" + Expect.hasLength it.Templates 2 "There should have been 2 templates" + Expect.equal it.Templates[0].Name "index" "Template 0 name incorrect" + Expect.equal it.Templates[0].Text "

{{ values_here }}

" "Template 0 text incorrect" + Expect.equal it.Templates[1].Name "single-post" "Template 1 name incorrect" + Expect.equal it.Templates[1].Text "

{{ the_post }}" "Template 1 text incorrect" +} + +let ``Save succeeds when updating a theme`` (data: IData) = task { + let themeId = ThemeId "test-theme" + do! data.Theme.Save + { Id = themeId + Name = "Updated Theme" + Version = "still evergreen" + Templates = + [ { Name = "index"; Text = "

{{ values_there }}

" } + { Name = "layout"; Text = "" } + { Name = "single-post"; Text = "

{{ the_post }}" } ] } + let! updated = data.Theme.FindById themeId + Expect.isSome updated "The updated theme should have been returned" + let it = updated.Value + Expect.equal it.Id themeId "ID was incorrect" + Expect.equal it.Name "Updated Theme" "Name was incorrect" + Expect.equal it.Version "still evergreen" "Version was incorrect" + Expect.hasLength it.Templates 3 "There should have been 3 templates" + Expect.equal it.Templates[0].Name "index" "Template 0 name incorrect" + Expect.equal it.Templates[0].Text "

{{ values_there }}

" "Template 0 text incorrect" + Expect.equal it.Templates[1].Name "layout" "Template 1 name incorrect" + Expect.equal it.Templates[1].Text "" "Template 1 text incorrect" + Expect.equal it.Templates[2].Name "single-post" "Template 2 name incorrect" + Expect.equal it.Templates[2].Text "

{{ the_post }}" "Template 2 text incorrect" +} + +let ``Delete succeeds when a theme is deleted`` (data: IData) = task { + let! deleted = data.Theme.Delete (ThemeId "test-theme") + Expect.isTrue deleted "The theme should have been deleted" +} + +let ``Delete succeeds when a theme is not deleted`` (data: IData) = task { + let! deleted = data.Theme.Delete (ThemeId "test-theme") // already deleted above + Expect.isFalse deleted "The theme should not have been deleted" +} diff --git a/src/MyWebLog.Tests/MyWebLog.Tests.fsproj b/src/MyWebLog.Tests/MyWebLog.Tests.fsproj index a4782e6..7b0f796 100644 --- a/src/MyWebLog.Tests/MyWebLog.Tests.fsproj +++ b/src/MyWebLog.Tests/MyWebLog.Tests.fsproj @@ -14,6 +14,7 @@ + diff --git a/src/MyWebLog.Tests/Program.fs b/src/MyWebLog.Tests/Program.fs index f5fc99b..ab848c5 100644 --- a/src/MyWebLog.Tests/Program.fs +++ b/src/MyWebLog.Tests/Program.fs @@ -1,13 +1,25 @@ open Expecto +/// Whether to only run RethinkDB data tests +let rethinkOnly = (RethinkDbDataTests.env "RETHINK_ONLY" "0") = "1" + +/// Whether to only run SQLite data tests +let sqliteOnly = (RethinkDbDataTests.env "SQLITE_ONLY" "0") = "1" + +/// Whether to only run PostgreSQL data tests +let postgresOnly = (RethinkDbDataTests.env "PG_ONLY" "0") = "1" + +/// Whether any of the data tests are being isolated +let dbOnly = rethinkOnly || sqliteOnly || postgresOnly + let allTests = testList "MyWebLog" [ - testList "Domain" [ SupportTypesTests.all; DataTypesTests.all; ViewModelsTests.all ] + if not dbOnly then testList "Domain" [ SupportTypesTests.all; DataTypesTests.all; ViewModelsTests.all ] testList "Data" [ - ConvertersTests.all - UtilsTests.all - RethinkDbDataTests.all - SQLiteDataTests.all - PostgresDataTests.all + if not dbOnly then ConvertersTests.all + if not dbOnly then UtilsTests.all + if not dbOnly || (dbOnly && rethinkOnly) then RethinkDbDataTests.all + if not dbOnly || (dbOnly && sqliteOnly) then SQLiteDataTests.all + if not dbOnly || (dbOnly && postgresOnly) then PostgresDataTests.all ] ]