feat(notes): add note model and storage layer

This commit is contained in:
devcodetools committed 2026-09-13 15:19:27 +02:00
1 parent 51584886b3
commit c64c5d408c
3 files changed
+95

No files matched your search

+60
View File
@@ -0,0 +1,60 @@
import { beforeEach, describe, expect, it } from 'vitest'
import { loadNotes, saveNotes } from './notesStorage'
import type { Note } from '../types'
const STORAGE_KEY = 'notes'
describe('notesStorage', () => {
beforeEach(() => {
localStorage.clear()
})
it('loads an empty array when nothing is stored', () => {
expect(loadNotes()).toEqual([])
})
it('saves and loads notes', () => {
const notes: Note[] = [
{ id: 1, title: 'Courses', content: 'Lait, oeufs' },
{ id: 2, title: 'Pense-bête', content: 'Rappeler le plombier' },
]
saveNotes(notes)
expect(JSON.parse(localStorage.getItem(STORAGE_KEY)!)).toEqual(notes)
expect(loadNotes()).toEqual(notes)
})
it('returns an empty array when the stored JSON is invalid', () => {
localStorage.setItem(STORAGE_KEY, 'not json {')
expect(loadNotes()).toEqual([])
})
it('returns an empty array when the stored value is not an array', () => {
localStorage.setItem(STORAGE_KEY, JSON.stringify({ id: 1, title: 'x', content: 'y' }))
expect(loadNotes()).toEqual([])
})
it('filters out entries that do not match the Note shape', () => {
localStorage.setItem(
STORAGE_KEY,
JSON.stringify([
{ id: 1, title: 'ok', content: 'ok' },
{ id: '2', title: 'bad id', content: 'x' },
{ title: 'missing id', content: 'x' },
'nope',
]),
)
expect(loadNotes()).toEqual([{ id: 1, title: 'ok', content: 'ok' }])
})
it('overwrites previously stored notes', () => {
saveNotes([{ id: 1, title: 'A', content: 'a' }])
const updated: Note[] = [{ id: 2, title: 'B', content: 'b' }]
saveNotes(updated)
expect(loadNotes()).toEqual(updated)
})
})
+30
View File
@@ -0,0 +1,30 @@
import type { Note } from '../types'
const STORAGE_KEY = 'notes'
export function loadNotes(): Note[] {
const raw = localStorage.getItem(STORAGE_KEY)
if (raw === null) return []
try {
const parsed: unknown = JSON.parse(raw)
if (!Array.isArray(parsed)) return []
return parsed.filter(isNote)
} catch {
return []
}
}
export function saveNotes(notes: Note[]): void {
localStorage.setItem(STORAGE_KEY, JSON.stringify(notes))
}
function isNote(value: unknown): value is Note {
if (typeof value !== 'object' || value === null) return false
const candidate = value as Record<string, unknown>
return (
typeof candidate.id === 'number' &&
typeof candidate.title === 'string' &&
typeof candidate.content === 'string'
)
}
+5
View File
@@ -0,0 +1,5 @@
export interface Note {
id: number
title: string
content: string
}