このコミットが含まれているのは:
@@ -70,27 +70,12 @@ RSpec.describe 'Tag description Wiki dual writes', type: :request do
|
|||||||
tag_name:, body: 'before', created_by_user: user)
|
tag_name:, body: 'before', created_by_user: user)
|
||||||
end
|
end
|
||||||
let!(:first_revision) { page.current_revision }
|
let!(:first_revision) { page.current_revision }
|
||||||
let!(:current_revision) do
|
|
||||||
# Repeated bodies create revisions, but no extra WikiVersion snapshot.
|
|
||||||
Wiki::Commit.content!(page:, body: 'before', created_user: user,
|
|
||||||
base_revision_id: first_revision.id)
|
|
||||||
end
|
|
||||||
let!(:description) do
|
let!(:description) do
|
||||||
TagDescription.create!(
|
TagDescription.find_by!(tag_id: tag.id, language_code: 'ja')
|
||||||
id: page.id, tag:, language_code: 'ja', body: 'before', version_no: 2,
|
|
||||||
created_by_user_id: user.id, updated_by_user_id: user.id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
def update_description body: 'after', title: tag_name.name, base: first_revision.id
|
||||||
[first_revision, current_revision].each_with_index do |revision, index|
|
|
||||||
TagDescriptionVersion.create!(
|
|
||||||
id: revision.id, tag_id: tag.id, language_code: 'ja', version_no: index + 1,
|
|
||||||
body: 'before', event_type: index.zero? ? 'create' : 'update',
|
|
||||||
created_by_user_id: user.id, created_at: revision.created_at)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_description body: 'after', title: tag_name.name, base: current_revision.id
|
|
||||||
put "/wiki/#{ page.id }",
|
put "/wiki/#{ page.id }",
|
||||||
params: { title:, body:, message: 'edit', base_revision_id: base },
|
params: { title:, body:, message: 'edit', base_revision_id: base },
|
||||||
headers: headers
|
headers: headers
|
||||||
@@ -98,7 +83,7 @@ RSpec.describe 'Tag description Wiki dual writes', type: :request do
|
|||||||
|
|
||||||
it 'increments the independent description sequence and shares revision identity' do
|
it 'increments the independent description sequence and shares revision identity' do
|
||||||
expect(page.reload.version_no).to eq(1)
|
expect(page.reload.version_no).to eq(1)
|
||||||
expect(description.version_no).to eq(2)
|
expect(description.version_no).to eq(1)
|
||||||
expect { update_description }
|
expect { update_description }
|
||||||
.to change(WikiRevision, :count).by(1)
|
.to change(WikiRevision, :count).by(1)
|
||||||
.and change(WikiVersion, :count).by(1)
|
.and change(WikiVersion, :count).by(1)
|
||||||
@@ -107,56 +92,116 @@ RSpec.describe 'Tag description Wiki dual writes', type: :request do
|
|||||||
|
|
||||||
revision = page.reload.current_revision
|
revision = page.reload.current_revision
|
||||||
version = TagDescriptionVersion.find(revision.id)
|
version = TagDescriptionVersion.find(revision.id)
|
||||||
expect(description.reload).to have_attributes(body: 'after', version_no: 3)
|
expect(description.reload).to have_attributes(body: 'after', version_no: 2)
|
||||||
expect(version).to have_attributes(
|
expect(version).to have_attributes(
|
||||||
body: 'after', version_no: 3, event_type: 'update', created_by_user_id: user.id)
|
body: 'after', version_no: 2, event_type: 'update', created_by_user_id: user.id)
|
||||||
expect(page).to have_attributes(body: 'after', version_no: 2)
|
expect(page).to have_attributes(body: 'after', version_no: 2)
|
||||||
expect(revision.body).to eq(version.body)
|
expect(revision.body).to eq(version.body)
|
||||||
expect(page.wiki_versions.order(:version_no).last.body).to eq(version.body)
|
expect(page.wiki_versions.order(:version_no).last.body).to eq(version.body)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'mirrors the Wiki revision for a title-only update despite identical bodies' do
|
it 'does not add body history for a title-only update' do
|
||||||
expect { update_description(body: 'before', title: 'description_renamed') }
|
revision_count = WikiRevision.count
|
||||||
.to change(WikiRevision, :count).by(1)
|
wiki_version_count = WikiVersion.count
|
||||||
.and change(TagDescriptionVersion, :count).by(1)
|
description_version_count = TagDescriptionVersion.count
|
||||||
|
wiki_version_no = page.reload.version_no
|
||||||
|
description_version_no = description.version_no
|
||||||
|
current_revision_id = page.current_revision.id
|
||||||
|
page_state = page.attributes
|
||||||
|
description_state = description.attributes
|
||||||
|
|
||||||
|
update_description(body: 'before', title: 'description_renamed')
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(tag_name.reload.name).to eq('description_renamed')
|
expect(tag_name.reload.name).to eq('description_renamed')
|
||||||
expect(description.reload).to have_attributes(body: 'before', version_no: 3)
|
expect(WikiRevision.count).to eq(revision_count)
|
||||||
|
expect(WikiVersion.count).to eq(wiki_version_count)
|
||||||
revision = page.reload.current_revision
|
expect(TagDescriptionVersion.count).to eq(description_version_count)
|
||||||
version = TagDescriptionVersion.find(revision.id)
|
expect(page.reload).to have_attributes(body: 'before', version_no: wiki_version_no)
|
||||||
expect(revision.body).to eq('before')
|
expect(page.current_revision.id).to eq(current_revision_id)
|
||||||
expect(version).to have_attributes(
|
expect(page.reload.attributes).to eq(page_state)
|
||||||
tag_id: tag.id, language_code: 'ja', body: 'before', version_no: 3,
|
expect(description.reload).to have_attributes(
|
||||||
event_type: 'update', created_by_user_id: user.id)
|
body: 'before', version_no: description_version_no)
|
||||||
expect(TagDescriptionVersion.where(tag_id: tag.id, language_code: 'ja').order(:id).ids)
|
expect(description.reload.attributes).to eq(description_state)
|
||||||
.to eq(page.wiki_revisions.order(:id).ids)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not add a description version for a TagName rename through tags' do
|
it 'does not add body history for a TagName rename through tags' do
|
||||||
expect do
|
revision_count = WikiRevision.count
|
||||||
patch "/tags/#{ tag.id }", params: { name: 'description_tag_renamed' }, headers: headers
|
wiki_version_count = WikiVersion.count
|
||||||
end.not_to change(TagDescriptionVersion, :count)
|
description_version_count = TagDescriptionVersion.count
|
||||||
|
page_version_no = page.reload.version_no
|
||||||
|
current_revision_id = page.current_revision.id
|
||||||
|
|
||||||
|
patch "/tags/#{ tag.id }",
|
||||||
|
params: { name: 'description_tag_renamed' },
|
||||||
|
headers:
|
||||||
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(tag_name.reload.name).to eq('description_tag_renamed')
|
expect(tag_name.reload.name).to eq('description_tag_renamed')
|
||||||
expect(description.reload).to have_attributes(body: 'before', version_no: 2)
|
expect(WikiRevision.count).to eq(revision_count)
|
||||||
|
expect(WikiVersion.count).to eq(wiki_version_count)
|
||||||
|
expect(TagDescriptionVersion.count).to eq(description_version_count)
|
||||||
|
expect(page.reload.version_no).to eq(page_version_no)
|
||||||
|
expect(page.current_revision.id).to eq(current_revision_id)
|
||||||
|
expect(description.reload).to have_attributes(
|
||||||
|
body: 'before', version_no: 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'keeps both systems and the title unchanged on a stale revision conflict' do
|
it 'keeps both systems and the title unchanged on a stale revision conflict' do
|
||||||
|
update_description(body: 'current body', base: first_revision.id)
|
||||||
|
expect(response).to have_http_status(:ok)
|
||||||
|
|
||||||
|
stale_revision_id = first_revision.id
|
||||||
before_state = stored_state
|
before_state = stored_state
|
||||||
update_description(title: 'conflicting_rename', base: first_revision.id)
|
|
||||||
|
update_description(
|
||||||
|
body: 'conflicting body',
|
||||||
|
title: 'conflicting_rename',
|
||||||
|
base: stale_revision_id)
|
||||||
|
|
||||||
expect(response).to have_http_status(:conflict)
|
expect(response).to have_http_status(:conflict)
|
||||||
expect(stored_state).to eq(before_state)
|
expect(stored_state).to eq(before_state)
|
||||||
|
expect(tag_name.reload.name).not_to eq('conflicting_rename')
|
||||||
end
|
end
|
||||||
|
|
||||||
[WikiPage, WikiRevision, WikiVersion, TagDescription, TagDescriptionVersion].each do |model|
|
[WikiPage, WikiRevision, WikiVersion, TagDescription, TagDescriptionVersion].each do |model|
|
||||||
it "rolls back both systems when #{ model.name } persistence fails" do
|
it "rolls back both systems when #{ model.name } persistence fails" do
|
||||||
before_state = stored_state
|
before_state = stored_state
|
||||||
aggregate_failures do
|
aggregate_failures do
|
||||||
fail_save(model) { update_description(title: 'rollback_rename') }
|
fail_save(model) do
|
||||||
|
update_description(body: 'rollback body', title: 'rollback_rename')
|
||||||
|
end
|
||||||
expect(stored_state).to eq(before_state)
|
expect(stored_state).to eq(before_state)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
[['identical body', 'before'],
|
||||||
|
['normalised-equivalent body', "before\n\n"]].each do |label, body|
|
||||||
|
it "does not write histories for #{ label }" do
|
||||||
|
before_state = stored_state
|
||||||
|
page_state = page.reload.attributes
|
||||||
|
description_state = description.reload.attributes
|
||||||
|
current_revision_id = page.current_revision.id
|
||||||
|
wiki_lines = WikiLine.order(:id).map(&:attributes)
|
||||||
|
revision_lines = WikiRevisionLine.order(:id).map(&:attributes)
|
||||||
|
page_version_no = page.version_no
|
||||||
|
description_version_no = description.version_no
|
||||||
|
|
||||||
|
update_description(body:)
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:ok)
|
||||||
|
expect(WikiRevision.count).to eq(before_state[1].length)
|
||||||
|
expect(WikiVersion.count).to eq(before_state[2].length)
|
||||||
|
expect(TagDescriptionVersion.count).to eq(before_state[4].length)
|
||||||
|
expect(page.reload.version_no).to eq(page_version_no)
|
||||||
|
expect(description.reload.version_no).to eq(description_version_no)
|
||||||
|
expect(page.current_revision.id).to eq(current_revision_id)
|
||||||
|
expect(page.reload.attributes).to eq(page_state)
|
||||||
|
expect(description.reload.attributes).to eq(description_state)
|
||||||
|
expect(WikiLine.order(:id).map(&:attributes)).to eq(wiki_lines)
|
||||||
|
expect(WikiRevisionLine.order(:id).map(&:attributes)).to eq(revision_lines)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -264,38 +264,49 @@ RSpec.describe 'Tag description native API', type: :request do
|
|||||||
tag
|
tag
|
||||||
Wiki::Commit.create_content!(tag_name:, body: 'before', created_by_user: author)
|
Wiki::Commit.create_content!(tag_name:, body: 'before', created_by_user: author)
|
||||||
end
|
end
|
||||||
let!(:second_revision) do
|
|
||||||
Wiki::Commit.content!(page:, body: 'before', created_user: author)
|
|
||||||
end
|
|
||||||
let!(:description) do
|
let!(:description) do
|
||||||
TagDescription.find_by!(tag_id: tag.id, language_code: 'ja')
|
TagDescription.find_by!(tag_id: tag.id, language_code: 'ja')
|
||||||
end
|
end
|
||||||
|
|
||||||
['after', 'before'].each do |body|
|
it 'writes matching histories when the body changes' do
|
||||||
it "appends matching revisions for body '#{ body }'" do
|
expect(page.reload.version_no).to eq(1)
|
||||||
history = TagDescriptionVersion.where(tag_id: tag.id).order(:version_no).map(&:attributes)
|
expect(description.version_no).to eq(1)
|
||||||
expect(page.reload.version_no).to eq(1)
|
expect { native_write(:put, body: 'after') }
|
||||||
expect(description.version_no).to eq(2)
|
.to change(WikiRevision, :count).by(1)
|
||||||
expect { native_write(:put, body:) }
|
.and change(WikiVersion, :count).by(1)
|
||||||
.to change(WikiRevision, :count).by(1)
|
.and change(TagDescriptionVersion, :count).by(1)
|
||||||
.and change(TagDescriptionVersion, :count).by(1)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(response).to have_http_status(:ok)
|
expect(description.reload).to have_attributes(
|
||||||
expect(description.reload).to have_attributes(
|
body: 'after', version_no: 2,
|
||||||
body:, version_no: 3, created_by_user_id: author.id, updated_by_user_id: editor.id)
|
created_by_user_id: author.id, updated_by_user_id: editor.id)
|
||||||
expect(page.reload.body).to eq(body)
|
expect(page.reload).to have_attributes(body: 'after', version_no: 2)
|
||||||
revision = page.current_revision
|
|
||||||
version = TagDescriptionVersion.find(revision.id)
|
revision = page.current_revision
|
||||||
expect(version).to have_attributes(
|
version = TagDescriptionVersion.find(revision.id)
|
||||||
tag_id: tag.id, language_code: 'ja', version_no: 3, event_type: 'update',
|
expect(version).to have_attributes(
|
||||||
body:, created_by_user_id: editor.id)
|
tag_id: tag.id, language_code: 'ja', version_no: 2, event_type: 'update',
|
||||||
expect(revision.body).to eq(body)
|
body: 'after', created_by_user_id: editor.id)
|
||||||
expect(page.wiki_versions.order(:version_no).last.body).to eq(body)
|
expect(revision.body).to eq(version.body)
|
||||||
expect(TagDescriptionVersion.where(id: history.pluck('id')).order(:version_no)
|
expect(page.wiki_versions.order(:version_no).last.body).to eq(version.body)
|
||||||
.map(&:attributes)).to eq(history)
|
get "/wiki/#{ description.id }"
|
||||||
|
expect(response).to have_http_status(:ok)
|
||||||
|
expect(json).to include('body' => 'after', 'revision_id' => version.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
['before', "before\n\n"].each do |body|
|
||||||
|
it 'does not write histories when the normalised body is unchanged' do
|
||||||
|
before_state = stored_state
|
||||||
|
page_state = page.reload.attributes
|
||||||
|
description_state = description.reload.attributes
|
||||||
|
current_revision_id = page.current_revision.id
|
||||||
|
|
||||||
|
native_write(:put, body:)
|
||||||
|
|
||||||
get "/wiki/#{ description.id }"
|
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
expect(json).to include('body' => body, 'revision_id' => version.id)
|
expect(stored_state).to eq(before_state)
|
||||||
|
expect(page.reload.attributes).to eq(page_state)
|
||||||
|
expect(description.reload.attributes).to eq(description_state)
|
||||||
|
expect(page.current_revision.id).to eq(current_revision_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
新しいイシューから参照
ユーザーをブロックする