Files
growstuff/spec/services/job_list_spec.rb
T
b77fa5d4c4 Add 'This week' reschedule option for jobs (#5118)
* Add 'This week' reschedule option for jobs

- Add JobList.week_date helper returning the Friday of the current week.
- Add move_week translation key in config/locales/en.yml.
- Render 'This week' option in app/views/jobs/_reschedule.haml when week_date is after tomorrow.
- Add unit specs in spec/services/job_list_spec.rb and view specs in spec/views/jobs/_reschedule.haml_spec.rb.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Remove low value tests

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Brenda Wallace <brenda@wallace.net.nz>
2026-10-27 18:56:13 +10:30

218 lines
6.9 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
describe JobList do
subject(:list) { described_class.new(jobs, today:) }
# A Wednesday, so the rest of the week is Thursday and Friday, then the weekend
# of the 24th and 25th.
let(:today) { Date.new(2026, 10, 21) }
let(:jobs) { [due_today, thursday, saturday, next_saturday, next_week, overdue, no_day] }
let(:thursday) { build(:job, due_date: Date.new(2026, 10, 22)) }
let(:due_today) { build(:job, due_date: today) }
let(:saturday) { build(:job, due_date: Date.new(2026, 10, 24)) }
let(:next_saturday) { build(:job, due_date: Date.new(2026, 10, 31)) }
let(:next_week) { build(:job, due_date: Date.new(2026, 10, 28)) }
let(:overdue) { build(:job, due_date: Date.new(2026, 10, 19)) }
let(:no_day) { build(:job, due_date: nil) }
def group(key)
list.groups.find { |group| group.key == key }
end
it 'shows the groups in order' do
expect(list.groups.map(&:key)).to eq %i(overdue today week weekend next_weekend later someday)
end
it 'puts jobs due today in Today' do
expect(group(:today).jobs).to eq [due_today]
end
it 'puts jobs for the rest of the week in This week' do
expect(group(:week).jobs).to eq [thursday]
end
it 'puts jobs for Saturday and Sunday in This weekend' do
expect(group(:weekend).jobs).to eq [saturday]
end
it 'puts jobs for the weekend after in Next weekend' do
expect(group(:next_weekend).jobs).to eq [next_saturday]
end
it 'puts jobs from before today in Overdue' do
expect(group(:overdue).jobs).to eq [overdue]
end
it 'puts jobs for after next weekend in Later' do
expect(group(:later).jobs).to eq [next_week]
end
it 'puts jobs without a day in Some day' do
expect(group(:someday).jobs).to eq [no_day]
end
it 'cannot drop a job on Overdue' do
expect(group(:overdue)).not_to be_droppable
end
context 'with a crossed off job that was due before today' do
let(:done) { build(:job, due_date: Date.new(2026, 10, 14), finished: true) }
let(:done_later) { build(:job, due_date: Date.new(2026, 10, 18), finished: true) }
let(:jobs) { [due_today, overdue, done, done_later] }
it 'puts it in Done, at the bottom' do
expect(list.groups.map(&:key)).to eq %i(overdue today week weekend next_weekend later someday done)
end
it 'leaves it out of Overdue' do
expect(group(:overdue).jobs).to eq [overdue]
end
it 'has the latest first' do
expect(group(:done).jobs).to eq [done_later, done]
end
it 'cannot be dropped on' do
expect(group(:done)).not_to be_droppable
end
end
context 'with a job crossed off in the page being looked at' do
subject(:list) { described_class.new(jobs, today:, pinned: [just_ticked.id]) }
let(:just_ticked) { create(:job, due_date: Date.new(2026, 10, 14), finished: true) }
let(:ticked_before) { create(:job, due_date: Date.new(2026, 10, 15), finished: true) }
let(:jobs) { [just_ticked, ticked_before] }
it 'leaves it where its day puts it' do
expect(group(:overdue).jobs).to eq [just_ticked]
end
it 'still moves the others that are crossed off to Done' do
expect(group(:done).jobs).to eq [ticked_before]
end
end
context 'with crossed off jobs that say when they were crossed off' do
let(:first) { build(:job, due_date: Date.new(2026, 10, 18), finished: true, finished_at: Time.zone.local(2026, 10, 20)) }
let(:last) { build(:job, due_date: Date.new(2026, 10, 14), finished: true, finished_at: Time.zone.local(2026, 10, 21)) }
let(:undated) { build(:job, due_date: nil, finished: true, finished_at: Time.zone.local(2026, 10, 19)) }
let(:jobs) { [first, undated, last] }
it 'puts the one crossed off last first, whatever its day' do
expect(group(:done).jobs).to eq [last, first, undated]
end
end
context 'with a crossed off job that has no day' do
let(:done_past) { build(:job, due_date: Date.new(2026, 10, 18), finished: true) }
let(:done_undated) { build(:job, due_date: nil, finished: true) }
let(:jobs) { [no_day, done_undated, done_past] }
it 'puts it in Done, not Some day' do
expect(group(:done).jobs).to include(done_undated)
end
it 'leaves a job without a day that is not crossed off in Some day' do
expect(group(:someday).jobs).to eq [no_day]
end
it 'puts it after the ones with a day' do
expect(group(:done).jobs).to eq [done_past, done_undated]
end
end
context 'with a crossed off job due today' do
let(:due_today) { build(:job, due_date: today, finished: true) }
it 'puts it in Done' do
expect(group(:done).jobs).to eq [due_today]
end
it 'leaves Today without it' do
expect(group(:today).jobs).to be_empty
end
end
context 'with a crossed off job due today that is pinned' do
let(:due_today) { build_stubbed(:job, due_date: today, finished: true) }
let(:list) { described_class.new(jobs, today:, pinned: [due_today.id]) }
it 'keeps it in Today' do
expect(group(:today).jobs).to eq [due_today]
end
end
context 'without any jobs' do
let(:jobs) { [] }
it 'still has places to drop one' do
expect(list.groups.map(&:key)).to eq %i(today week weekend next_weekend later someday)
end
end
describe '.week_date' do
it 'is the Friday for This week' do
expect(described_class.week_date(today)).to eq Date.new(2026, 10, 23)
end
end
describe 'the day a dropped job gets' do
it 'is today for Today' do
expect(group(:today).drop_date).to eq today
end
it 'is the Friday for This week' do
expect(group(:week).drop_date).to eq Date.new(2026, 10, 23)
end
it 'is the Saturday for This weekend' do
expect(group(:weekend).drop_date).to eq Date.new(2026, 10, 24)
end
it 'is the next Saturday for Next weekend' do
expect(group(:next_weekend).drop_date).to eq Date.new(2026, 10, 31)
end
it 'is no day for Some day' do
expect(group(:someday).drop_date).to be_nil
end
it 'is three weeks out for Later' do
expect(group(:later).drop_date).to eq Date.new(2026, 11, 11)
end
end
context 'when today is Sunday' do
let(:today) { Date.new(2026, 10, 25) }
let(:jobs) { [due_today] }
it 'has no This week or This weekend, as none of the week is left' do
expect(list.groups.map(&:key)).to eq %i(today next_weekend later someday)
end
end
context 'when today is Saturday' do
let(:today) { Date.new(2026, 10, 24) }
let(:jobs) { [] }
it 'drops on Sunday for This weekend' do
expect(group(:weekend).drop_date).to eq Date.new(2026, 10, 25)
end
end
context 'with more than five crossed off jobs' do
let(:jobs) { Array.new(7) { |i| build(:job, due_date: today - (i + 1).days, finished: true) } }
it 'shows the five most recently done' do
expect(group(:done).shown).to eq jobs.first(5)
end
it 'keeps the rest as older' do
expect(group(:done).older).to eq jobs.last(2)
end
end
end