require 'digest' require 'rails_helper' RSpec.describe Wiki::Commit do let(:user) { create_member_user! } def create_page title:, body: 'initial body' described_class.create_content!( tag_name: TagName.create!(name: title), body:, created_by_user: user, message: 'init') end describe '.create_content!' do it 'creates page, revision, and version with normalised body' do expect { described_class.create_content!( tag_name: TagName.create!(name: 'commit_integrity_create'), body: "a\r\nb\r\n\r\n", created_by_user: user, message: 'init') } .to change(WikiPage, :count).by(1) .and change(WikiRevision, :count).by(1) .and change(WikiVersion, :count).by(1) page = WikiPage.joins(:tag_name).find_by!(tag_names: { name: 'commit_integrity_create' }) revision = page.current_revision version = page.wiki_versions.order(:version_no).last expect(page.body).to eq("a\nb") expect(revision.lines_count).to eq(2) expect(version.body).to eq("a\nb") expect(version.reason).to eq('init') end it 'rejects body that becomes blank after normalisation' do tag_name = TagName.create!(name: 'commit_integrity_blank') expect { described_class.create_content!( tag_name:, body: "\r\n\r\n", created_by_user: user, message: 'blank') } .to raise_error(ActiveRecord::RecordInvalid) expect(WikiPage.where(tag_name:)).not_to exist end end describe '.content!' do it 'updates page body, revision, and version' do page = create_page(title: 'commit_integrity_update', body: 'before') current_id = page.current_revision.id expect { described_class.content!( page:, body: 'after', created_user: user, message: 'edit', base_revision_id: current_id) } .to change(WikiRevision, :count).by(1) .and change(WikiVersion, :count).by(1) page.reload version = page.wiki_versions.order(:version_no).last expect(page.body).to eq('after') expect(version.body).to eq('after') expect(version.reason).to eq('edit') end it 'does not record tag_version on body-only wiki update' do tag_name = TagName.create!(name: 'commit_integrity_linked_tag') tag = Tag.create!(tag_name:, category: :general) page = described_class.create_content!( tag_name:, body: 'before', created_by_user: user, message: 'init') TagVersionRecorder.record!( tag:, event_type: :create, created_by_user: user) before_count = tag.reload.tag_versions.count described_class.content!( page:, body: 'after', created_user: user, message: 'edit', base_revision_id: page.current_revision.id) expect(tag.reload.tag_versions.count).to eq(before_count) end it 'raises conflict and leaves page, revision, and version unchanged' do page = create_page(title: 'commit_integrity_conflict', body: 'first') stale_id = page.current_revision.id described_class.content!( page:, body: 'second', created_user: user, message: 'second', base_revision_id: stale_id) page.reload before_body = page.body before_revision_count = page.wiki_revisions.count before_version_count = page.wiki_versions.count expect { described_class.content!( page:, body: 'third', created_user: user, message: 'stale', base_revision_id: stale_id) } .to raise_error(Wiki::Commit::Conflict) page.reload expect(page.body).to eq(before_body) expect(page.wiki_revisions.count).to eq(before_revision_count) expect(page.wiki_versions.count).to eq(before_version_count) end it 'deduplicates duplicated missing wiki lines' do page = create_page(title: 'commit_integrity_dedup', body: 'before') duplicated = 'commit_integrity_duplicate_line' described_class.content!( page:, body: "#{ duplicated }\n#{ duplicated }", created_user: user, message: 'dedup', base_revision_id: page.current_revision.id) revision = page.reload.current_revision expect(WikiLine.where(body: duplicated).count).to eq(1) expect(revision.wiki_revision_lines.count).to eq(2) expect(revision.wiki_revision_lines.pluck(:wiki_line_id).uniq.size).to eq(1) end end describe '.redirect!' do it 'raises because redirect revisions are deprecated' do page = create_page(title: 'commit_integrity_redirect_source', body: 'source') target = create_page(title: 'commit_integrity_redirect_target', body: 'target') expect { described_class.redirect!( page:, redirect_page: target, created_user: user, message: 'redirect', base_revision_id: page.current_revision.id) } .to raise_error(RuntimeError, '廃止しました.') end end end