You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
docuseal/spec/lib/submissions/ensure_result_generated_spe...

190 lines
6.8 KiB

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Submissions::EnsureResultGenerated do
let(:account) { create(:account) }
let(:user) { create(:user, account:) }
let(:template) { create(:template, account:, author: user) }
let(:submission) { create(:submission, template:, created_by_user: user) }
let(:submitter) { create(:submitter, submission:, uuid: SecureRandom.uuid) }
before do
create(:encrypted_config, key: EncryptedConfig::ESIGN_CERTS_KEY,
value: GenerateCertificate.call.transform_values(&:to_pem))
end
describe '.call' do
context 'when submitter is not completed' do
before do
submitter.update!(completed_at: nil)
end
it 'raises NotCompletedYet error' do
expect do
described_class.call(submitter)
end.to raise_error(Submissions::EnsureResultGenerated::NotCompletedYet)
end
end
context 'when submitter is nil' do
it 'returns empty array' do
expect(described_class.call(nil)).to eq([])
end
end
context 'when documents exist and complete event is after completion' do
let(:blob) { ActiveStorage::Blob.create_and_upload!(io: StringIO.new('test'), filename: 'test.pdf') }
before do
submitter.update!(completed_at: 5.minutes.ago)
submitter.documents.attach(blob)
# Create complete event AFTER documents were generated
submitter.document_generation_events.create!(event_name: :complete)
end
it 'returns existing documents' do
result = described_class.call(submitter)
expect(result.map(&:blob)).to include(blob)
end
it 'does not generate new documents' do
allow(Submissions::GenerateResultAttachments).to receive(:call)
described_class.call(submitter)
expect(Submissions::GenerateResultAttachments).not_to have_received(:call)
end
end
context 'when complete event is stale (created before current completion)' do
let(:old_blob) { ActiveStorage::Blob.create_and_upload!(io: StringIO.new('old'), filename: 'old.pdf') }
before do
# Old completion cycle
submitter.update!(completed_at: 10.minutes.ago)
submitter.documents.attach(old_blob)
submitter.document_generation_events.create!(event_name: :complete)
# Update timestamps to be old
ActiveStorage::Attachment.where(record: submitter, name: 'documents')
.update_all(created_at: 10.minutes.ago)
submitter.document_generation_events.update_all(created_at: 10.minutes.ago)
# New completion (re-completion after change request)
submitter.update!(completed_at: Time.current)
end
it 'generates new documents' do
allow(Submissions::GenerateResultAttachments).to receive(:call).with(submitter).and_return([])
expect do
described_class.call(submitter)
end.to change { submitter.document_generation_events.count }.by(2) # retry + complete
expect(Submissions::GenerateResultAttachments).to have_received(:call).with(submitter)
end
it 'creates a retry event (not start, since events exist)' do
allow(Submissions::GenerateResultAttachments).to receive(:call).and_return([])
described_class.call(submitter)
# Should have 1 retry event
expect(submitter.document_generation_events.where(event_name: :retry).count).to eq(1)
end
it 'creates a new complete event after generation' do
allow(Submissions::GenerateResultAttachments).to receive(:call).and_return([])
described_class.call(submitter)
# Should have 2 complete events now (old + new)
expect(submitter.document_generation_events.where(event_name: :complete).count).to eq(2)
end
end
context 'when generation is in progress (start/retry event after completion)' do
before do
submitter.update!(completed_at: Time.current)
submitter.document_generation_events.create!(event_name: :start)
end
it 'waits for completion' do
# Simulate another process completing the generation
allow(described_class).to receive(:wait_for_complete_or_fail) do
submitter.document_generation_events.create!(event_name: :complete)
submitter.documents
end
described_class.call(submitter)
expect(described_class).to have_received(:wait_for_complete_or_fail).with(submitter)
end
end
context 'when stale start/retry event exists from previous completion' do
let(:old_blob) { ActiveStorage::Blob.create_and_upload!(io: StringIO.new('old'), filename: 'old.pdf') }
before do
# Old completion with stale start event
submitter.update!(completed_at: 10.minutes.ago)
submitter.document_generation_events.create!(event_name: :start)
# Update to make it old
submitter.document_generation_events.update_all(created_at: 10.minutes.ago)
# New completion
submitter.update!(completed_at: Time.current)
end
it 'does not wait for stale event' do
allow(described_class).to receive(:wait_for_complete_or_fail)
allow(Submissions::GenerateResultAttachments).to receive(:call).and_return([])
described_class.call(submitter)
expect(described_class).not_to have_received(:wait_for_complete_or_fail)
expect(Submissions::GenerateResultAttachments).to have_received(:call)
end
it 'creates retry event for current completion' do
allow(Submissions::GenerateResultAttachments).to receive(:call).and_return([])
expect do
described_class.call(submitter)
end.to change { submitter.document_generation_events.where(event_name: :retry).count }.by(1)
end
end
context 'when no events exist yet' do
before do
submitter.update!(completed_at: Time.current)
end
it 'creates start event and generates documents' do
allow(Submissions::GenerateResultAttachments).to receive(:call).with(submitter).and_return([])
expect do
described_class.call(submitter)
end.to change { submitter.document_generation_events.where(event_name: :start).count }.by(1)
expect(Submissions::GenerateResultAttachments).to have_received(:call).with(submitter)
end
end
context 'when generation fails' do
before do
submitter.update!(completed_at: Time.current)
allow(Submissions::GenerateResultAttachments).to receive(:call).and_raise(
StandardError.new('Generation failed')
)
end
it 'creates fail event' do
expect do
described_class.call(submitter)
end.to raise_error(StandardError)
expect(submitter.document_generation_events.where(event_name: :fail).count).to eq(1)
end
end
end
end