UNPKG

zotero-ts-api

Version:
276 lines 12.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const Item_1 = require("./Item"); const ZCreator_1 = require("./ZCreator"); const ZTag_1 = require("./ZTag"); (0, vitest_1.describe)('Item', () => { let item; let mockItemData; (0, vitest_1.beforeEach)(() => { mockItemData = { key: 'TESTITEM123', version: 1, title: 'Test Article', itemType: 'journalArticle', creators: [ { creatorType: 'author', firstName: 'John', lastName: 'Doe' } ], tags: [ { tag: 'science' } ], collections: ['COLLECTION123'], url: 'https://example.com', abstractNote: 'Test abstract', date: '2023-01-15', language: 'en', relations: {}, }; item = new Item_1.Item(mockItemData, 'test-api-key', 'user123', 'users'); }); (0, vitest_1.describe)('Constructor', () => { (0, vitest_1.it)('should create item with valid data', () => { (0, vitest_1.expect)(item.key).toBe('TESTITEM123'); (0, vitest_1.expect)(item.title).toBe('Test Article'); (0, vitest_1.expect)(item.itemType).toBe('journalArticle'); }); (0, vitest_1.it)('should create defensive copy of data', () => { const originalData = { ...mockItemData }; const testItem = new Item_1.Item(mockItemData, 'api-key', 'user', 'users'); mockItemData.title = 'Modified Title'; (0, vitest_1.expect)(testItem.title).toBe(originalData.title); }); }); (0, vitest_1.describe)('Getters', () => { (0, vitest_1.it)('should return correct key', () => { (0, vitest_1.expect)(item.key).toBe('TESTITEM123'); }); (0, vitest_1.it)('should return correct title', () => { (0, vitest_1.expect)(item.title).toBe('Test Article'); }); (0, vitest_1.it)('should return correct itemType', () => { (0, vitest_1.expect)(item.itemType).toBe('journalArticle'); }); (0, vitest_1.it)('should return correct url', () => { (0, vitest_1.expect)(item.url).toBe('https://example.com'); }); (0, vitest_1.it)('should return correct abstractNote', () => { (0, vitest_1.expect)(item.abstractNote).toBe('Test abstract'); }); (0, vitest_1.it)('should return correct date', () => { (0, vitest_1.expect)(item.date).toBe('2023-01-15'); }); (0, vitest_1.it)('should return correct language', () => { (0, vitest_1.expect)(item.language).toBe('en'); }); (0, vitest_1.it)('should return defensive copy of collections', () => { const collections = item.collections; collections.push('NEW_COLLECTION'); (0, vitest_1.expect)(item.collections).toEqual(['COLLECTION123']); }); (0, vitest_1.it)('should return ZTag instances', () => { const tags = item.tags; (0, vitest_1.expect)(tags).toHaveLength(1); (0, vitest_1.expect)(tags[0]).toBeInstanceOf(ZTag_1.ZTag); (0, vitest_1.expect)(tags[0].name).toBe('science'); }); (0, vitest_1.it)('should return ZCreator instances', () => { const creators = item.creators; (0, vitest_1.expect)(creators).toHaveLength(1); (0, vitest_1.expect)(creators[0]).toBeInstanceOf(ZCreator_1.ZCreator); (0, vitest_1.expect)(creators[0].firstName).toBe('John'); (0, vitest_1.expect)(creators[0].lastName).toBe('Doe'); }); (0, vitest_1.it)('should handle undefined optional fields', () => { const minimalData = { key: 'MINIMAL123', version: 1, title: 'Minimal Item', itemType: 'webpage', creators: [], tags: [], collections: [], relations: {}, }; const minimalItem = new Item_1.Item(minimalData, 'api-key', 'user', 'users'); (0, vitest_1.expect)(minimalItem.url).toBeUndefined(); (0, vitest_1.expect)(minimalItem.abstractNote).toBeUndefined(); (0, vitest_1.expect)(minimalItem.date).toBeUndefined(); (0, vitest_1.expect)(minimalItem.language).toBeUndefined(); }); }); (0, vitest_1.describe)('Setters', () => { (0, vitest_1.it)('should set title correctly', () => { item.title = 'New Title'; (0, vitest_1.expect)(item.title).toBe('New Title'); }); (0, vitest_1.it)('should trim title whitespace', () => { item.title = ' Spaced Title '; (0, vitest_1.expect)(item.title).toBe('Spaced Title'); }); (0, vitest_1.it)('should throw error for empty title', () => { (0, vitest_1.expect)(() => { item.title = ''; }) .toThrow('Title cannot be empty'); }); (0, vitest_1.it)('should throw error for whitespace-only title', () => { (0, vitest_1.expect)(() => { item.title = ' '; }) .toThrow('Title cannot be empty'); }); (0, vitest_1.it)('should throw error for null title', () => { (0, vitest_1.expect)(() => { item.title = null; }) .toThrow('Title cannot be empty'); }); (0, vitest_1.it)('should set itemType correctly', () => { item.itemType = 'book'; (0, vitest_1.expect)(item.itemType).toBe('book'); }); (0, vitest_1.it)('should trim itemType whitespace', () => { item.itemType = ' webpage '; (0, vitest_1.expect)(item.itemType).toBe('webpage'); }); (0, vitest_1.it)('should throw error for empty itemType', () => { (0, vitest_1.expect)(() => { item.itemType = ''; }) .toThrow('Item type cannot be empty'); }); (0, vitest_1.it)('should throw error for whitespace-only itemType', () => { (0, vitest_1.expect)(() => { item.itemType = ' '; }) .toThrow('Item type cannot be empty'); }); (0, vitest_1.it)('should set optional fields', () => { item.url = 'https://newurl.com'; item.abstractNote = 'New abstract'; item.date = '2024-01-01'; item.language = 'fr'; (0, vitest_1.expect)(item.url).toBe('https://newurl.com'); (0, vitest_1.expect)(item.abstractNote).toBe('New abstract'); (0, vitest_1.expect)(item.date).toBe('2024-01-01'); (0, vitest_1.expect)(item.language).toBe('fr'); }); (0, vitest_1.it)('should allow undefined for optional fields', () => { item.url = undefined; item.abstractNote = undefined; item.date = undefined; item.language = undefined; (0, vitest_1.expect)(item.url).toBeUndefined(); (0, vitest_1.expect)(item.abstractNote).toBeUndefined(); (0, vitest_1.expect)(item.date).toBeUndefined(); (0, vitest_1.expect)(item.language).toBeUndefined(); }); }); (0, vitest_1.describe)('Creator management', () => { (0, vitest_1.it)('should add creator', () => { const newCreator = new ZCreator_1.ZCreator({ creatorType: 'editor', firstName: 'Jane', lastName: 'Smith' }); item.addCreator(newCreator); const creators = item.creators; (0, vitest_1.expect)(creators).toHaveLength(2); (0, vitest_1.expect)(creators[1].firstName).toBe('Jane'); (0, vitest_1.expect)(creators[1].lastName).toBe('Smith'); }); (0, vitest_1.it)('should remove creator by valid index', () => { item.removeCreator(0); (0, vitest_1.expect)(item.creators).toHaveLength(0); }); (0, vitest_1.it)('should ignore invalid removal index (negative)', () => { const originalLength = item.creators.length; item.removeCreator(-1); (0, vitest_1.expect)(item.creators).toHaveLength(originalLength); }); (0, vitest_1.it)('should ignore invalid removal index (too high)', () => { const originalLength = item.creators.length; item.removeCreator(999); (0, vitest_1.expect)(item.creators).toHaveLength(originalLength); }); }); (0, vitest_1.describe)('Tag management', () => { (0, vitest_1.it)('should add tag', () => { const newTag = new ZTag_1.ZTag({ tag: 'technology' }); item.addTag(newTag); const tags = item.tags; (0, vitest_1.expect)(tags).toHaveLength(2); (0, vitest_1.expect)(tags[1].name).toBe('technology'); }); (0, vitest_1.it)('should remove tag by valid index', () => { item.removeTag(0); (0, vitest_1.expect)(item.tags).toHaveLength(0); }); (0, vitest_1.it)('should ignore invalid tag removal index (negative)', () => { const originalLength = item.tags.length; item.removeTag(-1); (0, vitest_1.expect)(item.tags).toHaveLength(originalLength); }); (0, vitest_1.it)('should ignore invalid tag removal index (too high)', () => { const originalLength = item.tags.length; item.removeTag(999); (0, vitest_1.expect)(item.tags).toHaveLength(originalLength); }); }); (0, vitest_1.describe)('update()', () => { (0, vitest_1.it)('should update item successfully', async () => { vitest_1.vi.mocked(fetch).mockResolvedValueOnce({ ok: true }); await (0, vitest_1.expect)(item.update()).resolves.toBeUndefined(); (0, vitest_1.expect)(fetch).toHaveBeenCalledWith('https://api.zotero.org/users/user123/items/TESTITEM123', { method: 'PUT', headers: { 'Zotero-API-Key': 'test-api-key', 'Content-Type': 'application/json' }, body: vitest_1.expect.stringContaining('"title":"Test Article"') }); }); (0, vitest_1.it)('should handle update failure', async () => { vitest_1.vi.mocked(fetch).mockResolvedValueOnce({ ok: false, statusText: 'Conflict' }); await (0, vitest_1.expect)(item.update()) .rejects.toThrow('Failed to update item TESTITEM123: Conflict'); }); (0, vitest_1.it)('should handle network error during update', async () => { vitest_1.vi.mocked(fetch).mockRejectedValueOnce(new Error('Network failure')); await (0, vitest_1.expect)(item.update()) .rejects.toThrow('Network failure'); }); }); (0, vitest_1.describe)('delete()', () => { (0, vitest_1.it)('should delete item successfully', async () => { vitest_1.vi.mocked(fetch).mockResolvedValueOnce({ ok: true }); await (0, vitest_1.expect)(item.delete()).resolves.toBeUndefined(); (0, vitest_1.expect)(fetch).toHaveBeenCalledWith('https://api.zotero.org/users/user123/items/TESTITEM123', { method: 'DELETE', headers: { 'Zotero-API-Key': 'test-api-key', 'If-Unmodified-Since-Version': '1' } }); }); (0, vitest_1.it)('should handle delete failure', async () => { vitest_1.vi.mocked(fetch).mockResolvedValueOnce({ ok: false, statusText: 'Forbidden' }); await (0, vitest_1.expect)(item.delete()) .rejects.toThrow('Failed to delete item TESTITEM123: Forbidden'); }); }); (0, vitest_1.describe)('toJSON()', () => { (0, vitest_1.it)('should return copy of item data', () => { const json = item.toJSON(); (0, vitest_1.expect)(json).toEqual(mockItemData); (0, vitest_1.expect)(json).not.toBe(mockItemData); }); (0, vitest_1.it)('should reflect current state after modifications', () => { item.title = 'Modified Title'; const json = item.toJSON(); (0, vitest_1.expect)(json.title).toBe('Modified Title'); }); }); }); //# sourceMappingURL=Item.test.js.map