feat: 別名を検索に展開(#20) (#243)

#20

#20 テスト・ケースのみ追記

#20

Co-authored-by: miteruzo <miteruzo@naver.com>
Reviewed-on: #243
This commit was merged in pull request #243.
This commit is contained in:
2026-01-28 23:47:56 +09:00
parent effde89b07
commit 200d457d22
8 changed files with 168 additions and 39 deletions
+40
View File
@@ -30,6 +30,7 @@ RSpec.describe 'Posts API', type: :request do
let!(:tag) { Tag.create!(tag_name:, category: "general") }
let!(:tag_name2) { TagName.create!(name: 'unko') }
let!(:tag2) { Tag.create!(tag_name: tag_name2, category: 'deerjikist') }
let!(:alias_tag_name) { TagName.create!(name: 'manko', canonical: tag_name) }
let!(:hit_post) do
Post.create!(uploaded_user: user, title: "hello spec world",
@@ -86,6 +87,25 @@ RSpec.describe 'Posts API', type: :request do
end
end
it "filters posts by q (hit case by alias)" do
get "/posts", params: { tags: "manko" }
expect(response).to have_http_status(:ok)
posts = json.fetch('posts')
ids = posts.map { |p| p['id'] }
expect(ids).to include(hit_post.id)
expect(ids).not_to include(miss_post.id)
expect(json['count']).to be_an(Integer)
posts.each do |p|
expect(p['tags']).to be_an(Array)
p['tags'].each do |t|
expect(t).to include('name', 'category', 'has_wiki')
end
end
end
it "returns empty posts when nothing matches" do
get "/posts", params: { tags: "no_such_keyword_12345" }
@@ -135,6 +155,7 @@ RSpec.describe 'Posts API', type: :request do
describe 'POST /posts' do
let(:member) { create(:user, :member) }
let!(:alias_tag_name) { TagName.create!(name: 'manko', canonical: tag_name) }
it '401 when not logged in' do
sign_out
@@ -167,6 +188,25 @@ RSpec.describe 'Posts API', type: :request do
expect(json['tags'][0]).to have_key('name')
end
it '201 and creates post + tags when member and tags have aliases' do
sign_in_as(member)
post '/posts', params: {
title: 'new post',
url: 'https://example.com/new',
tags: 'manko', # 既存タグ名を投げる
thumbnail: dummy_upload
}
expect(response).to have_http_status(:created)
expect(json).to include('id', 'title', 'url')
# tags が name を含むこと(API 側の serialization が正しいこと)
names = json.fetch('tags').map { |t| t['name'] }
expect(names).to include('spec_tag')
expect(names).not_to include('manko')
end
context "when nico tag already exists in tags" do
before do
Tag.find_or_create_by!(tag_name: TagName.find_or_create_by!(name: 'nico:nico_tag'),
+15
View File
@@ -5,6 +5,7 @@ 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') }
let!(:alias_tn) { TagName.create!(name: 'unko', canonical: tn) }
describe 'GET /tags' do
it 'returns tags with name' do
@@ -56,6 +57,20 @@ RSpec.describe 'Tags API', type: :request do
expect(json).to be_an(Array)
expect(json.map { |t| t['name'] }).to include('spec_tag')
t = json.find { |t| t['name'] == 'spec_tag' }
expect(t).to have_key('matched_alias')
expect(t['matched_alias']).to be(nil)
end
it 'returns matching canonical tags by q with aliases' do
get '/tags/autocomplete', params: { q: 'unk' }
expect(response).to have_http_status(:ok)
expect(json).to be_an(Array)
expect(json.map { |t| t['name'] }).to include('spec_tag')
t = json.find { |t| t['name'] == 'spec_tag' }
expect(t['matched_alias']).to eq('unko')
end
end