Skip to content

Commit cbf6672

Browse files
Merge pull request #6606 from NHSDigital/alistair/imports-date-validations
Improve date validations on imports
2 parents 994f9d9 + bbdb68b commit cbf6672

4 files changed

Lines changed: 122 additions & 2 deletions

File tree

app/lib/csv_parser.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ def to_date
4141

4242
parsed_values =
4343
DATE_FORMATS.lazy.filter_map do |format|
44-
Date.strptime(value, format)
44+
date = Date.strptime(value, format)
45+
date.year >= 1000 ? date : nil
4546
rescue ArgumentError, TypeError
4647
nil
4748
end

app/models/immunisation_import_row.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,11 @@ def validate_patient_date_of_birth
930930
patient_date_of_birth.header,
931931
"Enter a date of birth in the past."
932932
)
933+
elsif patient_date_of_birth.to_date < Date.new(2000, 1, 1)
934+
errors.add(
935+
patient_date_of_birth.header,
936+
"is too old to still be in school"
937+
)
933938
end
934939
end
935940

spec/lib/csv_parser/field_spec.rb

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# frozen_string_literal: true
2+
3+
describe CSVParser::Field do
4+
describe "#to_date" do
5+
subject(:to_date) { field.to_date }
6+
7+
let(:field) { described_class.new(value, "A", 2, "date") }
8+
9+
context "when value is nil" do
10+
let(:value) { nil }
11+
12+
it { should be_nil }
13+
end
14+
15+
context "when value is blank" do
16+
let(:value) { "" }
17+
18+
it { should be_nil }
19+
end
20+
21+
context "when value is not a date" do
22+
let(:value) { "not a date" }
23+
24+
it { should be_nil }
25+
end
26+
27+
context "with format DD/MM/YYYY" do
28+
let(:value) { "01/02/2025" }
29+
30+
it { should eq(Date.new(2025, 2, 1)) }
31+
end
32+
33+
context "with format YYYY-MM-DD" do
34+
let(:value) { "2025-02-01" }
35+
36+
it { should eq(Date.new(2025, 2, 1)) }
37+
end
38+
39+
context "with format YYYYMMDD" do
40+
let(:value) { "20250201" }
41+
42+
it { should eq(Date.new(2025, 2, 1)) }
43+
end
44+
45+
context "with format DD/MM/YY (2-digit year)" do
46+
let(:value) { "01/02/25" }
47+
48+
it { should be_nil }
49+
end
50+
51+
context "with format YY-MM-DD (2-digit year)" do
52+
let(:value) { "25-02-01" }
53+
54+
it { should be_nil }
55+
end
56+
57+
context "with format YYMMDD (2-digit year)" do
58+
let(:value) { "250201" }
59+
60+
it { should be_nil }
61+
end
62+
63+
context "with a 3-digit year" do
64+
let(:value) { "01/02/999" }
65+
66+
it { should be_nil }
67+
end
68+
69+
context "with an impossible date" do
70+
let(:value) { "31/02/2025" }
71+
72+
it { should be_nil }
73+
end
74+
75+
context "with an invalid month" do
76+
let(:value) { "01/13/2025" }
77+
78+
it { should be_nil }
79+
end
80+
end
81+
end

spec/models/immunisation_import_row_spec.rb

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,29 @@
446446
end
447447
end
448448

449-
context "with an invalid patient date of birth" do
449+
context "with a blank patient date of birth" do
450+
let(:data) { { "PERSON_DOB" => "" } }
451+
452+
it "has errors" do
453+
expect(immunisation_import_row).to be_invalid
454+
expect(immunisation_import_row.errors["PERSON_DOB"]).to eq(
455+
["Enter a date of birth."]
456+
)
457+
end
458+
end
459+
460+
context "with an unparseable patient date of birth" do
461+
let(:data) { { "PERSON_DOB" => "not-a-date" } }
462+
463+
it "has errors" do
464+
expect(immunisation_import_row).to be_invalid
465+
expect(immunisation_import_row.errors["PERSON_DOB"]).to eq(
466+
["Enter a date of birth in the correct format."]
467+
)
468+
end
469+
end
470+
471+
context "with a patient date of birth in the future" do
450472
let(:data) { { "PERSON_DOB" => "21000101" } }
451473

452474
it "has errors" do
@@ -457,6 +479,17 @@
457479
end
458480
end
459481

482+
context "with a patient date of birth before 2000-01-01" do
483+
let(:data) { { "PERSON_DOB" => "19991231" } }
484+
485+
it "has errors" do
486+
expect(immunisation_import_row).to be_invalid
487+
expect(immunisation_import_row.errors["PERSON_DOB"]).to eq(
488+
["is too old to still be in school"]
489+
)
490+
end
491+
end
492+
460493
context "when recording offline in to a clinic" do
461494
let(:valid_clinic_data) do
462495
valid_data.merge(

0 commit comments

Comments
 (0)