Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Modules/Sources/WordPressCore/WordPressClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,15 @@ public actor WordPressClient {
}
}

/// Updates site settings and replaces the cached settings with the
/// server's response, so `fetchSiteSettings()` stays coherent after a
/// save without a refetch.
public func updateSiteSettings(params: SiteSettingsUpdateParams) async throws -> SiteSettingsWithEditContext {
let updated = try await api.siteSettings.update(params: params).data
self.loadSiteSettingsTask = Task<SiteSettingsWithEditContext, Error> { updated }
return updated
}

/// Creates a new task to fetch the site settings from the server.
private func newSiteSettingsTask() -> Task<SiteSettingsWithEditContext, Error> {
Task {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ struct BlogServiceRemoteCoreRESTSettingsTests {
startOfWeek: UInt64 = 1,
defaultCategory: UInt64 = 1,
defaultPostFormat: String = "standard",
postsPerPage: UInt64 = 10
postsPerPage: UInt64 = 10,
siteIcon: UInt64 = 0
) -> SiteSettingsWithEditContext {
SiteSettingsWithEditContext(
title: title,
Expand All @@ -39,7 +40,7 @@ struct BlogServiceRemoteCoreRESTSettingsTests {
defaultPingStatus: .closed,
defaultCommentStatus: .closed,
siteLogo: nil,
siteIcon: 0,
siteIcon: siteIcon,
additionalFields: WpAdditionalFields()
)
}
Expand Down Expand Up @@ -124,4 +125,81 @@ struct BlogServiceRemoteCoreRESTSettingsTests {
)
#expect(result.postsPerPage == NSNumber(value: 25))
}

// MARK: - Write mapping

@Test func writeMapsTitleOnly() {
let sparse = RemoteBlogSettings()
sparse.name = "New Title"
let params = BlogServiceRemoteCoreREST.makeUpdateParams(from: sparse)
#expect(params.title == "New Title")
#expect(params.description == nil)
#expect(params.timezone == nil)
#expect(params.defaultCommentStatus == nil)
#expect(params.defaultPingStatus == nil)
#expect(params.siteIcon == nil)
}

@Test func writeMapsWritingFields() {
let sparse = RemoteBlogSettings()
sparse.tagline = "tag"
sparse.timezoneString = "Europe/Vienna"
sparse.dateFormat = "F j, Y"
sparse.timeFormat = "g:i a"
sparse.startOfWeek = "1"
sparse.defaultCategoryID = 7
sparse.postsPerPage = 12
let params = BlogServiceRemoteCoreREST.makeUpdateParams(from: sparse)
#expect(params.description == "tag")
#expect(params.timezone == "Europe/Vienna")
#expect(params.dateFormat == "F j, Y")
#expect(params.timeFormat == "g:i a")
#expect(params.startOfWeek == 1)
#expect(params.defaultCategory == 7)
#expect(params.postsPerPage == 12)
}

@Test func writeMapsStandardPostFormatToZero() {
let sparse = RemoteBlogSettings()
sparse.defaultPostFormat = "standard"
#expect(BlogServiceRemoteCoreREST.makeUpdateParams(from: sparse).defaultPostFormat == "0")
}

@Test func writeMapsNonStandardPostFormatVerbatim() {
let sparse = RemoteBlogSettings()
sparse.defaultPostFormat = "aside"
#expect(BlogServiceRemoteCoreREST.makeUpdateParams(from: sparse).defaultPostFormat == "aside")
}

@Test func writeOmitsNonNumericStartOfWeek() {
let sparse = RemoteBlogSettings()
sparse.startOfWeek = "monday"
#expect(BlogServiceRemoteCoreREST.makeUpdateParams(from: sparse).startOfWeek == nil)
}

@Test func writeMapsDiscussionBooleans() {
let sparse = RemoteBlogSettings()
sparse.commentsAllowed = true
sparse.pingbackInboundEnabled = false
let params = BlogServiceRemoteCoreREST.makeUpdateParams(from: sparse)
#expect(params.defaultCommentStatus == .open)
#expect(params.defaultPingStatus == .closed)
}

@Test func writeMapsIconAndRemoval() {
let set = RemoteBlogSettings()
set.iconMediaID = 42
#expect(BlogServiceRemoteCoreREST.makeUpdateParams(from: set).siteIcon == 42)

let removal = RemoteBlogSettings()
removal.iconMediaID = 0
#expect(BlogServiceRemoteCoreREST.makeUpdateParams(from: removal).siteIcon == 0)
}

// MARK: - Icon read mapping

@Test func readMapsSiteIcon() {
let result = BlogServiceRemoteCoreREST.mapSiteSettings(makeSiteSettings(siteIcon: 42))
#expect(result.iconMediaID == 42)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import XCTest
import OHHTTPStubs
import OHHTTPStubsSwift
import WordPressAPI
@testable import WordPress
@testable import WordPressCore

final class BlogServiceRemoteCoreRESTUpdateTests: XCTestCase {

override func tearDown() {
HTTPStubs.removeAllStubs()
super.tearDown()
}

func testTitleOnlyUpdateSendsOnlyTitle() async throws {
let api = try WordPressAPI(
urlSession: URLSession(configuration: .ephemeral),
siteInfo: .selfHosted(
siteUrl: .parse(input: "https://example.com"),
apiRoot: .parse(input: "https://example.com/wp-json")
),
authentication: .none
)
// WordPressClient's init eagerly starts api-root/user/theme/settings
// tasks. Install a host-wide stub before constructing it so those hit
// the stub instead of the network; the more specific settings stub
// registered below takes precedence for the request under test.
stub(condition: isHost("example.com")) { _ in
HTTPStubsResponse(data: Data(), statusCode: 200, headers: nil)
}
let client = WordPressClient(api: api, siteURL: URL(string: "https://example.com")!)
let remote = BlogServiceRemoteCoreREST(client: client)

var capturedBody: [String: Any] = [:]
stub(condition: { $0.url?.absoluteString.contains("/wp/v2/settings") == true || $0.url?.query?.contains("rest_route") == true }) { request in
if let body = request.ohhttpStubs_httpBody,
let json = try? JSONSerialization.jsonObject(with: body) as? [String: Any]
{
capturedBody = json
}
return HTTPStubsResponse(
data: WordPressClientSiteSettingsTests.settingsJSON.data(using: .utf8)!,
statusCode: 200,
headers: ["Content-Type": "application/json"]
)
}

let sparse = RemoteBlogSettings()
sparse.name = "Updated Title"
try await remote.updateBlogSettings(sparse)

XCTAssertEqual(capturedBody["title"] as? String, "Updated Title")
XCTAssertNil(capturedBody["description"])
XCTAssertNil(capturedBody["default_comment_status"])
XCTAssertNil(capturedBody["site_icon"])
}
}
Loading