diff --git a/backend/app/controllers/posts_controller.rb b/backend/app/controllers/posts_controller.rb index 648d42e..dde9f15 100644 --- a/backend/app/controllers/posts_controller.rb +++ b/backend/app/controllers/posts_controller.rb @@ -81,8 +81,6 @@ class PostsController < ApplicationController return head :unauthorized unless current_user return head :forbidden unless current_user.member? - # TODO: URL が正規のものがチェック,不正ならエラー - # TODO: URL は必須にする(タイトルは省略可). # TODO: サイトに応じて thumbnail_base 設定 title = params[:title].presence url = params[:url] @@ -105,6 +103,8 @@ class PostsController < ApplicationController else render json: { errors: post.errors.full_messages }, status: :unprocessable_entity end + rescue Tag::NicoTagNormalisationError + head :bad_request end def viewed @@ -142,6 +142,8 @@ class PostsController < ApplicationController else render json: post.errors, status: :unprocessable_entity end + rescue Tag::NicoTagNormalisationError + head :bad_request end def changes diff --git a/backend/app/models/tag.rb b/backend/app/models/tag.rb index 17546b5..a1372c7 100644 --- a/backend/app/models/tag.rb +++ b/backend/app/models/tag.rb @@ -1,4 +1,8 @@ class Tag < ApplicationRecord + class NicoTagNormalisationError < StandardError + ; + end + has_many :post_tags, dependent: :delete_all, inverse_of: :tag has_many :active_post_tags, -> { kept }, class_name: 'PostTag', inverse_of: :tag has_many :post_tags_with_discarded, -> { with_discarded }, class_name: 'PostTag' @@ -65,6 +69,8 @@ class Tag < ApplicationRecord def self.normalise_tags tag_names, with_tagme: true tags = tag_names.map do |name| + raise NicoTagNormalisationError if name.start_with?('nico:') + pf, cat = CATEGORY_PREFIXES.find { |p, _| name.start_with?(p) } || ['', nil] name.delete_prefix!(pf) find_or_create_by_tag_name!(name, category: (cat || 'general')).tap do |tag| diff --git a/backend/spec/requests/posts_spec.rb b/backend/spec/requests/posts_spec.rb index eb7ce9f..07523b1 100644 --- a/backend/spec/requests/posts_spec.rb +++ b/backend/spec/requests/posts_spec.rb @@ -167,16 +167,34 @@ RSpec.describe 'Posts API', type: :request do expect(json['tags'][0]).to have_key('name') 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'), + category: 'nico') + end + + it 'return 400' do + sign_in_as(member) + + post '/posts', params: { + title: 'new post', + url: 'https://example.com/nico_tag', + tags: 'nico:nico_tag', + thumbnail: dummy_upload } + + expect(response).to have_http_status(:bad_request) + end + end + context 'when url is blank' do it 'returns 422' do sign_in_as(member) post '/posts', params: { - title: 'new post', - url: ' ', - tags: 'spec_tag', # 既存タグ名を投げる - thumbnail: dummy_upload - } + title: 'new post', + url: ' ', + tags: 'spec_tag', # 既存タグ名を投げる + thumbnail: dummy_upload } expect(response).to have_http_status(:unprocessable_entity) end @@ -233,6 +251,23 @@ RSpec.describe 'Posts API', type: :request do names = json['tags'].map { |n| n['name'] } expect(names).to include('spec_tag_2') 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'), + category: 'nico') + end + + it 'return 400' do + sign_in_as(member) + + put "/posts/#{ post_record.id }", params: { + title: 'updated title', + tags: 'nico:nico_tag' } + + expect(response).to have_http_status(:bad_request) + end + end end describe 'GET /posts/random' do