<commit_before>require "rails_helper"

module Renalware
  module Pathology
    RSpec.describe CurrentObservationSet do
      include PathologySpecHelper
      it { is_expected.to belong_to(:patient) }
      it { is_expected.to validate_presence_of(:patient) }

      describe "values" do
        it "defaults to an empty hash" do
          expect(described_class.new.values).to eq({})
        end

        it "persists ok" do
          patient = create(:pathology_patient)
          obs_set = patient.fetch_current_observation_set
          hgb = { "result" => "23.1", "observed_at" => "2016-12-12 12:12:12" }
          obs_set.values["HGB"] = hgb
          obs_set.save!

          obs_set = patient.reload.fetch_current_observation_set
          expect(obs_set.values["HGB"]).to eq(hgb)
        end
      end

      describe "values_for_codes" do
        it "returns only the values matching the requested codes aray" do
          patient = create(:pathology_patient)
          set = patient.fetch_current_observation_set
          hgb = { "result" => 23.1, "observed_at" => "2016-12-12 12:12:12" }
          cre = { "result" => 2.1, "observed_at" => "2016-12-12 12:12:12" }
          set.values["HGB"] = hgb
          set.values["CRE"] = cre
          set.save!

          set.reload
          expect(set.values_for_codes("HGB")).to eq({ "HGB" => hgb })
        end
      end

      # describe "#all" do
      #   it "returns only the most recent path results" do
      #     patient = create_patient
      #     descriptions = create_descriptions(%w(x y z))
      #     travel_to(Time.zone.now) do
      #       # current
      #       create_observations(patient,
      #                           descriptions,
      #                           observed_at: Time.zone.now,
      #                           result: 99)
      #       # !! not current
      #       create_observations(patient,
      #                           descriptions,
      #                           observed_at: Time.zone.now - 1.day,
      #                           result: 1)

      #       obs = patient.current_observations.all

      #       expect(obs.length).to eq(3)
      #       expect(obs.map(&:observed_at).uniq).to eq([Time.zone.now])
      #       expect(obs.map(&:result).uniq).to eq(["99"])
      #     end
      #  end
      # end
    end
  end
end<commit_msg>Add tests for trigger on pathology_observations<commit_after># rubocop:disable Metrics/ModuleLength
require "rails_helper"

module Renalware
  module Pathology
    RSpec.describe CurrentObservationSet do
      include PathologySpecHelper
      it { is_expected.to belong_to(:patient) }
      it { is_expected.to validate_presence_of(:patient) }

      describe "values" do
        it "defaults to an empty hash" do
          expect(described_class.new.values).to eq({})
        end

        it "persists ok" do
          patient = create(:pathology_patient)
          obs_set = patient.fetch_current_observation_set
          hgb = { "result" => "23.1", "observed_at" => "2016-12-12 12:12:12" }
          obs_set.values["HGB"] = hgb
          obs_set.save!

          obs_set = patient.reload.fetch_current_observation_set
          expect(obs_set.values["HGB"]).to eq(hgb)
        end
      end

      describe "values_for_codes" do
        it "returns only the values matching the requested codes aray" do
          patient = create(:pathology_patient)
          set = patient.fetch_current_observation_set
          hgb = { "result" => 23.1, "observed_at" => "2016-12-12 12:12:12" }
          cre = { "result" => 2.1, "observed_at" => "2016-12-12 12:12:12" }
          set.values["HGB"] = hgb
          set.values["CRE"] = cre
          set.save!

          set.reload
          expect(set.values_for_codes("HGB")).to eq({ "HGB" => hgb })
        end
      end

      describe "the TRIGGER on pathology_observations that updates current_observation_set" do
        context "when a patient has no current_observation_set yet" do
          it "creating an observation adds it to the current_observation_set jsonb hash" do
            time = Time.zone.now
            patient = create(:pathology_patient)
            expect{
              create_hgb_observation(patient: patient, observed_at: time, result: 123.1)
            }.to change{ CurrentObservationSet.count }.by(1)
            # trigger has now updated the current_observation_set

            obs_set = CurrentObservationSet.find_by(patient_id: patient.id)
            hgb = obs_set.values[:HGB]
            expect_obs_to_match(hgb, "123.1", time)
          end
        end

        context "when a patient has a current_observation_set with an entry for HGB" do
          context "when a new HGB observation is created (importantly with a newer date)" do
            it "updates the values hash with the new result and time" do
              time = Time.zone.now
              patient = create(:pathology_patient)
              obs = create_hgb_observation(patient: patient, observed_at: time, result: 111.1)

              obs_set = CurrentObservationSet.find_by(patient_id: patient.id)
              hgb = obs_set.values[:HGB]
              expect_obs_to_match(hgb, 111.1, time)

              new_time = time + 1.hour
              expect{
                obs = create_hgb_observation(patient: patient, observed_at: new_time, result: 222.2)
              }.to change{ CurrentObservationSet.count }.by(0)
              # trigger has now updated the current_observation_set

              new_hgb = obs_set.reload.values[:HGB]
              expect(new_hgb).not_to eq(hgb)
              expect_obs_to_match(new_hgb, obs.result, new_time)
            end
          end

          context "when another HGB observation is created but with an OLDER date" do
            it "does not update the values hash" do
              time = Time.zone.now
              patient = create(:pathology_patient)
              obs = create_hgb_observation(patient: patient, observed_at: time, result: 111.1)
              # trigger has now updated the current_observation_set

              obs_set = CurrentObservationSet.find_by(patient_id: patient.id)
              hgb = obs_set.values[:HGB]
              expect_obs_to_match(hgb, obs.result, time)

              expect{
                obs = create_hgb_observation(
                  patient: patient,
                  observed_at:  time - 1.hour, # an older date,
                  result: 222.2
                )
              }.to change{ CurrentObservationSet.count }.by(0)

              expect(obs_set.reload.values[:HGB]).to eq(hgb)
            end
          end

          context "when another HGB observation is updated and has a NEWER date" do
            it "updates the values hash with the new result and time" do
              time = Time.zone.now
              patient = create(:pathology_patient)
              obs = create_hgb_observation(patient: patient, observed_at: time, result: 111.1)
              # trigger has now updated the current_observation_set

              new_time = time + 1.hour
              obs.update!(observed_at: new_time, result: 222.2)

              obs.reload
              obs_set = CurrentObservationSet.find_by(patient_id: patient.id)
              hgb = obs_set.values[:HGB]
              expect_obs_to_match(hgb, obs.result, new_time)
            end
          end

          context "when an HGB observation is updated with the same date but different result" do
            it "updates the values hash with the new result and time" do
              time = Time.zone.now
              patient = create(:pathology_patient)
              obs = create_hgb_observation(patient: patient, observed_at: time, result: 111.1)
              # trigger has now updated the current_observation_set

              obs.update!(result: 222.2)

              obs_set = CurrentObservationSet.find_by(patient_id: patient.id)
              hgb = obs_set.values[:HGB]
              expect_obs_to_match(hgb, obs.result, time)
            end
          end
        end
      end

      def create_hgb_observation(patient:, **observation_options)
        request = create(:pathology_observation_request, patient: patient)
        create(
          :pathology_observation,
          request: request,
          description: create(:pathology_observation_description, code: "HGB"),
          **observation_options
        )
      end

      # rubocop:disable Rails/TimeZone
      def expect_obs_to_match(obs, result, time)
        observed_at = I18n.l(Time.parse(obs[:observed_at]))
        expect(obs[:result]).to eq(result.to_s)
        expect(observed_at).to eq(I18n.l(time))
      end
      # rubocop:enable Rails/TimeZone
    end
  end
end
{'fraction_non_alphanumeric': 0.08910777688695452, 'fraction_numerical': 0.018440041232390333, 'mean_word_length': 1.9311849613964418, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '14869', 'n_tokens_mistral': 2656, 'n_tokens_neox': 2494, 'n_words': 616}