From d215a380117482b3ad353c814c58dfd697981a6e Mon Sep 17 00:00:00 2001 From: Dan Webb Date: Thu, 3 Sep 2026 23:24:55 +0100 Subject: [PATCH 1/2] test(insights): cover medication pause intervals --- .../detectors/adherence_streak_spec.rb | 31 +++++++++++++++++++ .../detectors/missed_dose_pattern_spec.rb | 29 +++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/spec/services/smart_insights/detectors/adherence_streak_spec.rb b/spec/services/smart_insights/detectors/adherence_streak_spec.rb index c1c9257c5..8e6d800da 100644 --- a/spec/services/smart_insights/detectors/adherence_streak_spec.rb +++ b/spec/services/smart_insights/detectors/adherence_streak_spec.rb @@ -3,6 +3,8 @@ require 'rails_helper' RSpec.describe SmartInsights::Detectors::AdherenceStreak do + fixtures :accounts + def context_with(daily_data) = instance_double(SmartInsights::Context, daily_data: daily_data) def day(expected:, actual:) = { expected: expected, actual: actual } @@ -41,4 +43,33 @@ def day(expected:, actual:) = { expected: expected, actual: actual } data = [day(expected: 2, actual: 1), day(expected: 1, actual: 1), day(expected: 1, actual: 1)] expect(described_class.new(context_with(data)).call).to eq([]) end + + it 'recognises adherence when only paused evening occurrences are unlogged' do + start_date = Date.new(2026, 4, 20) + person = create(:person) + schedule = create(:schedule, person: person, start_date: start_date, end_date: start_date + 2.days, + schedule_type: :multiple_daily, schedule_config: { 'times' => %w[08:00 20:00] }, + max_daily_doses: 2) + (start_date..(start_date + 2.days)).each do |date| + create(:medication_take, :for_schedule, schedule: schedule, taken_at: date.in_time_zone + 8.hours) + record_pause(schedule, started_at: date.in_time_zone + 20.hours, ended_at: (date + 1.day).in_time_zone + 8.hours) + end + context = SmartInsights::Context.new(people: [person], start_date: start_date, end_date: start_date + 2.days) + + insight = described_class.new(context).call.sole + + expect(insight.metric_value).to eq(I18n.t('smart_insights.detectors.adherence_streak.metric_value', count: 3)) + end + + def record_pause(schedule, started_at:, ended_at:) + FixtureHouseholdSetup.apply! + membership = accounts(:admin).household_memberships.find_by!(household: schedule.household) + schedule.medication_pause_periods.create!( + reason: 'clinician_advice', + started_at: started_at, + ended_at: ended_at, + recorded_by_membership: membership, + resumed_by_membership: membership + ) + end end diff --git a/spec/services/smart_insights/detectors/missed_dose_pattern_spec.rb b/spec/services/smart_insights/detectors/missed_dose_pattern_spec.rb index 2b7c25893..32b2b690d 100644 --- a/spec/services/smart_insights/detectors/missed_dose_pattern_spec.rb +++ b/spec/services/smart_insights/detectors/missed_dose_pattern_spec.rb @@ -3,6 +3,8 @@ require 'rails_helper' RSpec.describe SmartInsights::Detectors::MissedDosePattern do + fixtures :accounts + def context_with(daily_data) = instance_double(SmartInsights::Context, daily_data: daily_data) def day(expected:, actual:) = { expected: expected, actual: actual } @@ -39,4 +41,31 @@ def day(expected:, actual:) = { expected: expected, actual: actual } ] expect(described_class.new(context_with(data)).call.size).to eq(1) end + + it 'counts resumed misses without counting completed pause days' do + start_date = Date.new(2026, 4, 20) + person = create(:person) + schedule = create(:schedule, person: person, start_date: start_date, end_date: start_date + 3.days, + schedule_type: :multiple_daily, schedule_config: { 'times' => ['08:00'] }, + max_daily_doses: 1) + record_pause(schedule, started_at: start_date.in_time_zone + 8.hours, + ended_at: (start_date + 2.days).in_time_zone + 8.hours) + context = SmartInsights::Context.new(people: [person], start_date: start_date, end_date: start_date + 3.days) + + insight = described_class.new(context).call.sole + + expect(insight.metric_value).to eq(I18n.t('smart_insights.detectors.missed_dose_pattern.metric_value', count: 2)) + end + + def record_pause(schedule, started_at:, ended_at:) + FixtureHouseholdSetup.apply! + membership = accounts(:admin).household_memberships.find_by!(household: schedule.household) + schedule.medication_pause_periods.create!( + reason: 'clinician_advice', + started_at: started_at, + ended_at: ended_at, + recorded_by_membership: membership, + resumed_by_membership: membership + ) + end end From b13511f04280235665865524008a9a9772ef98cf Mon Sep 17 00:00:00 2001 From: Dan Webb Date: Thu, 3 Sep 2026 23:40:02 +0100 Subject: [PATCH 2/2] test(insights): load household fixture dependencies --- spec/services/smart_insights/detectors/adherence_streak_spec.rb | 2 +- .../smart_insights/detectors/missed_dose_pattern_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/services/smart_insights/detectors/adherence_streak_spec.rb b/spec/services/smart_insights/detectors/adherence_streak_spec.rb index 8e6d800da..78f728059 100644 --- a/spec/services/smart_insights/detectors/adherence_streak_spec.rb +++ b/spec/services/smart_insights/detectors/adherence_streak_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe SmartInsights::Detectors::AdherenceStreak do - fixtures :accounts + fixtures :accounts, :people def context_with(daily_data) = instance_double(SmartInsights::Context, daily_data: daily_data) def day(expected:, actual:) = { expected: expected, actual: actual } diff --git a/spec/services/smart_insights/detectors/missed_dose_pattern_spec.rb b/spec/services/smart_insights/detectors/missed_dose_pattern_spec.rb index 32b2b690d..7fd5a6f37 100644 --- a/spec/services/smart_insights/detectors/missed_dose_pattern_spec.rb +++ b/spec/services/smart_insights/detectors/missed_dose_pattern_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' RSpec.describe SmartInsights::Detectors::MissedDosePattern do - fixtures :accounts + fixtures :accounts, :people def context_with(daily_data) = instance_double(SmartInsights::Context, daily_data: daily_data) def day(expected:, actual:) = { expected: expected, actual: actual }