Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 95 additions & 4 deletions src/lib/db/store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ describe('DbStore', () => {
})

describe('#removeFolder', () => {
it('removes a folder and its notes', async () => {
it('removes a folder', async () => {
// Given
const { result } = prepareDbStore()
let storage: NoteStorage
Expand All @@ -177,10 +177,9 @@ describe('DbStore', () => {
expect(result.current.storageMap[storage!.id]!.folderMap).toEqual({
'/': expect.objectContaining({ pathname: '/' })
})
// TODO: check note deletion too.
})

it('removes its child folders', async () => {
it('removes its sub folders', async () => {
// Given
const { result } = prepareDbStore()
let storage: NoteStorage
Expand All @@ -199,7 +198,99 @@ describe('DbStore', () => {
})
})

// TODO: routing test when current folder or current folder's parent folder is deleted.
it('trashes child notes of target folder', async () => {
// Given
const { result } = prepareDbStore()
let storage: NoteStorage
let note: NoteDoc | undefined
await act(async () => {
await result.current.initialize()
storage = await result.current.createStorage('test')
await result.current.createFolder(storage.id, '/test')
note = await result.current.createNote(storage.id, {
folderPathname: '/test'
})

// When
await result.current.removeFolder(storage.id, '/test')
})

// Then
expect(
result.current.storageMap[storage!.id]!.noteMap[note!._id]!.trashed
).toEqual(true)
})

it('trashes child notes of sub folders', async () => {
// Given
const { result } = prepareDbStore()
let storage: NoteStorage
let note: NoteDoc | undefined
await act(async () => {
await result.current.initialize()
storage = await result.current.createStorage('test')
await result.current.createFolder(storage.id, '/test/childfolder')
note = await result.current.createNote(storage.id, {
folderPathname: '/test/childfolder'
})

// When
await result.current.removeFolder(storage.id, '/test')
})

// Then
expect(
result.current.storageMap[storage!.id]!.noteMap[note!._id]!.trashed
).toEqual(true)
})

it('updates tag map from child notes of target folder', async () => {
// Given
const { result } = prepareDbStore()
let storage: NoteStorage
await act(async () => {
await result.current.initialize()
storage = await result.current.createStorage('test')
await result.current.createFolder(storage.id, '/test')
await result.current.createNote(storage.id, {
folderPathname: '/test',
tags: ['tagTest']
})

// When
await result.current.removeFolder(storage.id, '/test')
})

// Then
expect(
result.current.storageMap[storage!.id]!.tagMap['tagTest']!.noteIdSet
.size
).toEqual(0)
})

it('updates tag map from child notes of sub folders', async () => {
// Given
const { result } = prepareDbStore()
let storage: NoteStorage
await act(async () => {
await result.current.initialize()
storage = await result.current.createStorage('test')
await result.current.createFolder(storage.id, '/test/childfolder')
await result.current.createNote(storage.id, {
folderPathname: '/test/childfolder',
tags: ['tagTest']
})

// When
await result.current.removeFolder(storage.id, '/test')
})

// Then
expect(
result.current.storageMap[storage!.id]!.tagMap['tagTest']!.noteIdSet
.size
).toEqual(0)
})
})

describe('#createNote', () => {
Expand Down
48 changes: 47 additions & 1 deletion src/lib/db/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,58 @@ export function createDbStoreCreator(
aPathname.startsWith(`${pathname}/`)
)
]
// TODO: Reflect deleted notes

const noteIds = Object.keys(storage.noteMap)
const affectedTagIdAndNotesIdMap = new Map<string, string[]>()
const modifiedNotes: ObjectMap<NoteDoc> = noteIds.reduce(
(acc, noteId) => {
const note = { ...storage.noteMap[noteId]! }
if (deletedFolderPathnames.includes(note.folderPathname)) {
note.tags.forEach(tag => {
if (affectedTagIdAndNotesIdMap.has(tag)) {
affectedTagIdAndNotesIdMap.get(tag)!.push(noteId)
} else {
affectedTagIdAndNotesIdMap.set(tag, [noteId])
}
})

note.trashed = true
acc[noteId] = note
}
return acc
},
{}
)

const modifiedTags: ObjectMap<PopulatedTagDoc> = [
...affectedTagIdAndNotesIdMap
].reduce((acc, val) => {
const tag = val[0]
const noteIds = val[1]
const newNoteIdSet = new Set(storage.tagMap[tag]!.noteIdSet)
noteIds.forEach(noteId => {
newNoteIdSet.delete(noteId)
})
acc[tag] = {
...storage.tagMap[tag]!,
noteIdSet: newNoteIdSet
}
return acc
}, {})

setStorageMap(
produce((draft: ObjectMap<NoteStorage>) => {
deletedFolderPathnames.forEach(aPathname => {
delete draft[id]!.folderMap[aPathname]
})
draft[id]!.noteMap = {
...draft[id]!.noteMap,
...modifiedNotes
}
draft[id]!.tagMap = {
...draft[id]!.tagMap,
...modifiedTags
}
})
)
},
Expand Down