From 4ff89b94e5d694b0c972dafa70d24f1809157d83 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Fri, 5 Jun 2026 01:06:53 +0900 Subject: [PATCH] #90 --- .../app/controllers/nico_tags_controller.rb | 28 +++++++++++++++---- backend/spec/requests/nico_tags_spec.rb | 28 +++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/backend/app/controllers/nico_tags_controller.rb b/backend/app/controllers/nico_tags_controller.rb index 002b66f..54e6892 100644 --- a/backend/app/controllers/nico_tags_controller.rb +++ b/backend/app/controllers/nico_tags_controller.rb @@ -33,13 +33,15 @@ class NicoTagsController < ApplicationController return render_bad_request('ニコニコ・タグを指定してください.') unless tag.nico? linked_tag_names = params[:tags].to_s.split - linked_tags = Tag.normalise_tags!(linked_tag_names, with_tagme: false, - with_no_deerjikist: false) - if linked_tags.any? { |t| t.nico? } - return render_unprocessable_entity('ニコニコ・タグ同士は連携できません.', field: :tags) - end + linked_tags = nil ApplicationRecord.transaction do + linked_tags = Tag.normalise_tags!(linked_tag_names, with_tagme: false, + with_no_deerjikist: false) + if linked_tags.any? { |t| t.nico? } + raise Tag::NicoTagNormalisationError + end + TagVersioning.record_tag_snapshots!(linked_tags, created_by_user: current_user) tag.linked_tags = linked_tags @@ -49,5 +51,21 @@ class NicoTagsController < ApplicationController end render json: tag.linked_tags.map { |t| TagRepr.base(t) }, status: :ok + rescue Tag::NicoTagNormalisationError + render_validation_error fields: { tags: ['ニコニコ・タグ同士は連携できません.'] } + rescue ActiveRecord::RecordInvalid => e + render_nico_tag_form_record_invalid e.record + end + + private + + def render_nico_tag_form_record_invalid record + if record.is_a?(TagName) || record.is_a?(Tag) + render_validation_error fields: { tags: record.errors.full_messages.map { |message| + "タグ名 “#{ record.name }”: #{ message }" + } } + else + render_validation_error record + end end end diff --git a/backend/spec/requests/nico_tags_spec.rb b/backend/spec/requests/nico_tags_spec.rb index 5b3b27c..5ad80d5 100644 --- a/backend/spec/requests/nico_tags_spec.rb +++ b/backend/spec/requests/nico_tags_spec.rb @@ -91,5 +91,33 @@ RSpec.describe 'NicoTags', type: :request do expect(json.fetch('errors')).to include( 'tags' => ['ニコニコ・タグ同士は連携できません.']) end + + it 'returns the tags field error when a nico tag is specified directly' do + sign_in_as(member) + + patch "/tags/nico/#{nico_tag.id}", params: { tags: 'nico:linked_ng' } + + expect(response).to have_http_status(:unprocessable_entity) + expect(json.fetch('errors')).to include( + 'tags' => ['ニコニコ・タグ同士は連携できません.']) + end + + it 'returns tag name validation errors on the tags field and rolls back created tags' do + sign_in_as(member) + TagNameSanitisationRule.create!( + priority: 1, + source_pattern: 'invalid', + replacement: 'valid' + ) + nico_tag + + expect { + patch "/tags/nico/#{nico_tag.id}", params: { tags: 'created_first invalid' } + }.not_to change(TagName, :count) + + expect(response).to have_http_status(:unprocessable_entity) + expect(json.fetch('errors').fetch('tags')).to include( + a_string_including('タグ名 “invalid”:', '名前に使用できない文字が含まれてゐます.')) + end end end