Add test project

- Create /data directory if necessary (#38)
This commit is contained in:
Daniel J. Summers 2024-01-06 17:04:05 -05:00
parent 75e13a5999
commit 2c052c1813
7 changed files with 162 additions and 1 deletions

View File

@ -214,6 +214,7 @@ type SQLiteData(conn: SqliteConnection, log: ILogger<SQLiteData>, ser: JsonSeria
|> Option.map (Utils.deserialize<Chapter list> ser) |> Option.map (Utils.deserialize<Chapter list> ser)
ChapterFile = Map.tryString "chapter_file" epRdr ChapterFile = Map.tryString "chapter_file" epRdr
ChapterType = Map.tryString "chapter_type" epRdr ChapterType = Map.tryString "chapter_type" epRdr
ChapterWaypoints = None
TranscriptUrl = Map.tryString "transcript_url" epRdr TranscriptUrl = Map.tryString "transcript_url" epRdr
TranscriptType = Map.tryString "transcript_type" epRdr TranscriptType = Map.tryString "transcript_type" epRdr
TranscriptLang = Map.tryString "transcript_lang" epRdr TranscriptLang = Map.tryString "transcript_lang" epRdr

View File

@ -656,6 +656,9 @@ type EditPostModel = {
/// The type of the chapter file (optional; defaults to application/json+chapters if chapterFile is provided) /// The type of the chapter file (optional; defaults to application/json+chapters if chapterFile is provided)
ChapterType: string ChapterType: string
/// Whether the chapter file (or chapters) contains/contain waypoints
ContainsWaypoints: bool
/// The URL for the transcript (may be permalink; optional) /// The URL for the transcript (may be permalink; optional)
TranscriptUrl: string TranscriptUrl: string
@ -714,6 +717,7 @@ type EditPostModel = {
Explicit = defaultArg (episode.Explicit |> Option.map string) "" Explicit = defaultArg (episode.Explicit |> Option.map string) ""
ChapterFile = defaultArg episode.ChapterFile "" ChapterFile = defaultArg episode.ChapterFile ""
ChapterType = defaultArg episode.ChapterType "" ChapterType = defaultArg episode.ChapterType ""
ContainsWaypoints = defaultArg episode.ChapterWaypoints false
TranscriptUrl = defaultArg episode.TranscriptUrl "" TranscriptUrl = defaultArg episode.TranscriptUrl ""
TranscriptType = defaultArg episode.TranscriptType "" TranscriptType = defaultArg episode.TranscriptType ""
TranscriptLang = defaultArg episode.TranscriptLang "" TranscriptLang = defaultArg episode.TranscriptLang ""
@ -775,6 +779,7 @@ type EditPostModel = {
Chapters = match post.Episode with Some e -> e.Chapters | None -> None Chapters = match post.Episode with Some e -> e.Chapters | None -> None
ChapterFile = noneIfBlank this.ChapterFile ChapterFile = noneIfBlank this.ChapterFile
ChapterType = noneIfBlank this.ChapterType ChapterType = noneIfBlank this.ChapterType
ChapterWaypoints = if this.ContainsWaypoints then Some true else None
TranscriptUrl = noneIfBlank this.TranscriptUrl TranscriptUrl = noneIfBlank this.TranscriptUrl
TranscriptType = noneIfBlank this.TranscriptType TranscriptType = noneIfBlank this.TranscriptType
TranscriptLang = noneIfBlank this.TranscriptLang TranscriptLang = noneIfBlank this.TranscriptLang

View File

@ -0,0 +1,119 @@
module Domain
open System
open Expecto
open MyWebLog
open NodaTime
/// Tests for the NodaTime-wrapping module
let nodaTests =
testList "Noda" [
test "epoch succeeds" {
Expect.equal
(Noda.epoch.ToDateTimeUtc())
(DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc))
"The Unix epoch value is not correct"
}
test "toSecondsPrecision succeeds" {
let testDate = Instant.FromDateTimeUtc(DateTime(1970, 1, 1, 0, 0, 0, 444, DateTimeKind.Utc))
// testDate.
Expect.equal
((Noda.toSecondsPrecision testDate).ToDateTimeUtc())
(Noda.epoch.ToDateTimeUtc())
"Instant value was not rounded to seconds precision"
}
test "fromDateTime succeeds" {
let testDate = DateTime(1970, 1, 1, 0, 0, 0, 444, DateTimeKind.Utc)
Expect.equal (Noda.fromDateTime testDate) Noda.epoch "fromDateTime did not truncate to seconds"
}
]
/// Tests for the AccessLevel type
let accessLevelTests =
testList "AccessLevel" [
testList "Parse" [
test "\"Author\" succeeds" {
Expect.equal Author (AccessLevel.Parse "Author") "Author not parsed correctly"
}
test "\"Editor\" succeeds" {
Expect.equal Editor (AccessLevel.Parse "Editor") "Editor not parsed correctly"
}
test "\"WebLogAdmin\" succeeds" {
Expect.equal WebLogAdmin (AccessLevel.Parse "WebLogAdmin") "WebLogAdmin not parsed correctly"
}
test "\"Administrator\" succeeds" {
Expect.equal Administrator (AccessLevel.Parse "Administrator") "Administrator not parsed correctly"
}
test "fails when given an unrecognized value" {
Expect.throwsT<ArgumentException>
(fun () -> ignore (AccessLevel.Parse "Hacker")) "Invalid value should have raised an exception"
}
]
testList "ToString" [
test "Author succeeds" {
Expect.equal (string Author) "Author" "Author string incorrect"
}
test "Editor succeeds" {
Expect.equal (string Editor) "Editor" "Editor string incorrect"
}
test "WebLogAdmin succeeds" {
Expect.equal (string WebLogAdmin) "WebLogAdmin" "WebLogAdmin string incorrect"
}
test "Administrator succeeds" {
Expect.equal (string Administrator) "Administrator" "Administrator string incorrect"
}
]
testList "HasAccess" [
test "Author has Author access" {
Expect.isTrue (Author.HasAccess Author) "Author should have Author access"
}
test "Author does not have Editor access" {
Expect.isFalse (Author.HasAccess Editor) "Author should not have Editor access"
}
test "Author does not have WebLogAdmin access" {
Expect.isFalse (Author.HasAccess WebLogAdmin) "Author should not have WebLogAdmin access"
}
test "Author does not have Administrator access" {
Expect.isFalse (Author.HasAccess Administrator) "Author should not have Administrator access"
}
test "Editor has Author access" {
Expect.isTrue (Editor.HasAccess Author) "Editor should have Author access"
}
test "Editor has Editor access" {
Expect.isTrue (Editor.HasAccess Editor) "Editor should have Editor access"
}
test "Editor does not have WebLogAdmin access" {
Expect.isFalse (Editor.HasAccess WebLogAdmin) "Editor should not have WebLogAdmin access"
}
test "Editor does not have Administrator access" {
Expect.isFalse (Editor.HasAccess Administrator) "Editor should not have Administrator access"
}
test "WebLogAdmin has Author access" {
Expect.isTrue (WebLogAdmin.HasAccess Author) "WebLogAdmin should have Author access"
}
test "WebLogAdmin has Editor access" {
Expect.isTrue (WebLogAdmin.HasAccess Editor) "WebLogAdmin should have Editor access"
}
test "WebLogAdmin has WebLogAdmin access" {
Expect.isTrue (WebLogAdmin.HasAccess WebLogAdmin) "WebLogAdmin should have WebLogAdmin access"
}
test "WebLogAdmin does not have Administrator access" {
Expect.isFalse (WebLogAdmin.HasAccess Administrator) "WebLogAdmin should not have Administrator access"
}
test "Administrator has Author access" {
Expect.isTrue (Administrator.HasAccess Author) "Administrator should have Author access"
}
test "Administrator has Editor access" {
Expect.isTrue (Administrator.HasAccess Editor) "Administrator should have Editor access"
}
test "Administrator has WebLogAdmin access" {
Expect.isTrue (Administrator.HasAccess WebLogAdmin) "Administrator should have WebLogAdmin access"
}
test "Administrator has Administrator access" {
Expect.isTrue (Administrator.HasAccess Administrator) "Administrator should have Administrator access"
}
]
]
/// All tests for the Domain namespace
let all = testList "Domain" [ nodaTests; accessLevelTests ]

View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<Compile Include="Domain.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Expecto" Version="10.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyWebLog\MyWebLog.fsproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,9 @@
open Expecto
let allTests =
testList
"MyWebLog"
[ Domain.all ]
[<EntryPoint>]
let main args = runTestsWithCLIArgs [] args allTests

View File

@ -9,6 +9,8 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MyWebLog.Data", "MyWebLog.D
EndProject EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MyWebLog", "MyWebLog\MyWebLog.fsproj", "{5655B63D-429F-4CCD-A14C-FBD74D987ECB}" Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MyWebLog", "MyWebLog\MyWebLog.fsproj", "{5655B63D-429F-4CCD-A14C-FBD74D987ECB}"
EndProject EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MyWebLog.Tests", "MyWebLog.Tests\MyWebLog.Tests.fsproj", "{D927D39F-26EC-4A54-989A-9D474F232398}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -27,6 +29,10 @@ Global
{5655B63D-429F-4CCD-A14C-FBD74D987ECB}.Debug|Any CPU.Build.0 = Debug|Any CPU {5655B63D-429F-4CCD-A14C-FBD74D987ECB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5655B63D-429F-4CCD-A14C-FBD74D987ECB}.Release|Any CPU.ActiveCfg = Release|Any CPU {5655B63D-429F-4CCD-A14C-FBD74D987ECB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5655B63D-429F-4CCD-A14C-FBD74D987ECB}.Release|Any CPU.Build.0 = Release|Any CPU {5655B63D-429F-4CCD-A14C-FBD74D987ECB}.Release|Any CPU.Build.0 = Release|Any CPU
{D927D39F-26EC-4A54-989A-9D474F232398}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D927D39F-26EC-4A54-989A-9D474F232398}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D927D39F-26EC-4A54-989A-9D474F232398}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D927D39F-26EC-4A54-989A-9D474F232398}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -50,6 +50,7 @@ type RedirectRuleMiddleware(next: RequestDelegate, log: ILogger<RedirectRuleMidd
open System open System
open System.IO
open BitBadger.Documents open BitBadger.Documents
open Microsoft.Extensions.DependencyInjection open Microsoft.Extensions.DependencyInjection
open MyWebLog.Data open MyWebLog.Data
@ -98,6 +99,7 @@ module DataImplementation =
log.LogInformation $"Using PostgreSQL database {conn.Database}" log.LogInformation $"Using PostgreSQL database {conn.Database}"
PostgresData(log, Json.configure (JsonSerializer.CreateDefault())) PostgresData(log, Json.configure (JsonSerializer.CreateDefault()))
else else
if not (Directory.Exists "./data") then Directory.CreateDirectory "./data" |> ignore
createSQLite "Data Source=./data/myweblog.db;Cache=Shared" createSQLite "Data Source=./data/myweblog.db;Cache=Shared"
@ -122,7 +124,6 @@ let showHelp () =
Task.FromResult() Task.FromResult()
open System.IO
open BitBadger.AspNetCore.CanonicalDomains open BitBadger.AspNetCore.CanonicalDomains
open Giraffe open Giraffe
open Giraffe.EndpointRouting open Giraffe.EndpointRouting