Skip to content
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) Create an Event when dependencies are updated by content blocks #2993

Merged
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 app/controllers/v2/content_items_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ def linkables
).call
end

def events
render json: Queries::GetEvents.call(
content_id: path_params[:content_id],
action: query_params[:action],
from: query_params[:from],
to: query_params[:to],
)
end

def host_content
results = GetHostContentService.new(
path_params[:content_id],
Expand Down
30 changes: 30 additions & 0 deletions app/queries/get_events.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module Queries
class GetEvents
def self.call(content_id:, action: nil, from: nil, to: nil)
new(content_id, action, from, to).call
end

def call
result = Event.where(**query)
result = result.where("created_at >= ?", from) if from.present?
result = result.where("created_at <= ?", to) if to.present?

result
end

private

attr_reader :content_id, :action, :from, :to

def query
{ content_id:, action: }.compact_blank!
end

def initialize(content_id, action, from, to)
@content_id = content_id
@action = action
@from = from
@to = to
end
end
end
44 changes: 34 additions & 10 deletions app/sidekiq/host_content_update_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,39 @@ class HostContentUpdateJob < DependencyResolutionJob
def downstream_live(dependent_content_id, locale)
return if draft?

DownstreamLiveJob.perform_async_in_queue(
DownstreamLiveJob::LOW_QUEUE,
"content_id" => dependent_content_id,
"locale" => locale,
"message_queue_event_type" => "host_content",
"update_dependencies" => false,
"dependency_resolution_source_content_id" => content_id,
"source_command" => source_command,
"source_fields" => source_fields,
)
event_payload = {
content_id: dependent_content_id,
locale:,
message: "Host content updated by content block update",
source_block: {
title: source_edition.title,
content_id: source_edition.content_id,
updated_by_user_uid: source_edition_publication_event&.user_uid,
},
}

EventLogger.log_command(self.class, event_payload) do |_event|
DownstreamLiveJob.perform_async_in_queue(
DownstreamLiveJob::LOW_QUEUE,
"content_id" => dependent_content_id,
"locale" => locale,
"message_queue_event_type" => "host_content",
"update_dependencies" => false,
"dependency_resolution_source_content_id" => content_id,
"source_command" => source_command,
"source_fields" => source_fields,
)
end
end

def source_edition_publication_event
@source_edition_publication_event ||= Event
.where(action: "Publish", content_id:)
.order(created_at: :desc)
.first
end

def source_edition
@source_edition ||= Document.find_by(content_id:).live
end
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def content_id_constraint(request)
get "/content/:content_id/host-content/:host_content_id", to: "content_items#host_content_item"
# Point legacy `embedded` endpoint to `host_content` endpoint
get "/content/:content_id/embedded", to: "content_items#host_content"
get "/content/:content_id/events", to: "content_items#events"
post "/content/:content_id/publish", to: "content_items#publish"
post "/content/:content_id/republish", to: "content_items#republish"
post "/content/:content_id/unpublish", to: "content_items#unpublish"
Expand Down
20 changes: 20 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ message queue for other apps (e.g. `email-alert-service`) to consume.
- [`GET /v2/content/:content_id`](#get-v2contentcontent_id)
- [`GET /v2/content/:content_id/host-content`](#get-v2contentcontent_idhost-content)
- [`GET /v2/content/:content_id/host-content/:host_content_id`](#get-v2contentcontent_idhost-contenthost_content_id)
- [`GET /v2/content/:content_id/events`](#get-v2contentcontent_idevents)
- [`PATCH /v2/links/:content_id`](#patch-v2linkscontent_id)
- [`GET /v2/links/:content_id`](#get-v2linkscontent_id)
- [`GET /v2/expanded-links/:content_id`](#get-v2expanded-linkscontent_id)
Expand Down Expand Up @@ -429,6 +430,25 @@ included within the response.
- Specify a particular edition of this document
- If omitted the most recent edition.

## `GET /v2/content/:content_id/events`

Retrieves a list of all events for a given `:content_id`

### Path parameters

- [`content_id`](model.md#content_id)
- Identifies the document to return events for

### Query parameters

- `action` *(optional)*
- Specify what action type to filter for
- If omitted, returns all actions
- `from` *(optional)*
- Filter for actions created after that particular datetime
- `to` *(optional)*
- Filter for actions created before that particular datetime

## `GET /v2/content/:content_id/host-content`

Retrieves a summary list of content which has an embedded reference to the target `:content_id`.
Expand Down
7 changes: 7 additions & 0 deletions spec/commands/v2/publish_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,13 @@
described_class.call(payload)
expect(ChangeNote.count).to eq(1)
end

it "creates an event" do
described_class.call(payload)
event = Event.find_by(content_id: document.content_id)

expect(event).to_not be_nil
end
end

context "dependency fields change on new publication" do
Expand Down
53 changes: 53 additions & 0 deletions spec/controllers/v2/content_items_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -553,4 +553,57 @@
expect(items.length).to eq(4)
end
end

describe "events" do
let(:edition) { create(:live_edition) }
let(:document) { edition.document }

let!(:put_content_events) { create_list(:event, 3, content_id: document.content_id, action: "PutContent", created_at: Time.zone.now - 1.day) }
let!(:publish_events) { create_list(:event, 3, content_id: document.content_id, action: "Publish", created_at: Time.zone.now - 2.days) }
let!(:other_events) { create_list(:event, 3, created_at: Time.zone.now - 3.days) }

it "returns all events for a content_id" do
get :events, params: { content_id: document.content_id }

expect(parsed_response).to eq([put_content_events, publish_events].flatten.map(&:as_json))
end

it "returns all events for a content_id and action type" do
get :events, params: { content_id: document.content_id, action: "Publish" }

expect(parsed_response).to eq(publish_events.flatten.map(&:as_json))
end

context "filtering by datetime" do
let(:start_date) { Time.zone.now - 12.hours }
let(:end_date) { Time.zone.now - 2.hours }

let!(:new_put_content_events) { create_list(:event, 3, content_id: document.content_id, action: "PutContent", created_at: start_date + 2.hours) }
let!(:new_publish_events) { create_list(:event, 3, content_id: document.content_id, action: "Publish", created_at: start_date + 2.hours) }

it "returns all events for a content_id and start_date" do
new_events = [new_put_content_events, new_publish_events].flatten

get :events, params: { content_id: document.content_id, from: start_date }

expect(parsed_response).to eq(new_events.map(&:as_json))
end

it "filters by action" do
get :events, params: { content_id: document.content_id, from: start_date, action: "Publish" }
expect(parsed_response).to eq(new_publish_events.map(&:as_json))
end

it "filters by start and end date" do
create_list(:event, 3, content_id: document.content_id, action: "PutContent", created_at: end_date + 1.hour)
create_list(:event, 3, content_id: document.content_id, action: "Publish", created_at: end_date + 2.hours)

get :events, params: { content_id: document.content_id, from: start_date, to: end_date }

expected_events = [new_put_content_events, new_publish_events].flatten

expect(parsed_response).to eq(expected_events.map(&:as_json))
end
end
end
end
65 changes: 65 additions & 0 deletions spec/queries/get_events_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
RSpec.describe Queries::GetEvents do
let(:edition) { create(:live_edition) }
let(:document) { edition.document }

let!(:patch_link_set_events) { create_list(:event, 2, content_id: document.content_id, action: "PatchLinkSet") }
let!(:put_content_events) { create_list(:event, 3, content_id: document.content_id, action: "PutContent") }
let!(:publish_events) { create_list(:event, 1, content_id: document.content_id, action: "Publish") }
let!(:host_content_update_events) { create_list(:event, 2, content_id: document.content_id, action: "HostContentUpdateJob") }
let!(:other_events) { create_list(:event, 4) }

let(:all_events) do
[
patch_link_set_events,
put_content_events,
publish_events,
host_content_update_events,
].flatten
end

it "returns all events" do
result = described_class.call(content_id: document.content_id)

expect(result).to match_array(all_events)
end

it "allows filtering by action" do
result = described_class.call(content_id: document.content_id, action: "HostContentUpdateJob")

expect(result).to match_array(host_content_update_events)
end

context "filtering by date" do
let(:start_date) { Time.zone.now }

it "returns no events when events have not been created since the start date" do
result = described_class.call(content_id: document.content_id, from: start_date)
expect(result).to match_array([])
end

it "returns all events created since the start date" do
create_list(:event, 2, content_id: document.content_id, created_at: start_date - 2.hours)
result = described_class.call(content_id: document.content_id, from: start_date - 1.hour)

expect(result).to match_array(all_events)
end

it "returns all events create between the start and end dates" do
create_list(:event, 2, content_id: document.content_id, created_at: start_date - 2.hours)
create_list(:event, 2, content_id: document.content_id, created_at: start_date + 2.hours)

result = described_class.call(content_id: document.content_id, from: start_date - 1.hour, to: start_date + 1.hour)

expect(result).to match_array(all_events)
end

it "filters by action" do
create_list(:event, 2, content_id: document.content_id, action: "PatchLinkSet", created_at: start_date + 1.hour)
publish_actions = create_list(:event, 2, content_id: document.content_id, action: "Publish", created_at: start_date + 1.hour)

result = described_class.call(content_id: document.content_id, from: start_date, action: "Publish")

expect(result).to match_array(publish_actions)
end
end
end
10 changes: 10 additions & 0 deletions spec/service_consumers/pact_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -720,4 +720,14 @@ def url_encode(str)
end
end
end

provider_state "a selection of events exists for content ID b317151d-0b05-4641-8494-596b6f880b20" do
set_up do
document = create(:document, content_id: "b317151d-0b05-4641-8494-596b6f880b20")

create(:event, content_id: document.content_id, action: "PutContent", created_at: "2023-01-01T00:00:00Z")
create(:event, content_id: document.content_id, action: "Publish", created_at: "2023-01-12T00:00:00Z")
create(:event, content_id: document.content_id, action: "HostContentUpdateJob", created_at: "2024-01-01T00:00:00Z")
end
end
end
24 changes: 24 additions & 0 deletions spec/sidekiq/host_content_update_job_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
RSpec.describe HostContentUpdateJob, :perform do
let(:content_id) { SecureRandom.uuid }
let(:edition) { build(:live_edition) }
let(:document) { build(:document, live: edition, content_id:) }

subject(:worker_perform) do
described_class.new.perform(
"content_id" => content_id,
Expand All @@ -19,6 +22,7 @@

before do
allow_any_instance_of(Queries::ContentDependencies).to receive(:call).and_return(dependencies)
allow(Document).to receive(:find_by).with(content_id:).and_return(document)
end

it "queues the Live host content for update" do
Expand All @@ -37,4 +41,24 @@
)
worker_perform
end

it "creates an event" do
create(:event, content_id:, action: "PatchLinkSet", created_at: 5.days.ago)
create(:event, content_id:, action: "PutContent", created_at: 4.days.ago)
create(:event, content_id:, action: "Publish", created_at: 3.days.ago)
create(:event, content_id:, action: "HostContentUpdateJob", created_at: 2.days.ago)
create(:event, content_id:, action: "PutContent", created_at: 1.day.ago)
latest_publish_event = create(:event, content_id:, action: "Publish", user_uid: SecureRandom.uuid, created_at: Time.zone.now)

expect { worker_perform }.to change(Event, :count).by(1)

event = Event.last

expect(event.action).to eq("HostContentUpdateJob")
expect(event.content_id).to eq(dependent_content_id)
expect(event.payload[:source_block][:title]).to eq(edition.title)
expect(event.payload[:source_block][:content_id]).to eq(content_id)
expect(event.payload[:source_block][:updated_by_user_uid]).to eq(latest_publish_event.user_uid)
expect(event.payload[:message]).to eq("Host content updated by content block update")
end
end
Loading