123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- require 'rails_helper'
- RSpec.describe Checklist::Item, :aggregate_failures, current_user_id: 1, type: :model do
- let(:ticket) { create(:ticket) }
- let(:checklist) { create(:checklist, item_count: 0, ticket:) }
- describe '#validate_item_count' do
- let(:checklist_full) { create(:checklist, item_count: 100) }
- it 'does not allow more than 100 items' do
- next_item = build(:checklist_item, checklist: checklist_full)
- next_item.valid?
- expect(next_item.errors.full_messages)
- .to include('Checklist items are limited to 100 items per checklist.')
- end
- it 'does not run a check when cloning' do
- next_item = build(:checklist_item, checklist: checklist_full, initial_clone: true)
- next_item.valid?
- expect(next_item.errors).to be_blank
- end
- end
- describe '#detect_ticket_loop_reference' do
- it 'passes when another ticket is referenced' do
- item = create(:checklist_item, checklist:, ticket: create(:ticket))
- expect(item).to be_persisted
- end
- it 'fails when parent ticket is referenced' do
- item = build(:checklist_item, checklist:, ticket:).tap(&:save)
- expect(item.errors.messages_for(:ticket)).to include('reference must not be the checklist ticket.')
- end
- end
- describe '#detect_ticket_reference' do
- let(:target_ticket) { create(:ticket) }
- let(:number) do
- ticket_hook = Setting.get('ticket_hook')
- ticket_hook_divider = Setting.get('ticket_hook_divider')
- "#{ticket_hook}#{ticket_hook_divider}#{target_ticket.number}"
- end
- it 'detects given ticket' do
- item = create(:checklist_item, checklist:, text: number)
- expect(item.ticket).to eq target_ticket
- end
- it 'skips detecting when using a template' do
- item = create(:checklist_item, checklist:, text: number, initial_clone: true)
- expect(item.ticket).to be_nil
- end
- it 'fails gracefully when non-existant number-like text is given' do
- item = create(:checklist_item, checklist:, text: "#{number}1")
- expect(item.ticket).to be_nil
- end
- end
- describe '#detect_ticket_reference_state' do
- let(:target_ticket) { create(:ticket) }
- it 'does not set ticket state if no ticket given' do
- target_ticket
- checklist
- allow(Checklist).to receive(:ticket_closed?)
- create(:checklist_item, checklist:)
- expect(Checklist).not_to have_received(:ticket_closed?)
- end
- it 'sets ticket state when setting a ticket' do
- allow(Checklist).to receive(:ticket_closed?)
- allow(Checklist).to receive(:ticket_closed?).with(target_ticket).and_return(true)
- item = create(:checklist_item, checklist:, ticket: target_ticket)
- expect(item).to be_checked
- end
- it 'does not set ticket state when setting another attribute' do
- item = create(:checklist_item, checklist:, ticket: target_ticket)
- allow(Checklist).to receive(:ticket_closed?)
- item.update!(text: 'another')
- expect(Checklist).not_to have_received(:ticket_closed?)
- end
- end
- describe '#update_checklist_on_destroy' do
- let(:item) { create(:checklist_item, checklist:) }
- before { item }
- it 'removes item from checklist sorted_item_ids when destroying' do
- expect { item.destroy! }
- .to change { checklist.reload.sorted_item_ids }
- .to be_blank
- end
- it 'works fine when parent checklist is destroyed' do
- expect { item.checklist.destroy! }.not_to raise_error
- end
- end
- describe '#update_checklist_on_save' do
- it 'adds the item to checklist sorted_item_ids' do
- item = create(:checklist_item, checklist:)
- expect(checklist.sorted_item_ids).to include(item.id.to_s)
- end
- it 'touches checklist when updating the item' do
- item = create(:checklist_item, checklist:)
- travel 10.minutes
- expect { item.update! checked: true }
- .to change { item.checklist.updated_at }
- end
- end
- describe '#update_referenced_ticket' do
- it 'touches referenced ticket' do
- target_ticket = create(:ticket)
- travel 10.minutes
- expect { create(:checklist_item, checklist:, ticket: target_ticket) }
- .to change { target_ticket.reload.updated_at }
- end
- it 'touches referenced ticket on destroying' do
- target_ticket = create(:ticket)
- item = create(:checklist_item, checklist:, ticket: target_ticket)
- travel 10.minutes
- expect { item.destroy! }
- .to change { target_ticket.reload.updated_at }
- end
- end
- describe '.incomplete' do
- it 'returns unchecked items' do
- unchecked = create(:checklist_item, checked: false, checklist:)
- create(:checklist_item, checked: true, checklist:)
- expect(described_class.incomplete).to contain_exactly(unchecked)
- end
- end
- describe 'history entries for checked' do
- let(:checklist) do
- create(:checklist, item_count: 1)
- end
- it 'creates history entries for checked' do
- checklist.items.first.update!(checked: true)
- history_type_id = History::Type.find_by(name: 'checklist_item_checked').id
- expect(History.last).to have_attributes(
- history_type_id: history_type_id,
- value_from: checklist.items.first.text,
- value_to: 'true',
- )
- checklist.items.first.update!(checked: false)
- expect(History.last).to have_attributes(
- history_type_id: history_type_id,
- value_from: checklist.items.first.text,
- value_to: 'false',
- )
- end
- end
- end
|