156 行
6.0 KiB
Ruby
156 行
6.0 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe 'Sitemap entries API', type: :request do
|
|
include_context 'Ainu locale'
|
|
|
|
let(:user) { create(:user, :member) }
|
|
|
|
it 'serves public resource counts with the default locale and page size' do
|
|
create(:post)
|
|
create(:tag, primary_name: 'sitemap_count_tag')
|
|
|
|
get '/sitemap_entries'
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json.fetch('page_size')).to eq(1_000)
|
|
counts = json.fetch('resources').to_h { |entry|
|
|
[entry.fetch('resource'), entry.fetch('count')]
|
|
}
|
|
expect(counts).to eq(
|
|
'posts' => Post.count, 'tags' => Tag.count, 'deerjikists' => 0,
|
|
'materials' => 0, 'descriptions' => 0, 'tag_groups' => 0, 'theatres' => 0)
|
|
end
|
|
|
|
it 'paginates public post IDs in ascending order without exposing post contents' do
|
|
stub_const('SitemapEntriesController::PAGE_SIZE', 2)
|
|
posts = create_list(:post, 3)
|
|
|
|
get '/sitemap_entries/posts'
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json).to eq('ids' => posts.first(2).map(&:id))
|
|
|
|
get '/sitemap_entries/posts', params: { page: 2 }
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json).to eq('ids' => [posts.last.id])
|
|
|
|
get '/sitemap_entries/posts', params: { page: 3 }
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
|
|
['0', '-1', 'invalid', '1.5'].each do |page|
|
|
it "rejects invalid sitemap page #{ page.inspect }" do
|
|
get '/sitemap_entries/posts', params: { page: }
|
|
|
|
expect(response).to have_http_status(:bad_request)
|
|
end
|
|
end
|
|
|
|
it 'rejects unsupported resource names' do
|
|
get '/sitemap_entries/users'
|
|
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
|
|
it 'returns an empty first page for a resource without entries' do
|
|
get '/sitemap_entries/posts'
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json).to eq('ids' => [])
|
|
end
|
|
|
|
it 'rejects unregistered, deprecated and unsupported locales' do
|
|
get '/sitemap_entries', params: { locale: 'ain-Kana' }
|
|
expect(response).to have_http_status(:not_found)
|
|
|
|
locale.update!(deprecated_at: Time.current)
|
|
['/sitemap_entries', '/sitemap_entries/posts'].each do |path|
|
|
get path, params: { locale: 'ain-Kana' }
|
|
expect(response).to have_http_status(:not_found)
|
|
|
|
get path, params: { locale: 'en' }
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
end
|
|
|
|
it 'only lists live materials and theatres' do
|
|
material = Material.create!(url: 'https://example.com/sitemap-material')
|
|
discarded_material = Material.create!(url: 'https://example.com/sitemap-discarded')
|
|
discarded_material.discard!
|
|
theatre = create(:theatre)
|
|
create(:theatre).discard!
|
|
|
|
get '/sitemap_entries/materials'
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json).to eq('ids' => [material.id])
|
|
|
|
get '/sitemap_entries/theatres'
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json).to eq('ids' => [theatre.id])
|
|
end
|
|
|
|
context 'with an active Ainu locale' do
|
|
before { locale }
|
|
|
|
it 'uses tag IDs and only includes deerjikists with linked accounts' do
|
|
tagged = create(:tag, primary_name: 'sitemap_deer', category: :deerjikist)
|
|
unlinked = create(:tag, primary_name: 'sitemap_unlinked', category: :deerjikist)
|
|
Deerjikist.create!(tag: tagged, platform: 'youtube', code: 'sitemap-channel')
|
|
Deerjikist.create!(tag: tagged, platform: 'nico', code: 'sitemap-nico')
|
|
|
|
get '/sitemap_entries/tags', params: { locale: 'ain-Kana' }
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json.fetch('ids')).to contain_exactly(tagged.id, unlinked.id)
|
|
|
|
get '/sitemap_entries/deerjikists', params: { locale: 'ain-Kana' }
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json).to eq('ids' => [tagged.id])
|
|
end
|
|
|
|
it 'lists description IDs for the requested language with a nonempty current version' do
|
|
tag = create(:tag, primary_name: 'sitemap_description')
|
|
japanese = TagDescriptionOperation.create!(
|
|
Locale.nipponese, tag:, body: 'Japanese sitemap body', created_by_user: user)
|
|
ainu = TagDescriptionOperation.create!(
|
|
locale, tag:, body: 'Ainu sitemap body', created_by_user: user)
|
|
unversioned_tag = create(:tag, primary_name: 'sitemap_unversioned')
|
|
TagDescription.create!(tag: unversioned_tag, language_code: 'ain',
|
|
body: 'No revision', version_no: 1)
|
|
empty_tag = create(:tag, primary_name: 'sitemap_empty')
|
|
# Legacy empty bodies can exist even though the write service rejects them.
|
|
empty = TagDescription.create!(tag: empty_tag, language_code: 'ain',
|
|
body: '', version_no: 1)
|
|
TagDescriptionVersion.create!(tag_id: empty_tag.id, language_code: 'ain',
|
|
body: '', version_no: 1, event_type: 'create',
|
|
created_by_user_id: user.id, created_at: Time.current)
|
|
|
|
get '/sitemap_entries/descriptions', params: { locale: 'ain-Kana' }
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json).to eq('ids' => [ainu.id])
|
|
expect(json.fetch('ids')).not_to include(japanese.id, empty.id)
|
|
|
|
get '/sitemap_entries/descriptions', params: { locale: 'ja' }
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json).to eq('ids' => [japanese.id])
|
|
|
|
get '/sitemap_entries', params: { locale: 'ain-Kana' }
|
|
expect(response).to have_http_status(:ok)
|
|
descriptions = json.fetch('resources').find { |entry|
|
|
entry.fetch('resource') == 'descriptions'
|
|
}
|
|
expect(descriptions.fetch('count')).to eq(1)
|
|
end
|
|
|
|
it 'excludes groups without a revision matching the current version' do
|
|
group = TagGroupOperation.create!(
|
|
Locale.nipponese, name: 'Sitemap group', description: 'Group description',
|
|
members: [], placements: [], actor: user)
|
|
TagGroup.create!(name: 'Unversioned sitemap group', version_no: 1)
|
|
|
|
get '/sitemap_entries/tag_groups', params: { locale: 'ain-Kana' }
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
expect(json).to eq('ids' => [group.id])
|
|
end
|
|
end
|
|
end
|