Version 2.1 #41

Merged
danieljsummers merged 123 commits from version-2.1 into main 2024-03-27 00:13:28 +00:00
2 changed files with 147 additions and 141 deletions
Showing only changes of commit cbe391fa89 - Show all commits

View File

@ -96,11 +96,10 @@ type DisplayCustomFeed = {
|> Option.defaultValue "--INVALID; DELETE THIS FEED--" |> Option.defaultValue "--INVALID; DELETE THIS FEED--"
|> sprintf "Category: %s" |> sprintf "Category: %s"
| Tag tag -> $"Tag: {tag}" | Tag tag -> $"Tag: {tag}"
{ Id = string feed.Id { Id = string feed.Id
Source = source Source = source
Path = string feed.Path Path = string feed.Path
IsPodcast = Option.isSome feed.Podcast IsPodcast = Option.isSome feed.Podcast }
}
/// Details about a page used to display page lists /// Details about a page used to display page lists
@ -138,18 +137,17 @@ type DisplayPage = {
} with } with
/// Create a minimal display page (no text or metadata) from a database page /// Create a minimal display page (no text or metadata) from a database page
static member FromPageMinimal (webLog: WebLog) (page: Page) = { static member FromPageMinimal (webLog: WebLog) (page: Page) =
Id = string page.Id { Id = string page.Id
AuthorId = string page.AuthorId AuthorId = string page.AuthorId
Title = page.Title Title = page.Title
Permalink = string page.Permalink Permalink = string page.Permalink
PublishedOn = webLog.LocalTime page.PublishedOn PublishedOn = webLog.LocalTime page.PublishedOn
UpdatedOn = webLog.LocalTime page.UpdatedOn UpdatedOn = webLog.LocalTime page.UpdatedOn
IsInPageList = page.IsInPageList IsInPageList = page.IsInPageList
IsDefault = string page.Id = webLog.DefaultPage IsDefault = string page.Id = webLog.DefaultPage
Text = "" Text = ""
Metadata = [] Metadata = [] }
}
/// Create a display page from a database page /// Create a display page from a database page
static member FromPage webLog page = static member FromPage webLog page =
@ -173,11 +171,10 @@ type DisplayRevision = {
} with } with
/// Create a display revision from an actual revision /// Create a display revision from an actual revision
static member FromRevision (webLog: WebLog) (rev : Revision) = { static member FromRevision (webLog: WebLog) (rev : Revision) =
AsOf = rev.AsOf.ToDateTimeUtc() { AsOf = rev.AsOf.ToDateTimeUtc()
AsOfLocal = webLog.LocalTime rev.AsOf AsOfLocal = webLog.LocalTime rev.AsOf
Format = rev.Text.SourceType Format = rev.Text.SourceType }
}
open System.IO open System.IO
@ -205,14 +202,13 @@ type DisplayTheme = {
} with } with
/// Create a display theme from a theme /// Create a display theme from a theme
static member FromTheme inUseFunc (theme: Theme) = { static member FromTheme inUseFunc (theme: Theme) =
Id = string theme.Id { Id = string theme.Id
Name = theme.Name Name = theme.Name
Version = theme.Version Version = theme.Version
TemplateCount = List.length theme.Templates TemplateCount = List.length theme.Templates
IsInUse = inUseFunc theme.Id IsInUse = inUseFunc theme.Id
IsOnDisk = File.Exists $"{theme.Id}-theme.zip" IsOnDisk = File.Exists $"{theme.Id}-theme.zip" }
}
/// Information about an uploaded file used for display /// Information about an uploaded file used for display
@ -238,12 +234,11 @@ type DisplayUpload = {
static member FromUpload (webLog: WebLog) (source: UploadDestination) (upload: Upload) = static member FromUpload (webLog: WebLog) (source: UploadDestination) (upload: Upload) =
let path = string upload.Path let path = string upload.Path
let name = Path.GetFileName path let name = Path.GetFileName path
{ Id = string upload.Id { Id = string upload.Id
Name = name Name = name
Path = path.Replace(name, "") Path = path.Replace(name, "")
UpdatedOn = Some (webLog.LocalTime upload.UpdatedOn) UpdatedOn = Some (webLog.LocalTime upload.UpdatedOn)
Source = string source Source = string source }
}
/// View model to display a user's information /// View model to display a user's information
@ -278,17 +273,16 @@ type DisplayUser = {
} with } with
/// Construct a displayed user from a web log user /// Construct a displayed user from a web log user
static member FromUser (webLog: WebLog) (user: WebLogUser) = { static member FromUser (webLog: WebLog) (user: WebLogUser) =
Id = string user.Id { Id = string user.Id
Email = user.Email Email = user.Email
FirstName = user.FirstName FirstName = user.FirstName
LastName = user.LastName LastName = user.LastName
PreferredName = user.PreferredName PreferredName = user.PreferredName
Url = defaultArg user.Url "" Url = defaultArg user.Url ""
AccessLevel = string user.AccessLevel AccessLevel = string user.AccessLevel
CreatedOn = webLog.LocalTime user.CreatedOn CreatedOn = webLog.LocalTime user.CreatedOn
LastSeenOn = user.LastSeenOn |> Option.map webLog.LocalTime |> Option.toNullable LastSeenOn = user.LastSeenOn |> Option.map webLog.LocalTime |> Option.toNullable }
}
/// View model for editing categories /// View model for editing categories
@ -311,13 +305,12 @@ type EditCategoryModel = {
} with } with
/// Create an edit model from an existing category /// Create an edit model from an existing category
static member FromCategory (cat: Category) = { static member FromCategory (cat: Category) =
CategoryId = string cat.Id { CategoryId = string cat.Id
Name = cat.Name Name = cat.Name
Slug = cat.Slug Slug = cat.Slug
Description = defaultArg cat.Description "" Description = defaultArg cat.Description ""
ParentId = cat.ParentId |> Option.map string |> Option.defaultValue "" ParentId = cat.ParentId |> Option.map string |> Option.defaultValue "" }
}
/// Is this a new category? /// Is this a new category?
member this.IsNew = member this.IsNew =
@ -392,29 +385,28 @@ type EditCustomFeedModel = {
} with } with
/// An empty custom feed model /// An empty custom feed model
static member Empty = { static member Empty =
Id = "" { Id = ""
SourceType = "category" SourceType = "category"
SourceValue = "" SourceValue = ""
Path = "" Path = ""
IsPodcast = false IsPodcast = false
Title = "" Title = ""
Subtitle = "" Subtitle = ""
ItemsInFeed = 25 ItemsInFeed = 25
Summary = "" Summary = ""
DisplayedAuthor = "" DisplayedAuthor = ""
Email = "" Email = ""
ImageUrl = "" ImageUrl = ""
AppleCategory = "" AppleCategory = ""
AppleSubcategory = "" AppleSubcategory = ""
Explicit = "no" Explicit = "no"
DefaultMediaType = "audio/mpeg" DefaultMediaType = "audio/mpeg"
MediaBaseUrl = "" MediaBaseUrl = ""
FundingUrl = "" FundingUrl = ""
FundingText = "" FundingText = ""
PodcastGuid = "" PodcastGuid = ""
Medium = "" Medium = "" }
}
/// Create a model from a custom feed /// Create a model from a custom feed
static member FromFeed (feed: CustomFeed) = static member FromFeed (feed: CustomFeed) =
@ -494,13 +486,12 @@ type EditMyInfoModel = {
} with } with
/// Create an edit model from a user /// Create an edit model from a user
static member FromUser (user: WebLogUser) = { static member FromUser (user: WebLogUser) =
FirstName = user.FirstName { FirstName = user.FirstName
LastName = user.LastName LastName = user.LastName
PreferredName = user.PreferredName PreferredName = user.PreferredName
NewPassword = "" NewPassword = ""
NewPasswordConfirm = "" NewPasswordConfirm = "" }
}
/// View model to edit a page /// View model to edit a page
@ -541,16 +532,15 @@ type EditPageModel = {
| Some rev -> rev | Some rev -> rev
| None -> Revision.Empty | None -> Revision.Empty
let page = if page.Metadata |> List.isEmpty then { page with Metadata = [ MetaItem.Empty ] } else page let page = if page.Metadata |> List.isEmpty then { page with Metadata = [ MetaItem.Empty ] } else page
{ PageId = string page.Id { PageId = string page.Id
Title = page.Title Title = page.Title
Permalink = string page.Permalink Permalink = string page.Permalink
Template = defaultArg page.Template "" Template = defaultArg page.Template ""
IsShownInPageList = page.IsInPageList IsShownInPageList = page.IsInPageList
Source = latest.Text.SourceType Source = latest.Text.SourceType
Text = latest.Text.Text Text = latest.Text.Text
MetaNames = page.Metadata |> List.map _.Name |> Array.ofList MetaNames = page.Metadata |> List.map _.Name |> Array.ofList
MetaValues = page.Metadata |> List.map _.Value |> Array.ofList MetaValues = page.Metadata |> List.map _.Value |> Array.ofList }
}
/// Whether this is a new page /// Whether this is a new page
member this.IsNew = member this.IsNew =
@ -697,41 +687,40 @@ type EditPostModel = {
| None -> Revision.Empty | None -> Revision.Empty
let post = if post.Metadata |> List.isEmpty then { post with Metadata = [ MetaItem.Empty ] } else post let post = if post.Metadata |> List.isEmpty then { post with Metadata = [ MetaItem.Empty ] } else post
let episode = defaultArg post.Episode Episode.Empty let episode = defaultArg post.Episode Episode.Empty
{ PostId = string post.Id { PostId = string post.Id
Title = post.Title Title = post.Title
Permalink = string post.Permalink Permalink = string post.Permalink
Source = latest.Text.SourceType Source = latest.Text.SourceType
Text = latest.Text.Text Text = latest.Text.Text
Tags = String.Join(", ", post.Tags) Tags = String.Join(", ", post.Tags)
Template = defaultArg post.Template "" Template = defaultArg post.Template ""
CategoryIds = post.CategoryIds |> List.map string |> Array.ofList CategoryIds = post.CategoryIds |> List.map string |> Array.ofList
Status = string post.Status Status = string post.Status
DoPublish = false DoPublish = false
MetaNames = post.Metadata |> List.map _.Name |> Array.ofList MetaNames = post.Metadata |> List.map _.Name |> Array.ofList
MetaValues = post.Metadata |> List.map _.Value |> Array.ofList MetaValues = post.Metadata |> List.map _.Value |> Array.ofList
SetPublished = false SetPublished = false
PubOverride = post.PublishedOn |> Option.map webLog.LocalTime |> Option.toNullable PubOverride = post.PublishedOn |> Option.map webLog.LocalTime |> Option.toNullable
SetUpdated = false SetUpdated = false
IsEpisode = Option.isSome post.Episode IsEpisode = Option.isSome post.Episode
Media = episode.Media Media = episode.Media
Length = episode.Length Length = episode.Length
Duration = defaultArg (episode.FormatDuration()) "" Duration = defaultArg (episode.FormatDuration()) ""
MediaType = defaultArg episode.MediaType "" MediaType = defaultArg episode.MediaType ""
ImageUrl = defaultArg episode.ImageUrl "" ImageUrl = defaultArg episode.ImageUrl ""
Subtitle = defaultArg episode.Subtitle "" Subtitle = defaultArg episode.Subtitle ""
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 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 ""
TranscriptCaptions = defaultArg episode.TranscriptCaptions false TranscriptCaptions = defaultArg episode.TranscriptCaptions false
SeasonNumber = defaultArg episode.SeasonNumber 0 SeasonNumber = defaultArg episode.SeasonNumber 0
SeasonDescription = defaultArg episode.SeasonDescription "" SeasonDescription = defaultArg episode.SeasonDescription ""
EpisodeNumber = defaultArg (episode.EpisodeNumber |> Option.map string) "" EpisodeNumber = defaultArg (episode.EpisodeNumber |> Option.map string) ""
EpisodeDescription = defaultArg episode.EpisodeDescription "" EpisodeDescription = defaultArg episode.EpisodeDescription "" }
}
/// Whether this is a new post /// Whether this is a new post
member this.IsNew = member this.IsNew =
@ -821,20 +810,18 @@ type EditRedirectRuleModel = {
} with } with
/// Create a model from an existing rule /// Create a model from an existing rule
static member FromRule idx (rule: RedirectRule) = { static member FromRule idx (rule: RedirectRule) =
RuleId = idx { RuleId = idx
From = rule.From From = rule.From
To = rule.To To = rule.To
IsRegex = rule.IsRegex IsRegex = rule.IsRegex
InsertAtTop = false InsertAtTop = false }
}
/// Update a rule with the values from this model /// Update a rule with the values from this model
member this.ToRule() = { member this.ToRule() =
From = this.From { From = this.From
To = this.To To = this.To
IsRegex = this.IsRegex IsRegex = this.IsRegex }
}
/// View model to edit RSS settings /// View model to edit RSS settings

View File

@ -831,6 +831,24 @@ let editPostModelTests = testList "EditPostModel" [
] ]
] ]
/// Unit tests for the EditRedirectRuleModel type
let editRedirectRuleModelTests = testList "EditRedirectRuleModel" [
test "FromRule succeeds" {
let model = EditRedirectRuleModel.FromRule 15 { From = "here"; To = "there"; IsRegex = true }
Expect.equal model.RuleId 15 "RuleId not filled properly"
Expect.equal model.From "here" "From not filled properly"
Expect.equal model.To "there" "To not filled properly"
Expect.isTrue model.IsRegex "IsRegex should have been set"
Expect.isFalse model.InsertAtTop "InsertAtTop should not have been set"
}
test "ToRule succeeds" {
let rule = { RuleId = 10; From = "me"; To = "you"; IsRegex = false; InsertAtTop = false }.ToRule()
Expect.equal rule.From "me" "From not filled properly"
Expect.equal rule.To "you" "To not filled properly"
Expect.isFalse rule.IsRegex "IsRegex should not have been set"
}
]
/// All tests in the Domain.ViewModels file /// All tests in the Domain.ViewModels file
let all = testList "ViewModels" [ let all = testList "ViewModels" [
addBaseToRelativeUrlsTests addBaseToRelativeUrlsTests
@ -845,4 +863,5 @@ let all = testList "ViewModels" [
editMyInfoModelTests editMyInfoModelTests
editPageModelTests editPageModelTests
editPostModelTests editPostModelTests
editRedirectRuleModelTests
] ]