|
|
|
@@ -1,7 +1,6 @@ |
|
|
|
require 'cgi' |
|
|
|
require 'rails_helper' |
|
|
|
|
|
|
|
|
|
|
|
RSpec.describe 'Tags API', type: :request do |
|
|
|
let!(:tn) { TagName.create!(name: 'spec_tag') } |
|
|
|
let!(:tag) { Tag.create!(tag_name: tn, category: :general) } |
|
|
|
@@ -197,6 +196,30 @@ RSpec.describe 'Tags API', type: :request do |
|
|
|
expect(response_tags.size).to eq(1) |
|
|
|
expect(response_names).to eq(['norm_a']) |
|
|
|
end |
|
|
|
|
|
|
|
it 'returns aliases and parent tags' do |
|
|
|
parent_tag = Tag.create!( |
|
|
|
tag_name: TagName.create!(name: 'index_parent_tag'), |
|
|
|
category: :meme |
|
|
|
) |
|
|
|
TagImplication.create!(tag:, parent_tag:) |
|
|
|
|
|
|
|
get '/tags', params: { name: 'spec_tag' } |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
|
|
|
|
row = response_tags.find { |t| t['name'] == 'spec_tag' } |
|
|
|
|
|
|
|
expect(row['aliases']).to include('unko') |
|
|
|
expect(row['parents'].map { |t| t['name'] }).to include('index_parent_tag') |
|
|
|
|
|
|
|
parent = row['parents'].find { |t| t['name'] == 'index_parent_tag' } |
|
|
|
expect(parent).to include( |
|
|
|
'id' => parent_tag.id, |
|
|
|
'name' => 'index_parent_tag', |
|
|
|
'category' => 'meme' |
|
|
|
) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
describe 'GET /tags/:id' do |
|
|
|
@@ -220,6 +243,28 @@ RSpec.describe 'Tags API', type: :request do |
|
|
|
expect(json).to have_key('created_at') |
|
|
|
expect(json).to have_key('updated_at') |
|
|
|
end |
|
|
|
|
|
|
|
it 'returns aliases and parent tags' do |
|
|
|
parent_tag = Tag.create!( |
|
|
|
tag_name: TagName.create!(name: 'show_parent_tag'), |
|
|
|
category: :character |
|
|
|
) |
|
|
|
TagImplication.create!(tag:, parent_tag:) |
|
|
|
|
|
|
|
request |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
|
|
|
|
expect(json['aliases']).to include('unko') |
|
|
|
expect(json['parents'].map { |t| t['name'] }).to include('show_parent_tag') |
|
|
|
|
|
|
|
parent = json['parents'].find { |t| t['name'] == 'show_parent_tag' } |
|
|
|
expect(parent).to include( |
|
|
|
'id' => parent_tag.id, |
|
|
|
'name' => 'show_parent_tag', |
|
|
|
'category' => 'character' |
|
|
|
) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
context 'when tag does not exist' do |
|
|
|
@@ -359,9 +404,9 @@ RSpec.describe 'Tags API', type: :request do |
|
|
|
expect(tag.category).to eq('meta') |
|
|
|
end |
|
|
|
|
|
|
|
it '存在しない id だと RecordNotFound になる(通常は 404)' do |
|
|
|
it '存在しない id なら 404 を返す' do |
|
|
|
patch '/tags/999999999', params: { name: 'x' } |
|
|
|
expect(response.status).to be_in([404, 500]) |
|
|
|
expect(response).to have_http_status(:not_found) |
|
|
|
end |
|
|
|
|
|
|
|
it 'nico category への変更は 422 を返す' do |
|
|
|
@@ -401,21 +446,18 @@ RSpec.describe 'Tags API', type: :request do |
|
|
|
expect(tag.reload.category).to eq('general') |
|
|
|
end |
|
|
|
|
|
|
|
it 'creates nico tag versions when updating nico tag name' do |
|
|
|
it 'returns 422 when updating nico tag name' do |
|
|
|
nico_tag_name = TagName.create!(name: 'nico:tags_spec_source') |
|
|
|
nico_tag = Tag.create!(tag_name: nico_tag_name, category: :nico) |
|
|
|
|
|
|
|
expect { |
|
|
|
patch "/tags/#{nico_tag.id}", params: { name: 'nico:tags_spec_renamed' } |
|
|
|
}.to change(NicoTagVersion, :count).by(2) |
|
|
|
patch "/tags/#{ nico_tag.id }", params: { name: 'nico:tags_spec_renamed' } |
|
|
|
}.not_to change(NicoTagVersion, :count) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
expect(response).to have_http_status(:unprocessable_entity) |
|
|
|
|
|
|
|
versions = nico_tag.reload.nico_tag_versions.order(:version_no) |
|
|
|
expect(versions.map(&:event_type)).to eq(['create', 'update']) |
|
|
|
expect(versions.first.name).to eq('nico:tags_spec_source') |
|
|
|
expect(versions.second.name).to eq('nico:tags_spec_renamed') |
|
|
|
expect(versions.second.created_by_user_id).to eq(member_user.id) |
|
|
|
expect(nico_tag.reload.name).to eq('nico:tags_spec_source') |
|
|
|
expect(nico_tag.category).to eq('nico') |
|
|
|
end |
|
|
|
|
|
|
|
it 'returns 422 when changing nico tag category to normal category' do |
|
|
|
@@ -571,4 +613,269 @@ RSpec.describe 'Tags API', type: :request do |
|
|
|
expect(response).to have_http_status(:not_found) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
describe 'PUT /tags/:id' do |
|
|
|
context '未ログイン' do |
|
|
|
before { stub_current_user(nil) } |
|
|
|
|
|
|
|
it '401 を返す' do |
|
|
|
put "/tags/#{ tag.id }", params: { |
|
|
|
name: 'new', |
|
|
|
category: 'general', |
|
|
|
aliases: '', |
|
|
|
parent_tags: '', |
|
|
|
} |
|
|
|
|
|
|
|
expect(response).to have_http_status(:unauthorized) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
context 'ログインしてゐるが member でない' do |
|
|
|
before { stub_current_user(non_member_user) } |
|
|
|
|
|
|
|
it '403 を返す' do |
|
|
|
put "/tags/#{ tag.id }", params: { |
|
|
|
name: 'new', |
|
|
|
category: 'general', |
|
|
|
aliases: '', |
|
|
|
parent_tags: '', |
|
|
|
} |
|
|
|
|
|
|
|
expect(response).to have_http_status(:forbidden) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
context 'member' do |
|
|
|
before { stub_current_user(member_user) } |
|
|
|
|
|
|
|
it '存在しない id なら 404 を返す' do |
|
|
|
put '/tags/999999999', params: { |
|
|
|
name: 'new', |
|
|
|
category: 'general', |
|
|
|
aliases: '', |
|
|
|
parent_tags: '', |
|
|
|
} |
|
|
|
|
|
|
|
expect(response).to have_http_status(:not_found) |
|
|
|
end |
|
|
|
|
|
|
|
it 'name が空なら 422 を返す' do |
|
|
|
put "/tags/#{ tag.id }", params: { |
|
|
|
name: '', |
|
|
|
category: 'general', |
|
|
|
aliases: '', |
|
|
|
parent_tags: '', |
|
|
|
} |
|
|
|
|
|
|
|
expect(response).to have_http_status(:unprocessable_entity) |
|
|
|
expect(tag.reload.name).to eq('spec_tag') |
|
|
|
end |
|
|
|
|
|
|
|
it 'category が空なら 422 を返す' do |
|
|
|
put "/tags/#{ tag.id }", params: { |
|
|
|
name: 'new', |
|
|
|
category: '', |
|
|
|
aliases: '', |
|
|
|
parent_tags: '', |
|
|
|
} |
|
|
|
|
|
|
|
expect(response).to have_http_status(:unprocessable_entity) |
|
|
|
expect(tag.reload.name).to eq('spec_tag') |
|
|
|
expect(tag.category).to eq('general') |
|
|
|
end |
|
|
|
|
|
|
|
it 'name, category, aliases, parent tags をまとめて更新できる' do |
|
|
|
old_parent = Tag.create!( |
|
|
|
tag_name: TagName.create!(name: 'put_old_parent'), |
|
|
|
category: :general |
|
|
|
) |
|
|
|
kept_parent = Tag.create!( |
|
|
|
tag_name: TagName.create!(name: 'put_kept_parent'), |
|
|
|
category: :general |
|
|
|
) |
|
|
|
TagImplication.create!(tag:, parent_tag: old_parent) |
|
|
|
TagImplication.create!(tag:, parent_tag: kept_parent) |
|
|
|
|
|
|
|
put "/tags/#{ tag.id }", params: { |
|
|
|
name: 'put_renamed_tag', |
|
|
|
category: 'meme', |
|
|
|
aliases: 'put_alias_a put_alias_b put_alias_a', |
|
|
|
parent_tags: 'put_kept_parent put_new_parent', |
|
|
|
} |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
|
|
|
|
tag.reload |
|
|
|
|
|
|
|
expect(tag.name).to eq('put_renamed_tag') |
|
|
|
expect(tag.category).to eq('meme') |
|
|
|
|
|
|
|
expect(TagName.find_by(name: 'put_alias_a').canonical).to eq(tag.tag_name) |
|
|
|
expect(TagName.find_by(name: 'put_alias_b').canonical).to eq(tag.tag_name) |
|
|
|
|
|
|
|
old_name_alias = TagName.find_by(name: 'spec_tag') |
|
|
|
expect(old_name_alias).to be_present |
|
|
|
expect(old_name_alias.canonical).to eq(tag.tag_name) |
|
|
|
|
|
|
|
expect(alias_tn.reload.canonical).to be_nil |
|
|
|
|
|
|
|
expect(tag.parents.map(&:name)).to contain_exactly( |
|
|
|
'put_kept_parent', |
|
|
|
'put_new_parent' |
|
|
|
) |
|
|
|
|
|
|
|
expect(TagImplication.where(tag:, parent_tag: old_parent)).not_to exist |
|
|
|
|
|
|
|
expect(json['name']).to eq('put_renamed_tag') |
|
|
|
expect(json['category']).to eq('meme') |
|
|
|
expect(json['aliases']).to contain_exactly( |
|
|
|
'put_alias_a', |
|
|
|
'put_alias_b', |
|
|
|
'spec_tag' |
|
|
|
) |
|
|
|
expect(json['parents'].map { |t| t['name'] }).to contain_exactly( |
|
|
|
'put_kept_parent', |
|
|
|
'put_new_parent' |
|
|
|
) |
|
|
|
end |
|
|
|
|
|
|
|
it 'aliases に現在名を指定しても alias には残さない' do |
|
|
|
put "/tags/#{ tag.id }", params: { |
|
|
|
name: 'spec_tag', |
|
|
|
category: 'general', |
|
|
|
aliases: 'spec_tag put_alias_self_test', |
|
|
|
parent_tags: '', |
|
|
|
} |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
|
|
|
|
tag.reload |
|
|
|
|
|
|
|
expect(TagName.find_by(name: 'put_alias_self_test').canonical).to eq(tag.tag_name) |
|
|
|
expect(json['aliases']).to include('put_alias_self_test') |
|
|
|
expect(json['aliases']).not_to include('spec_tag') |
|
|
|
end |
|
|
|
|
|
|
|
it 'parent_tags に自分自身を指定しても自己参照は作らない' do |
|
|
|
put "/tags/#{ tag.id }", params: { |
|
|
|
name: 'spec_tag', |
|
|
|
category: 'general', |
|
|
|
aliases: 'unko', |
|
|
|
parent_tags: 'spec_tag', |
|
|
|
} |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
|
|
|
|
expect(TagImplication.where(tag:, parent_tag: tag)).not_to exist |
|
|
|
expect(tag.reload.parents).to eq([]) |
|
|
|
end |
|
|
|
|
|
|
|
it 'initial and update tag versions を作成する' do |
|
|
|
expect { |
|
|
|
put "/tags/#{ tag.id }", params: { |
|
|
|
name: 'put_versioned_tag', |
|
|
|
category: 'meta', |
|
|
|
aliases: '', |
|
|
|
parent_tags: '', |
|
|
|
} |
|
|
|
}.to change(TagVersion, :count).by(2) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
|
|
|
|
versions = tag.reload.tag_versions.order(:version_no) |
|
|
|
|
|
|
|
expect(versions.map(&:event_type)).to eq(['create', 'update']) |
|
|
|
|
|
|
|
expect(versions.first.name).to eq('spec_tag') |
|
|
|
expect(versions.first.category).to eq('general') |
|
|
|
expect(versions.first.aliases.split).to include('unko') |
|
|
|
|
|
|
|
expect(versions.second.name).to eq('put_versioned_tag') |
|
|
|
expect(versions.second.category).to eq('meta') |
|
|
|
expect(versions.second.aliases.split).to include('spec_tag') |
|
|
|
expect(versions.second.created_by_user_id).to eq(member_user.id) |
|
|
|
end |
|
|
|
|
|
|
|
it 'parent tag の snapshot も作成する' do |
|
|
|
old_parent = Tag.create!( |
|
|
|
tag_name: TagName.create!(name: 'put_snapshot_old_parent'), |
|
|
|
category: :general |
|
|
|
) |
|
|
|
new_parent = Tag.create!( |
|
|
|
tag_name: TagName.create!(name: 'put_snapshot_new_parent'), |
|
|
|
category: :general |
|
|
|
) |
|
|
|
TagImplication.create!(tag:, parent_tag: old_parent) |
|
|
|
|
|
|
|
put "/tags/#{ tag.id }", params: { |
|
|
|
name: 'spec_tag', |
|
|
|
category: 'general', |
|
|
|
aliases: 'unko', |
|
|
|
parent_tags: new_parent.name, |
|
|
|
} |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
|
|
|
|
expect(old_parent.reload.tag_versions.map(&:event_type)).to include('create') |
|
|
|
expect(new_parent.reload.tag_versions.map(&:event_type)).to include('create') |
|
|
|
end |
|
|
|
|
|
|
|
it 'normal tag を nico category には変更できない' do |
|
|
|
expect { |
|
|
|
put "/tags/#{ tag.id }", params: { |
|
|
|
name: 'spec_tag', |
|
|
|
category: 'nico', |
|
|
|
aliases: '', |
|
|
|
parent_tags: '', |
|
|
|
} |
|
|
|
}.not_to change(TagVersion, :count) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:unprocessable_entity) |
|
|
|
|
|
|
|
expect(tag.reload.name).to eq('spec_tag') |
|
|
|
expect(tag.category).to eq('general') |
|
|
|
end |
|
|
|
|
|
|
|
it 'nico tag は更新できない' do |
|
|
|
nico_tag = Tag.create!( |
|
|
|
tag_name: TagName.create!(name: 'nico:put_update_all_ng'), |
|
|
|
category: :nico |
|
|
|
) |
|
|
|
|
|
|
|
expect { |
|
|
|
put "/tags/#{ nico_tag.id }", params: { |
|
|
|
name: 'nico:put_update_all_renamed', |
|
|
|
category: 'nico', |
|
|
|
aliases: '', |
|
|
|
parent_tags: '', |
|
|
|
} |
|
|
|
}.not_to change(NicoTagVersion, :count) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:unprocessable_entity) |
|
|
|
|
|
|
|
expect(nico_tag.reload.name).to eq('nico:put_update_all_ng') |
|
|
|
expect(nico_tag.category).to eq('nico') |
|
|
|
end |
|
|
|
|
|
|
|
it 'system tag の name は変更できない' do |
|
|
|
system_tag = Tag.tagme |
|
|
|
old_name = system_tag.name |
|
|
|
old_category = system_tag.category |
|
|
|
|
|
|
|
expect { |
|
|
|
put "/tags/#{ system_tag.id }", params: { |
|
|
|
name: 'put_system_tag_renamed', |
|
|
|
category: old_category, |
|
|
|
aliases: '', |
|
|
|
parent_tags: '', |
|
|
|
} |
|
|
|
}.not_to change(TagVersion, :count) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:unprocessable_entity) |
|
|
|
|
|
|
|
expect(system_tag.reload.name).to eq(old_name) |
|
|
|
expect(system_tag.category).to eq(old_category) |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |