Skip to content

Commit 5611541

Browse files
authored
Merge pull request #2476 from alphagov/copy-welsh
Update copy code to also copy Welsh
2 parents cf9ee9b + 321b410 commit 5611541

2 files changed

Lines changed: 164 additions & 4 deletions

File tree

app/services/form_copy_service.rb

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,35 @@ def initialize(form, logged_in_user)
1111
end
1212

1313
def copy(tag: "draft")
14+
# Copy the main form structure from English FormDocument first
1415
form_doc = FormDocument.find_by(form_id: @form.id, tag:, language: :en)
1516
return false if form_doc.blank?
1617

1718
content = form_doc.content
1819

1920
ActiveRecord::Base.transaction do
2021
copy_attributes(content)
21-
prepend_name
22+
prepend_name_for_language(:en)
2223

2324
copy_pages(content["steps"])
2425
copy_routing_conditions(content["steps"])
2526
copy_group
2627

2728
@copied_form.copied_from_id = @form.id
28-
2929
@copied_form.save!
30+
31+
# Copy Welsh translations if available
32+
if @form.available_languages.include?("cy")
33+
copy_welsh_translations(tag:)
34+
end
3035
rescue ActiveRecord::RecordInvalid => e
3136
Rails.logger.error("Failed to copy form #{@form.id}: #{e.message}")
3237
raise
3338
end
3439

3540
log_form_copied(original_form_id: @form.id, copied_form_id: @copied_form.id, creator_id: @logged_in_user.id)
3641

42+
@copied_form.reload
3743
@copied_form
3844
end
3945

@@ -72,8 +78,34 @@ def copy_page_attributes(page, step)
7278
)
7379
end
7480

75-
def prepend_name
76-
@copied_form.name = "Copy of #{@form.name}"
81+
def prepend_name_for_language(language)
82+
if language == :en
83+
@copied_form.name = "Copy of #{@form.name}"
84+
elsif language == :cy
85+
@copied_form.name_cy = "Copy of #{@form.name_cy}" if @form.name_cy.present?
86+
end
87+
end
88+
89+
def copy_welsh_translations(tag:)
90+
welsh_doc = FormDocument.find_by(form_id: @form.id, tag:, language: :cy)
91+
return unless welsh_doc
92+
93+
welsh_content = welsh_doc.content
94+
95+
# Copy Welsh translations from FormDocument content
96+
Mobility.with_locale(:cy) do
97+
# Only copy the translatable attributes in Welsh locale
98+
translatable_attrs = %w[name privacy_policy_url support_email support_phone support_url support_url_text declaration_text what_happens_next_markdown payment_url]
99+
welsh_content.slice(*translatable_attrs).each do |key, value|
100+
@copied_form.send("#{key}=", value) if value.present?
101+
end
102+
prepend_name_for_language(:cy)
103+
104+
# Copy Welsh page translations
105+
copy_welsh_page_translations(welsh_content["steps"])
106+
107+
@copied_form.save!
108+
end
77109
end
78110

79111
def copy_routing_conditions(steps)
@@ -106,4 +138,24 @@ def copy_condition(condition_data, page_id_mapping)
106138
def copy_group
107139
GroupForm.create(group_id: @form.group.id, form_id: @copied_form.id)
108140
end
141+
142+
def copy_welsh_page_translations(welsh_steps)
143+
return if welsh_steps.blank?
144+
145+
welsh_steps.each_with_index do |step, index|
146+
page = @copied_form.pages[index]
147+
next unless page
148+
149+
data = step["data"]
150+
# Copy Welsh translatable fields for the page
151+
# We need to reload to ensure Mobility has the right locale context
152+
page.reload
153+
page.question_text = data["question_text"] if data["question_text"].present?
154+
page.hint_text = data["hint_text"] if data["hint_text"].present?
155+
page.page_heading = data["page_heading"] if data["page_heading"].present?
156+
page.guidance_markdown = data["guidance_markdown"] if data["guidance_markdown"].present?
157+
page.answer_settings = data["answer_settings"] if data["answer_settings"].present?
158+
page.save!(validate: false)
159+
end
160+
end
109161
end

spec/services/form_copy_service_spec.rb

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,5 +228,113 @@
228228
expect(copied_form.group).to eq(group)
229229
end
230230
end
231+
232+
context "when source form has Welsh language version with translated content" do
233+
let(:source_form) do
234+
form = create(:form, :live, :with_pages, pages_count: 2, available_languages: %w[en cy])
235+
# Set Welsh-specific translations for form
236+
form.name_cy = "Ffurflen Gymraeg"
237+
form.privacy_policy_url_cy = "https://example.com/preifatrwydd"
238+
form.support_email_cy = "cymorth@example.com"
239+
form.support_phone_cy = "0800 111 222"
240+
form.support_url_cy = "https://example.com/cymorth"
241+
form.support_url_text_cy = "Cael cymorth"
242+
form.declaration_text_cy = "Rwy'n datgan bod hyn yn wir"
243+
form.what_happens_next_markdown_cy = "Byddwn yn cysylltu â chi"
244+
form.payment_url_cy = "https://example.com/talu"
245+
form.save!
246+
# Set Welsh translations for pages - must save each page individually
247+
form.pages.first.update!(question_text_cy: "Cwestiwn Cymraeg 1", hint_text_cy: "Awgrym Cymraeg 1", page_heading_cy: "Pennwr Tudalen Cymraeg 1")
248+
form.pages.last.update!(question_text_cy: "Cwestiwn Cymraeg 2", hint_text_cy: "Awgrym Cymraeg 2")
249+
# Synchronize live FormDocuments for both languages
250+
FormDocumentSyncService.new(form).synchronize_live_form
251+
form.reload
252+
form
253+
end
254+
255+
it "copies the Welsh-translated content from the source form" do
256+
source_welsh = source_form.form_documents.find_by(language: "cy", tag: "live")
257+
expect(source_welsh).to be_present
258+
expect(source_welsh.content["name"]).to eq("Ffurflen Gymraeg")
259+
260+
# Copied form should have Welsh FormDocument with translated content
261+
copied_welsh = copied_form.form_documents.find_by(language: "cy", tag: "draft")
262+
expect(copied_welsh).to be_present
263+
expect(copied_welsh.content["name"]).to eq("Copy of Ffurflen Gymraeg")
264+
expect(copied_welsh.content["privacy_policy_url"]).to eq("https://example.com/preifatrwydd")
265+
expect(copied_welsh.content["support_email"]).to eq("cymorth@example.com")
266+
expect(copied_welsh.content["support_phone"]).to eq("0800 111 222")
267+
expect(copied_welsh.content["support_url"]).to eq("https://example.com/cymorth")
268+
expect(copied_welsh.content["support_url_text"]).to eq("Cael cymorth")
269+
expect(copied_welsh.content["declaration_text"]).to eq("Rwy'n datgan bod hyn yn wir")
270+
expect(copied_welsh.content["what_happens_next_markdown"]).to eq("Byddwn yn cysylltu â chi")
271+
expect(copied_welsh.content["payment_url"]).to eq("https://example.com/talu")
272+
end
273+
274+
it "persists Welsh translations on the copied Form model" do
275+
# Ensure model-level Mobility translations are set correctly
276+
expect(copied_form.name_cy).to eq("Copy of Ffurflen Gymraeg")
277+
expect(copied_form.privacy_policy_url_cy).to eq("https://example.com/preifatrwydd")
278+
expect(copied_form.support_email_cy).to eq("cymorth@example.com")
279+
expect(copied_form.support_phone_cy).to eq("0800 111 222")
280+
expect(copied_form.support_url_cy).to eq("https://example.com/cymorth")
281+
expect(copied_form.support_url_text_cy).to eq("Cael cymorth")
282+
expect(copied_form.declaration_text_cy).to eq("Rwy'n datgan bod hyn yn wir")
283+
expect(copied_form.what_happens_next_markdown_cy).to eq("Byddwn yn cysylltu â chi")
284+
expect(copied_form.payment_url_cy).to eq("https://example.com/talu")
285+
286+
# Check that values are accessible in Welsh locale context
287+
Mobility.with_locale(:cy) do
288+
expect(copied_form.name).to eq("Copy of Ffurflen Gymraeg")
289+
expect(copied_form.privacy_policy_url).to eq("https://example.com/preifatrwydd")
290+
expect(copied_form.support_email).to eq("cymorth@example.com")
291+
end
292+
end
293+
294+
it "persists Welsh translations on copied pages" do
295+
expect(copied_form.pages.count).to eq(2)
296+
297+
# Reload to get the latest state from the database
298+
copied_form.reload
299+
first_page = copied_form.pages.first
300+
expect(first_page.question_text_cy).to eq("Cwestiwn Cymraeg 1")
301+
expect(first_page.hint_text_cy).to eq("Awgrym Cymraeg 1")
302+
expect(first_page.page_heading_cy).to eq("Pennwr Tudalen Cymraeg 1")
303+
304+
last_page = copied_form.pages.last
305+
expect(last_page.question_text_cy).to eq("Cwestiwn Cymraeg 2")
306+
expect(last_page.hint_text_cy).to eq("Awgrym Cymraeg 2")
307+
308+
# Check that page values are accessible in Welsh locale context
309+
Mobility.with_locale(:cy) do
310+
expect(first_page.question_text).to eq("Cwestiwn Cymraeg 1")
311+
expect(first_page.hint_text).to eq("Awgrym Cymraeg 1")
312+
end
313+
end
314+
end
315+
316+
context "when Welsh copy fails" do
317+
let(:source_form) do
318+
form = create(:form, :live, available_languages: %w[en cy])
319+
form.name_cy = "Ffurflen Gymraeg"
320+
form.save!
321+
FormDocumentSyncService.new(form).synchronize_live_form
322+
form
323+
end
324+
325+
it "rolls back the entire copy if Welsh translation copying fails" do
326+
# Stub the Welsh copying to raise an AR::RecordInvalid to simulate a failure mid-transaction
327+
service = described_class.new(source_form, logged_in_user)
328+
allow(service).to receive(:copy_welsh_translations)
329+
.and_raise(ActiveRecord::RecordInvalid.new(Form.new))
330+
331+
expect {
332+
service.copy(tag: "live")
333+
}.to raise_error(ActiveRecord::RecordInvalid)
334+
335+
# Ensure no copied form was persisted
336+
expect(Form.where(copied_from_id: source_form.id)).to be_empty
337+
end
338+
end
231339
end
232340
end

0 commit comments

Comments
 (0)