fix: unify theme system - fix theme switching persistence
- Unified localStorage key to 'theme-preference' across all components
- Fixed header.tsx using wrong localStorage key ('theme' instead of 'theme-preference')
- Added localStorage hybrid persistence for instant theme changes
- Removed router.refresh() which was causing stale data revert
- Replaced Blue theme with Sepia
- Consolidated auth() calls to prevent race conditions
- Updated UserSettingsData types to include all themes
This commit is contained in:
721
keep-notes/tests/migration/integrity.test.ts
Normal file
721
keep-notes/tests/migration/integrity.test.ts
Normal file
@@ -0,0 +1,721 @@
|
||||
/**
|
||||
* Data Integrity Tests
|
||||
* Validates that data is preserved and not corrupted during migration
|
||||
* Tests data loss prevention, foreign key relationships, and indexes
|
||||
*/
|
||||
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
import {
|
||||
setupTestEnvironment,
|
||||
createTestPrismaClient,
|
||||
initializeTestDatabase,
|
||||
cleanupTestDatabase,
|
||||
createSampleNotes,
|
||||
verifyDataIntegrity
|
||||
} from './setup'
|
||||
|
||||
describe('Data Integrity Tests', () => {
|
||||
let prisma: PrismaClient
|
||||
|
||||
beforeAll(async () => {
|
||||
await setupTestEnvironment()
|
||||
prisma = createTestPrismaClient()
|
||||
await initializeTestDatabase(prisma)
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await cleanupTestDatabase(prisma)
|
||||
})
|
||||
|
||||
describe('No Data Loss', () => {
|
||||
test('should preserve all notes after migration', async () => {
|
||||
// Create test notes
|
||||
const initialNotes = await createSampleNotes(prisma, 50)
|
||||
const initialCount = initialNotes.length
|
||||
|
||||
// Query after migration
|
||||
const notesAfterMigration = await prisma.note.findMany()
|
||||
const finalCount = notesAfterMigration.length
|
||||
|
||||
// Verify no data loss
|
||||
expect(finalCount).toBe(initialCount)
|
||||
})
|
||||
|
||||
test('should preserve note titles', async () => {
|
||||
const testTitles = [
|
||||
'Important Meeting Notes',
|
||||
'Shopping List',
|
||||
'Project Ideas',
|
||||
'Recipe Collection',
|
||||
'Book Reviews'
|
||||
]
|
||||
|
||||
// Create notes with specific titles
|
||||
for (const title of testTitles) {
|
||||
await prisma.note.create({
|
||||
data: {
|
||||
title,
|
||||
content: `Content for ${title}`,
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Verify all titles are preserved
|
||||
const notes = await prisma.note.findMany({
|
||||
where: { title: { in: testTitles } }
|
||||
})
|
||||
|
||||
const preservedTitles = notes.map(n => n.title)
|
||||
for (const title of testTitles) {
|
||||
expect(preservedTitles).toContain(title)
|
||||
}
|
||||
})
|
||||
|
||||
test('should preserve note content', async () => {
|
||||
const testContent = [
|
||||
'This is a simple text note',
|
||||
'Note with **markdown** formatting',
|
||||
'Note with [links](https://example.com)',
|
||||
'Note with numbers: 1, 2, 3, 4, 5',
|
||||
'Note with special characters: émojis 🎉 & çharacters'
|
||||
]
|
||||
|
||||
// Create notes with specific content
|
||||
for (const content of testContent) {
|
||||
await prisma.note.create({
|
||||
data: {
|
||||
title: `Content Test`,
|
||||
content,
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Verify all content is preserved
|
||||
const notes = await prisma.note.findMany({
|
||||
where: { title: 'Content Test' }
|
||||
})
|
||||
|
||||
const preservedContent = notes.map(n => n.content)
|
||||
for (const content of testContent) {
|
||||
expect(preservedContent).toContain(content)
|
||||
}
|
||||
})
|
||||
|
||||
test('should preserve note metadata', async () => {
|
||||
// Create note with all metadata
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Metadata Test Note',
|
||||
content: 'Test content',
|
||||
color: 'red',
|
||||
isPinned: true,
|
||||
isArchived: false,
|
||||
type: 'text',
|
||||
size: 'large',
|
||||
userId: 'test-user-id',
|
||||
order: 5
|
||||
}
|
||||
})
|
||||
|
||||
// Verify metadata is preserved
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.color).toBe('red')
|
||||
expect(retrieved?.isPinned).toBe(true)
|
||||
expect(retrieved?.isArchived).toBe(false)
|
||||
expect(retrieved?.type).toBe('text')
|
||||
expect(retrieved?.size).toBe('large')
|
||||
expect(retrieved?.order).toBe(5)
|
||||
})
|
||||
})
|
||||
|
||||
describe('No Data Corruption', () => {
|
||||
test('should preserve checkItems JSON structure', async () => {
|
||||
const checkItems = JSON.stringify([
|
||||
{ text: 'Buy groceries', done: false },
|
||||
{ text: 'Call dentist', done: true },
|
||||
{ text: 'Finish report', done: false },
|
||||
{ text: 'Schedule meeting', done: false }
|
||||
])
|
||||
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Checklist Test Note',
|
||||
content: 'My checklist',
|
||||
checkItems,
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
// Verify checkItems are preserved and can be parsed
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.checkItems).toBeDefined()
|
||||
|
||||
const parsedCheckItems = JSON.parse(retrieved?.checkItems || '[]')
|
||||
expect(parsedCheckItems.length).toBe(4)
|
||||
expect(parsedCheckItems[0].text).toBe('Buy groceries')
|
||||
expect(parsedCheckItems[0].done).toBe(false)
|
||||
expect(parsedCheckItems[1].done).toBe(true)
|
||||
})
|
||||
|
||||
test('should preserve images JSON structure', async () => {
|
||||
const images = JSON.stringify([
|
||||
{ url: 'image1.jpg', caption: 'First image' },
|
||||
{ url: 'image2.jpg', caption: 'Second image' },
|
||||
{ url: 'image3.jpg', caption: 'Third image' }
|
||||
])
|
||||
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Images Test Note',
|
||||
content: 'Note with images',
|
||||
images,
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
// Verify images are preserved and can be parsed
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.images).toBeDefined()
|
||||
|
||||
const parsedImages = JSON.parse(retrieved?.images || '[]')
|
||||
expect(parsedImages.length).toBe(3)
|
||||
expect(parsedImages[0].url).toBe('image1.jpg')
|
||||
expect(parsedImages[0].caption).toBe('First image')
|
||||
})
|
||||
|
||||
test('should preserve labels JSON structure', async () => {
|
||||
const labels = JSON.stringify(['work', 'important', 'project'])
|
||||
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Labels Test Note',
|
||||
content: 'Note with labels',
|
||||
labels,
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
// Verify labels are preserved and can be parsed
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.labels).toBeDefined()
|
||||
|
||||
const parsedLabels = JSON.parse(retrieved?.labels || '[]')
|
||||
expect(parsedLabels.length).toBe(3)
|
||||
expect(parsedLabels).toContain('work')
|
||||
expect(parsedLabels).toContain('important')
|
||||
expect(parsedLabels).toContain('project')
|
||||
})
|
||||
|
||||
test('should preserve embedding JSON structure', async () => {
|
||||
const embedding = JSON.stringify({
|
||||
vector: [0.1, 0.2, 0.3, 0.4, 0.5],
|
||||
model: 'text-embedding-ada-002',
|
||||
timestamp: new Date().toISOString()
|
||||
})
|
||||
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Embedding Test Note',
|
||||
content: 'Note with embedding',
|
||||
embedding,
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
// Verify embedding is preserved and can be parsed
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.embedding).toBeDefined()
|
||||
|
||||
const parsedEmbedding = JSON.parse(retrieved?.embedding || '{}')
|
||||
expect(parsedEmbedding.vector).toEqual([0.1, 0.2, 0.3, 0.4, 0.5])
|
||||
expect(parsedEmbedding.model).toBe('text-embedding-ada-002')
|
||||
})
|
||||
|
||||
test('should preserve links JSON structure', async () => {
|
||||
const links = JSON.stringify([
|
||||
{ url: 'https://example.com', title: 'Example' },
|
||||
{ url: 'https://docs.example.com', title: 'Documentation' }
|
||||
])
|
||||
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Links Test Note',
|
||||
content: 'Note with links',
|
||||
links,
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
// Verify links are preserved and can be parsed
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.links).toBeDefined()
|
||||
|
||||
const parsedLinks = JSON.parse(retrieved?.links || '[]')
|
||||
expect(parsedLinks.length).toBe(2)
|
||||
expect(parsedLinks[0].url).toBe('https://example.com')
|
||||
expect(parsedLinks[0].title).toBe('Example')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Foreign Key Relationships', () => {
|
||||
test('should maintain Note to User relationship', async () => {
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
email: 'fk-integrity@test.com',
|
||||
name: 'FK Integrity User'
|
||||
}
|
||||
})
|
||||
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'User Integrity Note',
|
||||
content: 'Test content',
|
||||
userId: user.id
|
||||
}
|
||||
})
|
||||
|
||||
// Verify relationship is maintained
|
||||
expect(note.userId).toBe(user.id)
|
||||
|
||||
// Query user's notes
|
||||
const userNotes = await prisma.note.findMany({
|
||||
where: { userId: user.id }
|
||||
})
|
||||
|
||||
expect(userNotes.length).toBeGreaterThan(0)
|
||||
expect(userNotes.some(n => n.id === note.id)).toBe(true)
|
||||
})
|
||||
|
||||
test('should maintain Note to Notebook relationship', async () => {
|
||||
const notebook = await prisma.notebook.create({
|
||||
data: {
|
||||
name: 'Integrity Notebook',
|
||||
order: 0,
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Notebook Integrity Note',
|
||||
content: 'Test content',
|
||||
userId: 'test-user-id',
|
||||
notebookId: notebook.id
|
||||
}
|
||||
})
|
||||
|
||||
// Verify relationship is maintained
|
||||
expect(note.notebookId).toBe(notebook.id)
|
||||
|
||||
// Query notebook's notes
|
||||
const notebookNotes = await prisma.note.findMany({
|
||||
where: { notebookId: notebook.id }
|
||||
})
|
||||
|
||||
expect(notebookNotes.length).toBeGreaterThan(0)
|
||||
expect(notebookNotes.some(n => n.id === note.id)).toBe(true)
|
||||
})
|
||||
|
||||
test('should maintain AiFeedback to Note relationship', async () => {
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Feedback Integrity Note',
|
||||
content: 'Test content',
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
const feedback = await prisma.aiFeedback.create({
|
||||
data: {
|
||||
noteId: note.id,
|
||||
userId: 'test-user-id',
|
||||
feedbackType: 'thumbs_up',
|
||||
feature: 'title_suggestion',
|
||||
originalContent: 'Test feedback'
|
||||
}
|
||||
})
|
||||
|
||||
// Verify relationship is maintained
|
||||
expect(feedback.noteId).toBe(note.id)
|
||||
|
||||
// Query note's feedback
|
||||
const noteFeedback = await prisma.aiFeedback.findMany({
|
||||
where: { noteId: note.id }
|
||||
})
|
||||
|
||||
expect(noteFeedback.length).toBeGreaterThan(0)
|
||||
expect(noteFeedback.some(f => f.id === feedback.id)).toBe(true)
|
||||
})
|
||||
|
||||
test('should maintain AiFeedback to User relationship', async () => {
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
email: 'feedback-user@test.com',
|
||||
name: 'Feedback User'
|
||||
}
|
||||
})
|
||||
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'User Feedback Note',
|
||||
content: 'Test content',
|
||||
userId: user.id
|
||||
}
|
||||
})
|
||||
|
||||
const feedback = await prisma.aiFeedback.create({
|
||||
data: {
|
||||
noteId: note.id,
|
||||
userId: user.id,
|
||||
feedbackType: 'thumbs_up',
|
||||
feature: 'title_suggestion',
|
||||
originalContent: 'Test feedback'
|
||||
}
|
||||
})
|
||||
|
||||
// Verify relationship is maintained
|
||||
expect(feedback.userId).toBe(user.id)
|
||||
|
||||
// Query user's feedback
|
||||
const userFeedback = await prisma.aiFeedback.findMany({
|
||||
where: { userId: user.id }
|
||||
})
|
||||
|
||||
expect(userFeedback.length).toBeGreaterThan(0)
|
||||
expect(userFeedback.some(f => f.id === feedback.id)).toBe(true)
|
||||
})
|
||||
|
||||
test('should maintain cascade delete correctly', async () => {
|
||||
// Create a note with feedback
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Cascade Delete Note',
|
||||
content: 'Test content',
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
const feedback = await prisma.aiFeedback.create({
|
||||
data: {
|
||||
noteId: note.id,
|
||||
userId: 'test-user-id',
|
||||
feedbackType: 'thumbs_up',
|
||||
feature: 'title_suggestion',
|
||||
originalContent: 'Test feedback'
|
||||
}
|
||||
})
|
||||
|
||||
// Verify feedback exists
|
||||
const feedbacksBefore = await prisma.aiFeedback.findMany({
|
||||
where: { noteId: note.id }
|
||||
})
|
||||
expect(feedbacksBefore.length).toBe(1)
|
||||
|
||||
// Delete note
|
||||
await prisma.note.delete({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
// Verify feedback is cascade deleted
|
||||
const feedbacksAfter = await prisma.aiFeedback.findMany({
|
||||
where: { noteId: note.id }
|
||||
})
|
||||
expect(feedbacksAfter.length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Index Integrity', () => {
|
||||
test('should maintain index on Note.isPinned', async () => {
|
||||
// Create notes with various pinned states
|
||||
await prisma.note.createMany({
|
||||
data: [
|
||||
{ title: 'Pinned 1', content: 'Content 1', userId: 'test-user-id', isPinned: true },
|
||||
{ title: 'Not Pinned 1', content: 'Content 2', userId: 'test-user-id', isPinned: false },
|
||||
{ title: 'Pinned 2', content: 'Content 3', userId: 'test-user-id', isPinned: true },
|
||||
{ title: 'Not Pinned 2', content: 'Content 4', userId: 'test-user-id', isPinned: false }
|
||||
]
|
||||
})
|
||||
|
||||
// Query by isPinned (should use index)
|
||||
const pinnedNotes = await prisma.note.findMany({
|
||||
where: { isPinned: true }
|
||||
})
|
||||
|
||||
expect(pinnedNotes.length).toBe(2)
|
||||
expect(pinnedNotes.every(n => n.isPinned === true)).toBe(true)
|
||||
})
|
||||
|
||||
test('should maintain index on Note.order', async () => {
|
||||
// Create notes with specific order
|
||||
await prisma.note.createMany({
|
||||
data: [
|
||||
{ title: 'Order 0', content: 'Content 0', userId: 'test-user-id', order: 0 },
|
||||
{ title: 'Order 1', content: 'Content 1', userId: 'test-user-id', order: 1 },
|
||||
{ title: 'Order 2', content: 'Content 2', userId: 'test-user-id', order: 2 },
|
||||
{ title: 'Order 3', content: 'Content 3', userId: 'test-user-id', order: 3 }
|
||||
]
|
||||
})
|
||||
|
||||
// Query ordered by order (should use index)
|
||||
const orderedNotes = await prisma.note.findMany({
|
||||
orderBy: { order: 'asc' }
|
||||
})
|
||||
|
||||
expect(orderedNotes[0].order).toBe(0)
|
||||
expect(orderedNotes[1].order).toBe(1)
|
||||
expect(orderedNotes[2].order).toBe(2)
|
||||
expect(orderedNotes[3].order).toBe(3)
|
||||
})
|
||||
|
||||
test('should maintain index on AiFeedback.noteId', async () => {
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Index Feedback Note',
|
||||
content: 'Test content',
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
// Create multiple feedback entries
|
||||
await prisma.aiFeedback.createMany({
|
||||
data: [
|
||||
{ noteId: note.id, userId: 'test-user-id', feedbackType: 'thumbs_up', feature: 'title_suggestion', originalContent: 'Feedback 1' },
|
||||
{ noteId: note.id, userId: 'test-user-id', feedbackType: 'thumbs_down', feature: 'semantic_search', originalContent: 'Feedback 2' },
|
||||
{ noteId: note.id, userId: 'test-user-id', feedbackType: 'thumbs_up', feature: 'paragraph_refactor', originalContent: 'Feedback 3' }
|
||||
]
|
||||
})
|
||||
|
||||
// Query by noteId (should use index)
|
||||
const feedbacks = await prisma.aiFeedback.findMany({
|
||||
where: { noteId: note.id }
|
||||
})
|
||||
|
||||
expect(feedbacks.length).toBe(3)
|
||||
})
|
||||
|
||||
test('should maintain index on AiFeedback.userId', async () => {
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'User Index Feedback Note',
|
||||
content: 'Test content',
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
// Create multiple feedback entries for same user
|
||||
await prisma.aiFeedback.createMany({
|
||||
data: [
|
||||
{ noteId: note.id, userId: 'test-user-id', feedbackType: 'thumbs_up', feature: 'title_suggestion', originalContent: 'Feedback 1' },
|
||||
{ noteId: note.id, userId: 'test-user-id', feedbackType: 'thumbs_down', feature: 'semantic_search', originalContent: 'Feedback 2' }
|
||||
]
|
||||
})
|
||||
|
||||
// Query by userId (should use index)
|
||||
const userFeedbacks = await prisma.aiFeedback.findMany({
|
||||
where: { userId: 'test-user-id' }
|
||||
})
|
||||
|
||||
expect(userFeedbacks.length).toBeGreaterThanOrEqual(2)
|
||||
})
|
||||
|
||||
test('should maintain index on AiFeedback.feature', async () => {
|
||||
const note1 = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Feature Index Note 1',
|
||||
content: 'Test content 1',
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
const note2 = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Feature Index Note 2',
|
||||
content: 'Test content 2',
|
||||
userId: 'test-user-id'
|
||||
}
|
||||
})
|
||||
|
||||
// Create feedback with same feature
|
||||
await prisma.aiFeedback.createMany({
|
||||
data: [
|
||||
{ noteId: note1.id, userId: 'test-user-id', feedbackType: 'thumbs_up', feature: 'title_suggestion', originalContent: 'Feedback 1' },
|
||||
{ noteId: note2.id, userId: 'test-user-id', feedbackType: 'thumbs_up', feature: 'title_suggestion', originalContent: 'Feedback 2' }
|
||||
]
|
||||
})
|
||||
|
||||
// Query by feature (should use index)
|
||||
const titleFeedbacks = await prisma.aiFeedback.findMany({
|
||||
where: { feature: 'title_suggestion' }
|
||||
})
|
||||
|
||||
expect(titleFeedbacks.length).toBeGreaterThanOrEqual(2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('AI Fields Integrity', () => {
|
||||
test('should preserve AI fields correctly', async () => {
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'AI Fields Integrity Note',
|
||||
content: 'Test content',
|
||||
userId: 'test-user-id',
|
||||
autoGenerated: true,
|
||||
aiProvider: 'openai',
|
||||
aiConfidence: 95,
|
||||
language: 'en',
|
||||
languageConfidence: 0.98,
|
||||
lastAiAnalysis: new Date()
|
||||
}
|
||||
})
|
||||
|
||||
// Verify all AI fields are preserved
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.autoGenerated).toBe(true)
|
||||
expect(retrieved?.aiProvider).toBe('openai')
|
||||
expect(retrieved?.aiConfidence).toBe(95)
|
||||
expect(retrieved?.language).toBe('en')
|
||||
expect(retrieved?.languageConfidence).toBeCloseTo(0.98)
|
||||
expect(retrieved?.lastAiAnalysis).toBeDefined()
|
||||
})
|
||||
|
||||
test('should preserve null AI fields correctly', async () => {
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Null AI Fields Note',
|
||||
content: 'Test content',
|
||||
userId: 'test-user-id'
|
||||
// All AI fields are null by default
|
||||
}
|
||||
})
|
||||
|
||||
// Verify all AI fields are null
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.autoGenerated).toBeNull()
|
||||
expect(retrieved?.aiProvider).toBeNull()
|
||||
expect(retrieved?.aiConfidence).toBeNull()
|
||||
expect(retrieved?.language).toBeNull()
|
||||
expect(retrieved?.languageConfidence).toBeNull()
|
||||
expect(retrieved?.lastAiAnalysis).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Batch Operations Integrity', () => {
|
||||
test('should preserve data integrity during batch insert', async () => {
|
||||
const notesData = Array.from({ length: 50 }, (_, i) => ({
|
||||
title: `Batch Integrity Note ${i}`,
|
||||
content: `Content ${i}`,
|
||||
userId: 'test-user-id',
|
||||
order: i,
|
||||
isPinned: i % 2 === 0
|
||||
}))
|
||||
|
||||
const result = await prisma.note.createMany({
|
||||
data: notesData
|
||||
})
|
||||
|
||||
expect(result.count).toBe(50)
|
||||
|
||||
// Verify all notes are created correctly
|
||||
const notes = await prisma.note.findMany({
|
||||
where: { title: { contains: 'Batch Integrity Note' } }
|
||||
})
|
||||
|
||||
expect(notes.length).toBe(50)
|
||||
|
||||
// Verify data integrity
|
||||
for (const note of notes) {
|
||||
expect(note.content).toBeDefined()
|
||||
expect(note.userId).toBe('test-user-id')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('Data Type Integrity', () => {
|
||||
test('should preserve boolean values correctly', async () => {
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Boolean Test Note',
|
||||
content: 'Test content',
|
||||
userId: 'test-user-id',
|
||||
isPinned: true,
|
||||
isArchived: false
|
||||
}
|
||||
})
|
||||
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.isPinned).toBe(true)
|
||||
expect(retrieved?.isArchived).toBe(false)
|
||||
})
|
||||
|
||||
test('should preserve numeric values correctly', async () => {
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Numeric Test Note',
|
||||
content: 'Test content',
|
||||
userId: 'test-user-id',
|
||||
order: 42,
|
||||
aiConfidence: 87,
|
||||
languageConfidence: 0.95
|
||||
}
|
||||
})
|
||||
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.order).toBe(42)
|
||||
expect(retrieved?.aiConfidence).toBe(87)
|
||||
expect(retrieved?.languageConfidence).toBeCloseTo(0.95)
|
||||
})
|
||||
|
||||
test('should preserve date values correctly', async () => {
|
||||
const testDate = new Date('2024-01-15T10:30:00Z')
|
||||
|
||||
const note = await prisma.note.create({
|
||||
data: {
|
||||
title: 'Date Test Note',
|
||||
content: 'Test content',
|
||||
userId: 'test-user-id',
|
||||
reminder: testDate,
|
||||
lastAiAnalysis: testDate
|
||||
}
|
||||
})
|
||||
|
||||
const retrieved = await prisma.note.findUnique({
|
||||
where: { id: note.id }
|
||||
})
|
||||
|
||||
expect(retrieved?.reminder).toBeDefined()
|
||||
expect(retrieved?.lastAiAnalysis).toBeDefined()
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user