Add theme tests
- Add flags to isolate data impl tests - Make most non-tests private - Add SQLite tests missed in initial development
This commit is contained in:
parent
8183da7d5f
commit
b1a0c207fb
@ -18,7 +18,9 @@ type PostgresThemeData(log: ILogger) =
|
|||||||
let all () =
|
let all () =
|
||||||
log.LogTrace "Theme.all"
|
log.LogTrace "Theme.all"
|
||||||
Custom.list
|
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
|
withoutTemplateText
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger<Rethi
|
|||||||
|
|
||||||
/// Function to exclude template text from themes
|
/// Function to exclude template text from themes
|
||||||
let withoutTemplateText (row: Ast.ReqlExpr) : obj =
|
let withoutTemplateText (row: Ast.ReqlExpr) : obj =
|
||||||
{| Templates = row[nameof Theme.Empty.Templates].Without [| nameof ThemeTemplate.Empty.Text |] |}
|
{| Templates = row[nameof Theme.Empty.Templates].Merge(r.HashMap(nameof ThemeTemplate.Empty.Text, "")) |}
|
||||||
|
|
||||||
/// Ensure field indexes exist, as well as special indexes for selected tables
|
/// Ensure field indexes exist, as well as special indexes for selected tables
|
||||||
let ensureIndexes table fields = backgroundTask {
|
let ensureIndexes table fields = backgroundTask {
|
||||||
@ -445,20 +445,16 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger<Rethi
|
|||||||
return result.Deleted > 0UL
|
return result.Deleted > 0UL
|
||||||
}
|
}
|
||||||
|
|
||||||
member _.FindById pageId webLogId = backgroundTask {
|
member _.FindById pageId webLogId =
|
||||||
let! page =
|
|
||||||
rethink<Page list> {
|
rethink<Page list> {
|
||||||
withTable Table.Page
|
withTable Table.Page
|
||||||
getAll [ pageId ]
|
getAll [ pageId ]
|
||||||
without [ nameof Page.Empty.PriorPermalinks; nameof Page.Empty.Revisions ]
|
filter (nameof Page.Empty.WebLogId) webLogId
|
||||||
|
merge (r.HashMap(nameof Page.Empty.PriorPermalinks, [||])
|
||||||
|
.With(nameof Page.Empty.Revisions, [||]))
|
||||||
result; withRetryDefault
|
result; withRetryDefault
|
||||||
}
|
}
|
||||||
|> tryFirst <| conn
|
|> tryFirst <| conn
|
||||||
return
|
|
||||||
page
|
|
||||||
|> Option.filter (fun pg -> pg.WebLogId = webLogId)
|
|
||||||
|> Option.map (fun pg -> { pg with Revisions = []; PriorPermalinks = [] })
|
|
||||||
}
|
|
||||||
|
|
||||||
member _.FindByPermalink permalink webLogId =
|
member _.FindByPermalink permalink webLogId =
|
||||||
rethink<Page list> {
|
rethink<Page list> {
|
||||||
@ -590,20 +586,16 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger<Rethi
|
|||||||
return result.Deleted > 0UL
|
return result.Deleted > 0UL
|
||||||
}
|
}
|
||||||
|
|
||||||
member _.FindById postId webLogId = backgroundTask {
|
member _.FindById postId webLogId =
|
||||||
let! post =
|
|
||||||
rethink<Post list> {
|
rethink<Post list> {
|
||||||
withTable Table.Post
|
withTable Table.Post
|
||||||
getAll [ postId ]
|
getAll [ postId ]
|
||||||
without [ nameof Post.Empty.PriorPermalinks; nameof Post.Empty.Revisions ]
|
filter (nameof Post.Empty.WebLogId) webLogId
|
||||||
|
merge (r.HashMap(nameof Post.Empty.PriorPermalinks, [||])
|
||||||
|
.With(nameof Post.Empty.Revisions, [||]))
|
||||||
result; withRetryDefault
|
result; withRetryDefault
|
||||||
}
|
}
|
||||||
|> tryFirst <| 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> {
|
||||||
@ -848,12 +840,14 @@ type RethinkDbData(conn: Net.IConnection, config: DataConfig, log: ILogger<Rethi
|
|||||||
resultOption; withRetryOptionDefault conn
|
resultOption; withRetryOptionDefault conn
|
||||||
}
|
}
|
||||||
|
|
||||||
member _.FindByIdWithoutText themeId = rethink<Theme> {
|
member _.FindByIdWithoutText themeId =
|
||||||
|
rethink<Theme list> {
|
||||||
withTable Table.Theme
|
withTable Table.Theme
|
||||||
get themeId
|
getAll [ themeId ]
|
||||||
merge withoutTemplateText
|
merge withoutTemplateText
|
||||||
resultOption; withRetryOptionDefault conn
|
result; withRetryDefault
|
||||||
}
|
}
|
||||||
|
|> tryFirst <| conn
|
||||||
|
|
||||||
member this.Delete themeId = backgroundTask {
|
member this.Delete themeId = backgroundTask {
|
||||||
match! this.FindByIdWithoutText themeId with
|
match! this.FindByIdWithoutText themeId with
|
||||||
|
@ -29,6 +29,10 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) =
|
|||||||
return { page with Revisions = revisions }
|
return { page with Revisions = revisions }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a page with no prior permalinks
|
||||||
|
let pageWithoutLinks rdr =
|
||||||
|
{ fromData<Page> rdr with PriorPermalinks = [] }
|
||||||
|
|
||||||
/// Update a page's revisions
|
/// Update a page's revisions
|
||||||
let updatePageRevisions (pageId: PageId) oldRevs newRevs =
|
let updatePageRevisions (pageId: PageId) oldRevs newRevs =
|
||||||
log.LogTrace "Page.updatePageRevisions"
|
log.LogTrace "Page.updatePageRevisions"
|
||||||
@ -102,7 +106,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 ])
|
||||||
(fun rdr -> { fromData<Page> rdr with PriorPermalinks = [] })
|
pageWithoutLinks
|
||||||
|
|
||||||
/// 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 =
|
||||||
@ -138,7 +142,7 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) =
|
|||||||
conn.customList
|
conn.customList
|
||||||
$"{Document.Query.selectByWebLog Table.Page} ORDER BY LOWER({titleField}) LIMIT @pageSize OFFSET @toSkip"
|
$"{Document.Query.selectByWebLog Table.Page} ORDER BY LOWER({titleField}) LIMIT @pageSize OFFSET @toSkip"
|
||||||
[ webLogParam webLogId; SqliteParameter("@pageSize", 26); SqliteParameter("@toSkip", (pageNbr - 1) * 25) ]
|
[ webLogParam webLogId; SqliteParameter("@pageSize", 26); SqliteParameter("@toSkip", (pageNbr - 1) * 25) ]
|
||||||
fromData<Page>
|
(fun rdr -> { pageWithoutLinks rdr with Metadata = [] })
|
||||||
|
|
||||||
/// Update a page
|
/// Update a page
|
||||||
let update (page: Page) = backgroundTask {
|
let update (page: Page) = backgroundTask {
|
||||||
|
@ -11,7 +11,7 @@ open MyWebLog.Data
|
|||||||
let rootId = WebLogId "uSitJEuD3UyzWC9jgOHc8g"
|
let rootId = WebLogId "uSitJEuD3UyzWC9jgOHc8g"
|
||||||
|
|
||||||
/// The ID of the Favorites category
|
/// The ID of the Favorites category
|
||||||
let favoritesId = CategoryId "S5JflPsJ9EG7gA2LD4m92A"
|
let private favoritesId = CategoryId "S5JflPsJ9EG7gA2LD4m92A"
|
||||||
|
|
||||||
let ``Add succeeds`` (data: IData) = task {
|
let ``Add succeeds`` (data: IData) = task {
|
||||||
let category =
|
let category =
|
||||||
|
@ -10,16 +10,16 @@ open MyWebLog.Data
|
|||||||
open NodaTime
|
open NodaTime
|
||||||
|
|
||||||
/// The ID of the root web log
|
/// The ID of the root web log
|
||||||
let rootId = WebLogId "uSitJEuD3UyzWC9jgOHc8g"
|
let private rootId = CategoryDataTests.rootId
|
||||||
|
|
||||||
/// The ID of the "A cool page" page
|
/// 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
|
/// 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
|
/// The ID of the "Yet Another Page" page
|
||||||
let otherPageId = PageId "KouRjvSmm0Wz6TMD8xf67A"
|
let private otherPageId = PageId "KouRjvSmm0Wz6TMD8xf67A"
|
||||||
|
|
||||||
let ``Add succeeds`` (data: IData) = task {
|
let ``Add succeeds`` (data: IData) = task {
|
||||||
let page =
|
let page =
|
||||||
|
@ -10,41 +10,41 @@ open MyWebLog.Data
|
|||||||
open NodaTime
|
open NodaTime
|
||||||
|
|
||||||
/// The ID of the root web log
|
/// The ID of the root web log
|
||||||
let rootId = WebLogId "uSitJEuD3UyzWC9jgOHc8g"
|
let private rootId = CategoryDataTests.rootId
|
||||||
|
|
||||||
/// The ID of podcast episode 1
|
/// The ID of podcast episode 1
|
||||||
let episode1 = PostId "osxMfWGlAkyugUbJ1-xD1g"
|
let private episode1 = PostId "osxMfWGlAkyugUbJ1-xD1g"
|
||||||
|
|
||||||
/// The published instant for episode 1
|
/// 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
|
/// The ID of podcast episode 2
|
||||||
let episode2 = PostId "l4_Eh4aFO06SqqJjOymNzA"
|
let private episode2 = PostId "l4_Eh4aFO06SqqJjOymNzA"
|
||||||
|
|
||||||
/// The ID of "Something May Happen" post
|
/// The ID of "Something May Happen" post
|
||||||
let something = PostId "QweKbWQiOkqqrjEdgP9wwg"
|
let private something = PostId "QweKbWQiOkqqrjEdgP9wwg"
|
||||||
|
|
||||||
/// The published instant for "Something May Happen" post
|
/// 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
|
/// The ID of "An Incomplete Thought" post
|
||||||
let incomplete = PostId "VweKbWQiOkqqrjEdgP9wwg"
|
let private incomplete = PostId "VweKbWQiOkqqrjEdgP9wwg"
|
||||||
|
|
||||||
/// The ID of "Test Post 1" post
|
/// The ID of "Test Post 1" post
|
||||||
let testPost1 = PostId "RCsCU2puYEmkpzotoi8p4g"
|
let private testPost1 = PostId "RCsCU2puYEmkpzotoi8p4g"
|
||||||
|
|
||||||
/// The published instant for "Test Post 1" post
|
/// 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"
|
/// 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
|
/// 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})"
|
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
|
/// Ensure that a list of posts has no revisions or prior permalinks
|
||||||
let ensureEmpty posts =
|
let private ensureEmpty posts =
|
||||||
for post in posts do
|
for post in posts do
|
||||||
Expect.isEmpty post.Revisions $"There should have been no revisions (post ID {post.Id})"
|
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})"
|
Expect.isEmpty post.PriorPermalinks $"There should have been no prior permalinks (post ID {post.Id})"
|
||||||
|
@ -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
|
/// Drop the throwaway PostgreSQL database
|
||||||
let environmentCleanUp = test "Clean Up" {
|
let environmentCleanUp = test "Clean Up" {
|
||||||
if db.IsSome then db.Value.Dispose()
|
if db.IsSome then db.Value.Dispose()
|
||||||
@ -429,5 +475,6 @@ let all =
|
|||||||
pageTests
|
pageTests
|
||||||
postTests
|
postTests
|
||||||
tagMapTests
|
tagMapTests
|
||||||
|
themeTests
|
||||||
environmentCleanUp ]
|
environmentCleanUp ]
|
||||||
|> testSequenced
|
|> testSequenced
|
||||||
|
@ -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
|
/// Drop the throwaway RethinkDB database
|
||||||
let environmentCleanUp = testTask "Clean Up" {
|
let environmentCleanUp = testTask "Clean Up" {
|
||||||
do! disposeData ()
|
do! disposeData ()
|
||||||
@ -429,5 +475,6 @@ let all =
|
|||||||
pageTests
|
pageTests
|
||||||
postTests
|
postTests
|
||||||
tagMapTests
|
tagMapTests
|
||||||
|
themeTests
|
||||||
environmentCleanUp ]
|
environmentCleanUp ]
|
||||||
|> testSequenced
|
|> testSequenced
|
||||||
|
@ -269,6 +269,18 @@ let pageTests = testList "Page" [
|
|||||||
finally dispose data
|
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" [
|
testList "Update" [
|
||||||
testTask "succeeds when the page exists" {
|
testTask "succeeds when the page exists" {
|
||||||
let data = mkData ()
|
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
|
/// Delete the SQLite database
|
||||||
let environmentCleanUp = test "Clean Up" {
|
let environmentCleanUp = test "Clean Up" {
|
||||||
File.Delete dbName
|
File.Delete dbName
|
||||||
@ -617,5 +697,6 @@ let all =
|
|||||||
pageTests
|
pageTests
|
||||||
postTests
|
postTests
|
||||||
tagMapTests
|
tagMapTests
|
||||||
|
themeTests
|
||||||
environmentCleanUp ]
|
environmentCleanUp ]
|
||||||
|> testSequenced
|
|> testSequenced
|
||||||
|
@ -8,13 +8,13 @@ open MyWebLog
|
|||||||
open MyWebLog.Data
|
open MyWebLog.Data
|
||||||
|
|
||||||
/// The ID of the root web log
|
/// The ID of the root web log
|
||||||
let rootId = CategoryDataTests.rootId
|
let private rootId = CategoryDataTests.rootId
|
||||||
|
|
||||||
/// The ID of the f# tag
|
/// The ID of the f# tag
|
||||||
let fSharpId = TagMapId "Icm027noqE-rPHKZA98vAw"
|
let private fSharpId = TagMapId "Icm027noqE-rPHKZA98vAw"
|
||||||
|
|
||||||
/// The ID of the ghoti tag
|
/// 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 ``FindById succeeds when a tag mapping is found`` (data: IData) = task {
|
||||||
let! tagMap = data.TagMap.FindById fSharpId rootId
|
let! tagMap = data.TagMap.FindById fSharpId rootId
|
||||||
|
121
src/MyWebLog.Tests/Data/ThemeDataTests.fs
Normal file
121
src/MyWebLog.Tests/Data/ThemeDataTests.fs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/// <summary>
|
||||||
|
/// Integration tests for <see cref="IThemeData" /> implementations
|
||||||
|
/// </summary>
|
||||||
|
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 = "<h1>{{ values_here }}</h1>" }
|
||||||
|
{ Name = "single-post"; Text = "<p>{{ 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 "<h1>{{ values_here }}</h1>" "Template 0 text incorrect"
|
||||||
|
Expect.equal it.Templates[1].Name "single-post" "Template 1 name incorrect"
|
||||||
|
Expect.equal it.Templates[1].Text "<p>{{ 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 = "<h1>{{ values_there }}</h1>" }
|
||||||
|
{ Name = "layout"; Text = "<!DOCTYPE html><etc />" }
|
||||||
|
{ Name = "single-post"; Text = "<p>{{ 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 "<h1>{{ values_there }}</h1>" "Template 0 text incorrect"
|
||||||
|
Expect.equal it.Templates[1].Name "layout" "Template 1 name incorrect"
|
||||||
|
Expect.equal it.Templates[1].Text "<!DOCTYPE html><etc />" "Template 1 text incorrect"
|
||||||
|
Expect.equal it.Templates[2].Name "single-post" "Template 2 name incorrect"
|
||||||
|
Expect.equal it.Templates[2].Text "<p>{{ 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"
|
||||||
|
}
|
@ -14,6 +14,7 @@
|
|||||||
<Compile Include="Data\PageDataTests.fs" />
|
<Compile Include="Data\PageDataTests.fs" />
|
||||||
<Compile Include="Data\PostDataTests.fs" />
|
<Compile Include="Data\PostDataTests.fs" />
|
||||||
<Compile Include="Data\TagMapDataTests.fs" />
|
<Compile Include="Data\TagMapDataTests.fs" />
|
||||||
|
<Compile Include="Data\ThemeDataTests.fs" />
|
||||||
<Compile Include="Data\RethinkDbDataTests.fs" />
|
<Compile Include="Data\RethinkDbDataTests.fs" />
|
||||||
<Compile Include="Data\SQLiteDataTests.fs" />
|
<Compile Include="Data\SQLiteDataTests.fs" />
|
||||||
<Compile Include="Data\PostgresDataTests.fs" />
|
<Compile Include="Data\PostgresDataTests.fs" />
|
||||||
|
@ -1,13 +1,25 @@
|
|||||||
open Expecto
|
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" [
|
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" [
|
testList "Data" [
|
||||||
ConvertersTests.all
|
if not dbOnly then ConvertersTests.all
|
||||||
UtilsTests.all
|
if not dbOnly then UtilsTests.all
|
||||||
RethinkDbDataTests.all
|
if not dbOnly || (dbOnly && rethinkOnly) then RethinkDbDataTests.all
|
||||||
SQLiteDataTests.all
|
if not dbOnly || (dbOnly && sqliteOnly) then SQLiteDataTests.all
|
||||||
PostgresDataTests.all
|
if not dbOnly || (dbOnly && postgresOnly) then PostgresDataTests.all
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user