Files
standardnotes-app-web/packages/models/src/Domain/Runtime/Display/ItemDisplayController.spec.ts

257 lines
8.0 KiB
TypeScript

import { CreateItemDelta } from './../Index/ItemDelta'
import { DeletedPayload } from './../../Abstract/Payload/Implementations/DeletedPayload'
import { createFile, createNote, createTagWithTitle, mockUuid, pinnedContent } from './../../Utilities/Test/SpecUtils'
import { ContentType } from '@standardnotes/common'
import { DeletedItem, EncryptedItem } from '../../Abstract/Item'
import { EncryptedPayload, PayloadTimestampDefaults } from '../../Abstract/Payload'
import { createNoteWithContent } from '../../Utilities/Test/SpecUtils'
import { ItemCollection } from './../Collection/Item/ItemCollection'
import { ItemDisplayController } from './ItemDisplayController'
import { SNNote } from '../../Syncable/Note'
describe('item display controller', () => {
it('should sort items', () => {
const collection = new ItemCollection()
const noteA = createNoteWithContent({ title: 'a' })
const noteB = createNoteWithContent({ title: 'b' })
collection.set([noteA, noteB])
const controller = new ItemDisplayController(collection, [ContentType.Note], {
sortBy: 'title',
sortDirection: 'asc',
})
expect(controller.items()[0]).toEqual(noteA)
expect(controller.items()[1]).toEqual(noteB)
controller.setDisplayOptions({ sortBy: 'title', sortDirection: 'dsc' })
expect(controller.items()[0]).toEqual(noteB)
expect(controller.items()[1]).toEqual(noteA)
})
it('should filter items', () => {
const collection = new ItemCollection()
const noteA = createNoteWithContent({ title: 'a' })
const noteB = createNoteWithContent({ title: 'b' })
collection.set([noteA, noteB])
const controller = new ItemDisplayController(collection, [ContentType.Note], {
sortBy: 'title',
sortDirection: 'asc',
})
controller.setDisplayOptions({
customFilter: (note) => {
return note.title !== 'a'
},
})
expect(controller.items()).toHaveLength(1)
expect(controller.items()[0].title).toEqual('b')
})
it('should resort items after collection change', () => {
const collection = new ItemCollection()
const noteA = createNoteWithContent({ title: 'a' })
collection.set([noteA])
const controller = new ItemDisplayController(collection, [ContentType.Note], {
sortBy: 'title',
sortDirection: 'asc',
})
expect(controller.items()).toHaveLength(1)
const noteB = createNoteWithContent({ title: 'b' })
const delta = CreateItemDelta({ changed: [noteB] })
collection.onChange(delta)
controller.onCollectionChange(delta)
expect(controller.items()).toHaveLength(2)
})
it('should not display encrypted items', () => {
const collection = new ItemCollection()
const noteA = new EncryptedItem(
new EncryptedPayload({
uuid: mockUuid(),
content_type: ContentType.Note,
content: '004:...',
enc_item_key: '004:...',
items_key_id: mockUuid(),
errorDecrypting: true,
waitingForKey: false,
...PayloadTimestampDefaults(),
}),
)
collection.set([noteA])
const controller = new ItemDisplayController(collection, [ContentType.Note], {
sortBy: 'title',
sortDirection: 'asc',
})
expect(controller.items()).toHaveLength(0)
})
it('pinned items should come first', () => {
const collection = new ItemCollection()
const noteA = createNoteWithContent({ title: 'a' })
const noteB = createNoteWithContent({ title: 'b' })
collection.set([noteA, noteB])
const controller = new ItemDisplayController(collection, [ContentType.Note], {
sortBy: 'title',
sortDirection: 'asc',
})
expect(controller.items()[0]).toEqual(noteA)
expect(controller.items()[1]).toEqual(noteB)
expect(collection.all()).toHaveLength(2)
const pinnedNoteB = new SNNote(
noteB.payload.copy({
content: {
...noteB.content,
...pinnedContent(),
},
}),
)
expect(pinnedNoteB.pinned).toBeTruthy()
const delta = CreateItemDelta({ changed: [pinnedNoteB] })
collection.onChange(delta)
controller.onCollectionChange(delta)
expect(controller.items()[0]).toEqual(pinnedNoteB)
expect(controller.items()[1]).toEqual(noteA)
})
it('should not display deleted items', () => {
const collection = new ItemCollection()
const noteA = createNoteWithContent({ title: 'a' })
collection.set([noteA])
const controller = new ItemDisplayController(collection, [ContentType.Note], {
sortBy: 'title',
sortDirection: 'asc',
})
const deletedItem = new DeletedItem(
new DeletedPayload({
...noteA.payload,
content: undefined,
deleted: true,
}),
)
const delta = CreateItemDelta({ changed: [deletedItem] })
collection.onChange(delta)
controller.onCollectionChange(delta)
expect(controller.items()).toHaveLength(0)
})
it('discarding elements should remove from display', () => {
const collection = new ItemCollection()
const noteA = createNoteWithContent({ title: 'a' })
collection.set([noteA])
const controller = new ItemDisplayController(collection, [ContentType.Note], {
sortBy: 'title',
sortDirection: 'asc',
})
const delta = CreateItemDelta({ discarded: [noteA] as unknown as DeletedItem[] })
collection.onChange(delta)
controller.onCollectionChange(delta)
expect(controller.items()).toHaveLength(0)
})
it('should ignore items not matching content type on construction', () => {
const collection = new ItemCollection()
const note = createNoteWithContent({ title: 'a' })
const tag = createTagWithTitle()
collection.set([note, tag])
const controller = new ItemDisplayController(collection, [ContentType.Note], {
sortBy: 'title',
sortDirection: 'asc',
})
expect(controller.items()).toHaveLength(1)
})
it('should ignore items not matching content type on sort change', () => {
const collection = new ItemCollection()
const note = createNoteWithContent({ title: 'a' })
const tag = createTagWithTitle()
collection.set([note, tag])
const controller = new ItemDisplayController(collection, [ContentType.Note], {
sortBy: 'title',
sortDirection: 'asc',
})
controller.setDisplayOptions({ sortBy: 'created_at', sortDirection: 'asc' })
expect(controller.items()).toHaveLength(1)
})
it('should ignore collection deltas with items not matching content types', () => {
const collection = new ItemCollection()
const note = createNoteWithContent({ title: 'a' })
collection.set([note])
const controller = new ItemDisplayController(collection, [ContentType.Note], {
sortBy: 'title',
sortDirection: 'asc',
})
const tag = createTagWithTitle()
const delta = CreateItemDelta({ inserted: [tag], changed: [note] })
collection.onChange(delta)
controller.onCollectionChange(delta)
expect(controller.items()).toHaveLength(1)
})
it('should display compound item types', () => {
const collection = new ItemCollection()
const note = createNoteWithContent({ title: 'Z' })
const file = createFile('A')
collection.set([note, file])
const controller = new ItemDisplayController(collection, [ContentType.Note, ContentType.File], {
sortBy: 'title',
sortDirection: 'asc',
})
expect(controller.items()[0]).toEqual(file)
expect(controller.items()[1]).toEqual(note)
controller.setDisplayOptions({ sortBy: 'title', sortDirection: 'dsc' })
expect(controller.items()[0]).toEqual(note)
expect(controller.items()[1]).toEqual(file)
})
it('should hide hidden types', () => {
const collection = new ItemCollection()
const note = createNote()
const file = createFile()
collection.set([note, file])
const controller = new ItemDisplayController(collection, [ContentType.Note, ContentType.File], {
sortBy: 'title',
sortDirection: 'asc',
})
expect(controller.items()).toHaveLength(2)
controller.setDisplayOptions({ hiddenContentTypes: [ContentType.File] })
expect(controller.items()).toHaveLength(1)
})
})