From 237331481f8487206bcd246f836f27984bfc9158 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Thu, 29 Oct 2026 21:38:38 +0900 Subject: [PATCH] #434 --- backend/spec/models/history_access_spec.rb | 4 +++- backend/spec/requests/counts_table_spec.rb | 4 ++-- .../post_locale_filter_identity_spec.rb | 24 ++++++++++++++++++- .../requests/tag_description_wiki_spec.rb | 4 ++-- backend/spec/services/counts_export_spec.rb | 7 +++++- frontend/server.ssr.test.mjs | 3 ++- .../components/counts/CountsTable.test.tsx | 3 ++- frontend/src/lib/locales.test.ts | 4 ++-- .../src/pages/posts/PostDetailPage.test.tsx | 9 ++++--- .../pages/posts/PostImportReviewPage.test.tsx | 9 +++---- .../pages/theatres/TheatreDetailPage.test.tsx | 11 ++++----- 11 files changed, 56 insertions(+), 26 deletions(-) diff --git a/backend/spec/models/history_access_spec.rb b/backend/spec/models/history_access_spec.rb index 4c3f537..313d196 100644 --- a/backend/spec/models/history_access_spec.rb +++ b/backend/spec/models/history_access_spec.rb @@ -29,7 +29,9 @@ RSpec.describe HistoryAccess do admin = create(:user, :admin) admin_metadata = described_class.set(user: admin) { described_class.authority } TagVersion.create!(tag:, version_no: 1, event_type: 'discard', name: 'private', - category: 'general', names: { ja: { name: 'private' } }, + category: 'general', + names: { ja: { name: 'private', script_code: 'Jpan', + auto_generated: false, aliases: [] } }, aliases: '', parent_tag_ids: '', created_at: Time.utc(2024)) described_class.set(user: nil) do expect(described_class.authorised_artifact?(public_metadata)).to be(false) diff --git a/backend/spec/requests/counts_table_spec.rb b/backend/spec/requests/counts_table_spec.rb index bda0ff3..90c7e1b 100644 --- a/backend/spec/requests/counts_table_spec.rb +++ b/backend/spec/requests/counts_table_spec.rb @@ -16,13 +16,13 @@ RSpec.describe 'Counts table API', type: :request do before do TagVersion.create!(tag:, version_no: 1, event_type: 'create', name: 'alpha', category: 'general', aliases: '', parent_tag_ids: '', - names: { ja: { name: 'alpha', script_code: 'Jpan', aliases: [] } }, + names: { ja: { name: 'alpha', script_code: 'Jpan', auto_generated: false, aliases: [] } }, created_at: Time.utc(2023)) NicoTagVersion.create!(external_tag: external, version_no: 1, event_type: 'create', name: 'beta', linked_tags: '', created_at: Time.utc(2023)) snapshots = [ { tag_id: tag.id, version_no: 1, name: 'alpha', category: 'general', sections: [] }, - { external_tag_id: external.id, name: 'beta', sections: [] }] + { external_tag_id: external.id }] [1, 2, 3].each do |number| PostVersion.create!(post: record, version_no: number, event_type: number == 1 ? 'create' : 'update', url: record.url, diff --git a/backend/spec/requests/post_locale_filter_identity_spec.rb b/backend/spec/requests/post_locale_filter_identity_spec.rb index 99a6416..3f165b1 100644 --- a/backend/spec/requests/post_locale_filter_identity_spec.rb +++ b/backend/spec/requests/post_locale_filter_identity_spec.rb @@ -21,7 +21,29 @@ RSpec.describe 'Post filter identity across locales', type: :request do ['nico:shared', 'union_alias', 'not:nico:shared'].each do |literal| it "preserves the complete match set for #{ literal }" do - get '/posts', params: { locale: 'ja', tags: literal } + reference_params = { tag_refs: '' } + + references.each_with_index do |reference, index| + %w[name tag_id external_tag_id negative missing].each do |field| + value = reference[field] + next if value.nil? + next if field == 'missing' && value == false + + reference_params["tag_refs.#{index}.#{field}"] = + case value + when true + '1' + when false + '0' + else + value.to_s + end + end + end + + get '/posts', params: { + locale: 'ain-Kana', + tags: references.map { _1.fetch('name') }.join(' ') }.merge(reference_params) expect(response).to have_http_status(:ok) original_ids = json.fetch('posts').map { _1.fetch('id') } expected = literal.start_with?('not:') ? [other_post.id] : diff --git a/backend/spec/requests/tag_description_wiki_spec.rb b/backend/spec/requests/tag_description_wiki_spec.rb index 5a52675..374b7dd 100644 --- a/backend/spec/requests/tag_description_wiki_spec.rb +++ b/backend/spec/requests/tag_description_wiki_spec.rb @@ -55,7 +55,7 @@ RSpec.describe 'Tag description Wiki compatibility', type: :request do end it 'does not fall back to a revision absent from new history' do - versions.first.destroy! + TagDescriptionVersion.where(id: versions.first.id).delete_all without_legacy_reads do get "/wiki/#{ description.id }", params: { version: versions.first.id } end @@ -190,7 +190,7 @@ RSpec.describe 'Tag description Wiki compatibility', type: :request do describe 'index' do [nil, 'description_contract'].each do |title| it "returns new content once in #{ title ? 'filtered' : 'unfiltered' } index" do - get '/wiki', params: { title: } + get '/wiki', params: title.nil? ? { } : { title: title } expect(response).to have_http_status(:ok) rows = json.select { |row| row.fetch('id') == description.id } expect(rows.size).to eq(1) diff --git a/backend/spec/services/counts_export_spec.rb b/backend/spec/services/counts_export_spec.rb index bf2c304..f7b92e3 100644 --- a/backend/spec/services/counts_export_spec.rb +++ b/backend/spec/services/counts_export_spec.rb @@ -12,11 +12,16 @@ RSpec.describe 'Counts export contracts' do around do |example| Dir.mktmpdir('counts-export-spec') do |path| - allow(CountsExportDownload).to receive(:directory).and_return(Pathname.new(path)) + @counts_export_dir = Pathname.new(path) HistoryAccess.set(user: nil) { example.run } end end + before do + allow(CountsExportDownload).to receive(:directory) + .and_return(@counts_export_dir) + end + context 'serialization after the authorised query' do let(:rows) { [{ title: "=formula\n\"quoted\"" }, { title: 'second' }] } let(:page) do diff --git a/frontend/server.ssr.test.mjs b/frontend/server.ssr.test.mjs index 55bc512..ab1b332 100644 --- a/frontend/server.ssr.test.mjs +++ b/frontend/server.ssr.test.mjs @@ -336,7 +336,8 @@ test ('counts SSR uses query/definitions, noindex and the common site title', as for (const locale of ['ja', 'ain-Kana']) { for (const resource of ['posts', 'tags']) { const column = resource === 'posts' ? 'title' : (locale === 'ja' ? 'name_ja' : 'name_ain') - const query = `definition=history&mode=details&columns=resource_id+${column}&user_id=4` + const query = + `definition=history&mode=details&columns=resource_id+${ column }&user_id=4&timezone=UTC` const result = await renderPage (`/${locale}/counts/${resource}?${query}`, origin, apiURL) assert.equal (result.status, 200) assert.match (result.html, /SSR count/) diff --git a/frontend/src/components/counts/CountsTable.test.tsx b/frontend/src/components/counts/CountsTable.test.tsx index 5ac15bc..f3f8b9c 100644 --- a/frontend/src/components/counts/CountsTable.test.tsx +++ b/frontend/src/components/counts/CountsTable.test.tsx @@ -9,11 +9,12 @@ import { renderWithProviders } from '@/test/render' import type { CountField } from '@/lib/counts' + const renderTable = () => renderWithProviders ( - first cellsecond + first cellsecond third diff --git a/frontend/src/lib/locales.test.ts b/frontend/src/lib/locales.test.ts index 10ef552..ee02c1f 100644 --- a/frontend/src/lib/locales.test.ts +++ b/frontend/src/lib/locales.test.ts @@ -28,7 +28,7 @@ describe ('locale URL generation', () => { '/tos', '/gekanator', '/more']) ('localises and redirects %s', pathname => { const location = { pathname, search: '?page=2&tag=a%23b', hash: '#section' } expect (localiseTo (pathname, 'ain-Kana')).toBe (`/ain-Kana${ pathname }`) - expect (legacyLocalePath (location)).toBe (`/ja${ pathname }${ location.search }#section`) + expect (legacyLocalePath (location, () => true)).toBe (`/ja${ pathname }${ location.search }#section`) expect (unlocalisedPath (`/ain-Kana${ pathname }`)).toBe (pathname) }) @@ -50,6 +50,6 @@ describe ('locale URL generation', () => { it.each (['/en/posts', '/ain/posts', '/unknown', '/api/tags', '/assets/image.png']) ( 'does not redirect invalid or non-page paths: %s', pathname => { - expect (legacyLocalePath ({ pathname, search: '', hash: '' })).toBeNull () + expect (legacyLocalePath ({ pathname, search: '', hash: '' }, () => false)).toBeNull () }) }) diff --git a/frontend/src/pages/posts/PostDetailPage.test.tsx b/frontend/src/pages/posts/PostDetailPage.test.tsx index a23d19a..cabe112 100644 --- a/frontend/src/pages/posts/PostDetailPage.test.tsx +++ b/frontend/src/pages/posts/PostDetailPage.test.tsx @@ -29,11 +29,10 @@ vi.mock ('@/components/PostEditForm', () => ({ default: () =>
Post edit form
, })) vi.mock ('framer-motion', () => ({ - motion: { - div: ({ children }: { children?: ReactNode }) =>
{children}
, - main: ({ children }: { children?: ReactNode }) =>
{children}
, - }, -})) + useReducedMotion: () => false, + motion: { + div: ({ children }: { children?: ReactNode }) =>
{children}
, + main: ({ children }: { children?: ReactNode }) =>
{children}
} })) const renderPage = (user = buildUser ({ role: 'member' })) => renderWithProviders ( diff --git a/frontend/src/pages/posts/PostImportReviewPage.test.tsx b/frontend/src/pages/posts/PostImportReviewPage.test.tsx index 3a27996..8620a10 100644 --- a/frontend/src/pages/posts/PostImportReviewPage.test.tsx +++ b/frontend/src/pages/posts/PostImportReviewPage.test.tsx @@ -15,10 +15,11 @@ const api = vi.hoisted (() => ({ vi.mock ('@/lib/api', () => api) vi.mock ('framer-motion', () => ({ - AnimatePresence: ({ children }: { children?: ReactNode }) => <>{children}, - motion: { - div: ({ children }: { children?: ReactNode }) =>
{children}
, - main: ({ children }: { children?: ReactNode }) =>
{children}
} })) + AnimatePresence: ({ children }: { children?: ReactNode }) => <>{children}, + useReducedMotion: () => false, + motion: { + div: ({ children }: { children?: ReactNode }) =>
{children}
, + main: ({ children }: { children?: ReactNode }) =>
{children}
} })) const metadata = (url: string, title: string) => ({ url, diff --git a/frontend/src/pages/theatres/TheatreDetailPage.test.tsx b/frontend/src/pages/theatres/TheatreDetailPage.test.tsx index 3f5eae4..86d45b4 100644 --- a/frontend/src/pages/theatres/TheatreDetailPage.test.tsx +++ b/frontend/src/pages/theatres/TheatreDetailPage.test.tsx @@ -65,12 +65,11 @@ vi.mock ('@/components/PostEditForm', () => ({ default: () =>
Post edit form
, })) vi.mock ('framer-motion', () => ({ - motion: { - aside: ({ children }: { children?: ReactNode }) => , - div: ({ children }: { children?: ReactNode }) =>
{children}
, - main: ({ children }: { children?: ReactNode }) =>
{children}
, - }, -})) + useReducedMotion: () => false, + motion: { + aside: ({ children }: { children?: ReactNode }) => , + div: ({ children }: { children?: ReactNode }) =>
{children}
, + main: ({ children }: { children?: ReactNode }) =>
{children}
} })) const currentPost = buildPost ({ id: 10,