Skip to content

Conversation

@kean
Copy link
Contributor

@kean kean commented Nov 27, 2025

Fixes https://linear.app/a8c/issue/CMM-1007/reader-subscriptions-to-jetpack-connected-sites-made-from-search-are (see ticket for RCA).

Testing Instructions

  • Open Reader / Search
  • Find a blog you are looking for
  • Verify that the title, description, and image are displayed in both the list and the full details page
  • Subscribe
  • Open Reader / Subscriptions
  • Verify that subscriptions are not duplicated

Repeat the steps for an RSS feed, a Dotcom site, and a Jetpack-connected site. I covered all three scenarios with unit tests.

Recording

Screen.Recording.2025-11-27.at.3.35.03.PM.mov

@kean kean added this to the 26.5 ❄️ milestone Nov 27, 2025
@kean kean added the Reader label Nov 27, 2025
@kean kean force-pushed the fix/reader-subscriptions-duplicated branch from dd694a3 to 875c009 Compare November 27, 2025 20:40
@dangermattic
Copy link
Collaborator

dangermattic commented Nov 27, 2025

2 Warnings
⚠️ This PR is larger than 500 lines of changes. Please consider splitting it into smaller PRs for easier and faster reviews.
⚠️ This PR is assigned to the milestone 26.5 ❄️. The due date for this milestone has already passed.
Please assign it to a milestone with a later deadline or check whether the release for this milestone has already been finished.
1 Message
📖 This PR contains changes to RELEASE-NOTES.txt.
Note that these changes won't affect the final version of the release notes as this version is in code freeze.
Please, get in touch with a release manager if you want to update the final release notes.

Generated by 🚫 Danger

/// Site/Feed URL with fallback: data.site → data.feed
/// Prioritizes site URL over feed URL for canonical representation
public var url: URL? {
site?.url ?? feed?.url
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opted to skip reading the fields inlined in the response and use data.feed and data.site directly as these seem to be more reliable for all three scenarios.

@kean kean requested review from crazytonyli and jkmassel and removed request for jkmassel November 27, 2025 20:42
@wpmobilebot
Copy link
Contributor

wpmobilebot commented Nov 27, 2025

App Icon📲 You can test the changes from this Pull Request in Jetpack by scanning the QR code below to install the corresponding build.
App NameJetpack
ConfigurationRelease-Alpha
Build Number30031
VersionPR #25026
Bundle IDcom.jetpack.alpha
Commit211a3cb
Installation URL2gv32dpon2q68
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@wpmobilebot
Copy link
Contributor

wpmobilebot commented Nov 27, 2025

App Icon📲 You can test the changes from this Pull Request in WordPress by scanning the QR code below to install the corresponding build.
App NameWordPress
ConfigurationRelease-Alpha
Build Number30031
VersionPR #25026
Bundle IDorg.wordpress.alpha
Commit211a3cb
Installation URL51f89vieulqug
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

let data = try? meta.nestedContainer(keyedBy: DataKeys.self, forKey: .data) {
self.feed = try? data.decode(FeedData.self, forKey: .feed)
self.site = try? data.decode(SiteData.self, forKey: .site)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like manually decoding defeats the purpose of using Decodable. The code would look cleaner if we use types that match the JSON structure, like

public struct ReaderFeed: Decodable {
    public init(from decoder: Decoder) throws {
        let feed = try Feed(from: decoder)
        self.feed = feed.meta?.data?.feed
        self.site = feed.meta?.data?.site
    }
}

// For parsing JSON only.
private struct Feed: Decodable {
    struct Meta: Decodable {
        struct Data: Decodable {
            var feed: FeedData?
            var site: SiteData?
        }

        var data: Data?
    }

    var meta: Meta?
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I added ReaderFeedJSON just like that. It's a bit easier to follow now.

let feedID: String?
let blogID: String?
let name: String?
let url: URL?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During testing the JSON parsing above, I found out by accident that this url can be an empty string, which causes JSONDecoder to throw an error, which is silenced at the moment because of the try? parsing code above.

You can search "WordPress.com News" and check out the "wpsites.net" site in the response.

Copy link
Contributor

@crazytonyli crazytonyli Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can change the URL properties to be String, and turn the string to URL in the ReaderFeed public API, which are all optional anyway.

Copy link
Contributor Author

@kean kean Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a custom init(from decoder:) for FeedData (same as SiteData already has). I don't trust every field to be the correct format, so it all try?s now. It will catch the URL issue too.

@kean kean force-pushed the fix/reader-subscriptions-duplicated branch from 875c009 to 8ab5420 Compare November 28, 2025 15:04
@kean kean requested a review from crazytonyli November 28, 2025 15:04
Copy link
Contributor

@crazytonyli crazytonyli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good ot me, but the unit tests failed due to parsing the stubbed JSON files.

@kean
Copy link
Contributor Author

kean commented Dec 1, 2025

The changes look good ot me, but the unit tests failed due to parsing the stubbed JSON files.

I fixed the tests by adding "inline data" parsing back. It should not be necessary in production, but it's just some defensive code.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 1, 2025

@kean kean requested a review from crazytonyli December 1, 2025 20:34
@kean kean merged commit f5fc777 into release/26.5 Dec 1, 2025
26 of 32 checks passed
@kean kean deleted the fix/reader-subscriptions-duplicated branch December 1, 2025 22:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants