Skip to content

Commit d5e21bf

Browse files
committed
Fix memoisation leak between MMR and MMRV in OfflineSessionExporter
The `OfflineSessionExporter` was an array of programme objects as a key for memoizing vaccine values. Because `Programme::Variant` delegates identity methods (`hash`, `==`) to the base `Programme` class, MMR and MMRV variants were producing identical hash keys. This caused the exporter to return cached MMR vaccines for MMRV patients. This commit updates the memoisation key to use the programme variant type if it's a programe variant, otherwise fallback for programme type. This ensures that MMR and MMRV cells have the correct vaccines.
1 parent 5bc4469 commit d5e21bf

2 files changed

Lines changed: 33 additions & 5 deletions

File tree

app/lib/reports/offline_session_exporter.rb

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ def add_existing_row_cells(row, vaccination_record:)
334334
row[:programme] = programme.import_names.first
335335
row[:vaccine_given] = Cell.new(
336336
vaccine&.upload_name,
337-
allowed_values: vaccine_values_for_programmes([programme])
337+
allowed_values: vaccine_values_for_programme(programme)
338338
)
339339
row[:performing_professional_email] = Cell.new(
340340
vaccination_record.performed_by_user&.email,
@@ -390,7 +390,7 @@ def add_new_row_cells(row, patient:, programme:)
390390
)
391391
row[:programme] = programme_variant.import_names.first
392392
row[:vaccine_given] = Cell.new(
393-
allowed_values: vaccine_values_for_programmes([programme_variant])
393+
allowed_values: vaccine_values_for_programme(programme_variant)
394394
)
395395
row[:performing_professional_email] = Cell.new(
396396
allowed_formula: performing_professionals_range
@@ -415,10 +415,15 @@ def add_new_row_cells(row, patient:, programme:)
415415
end
416416
end
417417

418-
def vaccine_values_for_programmes(programmes)
419-
@vaccines[programmes] ||= Vaccine
418+
def vaccine_values_for_programme(programme)
419+
# We use the variant_type or type strings as the cache key because
420+
# Programme::Variant delegates identity methods (hash, ==) to the base
421+
# Programme. Without this, MMR vaccines would be returned for an MMRV
422+
# variant.
423+
cache_key = programme.try(:variant_type) || programme.type
424+
@vaccines[cache_key] ||= Vaccine
420425
.active
421-
.for_programmes(programmes)
426+
.for_programmes([programme])
422427
.pluck(:upload_name)
423428
end
424429

spec/lib/reports/offline_session_exporter_spec.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,4 +1189,27 @@ def validation_formula(worksheet:, column_name:, row: 1)
11891189

11901190
include_examples "generates a report"
11911191
end
1192+
1193+
describe "#vaccine_values_for_programmes" do
1194+
let(:programme) { Programme.mmr }
1195+
let(:mmr_programme_variant) do
1196+
Programme::Variant.new(programme, variant_type: "mmr")
1197+
end
1198+
let(:mmrv_programme_variant) do
1199+
Programme::Variant.new(programme, variant_type: "mmrv")
1200+
end
1201+
let(:session) { create(:session, programmes: [programme]) }
1202+
1203+
it "returns the correct vaccines for the given programme variants" do
1204+
exporter = described_class.send(:new, session)
1205+
1206+
expect(
1207+
exporter.send(:vaccine_values_for_programme, mmr_programme_variant)
1208+
).to eq(%w[Priorix VaxPro])
1209+
1210+
expect(
1211+
exporter.send(:vaccine_values_for_programme, mmrv_programme_variant)
1212+
).to eq(%w[ProQuad Priorix-Tetra])
1213+
end
1214+
end
11921215
end

0 commit comments

Comments
 (0)