このコミットが含まれているのは:
@@ -0,0 +1,114 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { cleanupExpiredPostImportSessions,
|
||||
clearPostImportSourceDraft,
|
||||
loadPostImportSession,
|
||||
loadPostImportSourceDraft,
|
||||
savePostImportSession,
|
||||
savePostImportSourceDraft } from '@/lib/postImportSession'
|
||||
import { buildPostImportRow } from '@/test/postImportFactories'
|
||||
|
||||
describe ('post import storage', () => {
|
||||
beforeEach (() => {
|
||||
sessionStorage.clear ()
|
||||
vi.useRealTimers ()
|
||||
})
|
||||
|
||||
it ('round-trips a valid session and source draft', () => {
|
||||
const row = buildPostImportRow ({
|
||||
importStatus: 'skipped',
|
||||
skipReason: 'existing',
|
||||
existingPostId: 10 })
|
||||
|
||||
expect (savePostImportSession ('session', {
|
||||
source: row.url,
|
||||
rows: [row],
|
||||
repairMode: 'all' })).toBe (true)
|
||||
expect (loadPostImportSession ('session')).toMatchObject ({
|
||||
version: 2,
|
||||
source: row.url,
|
||||
rows: [{
|
||||
importStatus: 'skipped',
|
||||
skipReason: 'existing',
|
||||
existingPostId: 10 }] })
|
||||
|
||||
expect (savePostImportSourceDraft ('https://example.com')).toBe (true)
|
||||
expect (loadPostImportSourceDraft ()).toEqual ({ source: 'https://example.com' })
|
||||
clearPostImportSourceDraft ()
|
||||
expect (loadPostImportSourceDraft ()).toEqual ({ source: '' })
|
||||
})
|
||||
|
||||
it ('rejects inconsistent post IDs and terminal statuses', () => {
|
||||
const session = {
|
||||
version: 2,
|
||||
savedAt: new Date ().toISOString (),
|
||||
source: '',
|
||||
repairMode: 'all',
|
||||
rows: [buildPostImportRow ()] }
|
||||
const invalidRows = [
|
||||
{ ...session.rows[0], skipReason: 'existing', existingPostId: undefined },
|
||||
{ ...session.rows[0], existingPostId: 2, skipReason: undefined },
|
||||
{ ...session.rows[0], importStatus: 'created', createdPostId: undefined },
|
||||
{ ...session.rows[0], importStatus: 'failed', createdPostId: 3 }]
|
||||
|
||||
for (const [index, row] of invalidRows.entries ())
|
||||
{
|
||||
sessionStorage.setItem (`post-import-session:invalid-${ index }`, JSON.stringify ({
|
||||
...session,
|
||||
rows: [row] }))
|
||||
expect (loadPostImportSession (`invalid-${ index }`)).toBeNull ()
|
||||
}
|
||||
})
|
||||
|
||||
it ('rejects invalid attribute, provenance, tag-source, and snapshot data', () => {
|
||||
const row = buildPostImportRow ()
|
||||
const invalidRows = [
|
||||
{ ...row, attributes: { title: [] } },
|
||||
{ ...row, attributes: { unknown: 'value' } },
|
||||
{ ...row, provenance: { title: 'mapped' } },
|
||||
{ ...row, tagSources: { mapped: 'tag' } },
|
||||
{ ...row, resetSnapshot: { ...row.resetSnapshot,
|
||||
fieldWarnings: { title: 'warning' } } }]
|
||||
|
||||
invalidRows.forEach ((invalidRow, index) => {
|
||||
sessionStorage.setItem (`post-import-session:shape-${ index }`, JSON.stringify ({
|
||||
version: 2,
|
||||
savedAt: new Date ().toISOString (),
|
||||
source: '',
|
||||
rows: [invalidRow],
|
||||
repairMode: 'all' }))
|
||||
expect (loadPostImportSession (`shape-${ index }`)).toBeNull ()
|
||||
})
|
||||
})
|
||||
|
||||
it ('removes expired and malformed sessions without touching current sessions', () => {
|
||||
const current = {
|
||||
version: 2,
|
||||
savedAt: new Date ().toISOString (),
|
||||
source: '',
|
||||
rows: [buildPostImportRow ()],
|
||||
repairMode: 'all' }
|
||||
const expired = {
|
||||
...current,
|
||||
savedAt: new Date (Date.now () - 25 * 60 * 60 * 1000).toISOString () }
|
||||
sessionStorage.setItem ('post-import-session:current', JSON.stringify (current))
|
||||
sessionStorage.setItem ('post-import-session:expired', JSON.stringify (expired))
|
||||
sessionStorage.setItem ('post-import-session:malformed', '{')
|
||||
|
||||
cleanupExpiredPostImportSessions ()
|
||||
|
||||
expect (sessionStorage.getItem ('post-import-session:current')).not.toBeNull ()
|
||||
expect (sessionStorage.getItem ('post-import-session:expired')).toBeNull ()
|
||||
expect (sessionStorage.getItem ('post-import-session:malformed')).toBeNull ()
|
||||
})
|
||||
|
||||
it ('reports storage access failures without throwing', () => {
|
||||
const onError = vi.fn ()
|
||||
vi.spyOn (Storage.prototype, 'setItem').mockImplementation (() => {
|
||||
throw new DOMException ('quota')
|
||||
})
|
||||
|
||||
expect (savePostImportSourceDraft ('source', onError)).toBe (false)
|
||||
expect (onError).toHaveBeenCalledWith ('ブラウザへ保存できませんでした.')
|
||||
})
|
||||
})
|
||||
新しい課題から参照
ユーザをブロックする