added 260907 version of worker toolkit

This commit is contained in:
2026-09-08 20:30:51 -04:00
parent cbd3f0f8ca
commit 97aca37663
1283 changed files with 142951 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
require "rails_helper"
RSpec.describe ChartsPattern do
it "instantiates a ChartPattern instance" do
user = create(:user)
pattern = create(:pattern, encrypted_user_id: user.encrypted_id)
chart_pattern = ChartsPattern.new({start_at: pattern.start_at, end_at: pattern.end_at, pattern: pattern})
expect(chart_pattern.pattern.id).to eq pattern.id
end
it "generates chart data from a ChartPattern" do
user = create(:user)
pattern = create(:pattern, encrypted_user_id: user.encrypted_id)
chart_pattern = ChartsPattern.new({start_at: pattern.start_at, end_at: pattern.end_at, pattern: pattern})
chart_data = chart_pattern.chart_data
expect(chart_data[:pattern_name]).to eq pattern.name
expect(chart_data[:author_email]).to eq user.email
end
it "generates chart data from a ChartPattern with a valid category" do
user = create(:user)
pattern = create(:pattern, encrypted_user_id: user.encrypted_id, includes: [{category: "treatments"}])
chart_pattern = ChartsPattern.new({start_at: pattern.start_at, end_at: pattern.end_at, pattern: pattern})
chart_data = chart_pattern.chart_data
expect(chart_data[:pattern_name]).to eq pattern.name
expect(chart_data[:author_email]).to eq user.email
end
it "generates chart data from a ChartPattern with untracked category" do
user = create(:user)
pattern = create(:pattern, encrypted_user_id: user.encrypted_id, includes: [{category: "not-a-category"}])
chart_pattern = ChartsPattern.new({start_at: pattern.start_at, end_at: pattern.end_at, pattern: pattern})
chart_data = chart_pattern.chart_data
expect(chart_data[:pattern_name]).to eq pattern.name
expect(chart_data[:author_email]).to eq user.email
end
end

View File

@@ -0,0 +1,127 @@
require "rails_helper"
RSpec.describe Checkin::Creator do
let!(:user) { create(:user) }
let!(:condition_tracking) { create(:tracking, :active, :for_condition, user: user) }
let!(:condition) { condition_tracking.trackable }
let!(:symptom_tracking) { create(:tracking, :active, :for_symptom, user: user) }
let!(:symptom) { symptom_tracking.trackable }
let!(:treatment_tracking) { create(:tracking, :active, :for_treatment, user: user) }
let!(:treatment) { treatment_tracking.trackable }
let!(:date) { Time.zone.today }
subject { Checkin::Creator.new(user.id, date).create! }
describe "create" do
it "returns a new checkin prefilled with active trackables" do
expect(subject.id).to be_present
expect(subject.user_id).to eq user.id
expect(subject.date).to eq date
# Condition
checkin_condition = subject.conditions[0]
expect(checkin_condition.condition_id).to eq condition.id
expect(checkin_condition.color_id).to eq condition_tracking.color_id.to_s
expect(checkin_condition.position).to eq 0
# Symptom
checkin_symptom = subject.symptoms[0]
expect(checkin_symptom.symptom_id).to eq symptom.id
expect(checkin_symptom.color_id).to eq symptom_tracking.color_id.to_s
expect(checkin_symptom.position).to eq 0
# Treatment
checkin_treatment = subject.treatments[0]
expect(checkin_treatment.treatment_id).to eq treatment.id
expect(checkin_treatment.color_id).to eq treatment_tracking.color_id.to_s
expect(checkin_treatment.position).to eq 0
expect(checkin_treatment.is_taken).to be false
end
context "when recent dose exists for treatment in user's profile" do
before do
user.profile.set_most_recent_dose(treatment.id, "20 mg")
user.profile.save!
end
it "sets dose from profile on the new checkin" do
checkin_treatment = subject.treatments[0]
expect(checkin_treatment.treatment_id).to eq treatment.id
saved_dose = user.profile.most_recent_dose_for(treatment.id)
expect(checkin_treatment.value).to eq saved_dose
end
end
context "when recent position exists for a trackable in user's profile" do
before do
user.profile.set_most_recent_trackable_position(condition, 5)
user.profile.save!
end
it "sets trackable position from profile on the new checkin" do
checkin_condition = subject.conditions[0]
expect(checkin_condition.condition_id).to eq condition.id
saved_position = user.profile.most_recent_trackable_position_for(condition)
expect(checkin_condition.position).to eq saved_position
end
end
context "when no recent position exists for a trackable in user's profile" do
before { create(:tracking, :active, :for_condition, user: user) }
it "sets positions with auto-increment counter starting by 1" do
positions = subject.conditions.map(&:position)
expect(positions.to_set).to eq [0, 1].to_set
end
end
context "when trackables never used before" do
it "creates new usage records" do
# For Condition
expect(subject.conditions).to be_present
condition_usage = TrackableUsage.find_by(user: user, trackable: condition)
expect(condition_usage).to be_present
expect(condition_usage.count).to eq 1
# For Symptom
expect(subject.symptoms).to be_present
symptom_usage = TrackableUsage.find_by(user: user, trackable: symptom)
expect(symptom_usage).to be_present
expect(symptom_usage.count).to eq 1
# For Treatment
expect(subject.treatments).to be_present
treatment_usage = TrackableUsage.find_by(user: user, trackable: treatment)
expect(treatment_usage).to be_present
expect(treatment_usage.count).to eq 1
end
end
context "when trackables already used before" do
let!(:condition_usage) { TrackableUsage.create!(user: user, trackable: condition) }
let!(:condition_usage_count) { condition_usage.count }
let!(:symptom_usage) { TrackableUsage.create!(user: user, trackable: symptom) }
let!(:symptom_usage_count) { symptom_usage.count }
let!(:treatment_usage) { TrackableUsage.create!(user: user, trackable: treatment) }
let!(:treatment_usage_count) { treatment_usage.count }
it "increments count on usage records" do
# For Condition
expect(subject.conditions).to be_present
expect(condition_usage.reload.count).to eq(condition_usage_count + 1)
# For Symptom
expect(subject.symptoms).to be_present
expect(symptom_usage.reload.count).to eq(symptom_usage_count + 1)
# For Treatment
expect(subject.treatments).to be_present
expect(treatment_usage.reload.count).to eq(treatment_usage_count + 1)
end
end
context "when postal code is set on previous checkin" do
let(:weather) { create :weather }
let(:postal_code) { "55403" }
let(:position) { Position.create(postal_code: postal_code) }
let!(:previous_checkin) { create :checkin, user_id: user.id, position_id: position.id }
before { expect(WeatherRetriever).to receive(:get).and_return(weather) }
it "should ask for weather" do
expect(subject.position.postal_code).to eq(postal_code)
expect(subject.weather_id).to eq(weather.id)
end
end
end
end

View File

@@ -0,0 +1,207 @@
require "rails_helper"
RSpec.describe Checkin::Updater do
let(:user) { create(:user) }
let(:checkin) { create(:checkin, user_id: user.id, date: Time.zone.today) }
subject { Checkin::Updater.new(user, params).update! }
context "with permitted params" do
let(:params) { ActionController::Parameters.new(id: checkin.id.to_s, checkin: {note: "Blah"}) }
it "returns updated checkin" do
expect(subject.id).to eq checkin.id
expect(subject.note).to eq params[:checkin][:note]
end
end
context "with non-permitted params" do
let(:params) { ActionController::Parameters.new(id: checkin.id.to_s, checkin: {date: Date.yesterday}) }
it "returns checkin with no changes" do
expect(subject.id).to eq checkin.id
expect(subject.date).not_to eq params[:checkin][:date]
end
end
context "when recent dose exists for treatment in user's profile" do
let(:treatment) { create(:treatment) }
let(:params) do
ActionController::Parameters.new(
id: checkin.id.to_s,
checkin: {treatments_attributes: [{treatment_id: treatment.id}]}
)
end
before do
user.profile.set_most_recent_dose(treatment.id, "20 mg")
user.profile.save!
end
it "auto-sets the most recently used dose on added treatments" do
returned_treatment = subject.treatments[0]
expect(returned_treatment.treatment_id).to eq treatment.id
saved_dose = user.profile.most_recent_dose_for(treatment.id)
expect(returned_treatment.value).to eq saved_dose
end
end
context "trackable usages" do
context "when removing a trackable" do
let!(:checkin_condition) { create(:checkin_condition, checkin: checkin) }
let!(:condition) { Condition.find(checkin_condition.condition_id) }
let!(:usage) { create(:trackable_usage, user: user, trackable: condition) }
let(:params) do
ActionController::Parameters.new(
id: checkin.id.to_s,
checkin: {
conditions_attributes: [{
id: checkin_condition.id.to_s,
condition_id: checkin_condition.condition_id,
_destroy: "1"
}]
}
)
end
context "used once before" do
it "removes trackable and usage record" do
expect(subject.conditions.map(&:id)).not_to include checkin_condition.id
expect(TrackableUsage.find_by(user: user, trackable: condition)).to be_nil
end
end
context "used more than once before" do
let!(:previous_count) { usage.count }
before { usage.increment! :count }
it "removes trackable and decrements count on usage record" do
expect(subject.conditions.map(&:id)).not_to include checkin_condition.id
expect(usage.count).to eq(previous_count + 1)
end
end
end
context "when adding a trackable" do
let!(:condition) { create(:condition) }
let(:params) do
ActionController::Parameters.new(
id: checkin.id.to_s,
checkin: {
conditions_attributes: [{
condition_id: condition.id
}]
}
)
end
context "never used before" do
it "adds trackable and creates a new usage record" do
expect(subject.conditions.map(&:condition_id)).to include condition.id
expect(TrackableUsage.find_by(user: user, trackable: condition)).to be_present
end
end
context "already used before" do
let!(:usage) { TrackableUsage.find_or_create_by(user: user, trackable: condition) }
let!(:previous_count) { usage.count }
it "adds trackable and increments count on usage record" do
expect(subject.conditions.map(&:condition_id)).to include condition.id
expect(usage.reload.count).to eq(previous_count + 1)
end
end
end
end
context "trackables positions" do
let(:n) { 5 }
let(:trackables) do
result = []
n.times do |i|
result << create(:checkin_condition, checkin: checkin, position: i)
end
result
end
let(:trackables_attrs) do
trackables.map do |t|
{
id: t.id.to_s,
condition_id: t.condition_id,
position: t.position
}
end
end
context "when adding a trackable and client didn't pass position" do
let(:condition) { create(:condition) }
let(:params) do
ActionController::Parameters.new(
id: checkin.id.to_s,
checkin: {
conditions_attributes: trackables_attrs + [{condition_id: condition.id}]
}
)
end
it "auto-sets position to last" do
added_trackable = subject.conditions.find_by(condition_id: condition.id)
expect(added_trackable.position).to eq n
end
end
context "when removing a trackable" do
let(:params) do
ActionController::Parameters.new(
id: checkin.id.to_s,
checkin: {
conditions_attributes: trackables_attrs
}
)
end
let(:pos) { 1 }
before do
trackable_to_remove = params[:checkin][:conditions_attributes].find { |a| a[:position].eql? pos }
trackable_to_remove[:_destroy] = "1"
end
it "updates positions of removed trackable's successors" do
successors_attrs = params[:checkin][:conditions_attributes].select { |a| a[:position] > pos }
successors_attrs.each do |successor_attrs|
successor = subject.conditions.find(successor_attrs[:id])
expect(successor.position).to eq successor_attrs[:position] - 1
end
end
end
context "when reordering trackables" do
let(:params) do
ActionController::Parameters.new(
id: checkin.id.to_s,
checkin: {
conditions_attributes: trackables_attrs
}
)
end
before do
# swap first and last trackable's positions
attrs = params[:checkin][:conditions_attributes]
attrs[0][:position] = attrs[trackables_attrs.length - 1][:position]
end
context "on today's checkin" do
it "updates trackables positions in checkin and saves them in profile" do
params[:checkin][:conditions_attributes].each do |condition_attr|
checkin_condition = subject.conditions.find(condition_attr[:id])
expect(checkin_condition.position).to eq condition_attr[:position]
condition = Condition.find(condition_attr[:condition_id])
saved_position = user.profile.most_recent_trackable_position_for(condition)
expect(saved_position).to eq condition_attr[:position]
end
end
end
context "on a past checkin" do
let(:checkin) { create(:checkin, user_id: user.id, date: Time.zone.today - 1.day) }
it "updates trackables positions in checkin but doesn't save them in profile" do
params[:checkin][:conditions_attributes].each do |condition_attr|
checkin_condition = subject.conditions.find(condition_attr[:id])
expect(checkin_condition.position).to eq condition_attr[:position]
condition = Condition.find(condition_attr[:condition_id])
saved_position = user.profile.most_recent_trackable_position_for(condition)
expect(saved_position).to eq nil
end
end
end
end
end
end

View File

@@ -0,0 +1,91 @@
require "rails_helper"
MODELS = [Food, Tag].freeze
def occurrences_for(object_id, ids_key)
Checkin.where(ids_key => {"$elemMatch" => {"$eq" => object_id}}).count
end
describe CollectionRetriever do
let(:retrieved_objects) { subject.retrieve }
MODELS.each do |model|
model_name = model.name
model_slug = model_name.underscore
ids_key = "#{model_slug}_ids"
all_objects_are_model = "all objects are #{model_name}"
context model_name do
shared_examples all_objects_are_model do
it { expect(subject.retrieve.map(&:class).uniq.map(&:name)).to eq([model_name]) }
end
describe "most_popular" do
let(:objects) { create_list(model_slug, 20) }
let(:object_ids) { objects.map(&:id) }
before do
5.times do
create(:checkin, ids_key => object_ids.sample(5))
end
end
subject { described_class.new(model, :most_popular) }
it_behaves_like all_objects_are_model
it "retrieves the most popular" do
popular_object_ids = retrieved_objects.map(&:id)
non_popular_object_ids = object_ids - popular_object_ids
min_occurrence = subject.occurrences.to_a.last["count"]
non_popular_object_ids.each do |object_id|
expect(occurrences_for(object_id, ids_key)).to be <= min_occurrence
end
end
it "limits results to 10" do
expect(retrieved_objects.count).to eq 10
end
it "makes occurrences counts available after retrieve" do
subject.retrieve
max_occurrence = subject.occurrences.to_a.first["count"]
min_occurrence = subject.occurrences.to_a.last["count"]
expect(min_occurrence).to be < max_occurrence
subject.occurrences.each do |o|
expected_count = occurrences_for(o["_id"], ids_key)
expect(o["count"]).to eq expected_count
end
end
end
describe "most_recent" do
let(:user) { create(:user) }
let(:objects) { create_list(model_slug, 20) }
let(:object_ids) { objects.map(&:id) }
before do
today = Time.zone.today
5.times do |i|
create(
:checkin,
:user_id => user.id,
:date => today + i.days,
ids_key => [object_ids[i], object_ids[i + 5]]
)
end
end
subject { described_class.new(model, :most_recent, user) }
it_behaves_like all_objects_are_model
it "retrieves the most recent objects for the given user" do
retrieved_object_ids = retrieved_objects.map(&:id)
expect(retrieved_object_ids.to_set).to eq object_ids.slice(0..9).to_set
expect(retrieved_object_ids).not_to include object_ids.slice(10..19)
end
end
end
end
end

View File

@@ -0,0 +1,19 @@
require "rails_helper"
RSpec.describe Google::RecaptchaVerifier, :vcr do
subject { Google::RecaptchaVerifier.exec(recaptcha_response) }
context "given a non-expired ReCaptcha response" do
let(:recaptcha_response) { "non-expired-recaptcha-response-dummy-string" }
it "returns true" do
is_expected.to be true
end
end
context "given an expired ReCaptcha response" do
let(:recaptcha_response) { "expired-recaptcha-response-dummy-string" }
it "returns false" do
is_expected.to be false
end
end
end

View File

@@ -0,0 +1,32 @@
require "rails_helper"
RSpec.describe TrackableCreator do
context "for Condition" do
let!(:user) { create(:user) }
let!(:condition_name) { "coding addiction" }
let!(:trackable) { Condition.new(name: condition_name, global: false) }
subject { TrackableCreator.new(trackable, user).create! }
context "when no same condition exists" do
it "creates new non-global condition and associates to user" do
expect(subject.global?).to be false
expect(UserCondition.find_by(user_id: user.id, condition_id: subject.id)).to be_present
end
end
context "when global same condition exists" do
let!(:same_condition) { create(:condition, name: condition_name.titleize) }
it "returns existing condition" do
expect(subject.id).to eq same_condition.id
end
end
context "when non-global same condition exists" do
let!(:same_condition) { create(:user_condition).condition }
before { same_condition.update!(name: condition_name.titleize) }
it "returns existing condition and associates it to user" do
expect(subject.id).to eq same_condition.id
expect(UserCondition.find_by(user_id: user.id, condition_id: same_condition.id)).to be_present
end
end
end
end

View File

@@ -0,0 +1,30 @@
require "rails_helper"
describe WeatherRetriever, :vcr do
let(:date) { Date.parse "2016-01-06" }
let(:cassete) { "#{described_class.name}/#{postal_code}" }
let(:postal_code) { "55403" }
let(:perform) do
VCR.use_cassette cassete do
described_class.get(date, postal_code)
end
end
context "no weather cached" do
it { expect(perform).to be_a(Weather) }
it { expect { perform }.to change { Weather.count }.by(1) }
end
context "the weather is already cached" do
let(:position) { Position.create(postal_code: postal_code) }
let!(:weather) { create :weather, date: date, position_id: position.id }
before { expect(Weather).not_to receive(:create) }
before { expect(Geocoder).not_to receive(:search) }
before { expect(Tomorrowiorb).not_to receive(:forecast) }
it { expect(perform).to eq(weather) }
it { expect { perform }.not_to change { Weather.count } }
end
end