Skip to content
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
12 changes: 11 additions & 1 deletion app/controllers/api/form_documents_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,17 @@ def group
private

def form_document
@form_document ||= FormDocument.find_by!(form_document_params)
form_id, tag, language = form_document_params.values_at(:form_id, :tag, :language)

return FormDocument.find_by!(form_id:, tag:, language:) if tag == "draft"

latest_form_document = FormDocument.latest_live_or_archived(form_id:, language:)

raise NotFoundError unless latest_form_document&.tag == tag

CurrentLoggingAttributes.form_document_version = latest_form_document&.version

latest_form_document
end

def form_document_params
Expand Down
1 change: 1 addition & 0 deletions app/models/current_logging_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class CurrentLoggingAttributes < ActiveSupport::CurrentAttributes
:acting_as_user_email,
:acting_as_user_organisation_slug,
:form_id,
:form_document_version,
:page_id,
:answer_type,
:auth0_session_id,
Expand Down
7 changes: 7 additions & 0 deletions app/models/form_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,11 @@ class FormDocument < ApplicationRecord

validates :tag, presence: true
validates :language, presence: true, inclusion: { in: %w[en cy] }

def self.latest_live_or_archived(form_id:, language:)
FormDocument.where(form_id: form_id, language: language)
.where.not(version: nil)
.order(version: :desc)
.first
end
end
67 changes: 67 additions & 0 deletions spec/models/form_document_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,71 @@
form = create(:form) # also creates a draft form document
expect { create(:form_document, :draft, form: form, language: "cy") }.not_to raise_error
end

describe ".latest_live_or_archived" do
let(:form) { create :form }

context "when the form only has a draft form document" do
it "returns nil" do
expect(form.draft_form_document).to be_present
expect(described_class.latest_live_or_archived(form_id: form.id, language: "en")).to be_nil
end
end

context "when there is one form document with a version" do
let!(:form_document) { create :form_document, :live, form:, language: "en", version: 1 }

it "returns the form document" do
expect(described_class.latest_live_or_archived(form_id: form.id, language: "en")).to eq(form_document)
end

it "returns nil when no form document for the language exists" do
expect(described_class.latest_live_or_archived(form_id: form.id, language: "cy")).to be_nil
end
end

context "when there are multiple form documents with different versions" do
let(:latest_document) { create :form_document, :archived, form:, language: "en", version: 3 }

before do
create :form_document, :live, form:, language: "en", version: 1
latest_document
create :form_document, :live, form:, language: "en", version: 2
end

it "returns the latest form document with the highest version" do
expect(described_class.latest_live_or_archived(form_id: form.id, language: "en")).to eq(latest_document)
end
end

context "when there are form documents for different languages" do
let(:latest_english_document) { create :form_document, form:, language: "en", version: 2 }
let(:latest_welsh_document) { create :form_document, form:, language: "cy", version: 1 }

before do
create :form_document, form:, language: "en", version: 1
latest_english_document
latest_welsh_document
end

it "returns the latest English document regardless of Welsh versions" do
expect(described_class.latest_live_or_archived(form_id: form.id, language: "en")).to eq(latest_english_document)
end

it "returns the latest Welsh document regardless of English versions" do
expect(described_class.latest_live_or_archived(form_id: form.id, language: "cy")).to eq(latest_welsh_document)
end
end

context "when documents from other forms exist" do
let(:other_form) { create :form }
let!(:other_form_document) { create :form_document, :live, form: other_form, language: "en", version: 2 }
let!(:this_form_document) { create :form_document, :live, form:, language: "en", version: 1 }

it "only returns documents from the current form" do
expect(described_class.latest_live_or_archived(form_id: form.id, language: "en")).to eq(this_form_document)
expect(described_class.latest_live_or_archived(form_id: other_form.id, language: "en")).to eq(other_form_document)
end
end
end
end
69 changes: 46 additions & 23 deletions spec/requests/api/form_documents_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,51 +34,72 @@
end

context "when the tag is live" do
let(:live_form_name) { "Live form" }
let(:form) { create(:form, :live, name: live_form_name) }
let(:form) { create(:form, :live) }

before do
# change the form object so we can be sure we're returning the live form document
form.name = "Draft form"
form.save!

get "/api/v2/forms/#{form.id}/live", headers:
create :form_document, :live, form: form, version: 2, content: { name: "v2 form" }
create :form_document, :live, form: form, version: 3, content: { name: "v3 form" }
end

it "returns http success" do
get("/api/v2/forms/#{form.id}/live", headers:)
expect(response).to have_http_status(:success)
end

it "returns the live form document" do
it "returns the latest live form document" do
get("/api/v2/forms/#{form.id}/live", headers:)
expect(response.parsed_body).to include({
form_id: form.id.to_s,
name: live_form_name,
name: "v3 form",
})
end

it "logs the returned form document version", :capture_logging do
get("/api/v2/forms/#{form.id}/live", headers:)
expect(log_line["form_document_version"]).to eq 3
end

context "and the most recent version is archived" do
before do
create :form_document, :archived, form: form, version: 4
end

it "returns http not found" do
get("/api/v2/forms/#{form.id}/live", headers:)
expect(response).to have_http_status(:not_found)
end
end
end

context "when the tag is archived" do
let(:archived_form_name) { "Archived form" }
let(:form) { create(:form, :archived, name: archived_form_name) }
let(:form) { create(:form, :archived) }

before do
# change the form object so we can be sure we're returning the archived form document
form.name = "Draft form"
form.save!

get "/api/v2/forms/#{form.id}/archived"
create :form_document, :archived, form: form, version: 2, content: { name: "v2 form" }
create :form_document, :archived, form: form, version: 3, content: { name: "v3 form" }
end

it "returns http success" do
get("/api/v2/forms/#{form.id}/archived")
expect(response).to have_http_status(:success)
end

it "returns the archived form document" do
get("/api/v2/forms/#{form.id}/archived")
expect(response.parsed_body).to include({
form_id: form.id.to_s,
name: archived_form_name,
name: "v3 form",
})
end

context "and the most recent version is live" do
before do
create :form_document, :live, form: form, version: 4
end

it "returns http not found" do
get("/api/v2/forms/#{form.id}/archived")
expect(response).to have_http_status(:not_found)
end
end
end
end

Expand Down Expand Up @@ -123,22 +144,24 @@
let(:form) { create :form }

before do
create :form_document, :live, form: form, language: "en", content: { form_id: form.id.to_s, language: "en" }
create :form_document, :live, form: form, language: "cy", content: { form_id: form.id.to_s, language: "cy" }
create :form_document, :live, form: form, language: "en", version: 1
create :form_document, :live, form: form, language: "en", version: 2, content: { name: "Live form v2", language: "en" }
create :form_document, :live, form: form, language: "cy", version: 1
create :form_document, :live, form: form, language: "cy", version: 2, content: { name: "Welsh live form v2", language: "cy" }
end

it "when not given a language, defaults to english returns the live form document in english" do
get("/api/v2/forms/#{form.id}/live", headers:)
expect(response.parsed_body).to include({
form_id: form.id.to_s,
name: "Live form v2",
language: "en",
})
end

it "when given welsh param returns the live form document in welsh" do
get("/api/v2/forms/#{form.id}/live?language=cy", headers:)
expect(response.parsed_body).to include({
form_id: form.id.to_s,
name: "Welsh live form v2",
language: "cy",
})
end
Expand Down