-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(688) Add content block updates to a document's timeline #9754
base: main
Are you sure you want to change the base?
Conversation
54a8428
to
b4e2cbd
Compare
This better matches what we’re trying to do, and also moves us out of the `Query` namespace, as we’ll soon be handling decorating versions elsewhere.
This removes some of the logic to the Document model, menaing the only thing the query class needs to worry about is building and running the SQL
This allows us to define and fetch when a piece of host content has been updated for a document and a date window.
This uses the Minitest Spec DSL to make the tests easier to follow
6e8ccbc
to
0cee0a5
Compare
We’ll need this to be able to work out what upstream changed apply to what edition, as Publishing API doesn’t have the concept of “editions”
This will be used in the paginated timeline in a future commit
Working out what event “belongs” to an edition is tricky, as Publishing API doesn’t have the concept of editions. With this in mind we have a bunch of logic: - If an edition is superseded and the event happened after the edition was superseded, it’s for a newer edition - If an edition is published, and the event happened after the edition was published AND the event is not for a newer edition, it’s for the current edition - If neither of the above is true, it’s for an older edition
This calls the new methods on each entry, simplifying the code, and allowing us to stub the response, rather than relying on the objects set up in `seed_document_event_history`
0cee0a5
to
e79be6f
Compare
e79be6f
to
14b321a
Compare
I’ve also added a lightweight Cucumber test to ensure everything fits together as we expect. I had to make a slight change to one of the steps to ensure we’re always visiting the edit page for the latest edition
14b321a
to
297f3b5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice and easy to follow 👍 some suggestions for code refactoring and commit structure, but nothing blocking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice tests ⭐
@@ -17,7 +17,7 @@ class PaginatedTimelineTest < ActiveSupport::TestCase | |||
assert_equal entry_timestamps.sort.reverse, entry_timestamps | |||
end | |||
|
|||
it "is is a list of VersionDecorator and EditorialRemark objects when no 'only' argument is passed in" do | |||
it "is is a list of VersionDecorator and EditorialRemark objects when no 'only' argument is not passed in" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is difficult to parse 😅 can we reword to remove the double negative?
Similarly on line 92
def next_page_entries | ||
if next_page | ||
Document::PaginatedTimelineQuery.new(document:, page: next_page, only:).raw_entries | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd move this below def date_window
as it isn't called until further down in the file (nice to have methods defined in the order they're called)
def date_window | ||
@date_window ||= begin | ||
start = page == 1 ? Time.zone.now : query.raw_entries.first.created_at | ||
ends = next_page_entries ? next_page_entries.first.created_at : query.raw_entries.last.created_at |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The next_page
logic is surprising - can you add to the commit detail what you've added to the PR description?
This is complicated slightly by the fact that the history is paginated. To compensate for this, we are having to "look ahead" to the next page to get the date of the next event to give us a window to query Publishing API for events.
Better yet, perhaps just handle the first page in this first commit, and then add the "next page" logic in a subsequent commit, rather than doing it all at once.
@@ -3,4 +3,16 @@ class EditorialRemark < ApplicationRecord | |||
belongs_to :author, class_name: "User" | |||
|
|||
validates :edition, :body, :author, presence: true | |||
|
|||
def is_for_newer_edition?(edition) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems a shame to have to duplicate this - did you consider any alternatives (e.g. extract into a module?)
I don't feel strongly about it though, agree that duplication is better than the wrong abstraction! And at least the code is simple.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Stu's duplication choice - the fact that the algorithm for sorting editorial remarks and versions is identical seems like coincidental rather than fundamental duplication to me.
else | ||
entry.item_id > edition.id | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Niiice ⭐
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought I'd chuck in my two penneth as well, hope you don't mind.
On a macro level I do look forward to revisiting the entirety of how document history works at some point, it has always felt a lot harder than it needs to be for some reason
def superseded_at | ||
versions.find { |v| v.state == "superseded" }&.created_at | ||
end | ||
|
||
def published_at | ||
versions.find { |v| v.state == "published" }&.created_at | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think these should live in this concern, because we've created an implicit dependency on the versions association declared in AuditTrail concern. We should either move these methods up to the main model, in to the AudtiTrail concern, or move the dependency on AuditTrail
in to this concern (but that doesn't feel right)
@@ -0,0 +1,45 @@ | |||
class VersionDecorator < SimpleDelegator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nice if the name of this decorator said something about why we have chosen to use a decorator rather than simply adding these behaviours on to the version model. If I understand your intentions correctly, it's because we only expect these behaviours to be useful in the context of constructing a document history timeline, but I'm struggling to think of a way to communicate that pithily via a class name
@@ -3,4 +3,16 @@ class EditorialRemark < ApplicationRecord | |||
belongs_to :author, class_name: "User" | |||
|
|||
validates :edition, :body, :author, presence: true | |||
|
|||
def is_for_newer_edition?(edition) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Stu's duplication choice - the fact that the algorithm for sorting editorial remarks and versions is identical seems like coincidental rather than fundamental duplication to me.
Trello card: https://trello.com/c/PTDFVt1z/688-pull-in-when-content-has-been-updated-by-an-update-to-a-content-block-within-publishing-apps
As discussed in #9666, we need a way of pulling in content block updates to a document's history. After much to-ing and fro-ing, we have settled on doing this in-app, when fetching the history. This is complicated slightly by the fact that the history is paginated. To compensate for this, we are having to "look ahead" to the next page to get the date of the next event to give us a window to query Publishing API for events.
We also have an extra complication as we don't know what updates "belong" to an edition. We've got around this by adding some event-based helpers to an edition, so we know when an edition was published and superseded. To simplify the logic in the paginated timeline class, we've moved the logic to work out what object belongs to an edition to the model classes themselves.
Additionally, there's a bit more tidying up and refactoring of the history-related work so we're doing away with complexity before adding any more!
Hopefully this isn't too much of a monster to review (especially with 🎄 on the horizon). I've tried to break it down as much as possible, but if you want me to break it up into seperate PRs, I'm happy to do that!
Screenshot