このコミットが含まれているのは:
2026-06-14 05:31:00 +09:00
コミット 791b52e894
5個のファイルの変更413行の追加13行の削除
+112
ファイルの表示
@@ -0,0 +1,112 @@
require 'rails_helper'
RSpec.describe Gekanator::QuestionSuggestionAiConverter do
let(:user) { create(:user, :member) }
let(:guessed_post) { Post.create!(title: 'guess', url: 'https://example.com/guess') }
let(:correct_post) { Post.create!(title: 'correct', url: 'https://example.com/correct') }
let(:game) do
GekanatorGame.create!(
user: user,
guessed_post: guessed_post,
correct_post: correct_post,
won: false,
question_count: 1,
answers: [{ 'question_id' => 'tag:1', 'answer' => 'yes' }]
)
end
def create_suggestion!(question_text:, answer: 'yes')
GekanatorQuestionSuggestion.create!(
gekanator_game: game,
user: user,
question_text: question_text,
answer: answer
)
end
it 'converts title-contains suggestions to pending ai-generated questions' do
suggestion = create_suggestion!(question_text: '題名に「結束バンド」が含まれる?')
expect {
described_class.call(suggestion: suggestion, user: user)
}.to change { GekanatorQuestion.count }.by(1)
.and change { GekanatorAiRun.count }.by(1)
question = GekanatorQuestion.last
expect(question).to have_attributes(
text: '題名に「結束バンド」が含まれる?',
kind: 'title',
source: 'ai_generated',
status: 'pending',
priority_weight: 0.95,
gekanator_question_suggestion_id: suggestion.id,
created_by_id: user.id
)
expect(question.condition).to include(
'type' => 'title-contains',
'text' => '結束バンド'
)
expect(GekanatorAiRun.last).to have_attributes(
gekanator_question_suggestion_id: suggestion.id,
model: 'heuristic_converter_v1',
status: 'succeeded'
)
end
it 'converts concrete non-unknown suggestions to post-similarity questions' do
suggestion = create_suggestion!(
question_text: '喜多ちゃんが泣いてる?',
answer: 'partial'
)
question = described_class.call(suggestion: suggestion, user: user)
expect(question).to have_attributes(
text: '喜多ちゃんが泣いてる?',
kind: 'post_similarity',
source: 'ai_generated',
status: 'pending',
priority_weight: 1.0
)
expect(question.condition).to include(
'type' => 'post-similarity',
'postId' => correct_post.id,
'answer' => 'partial',
'threshold' => 0.65
)
end
it 'records a failed run when the suggestion cannot be converted' do
suggestion = create_suggestion!(
question_text: 'よく分からない質問?',
answer: 'unknown'
)
expect {
expect(described_class.call(suggestion: suggestion, user: user)).to be_nil
}.not_to change { GekanatorQuestion.count }
expect(GekanatorAiRun.last).to have_attributes(
gekanator_question_suggestion_id: suggestion.id,
status: 'failed'
)
end
it 'returns an existing generated question without creating a duplicate run' do
suggestion = create_suggestion!(question_text: 'タイトルは 10 文字以上?')
existing = GekanatorQuestion.create!(
text: 'タイトルは 10 文字以上?',
kind: 'title',
source: 'ai_generated',
status: 'pending',
priority_weight: 0.95,
condition: { type: 'title-length-at-least', length: 10 },
gekanator_question_suggestion: suggestion,
created_by: user
)
expect {
expect(described_class.call(suggestion: suggestion, user: user)).to eq(existing)
}.not_to change { GekanatorAiRun.count }
end
end