このコミットが含まれているのは:
2026-10-04 23:06:14 +09:00
コミット d63e0b95fa
13個のファイルの変更、165行の追加、115行の削除
+68 -2
ファイルの表示
@@ -52,6 +52,58 @@ RSpec.describe 'Tag description Wiki dual writes', type: :request do
expect(page.wiki_versions.last.body).to eq(version.body)
end
['missing_description', 'orphan_description'].each do |title|
it "rejects the bare title #{ title } without writing any resource" do
create(:tag_name, name: title) if title == 'orphan_description'
before_state = stored_state
post '/wiki', params: { title:, body: 'initial' }, headers: headers
expect(response).to have_http_status(:unprocessable_entity)
expect(json).to include('type' => 'validation_error')
expect(stored_state).to eq(before_state)
end
end
it 'creates a namespaced legacy Wiki resource without a Tag' do
expect do
post '/wiki', params: { title: 'Help:description_write', body: 'legacy' },
headers: headers
end.to change(WikiPage, :count).by(1)
.and change(WikiRevision, :count).by(1)
.and change(WikiVersion, :count).by(1)
.and change(TagDescription, :count).by(0)
.and change(TagDescriptionVersion, :count).by(0)
expect(response).to have_http_status(:created)
page = WikiPage.find(json.fetch('id'))
expect(page.tag_name.tag).to be_nil
expect(page.body).to eq('legacy')
expect(page.current_revision.body).to eq('legacy')
end
it 'creates only legacy Wiki for a namespaced title with an existing Tag' do
namespaced_name = create(:tag_name, name: 'help:foo')
namespaced_tag = create(:tag, primary_tag_name: namespaced_name)
expect do
post '/wiki', params: { title: namespaced_name.name, body: 'legacy' },
headers: headers
end.to change(WikiPage, :count).by(1)
.and change(WikiRevision, :count).by(1)
.and change(WikiVersion, :count).by(1)
.and change(TagName, :count).by(0)
.and change(TagDescription, :count).by(0)
.and change(TagDescriptionVersion, :count).by(0)
expect(response).to have_http_status(:created)
page = WikiPage.find(json.fetch('id'))
expect(page).to have_attributes(tag_name_id: namespaced_name.id, body: 'legacy')
expect(page.tag_name.tag).to eq(namespaced_tag)
expect(page.current_revision.body).to eq('legacy')
expect(page.wiki_versions.last.body).to eq('legacy')
end
[WikiPage, WikiRevision, WikiVersion, TagDescription, TagDescriptionVersion].each do |model|
it "rolls back both systems when #{ model.name } persistence fails" do
tag_name
@@ -101,6 +153,20 @@ RSpec.describe 'Tag description Wiki dual writes', type: :request do
expect(page.wiki_versions.order(:version_no).last.body).to eq(version.body)
end
it 'uses description identity even when its Wiki TagName no longer owns the Tag' do
tag_name.update_columns(tag_id: nil)
expect { update_description }
.to change(WikiRevision, :count).by(1)
.and change(WikiVersion, :count).by(1)
.and change(TagDescriptionVersion, :count).by(1)
expect(response).to have_http_status(:ok)
expect(description.reload).to have_attributes(body: 'after', version_no: 2)
expect(TagDescriptionVersion.find(page.reload.current_revision.id))
.to have_attributes(tag_id: tag.id, body: 'after', version_no: 2)
end
it 'does not add body history for a title-only update' do
revision_count = WikiRevision.count
wiki_version_count = WikiVersion.count
@@ -111,10 +177,10 @@ RSpec.describe 'Tag description Wiki dual writes', type: :request do
page_state = page.attributes
description_state = description.attributes
update_description(body: 'before', title: 'description_renamed')
update_description(body: 'before', title: 'Help:description_renamed')
expect(response).to have_http_status(:ok)
expect(tag_name.reload.name).to eq('description_renamed')
expect(tag_name.reload.name).to eq('Help:description_renamed')
expect(WikiRevision.count).to eq(revision_count)
expect(WikiVersion.count).to eq(wiki_version_count)
expect(TagDescriptionVersion.count).to eq(description_version_count)
+8 -18
ファイルの表示
@@ -25,9 +25,10 @@ RSpec.describe 'Tag and wiki history integrity', type: :request do
end
describe 'PATCH /tags/:id' do
it 'records wiki_version when tag name changes and tag has wiki' do
it 'renames the current Wiki resource without adding body history' do
tag = create_tag!(name: 'patch_tag_wiki_before')
wiki_page = create_wiki_for_tag!(tag:, body: 'wiki body before')
wiki_history = wiki_page.wiki_versions.map(&:attributes)
expect {
patch "/tags/#{ tag.id }", params: {
@@ -35,23 +36,17 @@ RSpec.describe 'Tag and wiki history integrity', type: :request do
}
}
.to change(TagVersion, :count).by(2)
.and change(WikiVersion, :count).by(1)
.and change(WikiVersion, :count).by(0)
expect(response).to have_http_status(:ok)
tag.reload
wiki_page.reload
version = wiki_page.wiki_versions.order(:version_no).last
expect(primary_tag_name_for(tag, 'ja').name).to eq('patch_tag_wiki_after')
expect(wiki_page.title).to eq('patch_tag_wiki_after')
expect(version).to have_attributes(
event_type: 'update',
title: 'patch_tag_wiki_after',
body: 'wiki body before',
created_by_user_id: member_user.id
)
expect(wiki_page.wiki_versions.reload.map(&:attributes)).to eq(wiki_history)
end
it 'does not record wiki_version when only category changes' do
@@ -79,9 +74,10 @@ RSpec.describe 'Tag and wiki history integrity', type: :request do
end
describe 'PUT /tags/:id' do
it 'records wiki_version when tag name changes and tag has wiki' do
it 'renames the current Wiki resource without adding body history' do
tag = create_tag!(name: 'put_tag_wiki_before')
wiki_page = create_wiki_for_tag!(tag:, body: 'wiki body before')
wiki_history = wiki_page.wiki_versions.map(&:attributes)
expect {
put "/tags/#{ tag.id }", params: {
@@ -93,23 +89,17 @@ RSpec.describe 'Tag and wiki history integrity', type: :request do
}
}
.to change(TagVersion, :count).by(2)
.and change(WikiVersion, :count).by(1)
.and change(WikiVersion, :count).by(0)
expect(response).to have_http_status(:ok)
tag.reload
wiki_page.reload
version = wiki_page.wiki_versions.order(:version_no).last
expect(primary_tag_name_for(tag, 'ja').name).to eq('put_tag_wiki_after')
expect(wiki_page.title).to eq('put_tag_wiki_after')
expect(version).to have_attributes(
event_type: 'update',
title: 'put_tag_wiki_after',
body: 'wiki body before',
created_by_user_id: member_user.id
)
expect(wiki_page.wiki_versions.reload.map(&:attributes)).to eq(wiki_history)
end
it 'does not record wiki_version when only category changes' do
+22 -35
ファイルの表示
@@ -727,7 +727,7 @@ RSpec.describe 'Tags API', type: :request do
expect(tag.reload.category).to eq('general')
end
it 'PATCH で tag の name を変更すると対応する wiki version を作成する' do
it 'PATCH の名称変更で Wiki の本文履歴を追加しない' do
wiki_page =
Wiki::Commit.create_content!(
tag_name: primary_tag_name_for(tag, 'ja'),
@@ -735,24 +735,20 @@ RSpec.describe 'Tags API', type: :request do
created_by_user: member_user,
message: 'init')
wiki_history = wiki_page.wiki_versions.map(&:attributes)
expect {
patch "/tags/#{ tag.id }", params: {
name: 'patch_wiki_renamed_tag',
}
}
.to change(TagVersion, :count).by(2)
.and change(WikiVersion, :count).by(1)
.and change(WikiVersion, :count).by(0)
expect(response).to have_http_status(:ok)
version = wiki_page.reload.wiki_versions.order(:version_no).last
expect(version).to have_attributes(
event_type: 'update',
title: 'patch_wiki_renamed_tag',
body: 'wiki body before',
created_by_user_id: member_user.id
)
expect(wiki_page.reload.title).to eq('patch_wiki_renamed_tag')
expect(wiki_page.wiki_versions.reload.map(&:attributes)).to eq(wiki_history)
end
it 'tag の category だけを変更しても wiki version は作成しない' do
@@ -1380,7 +1376,7 @@ RSpec.describe 'Tags API', type: :request do
expect(system_tag.category).to eq(old_category)
end
it 'wiki を持つ tag を更新すると wiki version も作成する' do
it 'Wiki を持つ Tag の名称変更で本文履歴を追加しない' do
wiki_page =
Wiki::Commit.create_content!(
tag_name: primary_tag_name_for(tag, 'ja'),
@@ -1395,6 +1391,8 @@ RSpec.describe 'Tags API', type: :request do
message: 'init'
)
wiki_history = wiki_page.wiki_versions.map(&:attributes)
expect {
put "/tags/#{ tag.id }", params: {
name: 'put_wiki_version_tag',
@@ -1405,18 +1403,12 @@ RSpec.describe 'Tags API', type: :request do
}
}
.to change(TagVersion, :count).by(2)
.and change(WikiVersion, :count).by(1)
.and change(WikiVersion, :count).by(0)
expect(response).to have_http_status(:ok)
version = wiki_page.reload.wiki_versions.order(:version_no).last
expect(version).to have_attributes(
event_type: 'update',
title: 'put_wiki_version_tag',
body: 'wiki body before',
created_by_user_id: member_user.id
)
expect(wiki_page.reload.title).to eq('put_wiki_version_tag')
expect(wiki_page.wiki_versions.reload.map(&:attributes)).to eq(wiki_history)
end
it 'wiki を持つ tag を旧 alias へ戻しても wiki を新しい正本名へ移す' do
@@ -1426,6 +1418,7 @@ RSpec.describe 'Tags API', type: :request do
body: 'wiki body before',
created_by_user: member_user,
message: 'init')
wiki_history = wiki_page.wiki_versions.map(&:attributes)
expect {
put "/tags/#{ tag.id }", params: {
@@ -1445,7 +1438,7 @@ RSpec.describe 'Tags API', type: :request do
}
}
.to change(TagVersion, :count).by(3)
.and change(WikiVersion, :count).by(2)
.and change(WikiVersion, :count).by(0)
expect(response).to have_http_status(:ok)
@@ -1457,10 +1450,8 @@ RSpec.describe 'Tags API', type: :request do
expect(TagName.find_by!(language_code: 'ja', name: 'put_wiki_roundtrip_b'))
.to have_attributes(tag_id: tag.id, primary_flg: false)
versions = wiki_page.wiki_versions.order(:version_no).last(2)
expect(versions.map(&:event_type)).to eq(['update', 'update'])
expect(versions.map(&:title)).to eq(['put_wiki_roundtrip_b', 'spec_tag'])
expect(wiki_page.title).to eq('spec_tag')
expect(wiki_page.wiki_versions.reload.map(&:attributes)).to eq(wiki_history)
end
it '別名を他 tag から奪った場合、奪はれた側の tag version も作成する' do
@@ -1570,7 +1561,7 @@ RSpec.describe 'Tags API', type: :request do
expect(TagImplication.where(tag:, parent_tag: child)).not_to exist
end
it 'tag の name を変更すると対応する wiki version を作成する' do
it 'Tag の名称変更で Wiki の本文履歴を追加しない' do
wiki_page =
Wiki::Commit.create_content!(
tag_name: primary_tag_name_for(tag, 'ja'),
@@ -1578,6 +1569,8 @@ RSpec.describe 'Tags API', type: :request do
created_by_user: member_user,
message: 'init')
wiki_history = wiki_page.wiki_versions.map(&:attributes)
expect {
put "/tags/#{ tag.id }", params: {
name: 'put_wiki_renamed_tag',
@@ -1588,18 +1581,12 @@ RSpec.describe 'Tags API', type: :request do
}
}
.to change(TagVersion, :count).by(2)
.and change(WikiVersion, :count).by(1)
.and change(WikiVersion, :count).by(0)
expect(response).to have_http_status(:ok)
version = wiki_page.reload.wiki_versions.order(:version_no).last
expect(version).to have_attributes(
event_type: 'update',
title: 'put_wiki_renamed_tag',
body: 'wiki body before',
created_by_user_id: member_user.id
)
expect(wiki_page.reload.title).to eq('put_wiki_renamed_tag')
expect(wiki_page.wiki_versions.reload.map(&:attributes)).to eq(wiki_history)
end
end
end
+10 -8
ファイルの表示
@@ -21,7 +21,7 @@ RSpec.describe 'Wiki history integrity', type: :request do
expect {
post '/wiki',
params: {
title: 'wiki_history_create_atomic',
title: 'Help:wiki_history_create_atomic',
body: "a\nb\nc",
message: 'initial commit',
},
@@ -37,7 +37,7 @@ RSpec.describe 'Wiki history integrity', type: :request do
revision = page.current_revision
version = page.wiki_versions.order(:version_no).last
expect(page.title).to eq('wiki_history_create_atomic')
expect(page.title).to eq('Help:wiki_history_create_atomic')
expect(page.body).to eq("a\nb\nc")
expect(revision).to be_content
@@ -47,7 +47,7 @@ RSpec.describe 'Wiki history integrity', type: :request do
expect(version).to have_attributes(
version_no: 1,
event_type: 'create',
title: 'wiki_history_create_atomic',
title: 'Help:wiki_history_create_atomic',
body: "a\nb\nc",
reason: 'initial commit',
created_by_user_id: user.id
@@ -58,7 +58,7 @@ RSpec.describe 'Wiki history integrity', type: :request do
expect {
post '/wiki',
params: {
title: 'wiki_history_blank_body',
title: 'Help:wiki_history_blank_body',
body: "\r\n\r\n",
message: 'blank',
},
@@ -67,16 +67,17 @@ RSpec.describe 'Wiki history integrity', type: :request do
.not_to change(WikiPage, :count)
expect(response).to have_http_status(:unprocessable_entity)
expect(WikiPage.joins(:tag_name).where(tag_names: { name: 'wiki_history_blank_body' })).not_to exist
expect(WikiPage.joins(:tag_name)
.where(tag_names: { name: 'Help:wiki_history_blank_body' })).not_to exist
end
it 'returns 422 and creates no partial page when title already exists' do
create_wiki_page(title: 'wiki_history_duplicate_title', body: 'first')
create_wiki_page(title: 'Help:wiki_history_duplicate_title', body: 'first')
expect {
post '/wiki',
params: {
title: 'wiki_history_duplicate_title',
title: 'Help:wiki_history_duplicate_title',
body: 'second',
message: 'duplicate',
},
@@ -85,7 +86,8 @@ RSpec.describe 'Wiki history integrity', type: :request do
.not_to change(WikiPage, :count)
expect(response).to have_http_status(:unprocessable_entity)
expect(WikiPage.joins(:tag_name).where(tag_names: { name: 'wiki_history_duplicate_title' }).count).to eq(1)
expect(WikiPage.joins(:tag_name)
.where(tag_names: { name: 'Help:wiki_history_duplicate_title' }).count).to eq(1)
end
end
+7 -6
ファイルの表示
@@ -111,7 +111,7 @@ RSpec.describe 'Wiki API', type: :request do
context 'when success' do
it 'creates wiki_page and first content revision' do
expect do
post endpoint, params: { title: 'TestPage', body: "a\nb\nc", message: 'init' },
post endpoint, params: { title: 'Help:TestPage', body: "a\nb\nc", message: 'init' },
headers: auth_headers(member)
end
.to change(WikiPage, :count).by(1)
@@ -121,7 +121,7 @@ RSpec.describe 'Wiki API', type: :request do
expect(response).to have_http_status(:created)
page_id = json.fetch('id')
expect(json.fetch('title')).to eq('TestPage')
expect(json.fetch('title')).to eq('Help:TestPage')
created_page = WikiPage.find(page_id)
version = created_page.wiki_versions.order(:version_no).last
@@ -129,7 +129,7 @@ RSpec.describe 'Wiki API', type: :request do
expect(version).to have_attributes(
version_no: 1,
event_type: 'create',
title: 'TestPage',
title: 'Help:TestPage',
body: "a\nb\nc",
created_by_user_id: member.id
)
@@ -151,7 +151,7 @@ RSpec.describe 'Wiki API', type: :request do
WikiLine.create!(sha256: Digest::SHA256.hexdigest('a'), body: 'a', created_at: Time.current, updated_at: Time.current)
post endpoint,
params: { title: 'Reuse', body: "a\na" },
params: { title: 'Help:Reuse', body: "a\na" },
headers: auth_headers(member)
page = WikiPage.find(JSON.parse(response.body).fetch('id'))
@@ -166,7 +166,7 @@ RSpec.describe 'Wiki API', type: :request do
duplicated = 'duplicated_line_for_wiki_line_upsert_spec'
post endpoint,
params: { title: 'DuplicateNewLine', body: "#{ duplicated }\n#{ duplicated }" },
params: { title: 'Help:DuplicateNewLine', body: "#{ duplicated }\n#{ duplicated }" },
headers: auth_headers(member)
expect(response).to have_http_status(:created)
@@ -182,7 +182,8 @@ RSpec.describe 'Wiki API', type: :request do
it 'normalises CRLF and strips trailing newlines' do
post endpoint,
params: { title: 'NormalisedBody', body: "a\r\nb\r\n\r\n", message: 'normalise' },
params: { title: 'Help:NormalisedBody',
body: "a\r\nb\r\n\r\n", message: 'normalise' },
headers: auth_headers(member)
expect(response).to have_http_status(:created)
+2 -2
ファイルの表示
@@ -44,12 +44,12 @@ RSpec.describe 'Wiki title collision', type: :request do
end
it 'returns 422 when creating wiki with existing title' do
create_wiki_page(title: 'wiki_collision_create', body: 'already exists')
create_wiki_page(title: 'Help:wiki_collision_create', body: 'already exists')
expect {
post '/wiki',
params: {
title: 'wiki_collision_create',
title: 'Help:wiki_collision_create',
body: 'new body',
message: 'duplicate create',
},
+19
ファイルの表示
@@ -14,6 +14,25 @@ RSpec.describe 'Unmigrated Wiki compatibility', type: :request do
before { expect(TagDescription.exists?(id: page.id)).to be(false) }
it 'keeps a Tag-linked legacy page in the legacy domain when its title changes' do
create(:tag, primary_tag_name: tag_name)
expect do
put "/wiki/#{ page.id }",
params: { title: 'legacy_tag_renamed', body: 'changed legacy body',
message: 'legacy rename', base_revision_id: last_revision.id },
headers: { 'X-Transfer-Code' => user.inheritance_code }
end.to change(WikiRevision, :count).by(1)
.and change(WikiVersion, :count).by(1)
.and change(TagDescription, :count).by(0)
.and change(TagDescriptionVersion, :count).by(0)
expect(response).to have_http_status(:ok)
expect(page.reload).to have_attributes(body: 'changed legacy body')
expect(page.title).to eq('legacy_tag_renamed')
expect(page.current_revision).to have_attributes(message: 'legacy rename')
end
it 'shows legacy current and historical content by ID' do
get "/wiki/#{ page.id }"
expect(response).to have_http_status(:ok)