Version 2.1 #41

Merged
danieljsummers merged 123 commits from version-2.1 into main 2024-03-27 00:13:28 +00:00
12 changed files with 298 additions and 57 deletions
Showing only changes of commit 24d49e26e5 - Show all commits

View File

@ -94,10 +94,13 @@ type PostgresPageData(log: ILogger) =
} }
/// Find a page by its permalink for the given web log /// 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" log.LogTrace "Page.findByPermalink"
Find.byContains<Page> Table.Page {| webLogDoc webLogId with Permalink = permalink |} let! page =
|> tryHead Find.byContains<Page> 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 /// Find the current permalink within a set of potential prior permalinks for the given web log
let findCurrentPermalink (permalinks: Permalink list) webLogId = backgroundTask { let findCurrentPermalink (permalinks: Permalink list) webLogId = backgroundTask {

View File

@ -42,9 +42,12 @@ type PostgresPostData(log: ILogger) =
Count.byContains Table.Post {| webLogDoc webLogId with Status = status |} Count.byContains Table.Post {| webLogDoc webLogId with Status = status |}
/// Find a post by its ID for the given web log (excluding revisions) /// 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" log.LogTrace "Post.findById"
Document.findByIdAndWebLog<PostId, Post> Table.Post postId webLogId match! Document.findByIdAndWebLog<PostId, Post> 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) /// Find a post by its permalink for the given web log (excluding revisions)
let findByPermalink (permalink: Permalink) webLogId = let findByPermalink (permalink: Permalink) webLogId =
@ -52,12 +55,12 @@ type PostgresPostData(log: ILogger) =
Custom.single Custom.single
(selectWithCriteria Table.Post) (selectWithCriteria Table.Post)
[ jsonParam "@criteria" {| webLogDoc webLogId with Permalink = permalink |} ] [ jsonParam "@criteria" {| webLogDoc webLogId with Permalink = permalink |} ]
fromData<Post> (fun row -> { fromData<Post> row with PriorPermalinks = [] })
/// Find a complete post by its ID for the given web log /// Find a complete post by its ID for the given web log
let findFullById postId webLogId = backgroundTask { let findFullById postId webLogId = backgroundTask {
log.LogTrace "Post.findFullById" log.LogTrace "Post.findFullById"
match! findById postId webLogId with match! Document.findByIdAndWebLog<PostId, Post> Table.Post postId webLogId with
| Some post -> | Some post ->
let! withRevisions = appendPostRevisions post let! withRevisions = appendPostRevisions post
return Some withRevisions return Some withRevisions

View File

@ -178,6 +178,7 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger<Rethi
[| row[nameof WebLogUser.Empty.WebLogId]; row[nameof WebLogUser.Empty.Email] |] :> obj) [| row[nameof WebLogUser.Empty.WebLogId]; row[nameof WebLogUser.Empty.Email] |] :> obj)
write; withRetryOnce; ignoreResult conn write; withRetryOnce; ignoreResult conn
} }
do! rethink { withTable table; indexWait; result; withRetryDefault; ignoreResult conn }
} }
/// The batch size for restoration methods /// The batch size for restoration methods
@ -589,20 +590,27 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger<Rethi
return result.Deleted > 0UL return result.Deleted > 0UL
} }
member _.FindById postId webLogId = member _.FindById postId webLogId = backgroundTask {
rethink<Post> { let! post =
withTable Table.Post rethink<Post list> {
get postId withTable Table.Post
without [ nameof Post.Empty.PriorPermalinks; nameof Post.Empty.Revisions ] getAll [ postId ]
resultOption; withRetryOptionDefault without [ nameof Post.Empty.PriorPermalinks; nameof Post.Empty.Revisions ]
} result; withRetryDefault
|> verifyWebLog webLogId _.WebLogId <| conn }
|> tryFirst <| conn
return
post
|> Option.filter (fun p -> p.WebLogId = webLogId)
|> Option.map (fun p -> { p with Revisions = []; PriorPermalinks = [] })
}
member _.FindByPermalink permalink webLogId = member _.FindByPermalink permalink webLogId =
rethink<Post list> { rethink<Post list> {
withTable Table.Post withTable Table.Post
getAll [ [| webLogId :> obj; permalink |] ] (nameof Post.Empty.Permalink) 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 limit 1
result; withRetryDefault result; withRetryDefault
} }

View File

@ -102,7 +102,7 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) =
conn.customSingle conn.customSingle
$"""{Document.Query.selectByWebLog Table.Page} AND {Query.whereByField linkParam "@link"}""" $"""{Document.Query.selectByWebLog Table.Page} AND {Query.whereByField linkParam "@link"}"""
(addFieldParam "@link" linkParam [ webLogParam webLogId ]) (addFieldParam "@link" linkParam [ webLogParam webLogId ])
fromData<Page> (fun rdr -> { fromData<Page> rdr with PriorPermalinks = [] })
/// Find the current permalink within a set of potential prior permalinks for the given web log /// Find the current permalink within a set of potential prior permalinks for the given web log
let findCurrentPermalink (permalinks: Permalink list) webLogId = let findCurrentPermalink (permalinks: Permalink list) webLogId =

View File

@ -54,9 +54,12 @@ type SQLitePostData(conn: SqliteConnection, log: ILogger) =
(toCount >> int) (toCount >> int)
/// Find a post by its ID for the given web log (excluding revisions) /// 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" log.LogTrace "Post.findById"
Document.findByIdAndWebLog<PostId, Post> Table.Post postId webLogId conn match! Document.findByIdAndWebLog<PostId, Post> 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) /// Find a post by its permalink for the given web log (excluding revisions)
let findByPermalink (permalink: Permalink) webLogId = let findByPermalink (permalink: Permalink) webLogId =
@ -65,12 +68,12 @@ type SQLitePostData(conn: SqliteConnection, log: ILogger) =
conn.customSingle conn.customSingle
$"""{Document.Query.selectByWebLog Table.Post} AND {Query.whereByField linkParam "@link"}""" $"""{Document.Query.selectByWebLog Table.Post} AND {Query.whereByField linkParam "@link"}"""
(addFieldParam "@link" linkParam [ webLogParam webLogId ]) (addFieldParam "@link" linkParam [ webLogParam webLogId ])
fromData<Post> (fun rdr -> { fromData<Post> rdr with PriorPermalinks = [] })
/// Find a complete post by its ID for the given web log /// Find a complete post by its ID for the given web log
let findFullById postId webLogId = backgroundTask { let findFullById postId webLogId = backgroundTask {
log.LogTrace "Post.findFullById" log.LogTrace "Post.findFullById"
match! findById postId webLogId with match! Document.findByIdAndWebLog<PostId, Post> Table.Post postId webLogId conn with
| Some post -> | Some post ->
let! post = appendPostRevisions post let! post = appendPostRevisions post
return Some post return Some post

View File

@ -24,7 +24,7 @@ type SQLiteWebLogData(conn: SqliteConnection, log: ILogger) =
let delete webLogId = let delete webLogId =
log.LogTrace "WebLog.delete" log.LogTrace "WebLog.delete"
let webLogMatches = Query.whereByField (Field.EQ "WebLogId" "") "@webLogId" 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 Custom.nonQuery
$"""DELETE FROM {Table.PostComment} WHERE data ->> 'PostId' IN {subQuery Table.Post}; $"""DELETE FROM {Table.PostComment} WHERE data ->> 'PostId' IN {subQuery Table.Post};
DELETE FROM {Table.PostRevision} WHERE post_id IN {subQuery Table.Post}; DELETE FROM {Table.PostRevision} WHERE post_id IN {subQuery Table.Post};

View File

@ -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.IsInPageList page.IsInPageList "Is in page list flag not saved properly"
Expect.equal pg.Template page.Template "Template not saved properly" Expect.equal pg.Template page.Template "Template not saved properly"
Expect.equal pg.Text page.Text "Text 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 page.Metadata "Metadata not saved properly"
Expect.equal pg.Metadata[0].Name page.Metadata[0].Name "Metadata name not saved properly" Expect.equal pg.PriorPermalinks page.PriorPermalinks "Prior permalinks not saved properly"
Expect.equal pg.Metadata[0].Value page.Metadata[0].Value "Metadata value not saved properly" Expect.equal pg.Revisions page.Revisions "Revisions 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"
} }
let ``All succeeds`` (data: IData) = task { 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.equal pg.UpdatedOn coolPagePublished "Updated On is incorrect"
Expect.isFalse pg.IsInPageList "Is in page list flag should not have been set" Expect.isFalse pg.IsInPageList "Is in page list flag should not have been set"
Expect.equal pg.Text "<h1 id=\"a-cool-page\">A Cool Page</h1>\n<p>It really is cool!</p>\n" "Text is incorrect" Expect.equal pg.Text "<h1 id=\"a-cool-page\">A Cool Page</h1>\n<p>It really is cool!</p>\n" "Text is incorrect"
Expect.hasLength pg.Metadata 2 "There should be 2 metadata items on this page" Expect.equal
Expect.equal pg.Metadata[0].Name "Cool" "Meta item 0 name is incorrect" pg.Metadata [ { Name = "Cool"; Value = "true" }; { Name = "Warm"; Value = "false" } ] "Metadata 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.isEmpty pg.Revisions "Revisions should not have been retrieved" Expect.isEmpty pg.Revisions "Revisions should not have been retrieved"
Expect.isEmpty pg.PriorPermalinks "Prior permalinks 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" Expect.isSome page "A page should have been returned"
let pg = page.Value let pg = page.Value
Expect.equal pg.Id coolPageId "The wrong page was retrieved" 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 { 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 let pg = page.Value
Expect.equal pg.Id coolPageId "The wrong page was retrieved" 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.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
Expect.equal pg.Revisions[0].AsOf coolPagePublished "Revision 0 as-of is incorrect" pg.Revisions
Expect.equal pg.Revisions[0].Text (Markdown "# A Cool Page\n\nIt really is cool!") "Revision 0 text is incorrect" [ { AsOf = coolPagePublished; Text = Markdown "# A Cool Page\n\nIt really is cool!" } ]
Expect.hasLength pg.PriorPermalinks 1 "There should be 1 prior permalink" "Revisions are incorrect"
Expect.equal pg.PriorPermalinks[0] (Permalink "a-cool-pg.html") "Prior permalink 0 is 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 { 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.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.isTrue pg.IsInPageList "Is in page list flag should have been set"
Expect.equal pg.Text "<p>I have been updated" "Text is incorrect" Expect.equal pg.Text "<p>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 [ { Name = "Cool"; Value = "true" } ] "Metadata is incorrect"
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.PriorPermalinks [ Permalink "a-cool-page.html" ] "Prior permalinks are 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
Expect.equal pg.Revisions[0].AsOf (coolPagePublished + Duration.FromHours 5) "As Of for revision 0 incorrect" pg.Revisions
Expect.equal pg.Revisions[0].Text (Html "<p>I have been updated") "Text for revision 0 is incorrect" [ { AsOf = coolPagePublished + Duration.FromHours 5; Text = Html "<p>I have been updated" }
Expect.equal pg.Revisions[1].AsOf coolPagePublished "As Of for revision 1 is incorrect" { 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 { let ``Update succeeds when the page does not exist`` (data: IData) = task {

View File

@ -3,6 +3,7 @@
/// </summary> /// </summary>
module PostDataTests module PostDataTests
open System
open Expecto open Expecto
open MyWebLog open MyWebLog
open MyWebLog.Data open MyWebLog.Data
@ -11,6 +12,12 @@ open NodaTime
/// The ID of the root web log /// The ID of the root web log
let rootId = WebLogId "uSitJEuD3UyzWC9jgOHc8g" 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 ``Add succeeds`` (data: IData) = task {
let post = let post =
{ Id = PostId "a-new-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.PriorPermalinks post.PriorPermalinks "Prior permalinks not saved properly"
Expect.equal it.Revisions post.Revisions "Revisions 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 "<p>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"
}

View File

@ -226,6 +226,39 @@ let postTests = testList "Post" [
do! freshEnvironment () do! freshEnvironment ()
do! PostDataTests.``Add succeeds`` (mkData ()) 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 /// Drop the throwaway PostgreSQL database

View File

@ -225,6 +225,39 @@ let postTests = testList "Post" [
do! freshEnvironment () do! freshEnvironment ()
do! PostDataTests.``Add succeeds`` data.Value 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 /// Drop the throwaway RethinkDB database

View File

@ -1,7 +1,7 @@
module SQLiteDataTests module SQLiteDataTests
open System.IO open System.IO
open BitBadger.Documents open BitBadger.Documents.Sqlite
open Expecto open Expecto
open Microsoft.Extensions.Logging.Abstractions open Microsoft.Extensions.Logging.Abstractions
open MyWebLog open MyWebLog
@ -18,25 +18,44 @@ let dbName =
/// Create a SQLiteData instance for testing /// Create a SQLiteData instance for testing
let mkData () = let mkData () =
Sqlite.Configuration.useConnectionString $"Data Source=./{dbName}" Configuration.useConnectionString $"Data Source=./{dbName}"
let conn = Sqlite.Configuration.dbConn () let conn = Configuration.dbConn ()
SQLiteData(conn, NullLogger<SQLiteData>(), ser) :> IData SQLiteData(conn, NullLogger<SQLiteData>(), 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>()
// SQLiteData(conn, myLogger, ser) :> IData
/// Dispose the connection associated with the SQLiteData instance /// Dispose the connection associated with the SQLiteData instance
let dispose (data: IData) = let dispose (data: IData) =
(data :?> SQLiteData).Conn.Dispose() (data :?> SQLiteData).Conn.Dispose()
/// Create a fresh environment from the root backup /// Create a fresh environment from the root backup
let freshEnvironment (data: IData option) = task { let freshEnvironment (data: IData option) = task {
let env = let! env = task {
match data with match data with
| Some d -> | Some d ->
System.Console.WriteLine "Existing data" return d
d
| None -> | None ->
System.Console.WriteLine $"No data; deleting {dbName}" let d = mkData ()
File.Delete dbName // Thank you, kind Internet stranger... https://stackoverflow.com/a/548297
mkData () 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() do! env.StartUp()
// This exercises Restore for all implementations; all tests are dependent on it working as expected // 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 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 try do! PostDataTests.``Add succeeds`` data
finally dispose 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 /// Delete the SQLite database

View File

@ -272,7 +272,9 @@
"Value": "Low" "Value": "Low"
} }
], ],
"PriorPermalinks": [], "PriorPermalinks": [
"2024/ep-1.html"
],
"Revisions": [ "Revisions": [
{ {
"AsOf": "2024-01-20T22:24:01Z", "AsOf": "2024-01-20T22:24:01Z",