投稿検索ページ(#206) (#274)

#206 エラー修正

#206 updated_at の並び順修正

Merge remote-tracking branch 'origin/main' into feature/206

Merge branch 'main' into feature/206

Merge branch 'main' into feature/206

Merge branch 'main' into feature/206

#206

#206

#206

#206

#206

#206 タグ補完追加

#206

#206

#206

#206

#206

Merge remote-tracking branch 'origin/main' into feature/206

#206

Co-authored-by: miteruzo <miteruzo@naver.com>
Reviewed-on: #274
This commit was merged in pull request #274.
This commit is contained in:
2026-03-08 23:12:16 +09:00
parent 16e9b8ca49
commit 9e3cbd2469
19 changed files with 864 additions and 95 deletions
+200 -1
View File
@@ -1,7 +1,8 @@
include ActiveSupport::Testing::TimeHelpers
require 'rails_helper'
require 'set'
RSpec.describe 'Posts API', type: :request do
# create / update で thumbnail.attach は走るが、
# resized_thumbnail! が MiniMagick 依存でコケやすいので request spec ではスタブしとくのが無難。
@@ -114,6 +115,204 @@ RSpec.describe 'Posts API', type: :request do
expect(json.fetch('count')).to eq(0)
end
end
context 'when url is provided' do
let!(:url_hit_post) do
Post.create!(uploaded_user: user, title: 'url hit',
url: 'https://example.com/needle-url-xyz').tap do |p|
PostTag.create!(post: p, tag:)
end
end
let!(:url_miss_post) do
Post.create!(uploaded_user: user, title: 'url miss',
url: 'https://example.com/other-url').tap do |p|
PostTag.create!(post: p, tag:)
end
end
it 'filters posts by url substring' do
get '/posts', params: { url: 'needle-url-xyz' }
expect(response).to have_http_status(:ok)
ids = json.fetch('posts').map { |p| p['id'] }
expect(ids).to include(url_hit_post.id)
expect(ids).not_to include(url_miss_post.id)
expect(json.fetch('count')).to eq(1)
end
end
context 'when title is provided' do
let!(:title_hit_post) do
Post.create!(uploaded_user: user, title: 'needle-title-xyz',
url: 'https://example.com/title-hit').tap do |p|
PostTag.create!(post: p, tag:)
end
end
let!(:title_miss_post) do
Post.create!(uploaded_user: user, title: 'other title',
url: 'https://example.com/title-miss').tap do |p|
PostTag.create!(post: p, tag:)
end
end
it 'filters posts by title substring' do
get '/posts', params: { title: 'needle-title-xyz' }
expect(response).to have_http_status(:ok)
ids = json.fetch('posts').map { |p| p['id'] }
expect(ids).to include(title_hit_post.id)
expect(ids).not_to include(title_miss_post.id)
expect(json.fetch('count')).to eq(1)
end
end
context 'when created_from/created_to are provided' do
let(:t_created_hit) { Time.zone.local(2010, 1, 5, 12, 0, 0) }
let(:t_created_miss) { Time.zone.local(2012, 1, 5, 12, 0, 0) }
let!(:created_hit_post) do
travel_to(t_created_hit) do
Post.create!(uploaded_user: user, title: 'created hit',
url: 'https://example.com/created-hit').tap do |p|
PostTag.create!(post: p, tag:)
end
end
end
let!(:created_miss_post) do
travel_to(t_created_miss) do
Post.create!(uploaded_user: user, title: 'created miss',
url: 'https://example.com/created-miss').tap do |p|
PostTag.create!(post: p, tag:)
end
end
end
it 'filters posts by created_at range' do
get '/posts', params: {
created_from: Time.zone.local(2010, 1, 1, 0, 0, 0).iso8601,
created_to: Time.zone.local(2010, 12, 31, 23, 59, 59).iso8601
}
expect(response).to have_http_status(:ok)
ids = json.fetch('posts').map { |p| p['id'] }
expect(ids).to include(created_hit_post.id)
expect(ids).not_to include(created_miss_post.id)
expect(json.fetch('count')).to eq(1)
end
end
context 'when updated_from/updated_to are provided' do
let(:t0) { Time.zone.local(2011, 2, 1, 12, 0, 0) }
let(:t1) { Time.zone.local(2011, 2, 10, 12, 0, 0) }
let!(:updated_hit_post) do
p = nil
travel_to(t0) do
p = Post.create!(uploaded_user: user, title: 'updated hit',
url: 'https://example.com/updated-hit').tap do |pp|
PostTag.create!(post: pp, tag:)
end
end
travel_to(t1) do
p.update!(title: 'updated hit v2')
end
p
end
let!(:updated_miss_post) do
travel_to(Time.zone.local(2013, 1, 1, 12, 0, 0)) do
Post.create!(uploaded_user: user, title: 'updated miss',
url: 'https://example.com/updated-miss').tap do |p|
PostTag.create!(post: p, tag:)
end
end
end
it 'filters posts by updated_at range' do
get '/posts', params: {
updated_from: Time.zone.local(2011, 2, 5, 0, 0, 0).iso8601,
updated_to: Time.zone.local(2011, 2, 20, 23, 59, 59).iso8601
}
expect(response).to have_http_status(:ok)
ids = json.fetch('posts').map { |p| p['id'] }
expect(ids).to include(updated_hit_post.id)
expect(ids).not_to include(updated_miss_post.id)
expect(json.fetch('count')).to eq(1)
end
end
context 'when original_created_from/original_created_to are provided' do
# 注意: controller の現状ロジックに合わせてる
# original_created_from は `original_created_before > ?`
# original_created_to は `original_created_from <= ?`
let!(:oc_hit_post) do
Post.create!(uploaded_user: user, title: 'oc hit',
url: 'https://example.com/oc-hit',
original_created_from: Time.zone.local(2015, 1, 1, 0, 0, 0),
original_created_before: Time.zone.local(2015, 1, 10, 0, 0, 0)).tap do |p|
PostTag.create!(post: p, tag:)
end
end
# original_created_from の条件は「original_created_before > param」なので、
# before が param 以下になるようにする(ただし before >= from は守る)
let!(:oc_miss_post_for_from) do
Post.create!(
uploaded_user: user,
title: 'oc miss for from',
url: 'https://example.com/oc-miss-from',
original_created_from: Time.zone.local(2014, 12, 1, 0, 0, 0),
original_created_before: Time.zone.local(2015, 1, 1, 0, 0, 0)
).tap { |p| PostTag.create!(post: p, tag:) }
end
# original_created_to の条件は「original_created_from <= param」なので、
# from が param より後になるようにする(before >= from は守る)
let!(:oc_miss_post_for_to) do
Post.create!(
uploaded_user: user,
title: 'oc miss for to',
url: 'https://example.com/oc-miss-to',
original_created_from: Time.zone.local(2015, 2, 1, 0, 0, 0),
original_created_before: Time.zone.local(2015, 2, 10, 0, 0, 0)
).tap { |p| PostTag.create!(post: p, tag:) }
end
it 'filters posts by original_created_from (current controller behavior)' do
get '/posts', params: {
original_created_from: Time.zone.local(2015, 1, 5, 0, 0, 0).iso8601
}
expect(response).to have_http_status(:ok)
ids = json.fetch('posts').map { |p| p['id'] }
expect(ids).to include(oc_hit_post.id)
expect(ids).not_to include(oc_miss_post_for_from.id)
expect(json.fetch('count')).to eq(2)
end
it 'filters posts by original_created_to (current controller behavior)' do
get '/posts', params: {
original_created_to: Time.zone.local(2015, 1, 15, 0, 0, 0).iso8601
}
expect(response).to have_http_status(:ok)
ids = json.fetch('posts').map { |p| p['id'] }
expect(ids).to include(oc_hit_post.id)
expect(ids).not_to include(oc_miss_post_for_to.id)
expect(json.fetch('count')).to eq(2)
end
end
end
describe 'GET /posts/:id' do