Compare commits

..

3 Commits

Author SHA1 Message Date
みてるぞ fca160ae42 #63 2026-05-04 03:35:45 +09:00
みてるぞ 1653e1ae79 #63 2026-05-04 03:14:50 +09:00
みてるぞ 5c1295f0ff #63 2026-05-04 03:12:50 +09:00
6 changed files with 234 additions and 22 deletions
@@ -434,5 +434,7 @@ class TagsController < ApplicationController
return canonical if canonical
html[/"channelId":"(UC[a-zA-Z0-9_-]{22})"/, 1] || html[/\bUC[a-zA-Z0-9_-]{22}\b/]
rescue
nil
end
end
+220 -10
View File
@@ -8,8 +8,10 @@ RSpec.describe 'Tags deerjikists API', type: :request do
let!(:tag) { create(:tag, category: :deerjikist) }
let(:member) { create(:user, :member) }
let(:guest) { create(:user, role: :guest) }
before do
# show_by_name / deerjikists_by_name 用に名前を固定
tag.tag_name.update!(name: 'deerjika')
end
@@ -21,10 +23,20 @@ RSpec.describe 'Tags deerjikists API', type: :request do
let(:tag_id) { tag.id }
context 'when tag exists and has no deerjikists' do
it 'returns 200 and empty array' do
it 'returns 200 with tag and empty deerjikists array' do
do_request
expect(response).to have_http_status(:ok)
expect(json).to eq([])
expect(json).to be_a(Hash)
expect(json['tag']).to be_a(Hash)
expect(json['tag']['id']).to eq(tag.id)
expect(json['tag']['name']).to eq('deerjika')
expect(json['tag']['category']).to eq('deerjikist')
expect(json['tag']['has_deerjikists']).to eq(false)
expect(json['deerjikists']).to eq([])
end
end
@@ -34,14 +46,24 @@ RSpec.describe 'Tags deerjikists API', type: :request do
Deerjikist.create!(platform: platform2, code: code2, tag: tag)
end
it 'returns 200 and deerjikists array' do
it 'returns 200 with tag and deerjikists array' do
do_request
expect(response).to have_http_status(:ok)
expect(json).to be_a(Array)
expect(json.size).to eq(2)
expect(json).to be_a(Hash)
expect(json.map { |h| [h['platform'], h['code']] }).to contain_exactly(
expect(json['tag']).to be_a(Hash)
expect(json['tag']['id']).to eq(tag.id)
expect(json['tag']['name']).to eq('deerjika')
expect(json['tag']['category']).to eq('deerjikist')
expect(json['tag']['has_deerjikists']).to eq(true)
expect(json['deerjikists']).to be_a(Array)
expect(json['deerjikists'].size).to eq(2)
expect(json['deerjikists'].map { |h| [h['platform'], h['code']] })
.to contain_exactly(
[platform1, code1],
[platform2, code2],
)
@@ -53,6 +75,7 @@ RSpec.describe 'Tags deerjikists API', type: :request do
it 'returns 404' do
do_request
expect(response).to have_http_status(:not_found)
end
end
@@ -70,6 +93,7 @@ RSpec.describe 'Tags deerjikists API', type: :request do
it 'returns 400' do
do_request
expect(response).to have_http_status(:bad_request)
end
end
@@ -79,23 +103,209 @@ RSpec.describe 'Tags deerjikists API', type: :request do
it 'returns 404' do
do_request
expect(response).to have_http_status(:not_found)
end
end
context 'when tag exists and has no deerjikists' do
it 'returns 200 with tag and empty deerjikists array' do
do_request
expect(response).to have_http_status(:ok)
expect(json).to be_a(Hash)
expect(json['tag']).to be_a(Hash)
expect(json['tag']['id']).to eq(tag.id)
expect(json['tag']['name']).to eq('deerjika')
expect(json['tag']['category']).to eq('deerjikist')
expect(json['tag']['has_deerjikists']).to eq(false)
expect(json['deerjikists']).to eq([])
end
end
context 'when tag exists and has deerjikists' do
before do
Deerjikist.create!(platform: platform1, code: code1, tag: tag)
end
it 'returns 200 and deerjikists array' do
it 'returns 200 with tag and deerjikists array' do
do_request
expect(response).to have_http_status(:ok)
expect(json).to be_a(Hash)
expect(json['tag']).to be_a(Hash)
expect(json['tag']['id']).to eq(tag.id)
expect(json['tag']['name']).to eq('deerjika')
expect(json['tag']['category']).to eq('deerjikist')
expect(json['tag']['has_deerjikists']).to eq(true)
expect(json['deerjikists']).to be_a(Array)
expect(json['deerjikists'].size).to eq(1)
expect(json['deerjikists'][0]['platform']).to eq(platform1)
expect(json['deerjikists'][0]['code']).to eq(code1)
end
end
end
describe 'PUT /tags/:id/deerjikists' do
subject(:do_request) do
put "/tags/#{tag_id}/deerjikists", params: payload, as: :json
end
let(:tag_id) { tag.id }
let(:payload) do
[
{ platform: platform1, code: code1 },
{ platform: platform2, code: code2 },
]
end
context 'when not logged in' do
it 'returns 401' do
do_request
expect(response).to have_http_status(:unauthorized)
end
end
context 'when logged in but not member' do
before do
sign_in_as guest
end
it 'returns 403' do
do_request
expect(response).to have_http_status(:forbidden)
end
end
context 'when tag does not exist' do
let(:tag_id) { 9_999_999 }
before do
sign_in_as member
end
it 'returns 404' do
do_request
expect(response).to have_http_status(:not_found)
end
end
context 'when logged in as member' do
before do
sign_in_as member
end
context 'when tag has no deerjikists' do
it 'creates deerjikists and returns deerjikists array' do
expect {
do_request
}.to change { Deerjikist.where(tag: tag).count }.from(0).to(2)
expect(response).to have_http_status(:ok)
expect(json).to be_a(Array)
expect(json.map { |h| [h['platform'], h['code']] })
.to contain_exactly(
[platform1, code1],
[platform2, code2],
)
expect(Deerjikist.where(tag: tag).map { |d| [d.platform, d.code] })
.to contain_exactly(
[platform1, code1],
[platform2, code2],
)
end
end
context 'when tag already has deerjikists' do
before do
Deerjikist.create!(platform: platform1, code: 'old-code-1', tag: tag)
Deerjikist.create!(platform: platform2, code: 'old-code-2', tag: tag)
end
it 'replaces deerjikists and returns deerjikists array' do
do_request
expect(response).to have_http_status(:ok)
expect(Deerjikist.where(tag: tag).map { |d| [d.platform, d.code] })
.to contain_exactly(
[platform1, code1],
[platform2, code2],
)
expect(Deerjikist.exists?(platform: platform1, code: 'old-code-1')).to eq(false)
expect(Deerjikist.exists?(platform: platform2, code: 'old-code-2')).to eq(false)
expect(json).to be_a(Array)
expect(json.map { |h| [h['platform'], h['code']] })
.to contain_exactly(
[platform1, code1],
[platform2, code2],
)
end
end
context 'when payload is empty array' do
let(:payload) { [] }
before do
Deerjikist.create!(platform: platform1, code: code1, tag: tag)
Deerjikist.create!(platform: platform2, code: code2, tag: tag)
end
it 'clears deerjikists and returns empty array' do
expect {
do_request
}.to change { Deerjikist.where(tag: tag).count }.from(2).to(0)
expect(response).to have_http_status(:ok)
expect(json).to eq([])
end
end
context 'when youtube code is handle' do
let(:channel_id) { 'UCabcdefghijklmnopqrstuv' }
let(:payload) do
[
{ platform: 'youtube', code: '@deerjika' },
]
end
before do
allow(Net::HTTP).to receive(:get).and_return(
%(<link rel="canonical" href="https://www.youtube.com/channel/#{channel_id}">),
)
end
it 'normalises youtube handle to channel id' do
expect {
do_request
}.to change { Deerjikist.where(tag: tag).count }.from(0).to(1)
expect(response).to have_http_status(:ok)
expect(Net::HTTP).to have_received(:get)
expect(Deerjikist.exists?(platform: 'youtube', code: channel_id, tag: tag))
.to eq(true)
expect(json).to be_a(Array)
expect(json.size).to eq(1)
expect(json[0]['platform']).to eq(platform1)
expect(json[0]['code']).to eq(code1)
expect(json[0]['platform']).to eq('youtube')
expect(json[0]['code']).to eq(channel_id)
end
end
end
end
+1 -1
View File
@@ -55,7 +55,7 @@ export default (({ tag,
?
</PrefetchLink>)
: (
tag.hasWiki
tag.materialId != null
? (
<PrefetchLink
to={`/materials/${ tag.materialId }`}
+2 -2
View File
@@ -31,11 +31,11 @@ export const FETCH_POSTS_ORDER_FIELDS = [
'updated_at',
] as const
export const PLATFORMS = ['nico', 'youtube'] as const
export const PLATFORM_NAMES: Record<Platform, string> =
{ nico: 'ニコニコ', youtube: 'YouTube' } as const
export const PLATFORMS = ['nico', 'youtube'] as const
export const TAG_COLOUR = {
deerjikist: 'rose',
meme: 'purple',
@@ -65,7 +65,7 @@ export default (() => {
setData (deerjikists)
setDisabled (false)
}, [deerjikists])
}, [tag, deerjikists])
return (
<MainArea>
+1 -1
View File
@@ -183,7 +183,7 @@ export type Tag = {
createdAt: string
updatedAt: string
hasWiki: boolean
materialId: number
materialId: number | null
hasDeerjikists: boolean
children?: Tag[]
matchedAlias?: string | null }