From 24d49e26e52e047c075fd93ccb271d6eec8b0d18 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Tue, 30 Jan 2024 22:45:33 -0500 Subject: [PATCH] Add tests through post curr permalink - Resolve SQLite / RethinkDB env refresh hiccups --- .../Postgres/PostgresPageData.fs | 9 +- .../Postgres/PostgresPostData.fs | 11 ++- src/MyWebLog.Data/RethinkDbData.fs | 26 ++++-- src/MyWebLog.Data/SQLite/SQLitePageData.fs | 2 +- src/MyWebLog.Data/SQLite/SQLitePostData.fs | 11 ++- src/MyWebLog.Data/SQLite/SQLiteWebLogData.fs | 2 +- src/MyWebLog.Tests/Data/PageDataTests.fs | 43 ++++----- src/MyWebLog.Tests/Data/PostDataTests.fs | 93 +++++++++++++++++++ src/MyWebLog.Tests/Data/PostgresDataTests.fs | 33 +++++++ src/MyWebLog.Tests/Data/RethinkDbDataTests.fs | 33 +++++++ src/MyWebLog.Tests/Data/SQLiteDataTests.fs | 88 ++++++++++++++++-- src/MyWebLog.Tests/root-weblog.json | 4 +- 12 files changed, 298 insertions(+), 57 deletions(-) diff --git a/src/MyWebLog.Data/Postgres/PostgresPageData.fs b/src/MyWebLog.Data/Postgres/PostgresPageData.fs index 824fba6..3c6e023 100644 --- a/src/MyWebLog.Data/Postgres/PostgresPageData.fs +++ b/src/MyWebLog.Data/Postgres/PostgresPageData.fs @@ -94,10 +94,13 @@ type PostgresPageData(log: ILogger) = } /// Find a page by its permalink for the given web log - let findByPermalink (permalink: Permalink) webLogId = + let findByPermalink (permalink: Permalink) webLogId = backgroundTask { log.LogTrace "Page.findByPermalink" - Find.byContains Table.Page {| webLogDoc webLogId with Permalink = permalink |} - |> tryHead + let! page = + Find.byContains Table.Page {| webLogDoc webLogId with Permalink = permalink |} + |> tryHead + return page |> Option.map (fun pg -> { pg with PriorPermalinks = [] }) + } /// Find the current permalink within a set of potential prior permalinks for the given web log let findCurrentPermalink (permalinks: Permalink list) webLogId = backgroundTask { diff --git a/src/MyWebLog.Data/Postgres/PostgresPostData.fs b/src/MyWebLog.Data/Postgres/PostgresPostData.fs index 6f858af..c41ccee 100644 --- a/src/MyWebLog.Data/Postgres/PostgresPostData.fs +++ b/src/MyWebLog.Data/Postgres/PostgresPostData.fs @@ -42,9 +42,12 @@ type PostgresPostData(log: ILogger) = Count.byContains Table.Post {| webLogDoc webLogId with Status = status |} /// Find a post by its ID for the given web log (excluding revisions) - let findById postId webLogId = + let findById postId webLogId = backgroundTask { log.LogTrace "Post.findById" - Document.findByIdAndWebLog Table.Post postId webLogId + match! Document.findByIdAndWebLog Table.Post postId webLogId with + | Some post -> return Some { post with PriorPermalinks = [] } + | None -> return None + } /// Find a post by its permalink for the given web log (excluding revisions) let findByPermalink (permalink: Permalink) webLogId = @@ -52,12 +55,12 @@ type PostgresPostData(log: ILogger) = Custom.single (selectWithCriteria Table.Post) [ jsonParam "@criteria" {| webLogDoc webLogId with Permalink = permalink |} ] - fromData + (fun row -> { fromData row with PriorPermalinks = [] }) /// Find a complete post by its ID for the given web log let findFullById postId webLogId = backgroundTask { log.LogTrace "Post.findFullById" - match! findById postId webLogId with + match! Document.findByIdAndWebLog Table.Post postId webLogId with | Some post -> let! withRevisions = appendPostRevisions post return Some withRevisions diff --git a/src/MyWebLog.Data/RethinkDbData.fs b/src/MyWebLog.Data/RethinkDbData.fs index 0748df5..5a86813 100644 --- a/src/MyWebLog.Data/RethinkDbData.fs +++ b/src/MyWebLog.Data/RethinkDbData.fs @@ -178,6 +178,7 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger obj) write; withRetryOnce; ignoreResult conn } + do! rethink { withTable table; indexWait; result; withRetryDefault; ignoreResult conn } } /// The batch size for restoration methods @@ -589,20 +590,27 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger 0UL } - member _.FindById postId webLogId = - rethink { - withTable Table.Post - get postId - without [ nameof Post.Empty.PriorPermalinks; nameof Post.Empty.Revisions ] - resultOption; withRetryOptionDefault - } - |> verifyWebLog webLogId _.WebLogId <| conn + 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 _.FindByPermalink permalink webLogId = rethink { withTable Table.Post getAll [ [| webLogId :> obj; permalink |] ] (nameof Post.Empty.Permalink) - without [ nameof Post.Empty.PriorPermalinks; nameof Post.Empty.Revisions ] + merge (r.HashMap(nameof Post.Empty.PriorPermalinks, [||]) + .With(nameof Post.Empty.Revisions, [||])) limit 1 result; withRetryDefault } diff --git a/src/MyWebLog.Data/SQLite/SQLitePageData.fs b/src/MyWebLog.Data/SQLite/SQLitePageData.fs index 38f2f32..e2561fc 100644 --- a/src/MyWebLog.Data/SQLite/SQLitePageData.fs +++ b/src/MyWebLog.Data/SQLite/SQLitePageData.fs @@ -102,7 +102,7 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) = conn.customSingle $"""{Document.Query.selectByWebLog Table.Page} AND {Query.whereByField linkParam "@link"}""" (addFieldParam "@link" linkParam [ webLogParam webLogId ]) - fromData + (fun rdr -> { fromData rdr with PriorPermalinks = [] }) /// Find the current permalink within a set of potential prior permalinks for the given web log let findCurrentPermalink (permalinks: Permalink list) webLogId = diff --git a/src/MyWebLog.Data/SQLite/SQLitePostData.fs b/src/MyWebLog.Data/SQLite/SQLitePostData.fs index 3a67a9c..62e8826 100644 --- a/src/MyWebLog.Data/SQLite/SQLitePostData.fs +++ b/src/MyWebLog.Data/SQLite/SQLitePostData.fs @@ -54,9 +54,12 @@ type SQLitePostData(conn: SqliteConnection, log: ILogger) = (toCount >> int) /// Find a post by its ID for the given web log (excluding revisions) - let findById postId webLogId = + let findById postId webLogId = backgroundTask { log.LogTrace "Post.findById" - Document.findByIdAndWebLog Table.Post postId webLogId conn + match! Document.findByIdAndWebLog Table.Post postId webLogId conn with + | Some post -> return Some { post with PriorPermalinks = [] } + | None -> return None + } /// Find a post by its permalink for the given web log (excluding revisions) let findByPermalink (permalink: Permalink) webLogId = @@ -65,12 +68,12 @@ type SQLitePostData(conn: SqliteConnection, log: ILogger) = conn.customSingle $"""{Document.Query.selectByWebLog Table.Post} AND {Query.whereByField linkParam "@link"}""" (addFieldParam "@link" linkParam [ webLogParam webLogId ]) - fromData + (fun rdr -> { fromData rdr with PriorPermalinks = [] }) /// Find a complete post by its ID for the given web log let findFullById postId webLogId = backgroundTask { log.LogTrace "Post.findFullById" - match! findById postId webLogId with + match! Document.findByIdAndWebLog Table.Post postId webLogId conn with | Some post -> let! post = appendPostRevisions post return Some post diff --git a/src/MyWebLog.Data/SQLite/SQLiteWebLogData.fs b/src/MyWebLog.Data/SQLite/SQLiteWebLogData.fs index 93af895..4c5a797 100644 --- a/src/MyWebLog.Data/SQLite/SQLiteWebLogData.fs +++ b/src/MyWebLog.Data/SQLite/SQLiteWebLogData.fs @@ -24,7 +24,7 @@ type SQLiteWebLogData(conn: SqliteConnection, log: ILogger) = let delete webLogId = log.LogTrace "WebLog.delete" let webLogMatches = Query.whereByField (Field.EQ "WebLogId" "") "@webLogId" - let subQuery table = $"(SELECT data ->> 'Id' FROM {table} WHERE {webLogMatches}" + let subQuery table = $"(SELECT data ->> 'Id' FROM {table} WHERE {webLogMatches})" Custom.nonQuery $"""DELETE FROM {Table.PostComment} WHERE data ->> 'PostId' IN {subQuery Table.Post}; DELETE FROM {Table.PostRevision} WHERE post_id IN {subQuery Table.Post}; diff --git a/src/MyWebLog.Tests/Data/PageDataTests.fs b/src/MyWebLog.Tests/Data/PageDataTests.fs index 03159b8..8a2a95d 100644 --- a/src/MyWebLog.Tests/Data/PageDataTests.fs +++ b/src/MyWebLog.Tests/Data/PageDataTests.fs @@ -50,14 +50,9 @@ let ``Add succeeds`` (data: IData) = task { Expect.equal pg.IsInPageList page.IsInPageList "Is in page list flag not saved properly" Expect.equal pg.Template page.Template "Template not saved properly" Expect.equal pg.Text page.Text "Text not saved properly" - Expect.hasLength pg.Metadata 1 "There should have been one meta item properly" - Expect.equal pg.Metadata[0].Name page.Metadata[0].Name "Metadata name not saved properly" - Expect.equal pg.Metadata[0].Value page.Metadata[0].Value "Metadata value not saved properly" - Expect.hasLength pg.PriorPermalinks 1 "There should have been one prior permalink" - Expect.equal pg.PriorPermalinks[0] page.PriorPermalinks[0] "Prior permalink not saved properly" - Expect.hasLength pg.Revisions 1 "There should have been one revision" - Expect.equal pg.Revisions[0].AsOf page.Revisions[0].AsOf "Revision as of not saved properly" - Expect.equal pg.Revisions[0].Text page.Revisions[0].Text "Revision text not saved properly" + Expect.equal pg.Metadata page.Metadata "Metadata not saved properly" + Expect.equal pg.PriorPermalinks page.PriorPermalinks "Prior permalinks not saved properly" + Expect.equal pg.Revisions page.Revisions "Revisions not saved properly" } let ``All succeeds`` (data: IData) = task { @@ -95,11 +90,8 @@ let ``FindById succeeds when a page is found`` (data: IData) = task { Expect.equal pg.UpdatedOn coolPagePublished "Updated On is incorrect" Expect.isFalse pg.IsInPageList "Is in page list flag should not have been set" Expect.equal pg.Text "

A Cool Page

\n

It really is cool!

\n" "Text is incorrect" - Expect.hasLength pg.Metadata 2 "There should be 2 metadata items on this page" - Expect.equal pg.Metadata[0].Name "Cool" "Meta item 0 name is incorrect" - Expect.equal pg.Metadata[0].Value "true" "Meta item 0 value is incorrect" - Expect.equal pg.Metadata[1].Name "Warm" "Meta item 1 name is incorrect" - Expect.equal pg.Metadata[1].Value "false" "Meta item 1 value is incorrect" + Expect.equal + pg.Metadata [ { Name = "Cool"; Value = "true" }; { Name = "Warm"; Value = "false" } ] "Metadata is incorrect" Expect.isEmpty pg.Revisions "Revisions should not have been retrieved" Expect.isEmpty pg.PriorPermalinks "Prior permalinks should not have been retrieved" } @@ -119,6 +111,8 @@ let ``FindByPermalink succeeds when a page is found`` (data: IData) = task { Expect.isSome page "A page should have been returned" let pg = page.Value Expect.equal pg.Id coolPageId "The wrong page was retrieved" + Expect.isEmpty pg.Revisions "Revisions should not have been retrieved" + Expect.isEmpty pg.PriorPermalinks "Prior permalinks should not have been retrieved" } let ``FindByPermalink succeeds when a page is not found (incorrect weblog)`` (data: IData) = task { @@ -148,11 +142,11 @@ let ``FindFullById succeeds when a page is found`` (data: IData) = task { let pg = page.Value Expect.equal pg.Id coolPageId "The wrong page was retrieved" Expect.equal pg.WebLogId rootId "The page's web log did not match the called parameter" - Expect.hasLength pg.Revisions 1 "There should be 1 revision" - Expect.equal pg.Revisions[0].AsOf coolPagePublished "Revision 0 as-of is incorrect" - Expect.equal pg.Revisions[0].Text (Markdown "# A Cool Page\n\nIt really is cool!") "Revision 0 text is incorrect" - Expect.hasLength pg.PriorPermalinks 1 "There should be 1 prior permalink" - Expect.equal pg.PriorPermalinks[0] (Permalink "a-cool-pg.html") "Prior permalink 0 is incorrect" + Expect.equal + pg.Revisions + [ { AsOf = coolPagePublished; Text = Markdown "# A Cool Page\n\nIt really is cool!" } ] + "Revisions are incorrect" + Expect.equal pg.PriorPermalinks [ Permalink "a-cool-pg.html" ] "Prior permalinks are incorrect" } let ``FindFullById succeeds when a page is not found`` (data: IData) = task { @@ -230,14 +224,13 @@ let ``Update succeeds when the page exists`` (data: IData) = task { Expect.equal pg.UpdatedOn (coolPagePublished + Duration.FromHours 5) "Updated On is incorrect" Expect.isTrue pg.IsInPageList "Is in page list flag should have been set" Expect.equal pg.Text "

I have been updated" "Text is incorrect" - Expect.hasLength pg.Metadata 1 "There should be 1 metadata item on this page" - Expect.equal pg.Metadata[0].Name "Cool" "Meta item 0 name is incorrect" - Expect.equal pg.Metadata[0].Value "true" "Meta item 0 value is incorrect" + Expect.equal pg.Metadata [ { Name = "Cool"; Value = "true" } ] "Metadata is incorrect" Expect.equal pg.PriorPermalinks [ Permalink "a-cool-page.html" ] "Prior permalinks are incorrect" - Expect.hasLength pg.Revisions 2 "There should be 2 revisions" - Expect.equal pg.Revisions[0].AsOf (coolPagePublished + Duration.FromHours 5) "As Of for revision 0 incorrect" - Expect.equal pg.Revisions[0].Text (Html "

I have been updated") "Text for revision 0 is incorrect" - Expect.equal pg.Revisions[1].AsOf coolPagePublished "As Of for revision 1 is incorrect" + Expect.equal + pg.Revisions + [ { AsOf = coolPagePublished + Duration.FromHours 5; Text = Html "

I have been updated" } + { AsOf = coolPagePublished; Text = Markdown "# A Cool Page\n\nIt really is cool!" } ] + "Revisions are incorrect" } let ``Update succeeds when the page does not exist`` (data: IData) = task { diff --git a/src/MyWebLog.Tests/Data/PostDataTests.fs b/src/MyWebLog.Tests/Data/PostDataTests.fs index 45f2063..6a129f4 100644 --- a/src/MyWebLog.Tests/Data/PostDataTests.fs +++ b/src/MyWebLog.Tests/Data/PostDataTests.fs @@ -3,6 +3,7 @@ /// module PostDataTests +open System open Expecto open MyWebLog open MyWebLog.Data @@ -11,6 +12,12 @@ open NodaTime /// The ID of the root web log let rootId = WebLogId "uSitJEuD3UyzWC9jgOHc8g" +/// The ID of podcast episode 1 +let episode1 = PostId "osxMfWGlAkyugUbJ1-xD1g" + +/// The published instant for episode 1 +let episode1Published = Instant.FromDateTimeOffset(DateTimeOffset.Parse "2024-01-20T22:24:01Z") + let ``Add succeeds`` (data: IData) = task { let post = { Id = PostId "a-new-post" @@ -50,3 +57,89 @@ let ``Add succeeds`` (data: IData) = task { Expect.equal it.PriorPermalinks post.PriorPermalinks "Prior permalinks not saved properly" Expect.equal it.Revisions post.Revisions "Revisions not saved properly" } + +let ``CountByStatus succeeds`` (data: IData) = task { + let! count = data.Post.CountByStatus Published rootId + Expect.equal count 4 "There should be 4 published posts" +} + +let ``FindById succeeds when a post is found`` (data: IData) = task { + let! post = data.Post.FindById episode1 rootId + Expect.isSome post "There should have been a post returned" + let it = post.Value + Expect.equal it.Id episode1 "An incorrect post was retrieved" + Expect.equal it.WebLogId rootId "The post belongs to an incorrect web log" + Expect.equal it.AuthorId (WebLogUserId "5EM2rimH9kONpmd2zQkiVA") "Author ID is incorrect" + Expect.equal it.Status Published "Status is incorrect" + Expect.equal it.Title "Episode 1" "Title is incorrect" + Expect.equal it.Permalink (Permalink "2024/episode-1.html") "Permalink is incorrect" + Expect.equal it.PublishedOn (Some episode1Published) "Published On is incorrect" + Expect.equal it.UpdatedOn episode1Published "Updated On is incorrect" + Expect.equal it.Text "

It's the launch of my new podcast - y'all come listen!" "Text is incorrect" + Expect.equal it.CategoryIds [ CategoryId "S5JflPsJ9EG7gA2LD4m92A" ] "Category IDs are incorrect" + Expect.equal it.Tags [ "general"; "podcast" ] "Tags are incorrect" + Expect.isSome it.Episode "There should be an episode associated with this post" + let ep = it.Episode.Value + Expect.equal ep.Media "episode-1.mp3" "Episode media is incorrect" + Expect.equal ep.Length 124302L "Episode length is incorrect" + Expect.equal + ep.Duration (Some (Duration.FromMinutes 12L + Duration.FromSeconds 22L)) "Episode duration is incorrect" + Expect.equal ep.ImageUrl (Some "images/ep1-cover.png") "Episode image URL is incorrect" + Expect.equal ep.Subtitle (Some "An introduction to this podcast") "Episode subtitle is incorrect" + Expect.equal ep.Explicit (Some Clean) "Episode explicit rating is incorrect" + Expect.equal ep.ChapterFile (Some "uploads/chapters.json") "Episode chapter file is incorrect" + Expect.equal ep.TranscriptUrl (Some "uploads/transcript.srt") "Episode transcript URL is incorrect" + Expect.equal ep.TranscriptType (Some "application/srt") "Episode transcript type is incorrect" + Expect.equal ep.TranscriptLang (Some "en") "Episode transcript language is incorrect" + Expect.equal ep.TranscriptCaptions (Some true) "Episode transcript caption flag is incorrect" + Expect.equal ep.SeasonNumber (Some 1) "Episode season number is incorrect" + Expect.equal ep.SeasonDescription (Some "The First Season") "Episode season description is incorrect" + Expect.equal ep.EpisodeNumber (Some 1.) "Episode number is incorrect" + Expect.equal ep.EpisodeDescription (Some "The first episode ever!") "Episode description is incorrect" + Expect.equal + it.Metadata + [ { Name = "Density"; Value = "Non-existent" }; { Name = "Intensity"; Value = "Low" } ] + "Metadata is incorrect" + Expect.isEmpty it.PriorPermalinks "Prior permalinks should have been empty" + Expect.isEmpty it.Revisions "Revisions should have been empty" +} + +let ``FindById succeeds when a post is not found (incorrect weblog)`` (data: IData) = task { + let! post = data.Post.FindById episode1 (WebLogId "wrong") + Expect.isNone post "The post should not have been retrieved" +} + +let ``FindById succeeds when a post is not found (bad post ID)`` (data: IData) = task { + let! post = data.Post.FindById (PostId "absent") rootId + Expect.isNone post "The post should not have been retrieved" +} + +let ``FindByPermalink succeeds when a post is found`` (data: IData) = task { + let! post = data.Post.FindByPermalink (Permalink "2024/episode-1.html") rootId + Expect.isSome post "A post should have been returned" + let it = post.Value + Expect.equal it.Id episode1 "The wrong post was retrieved" + Expect.isEmpty it.PriorPermalinks "Prior permalinks should have been empty" + Expect.isEmpty it.Revisions "Revisions should have been empty" +} + +let ``FindByPermalink succeeds when a post is not found (incorrect weblog)`` (data: IData) = task { + let! post = data.Post.FindByPermalink (Permalink "2024/episode-1.html") (WebLogId "incorrect") + Expect.isNone post "The post should not have been retrieved" +} + +let ``FindByPermalink succeeds when a post is not found (no such permalink)`` (data: IData) = task { + let! post = data.Post.FindByPermalink (Permalink "404") rootId + Expect.isNone post "The post should not have been retrieved" +} + +let ``FindCurrentPermalink succeeds when a post is found`` (data: IData) = task { + let! link = data.Post.FindCurrentPermalink [ Permalink "2024/ep-1.html"; Permalink "2024/ep-1.html/" ] rootId + Expect.isSome link "A permalink should have been returned" + Expect.equal link (Some (Permalink "2024/episode-1.html")) "The wrong permalink was retrieved" +} + +let ``FindCurrentPermalink succeeds when a post is not found`` (data: IData) = task { + let! link = data.Post.FindCurrentPermalink [ Permalink "oops/"; Permalink "oops" ] rootId + Expect.isNone link "A permalink should not have been returned" +} diff --git a/src/MyWebLog.Tests/Data/PostgresDataTests.fs b/src/MyWebLog.Tests/Data/PostgresDataTests.fs index 7b4dc1c..623e108 100644 --- a/src/MyWebLog.Tests/Data/PostgresDataTests.fs +++ b/src/MyWebLog.Tests/Data/PostgresDataTests.fs @@ -226,6 +226,39 @@ let postTests = testList "Post" [ do! freshEnvironment () do! PostDataTests.``Add succeeds`` (mkData ()) } + testTask "CountByStatus succeeds" { + do! PostDataTests.``CountByStatus succeeds`` (mkData ()) + } + testList "FindById" [ + testTask "succeeds when a post is found" { + do! PostDataTests.``FindById succeeds when a post is found`` (mkData ()) + } + testTask "succeeds when a post is not found (incorrect weblog)" { + do! PostDataTests.``FindById succeeds when a post is not found (incorrect weblog)`` (mkData ()) + } + testTask "succeeds when a post is not found (bad post ID)" { + do! PostDataTests.``FindById succeeds when a post is not found (bad post ID)`` (mkData ()) + } + ] + testList "FindByPermalink" [ + testTask "succeeds when a post is found" { + do! PostDataTests.``FindByPermalink succeeds when a post is found`` (mkData ()) + } + testTask "succeeds when a post is not found (incorrect weblog)" { + do! PostDataTests.``FindByPermalink succeeds when a post is not found (incorrect weblog)`` (mkData ()) + } + testTask "succeeds when a post is not found (no such permalink)" { + do! PostDataTests.``FindByPermalink succeeds when a post is not found (no such permalink)`` (mkData ()) + } + ] + testList "FindCurrentPermalink" [ + testTask "succeeds when a post is found" { + do! PostDataTests.``FindCurrentPermalink succeeds when a post is found`` (mkData ()) + } + testTask "succeeds when a post is not found" { + do! PostDataTests.``FindCurrentPermalink succeeds when a post is not found`` (mkData ()) + } + ] ] /// Drop the throwaway PostgreSQL database diff --git a/src/MyWebLog.Tests/Data/RethinkDbDataTests.fs b/src/MyWebLog.Tests/Data/RethinkDbDataTests.fs index 6ac7d6e..a370a83 100644 --- a/src/MyWebLog.Tests/Data/RethinkDbDataTests.fs +++ b/src/MyWebLog.Tests/Data/RethinkDbDataTests.fs @@ -225,6 +225,39 @@ let postTests = testList "Post" [ do! freshEnvironment () do! PostDataTests.``Add succeeds`` data.Value } + testTask "CountByStatus succeeds" { + do! PostDataTests.``CountByStatus succeeds`` data.Value + } + testList "FindById" [ + testTask "succeeds when a post is found" { + do! PostDataTests.``FindById succeeds when a post is found`` data.Value + } + testTask "succeeds when a post is not found (incorrect weblog)" { + do! PostDataTests.``FindById succeeds when a post is not found (incorrect weblog)`` data.Value + } + testTask "succeeds when a post is not found (bad post ID)" { + do! PostDataTests.``FindById succeeds when a post is not found (bad post ID)`` data.Value + } + ] + testList "FindByPermalink" [ + testTask "succeeds when a post is found" { + do! PostDataTests.``FindByPermalink succeeds when a post is found`` data.Value + } + testTask "succeeds when a post is not found (incorrect weblog)" { + do! PostDataTests.``FindByPermalink succeeds when a post is not found (incorrect weblog)`` data.Value + } + testTask "succeeds when a post is not found (no such permalink)" { + do! PostDataTests.``FindByPermalink succeeds when a post is not found (no such permalink)`` data.Value + } + ] + testList "FindCurrentPermalink" [ + testTask "succeeds when a post is found" { + do! PostDataTests.``FindCurrentPermalink succeeds when a post is found`` data.Value + } + testTask "succeeds when a post is not found" { + do! PostDataTests.``FindCurrentPermalink succeeds when a post is not found`` data.Value + } + ] ] /// Drop the throwaway RethinkDB database diff --git a/src/MyWebLog.Tests/Data/SQLiteDataTests.fs b/src/MyWebLog.Tests/Data/SQLiteDataTests.fs index 06dc659..e033a73 100644 --- a/src/MyWebLog.Tests/Data/SQLiteDataTests.fs +++ b/src/MyWebLog.Tests/Data/SQLiteDataTests.fs @@ -1,7 +1,7 @@ module SQLiteDataTests open System.IO -open BitBadger.Documents +open BitBadger.Documents.Sqlite open Expecto open Microsoft.Extensions.Logging.Abstractions open MyWebLog @@ -18,25 +18,44 @@ let dbName = /// Create a SQLiteData instance for testing let mkData () = - Sqlite.Configuration.useConnectionString $"Data Source=./{dbName}" - let conn = Sqlite.Configuration.dbConn () + Configuration.useConnectionString $"Data Source=./{dbName}" + let conn = Configuration.dbConn () SQLiteData(conn, NullLogger(), ser) :> IData +// /// Create a SQLiteData instance for testing +// let mkTraceData () = +// Sqlite.Configuration.useConnectionString $"Data Source=./{dbName}" +// let conn = Sqlite.Configuration.dbConn () +// let myLogger = +// LoggerFactory +// .Create(fun builder -> +// builder +// .AddSimpleConsole() +// .SetMinimumLevel(LogLevel.Trace) +// |> ignore) +// .CreateLogger() +// SQLiteData(conn, myLogger, ser) :> IData + /// Dispose the connection associated with the SQLiteData instance let dispose (data: IData) = (data :?> SQLiteData).Conn.Dispose() /// Create a fresh environment from the root backup let freshEnvironment (data: IData option) = task { - let env = + let! env = task { match data with | Some d -> - System.Console.WriteLine "Existing data" - d + return d | None -> - System.Console.WriteLine $"No data; deleting {dbName}" - File.Delete dbName - mkData () + let d = mkData () + // Thank you, kind Internet stranger... https://stackoverflow.com/a/548297 + do! (d :?> SQLiteData).Conn.customNonQuery + "PRAGMA writable_schema = 1; + DELETE FROM sqlite_master WHERE type IN ('table', 'index'); + PRAGMA writable_schema = 0; + VACUUM" [] + return d + } do! env.StartUp() // This exercises Restore for all implementations; all tests are dependent on it working as expected do! Maintenance.Backup.restoreBackup "root-weblog.json" None false false env @@ -296,6 +315,57 @@ let postTests = testList "Post" [ try do! PostDataTests.``Add succeeds`` data finally dispose data } + testTask "CountPostsByStatus succeeds" { + let data = mkData () + try do! PostDataTests.``CountByStatus succeeds`` data + finally dispose data + } + testList "FindById" [ + testTask "succeeds when a post is found" { + let data = mkData () + try do! PostDataTests.``FindById succeeds when a post is found`` data + finally dispose data + } + testTask "succeeds when a post is not found (incorrect weblog)" { + let data = mkData () + try do! PostDataTests.``FindById succeeds when a post is not found (incorrect weblog)`` data + finally dispose data + } + testTask "succeeds when a post is not found (bad post ID)" { + let data = mkData () + try do! PostDataTests.``FindById succeeds when a post is not found (bad post ID)`` data + finally dispose data + } + ] + testList "FindByPermalink" [ + testTask "succeeds when a post is found" { + let data = mkData () + try do! PostDataTests.``FindByPermalink succeeds when a post is found`` data + finally dispose data + } + testTask "succeeds when a post is not found (incorrect weblog)" { + let data = mkData () + try do! PostDataTests.``FindByPermalink succeeds when a post is not found (incorrect weblog)`` data + finally dispose data + } + testTask "succeeds when a post is not found (no such permalink)" { + let data = mkData () + try do! PostDataTests.``FindByPermalink succeeds when a post is not found (no such permalink)`` data + finally dispose data + } + ] + testList "FindCurrentPermalink" [ + testTask "succeeds when a post is found" { + let data = mkData () + try do! PostDataTests.``FindCurrentPermalink succeeds when a post is found`` data + finally dispose data + } + testTask "succeeds when a post is not found" { + let data = mkData () + try do! PostDataTests.``FindCurrentPermalink succeeds when a post is not found`` data + finally dispose data + } + ] ] /// Delete the SQLite database diff --git a/src/MyWebLog.Tests/root-weblog.json b/src/MyWebLog.Tests/root-weblog.json index 39babe3..a4b45a0 100644 --- a/src/MyWebLog.Tests/root-weblog.json +++ b/src/MyWebLog.Tests/root-weblog.json @@ -272,7 +272,9 @@ "Value": "Low" } ], - "PriorPermalinks": [], + "PriorPermalinks": [ + "2024/ep-1.html" + ], "Revisions": [ { "AsOf": "2024-01-20T22:24:01Z",