"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const BaseModel_1 = require("../../BaseModel");
const test_utils_1 = require("../../testing/test-utils");
const Folder_1 = require("../Folder");
const Note_1 = require("../Note");
const Resource_1 = require("../Resource");
const Tag_1 = require("../Tag");
const userData_1 = require("./userData");
const loadOptions = { fields: ['id', 'parent_id', 'user_data', 'updated_time'] };
describe('utils/userData', () => {
    beforeEach(async () => {
        await (0, test_utils_1.setupDatabaseAndSynchronizer)(1);
        await (0, test_utils_1.switchClient)(1);
    });
    it('should set and get user data on a note', async () => {
        const folder = await Folder_1.default.save({});
        let note = await Note_1.default.save({ parent_id: folder.id });
        note = await Note_1.default.load(note.id, loadOptions);
        await (0, test_utils_1.msleep)(5);
        await (0, userData_1.setNoteUserData)(note, 'org.joplin', 'my-key', 'something');
        const noteReloaded = await Note_1.default.load(note.id);
        expect(await (0, userData_1.getNoteUserData)(noteReloaded, 'org.joplin', 'my-key')).toBe('something');
        // Check that the updated_time has been updated (for sync purposes), but
        // not the user_updated_time.
        expect(noteReloaded.updated_time).toBeGreaterThan(note.updated_time);
        expect(noteReloaded.user_updated_time).toBe(note.updated_time);
        // Check for non-existing props
        expect(await (0, userData_1.getNoteUserData)(noteReloaded, 'org.doesntexist', 'my-key')).toBe(undefined);
        expect(await (0, userData_1.getNoteUserData)(noteReloaded, 'org.joplin', 'doesntexist')).toBe(undefined);
    });
    it('should set and get user data on any item', async () => {
        const folder = await Folder_1.default.save({});
        const tag = await Tag_1.default.save({});
        const resource = await Resource_1.default.save({ mime: 'plain/text' });
        await (0, userData_1.setItemUserData)(BaseModel_1.ModelType.Folder, folder.id, 'foldertest', 'folderkey', 123);
        expect(await (0, userData_1.getItemUserData)(BaseModel_1.ModelType.Folder, folder.id, 'foldertest', 'folderkey')).toBe(123);
        await (0, userData_1.deleteItemUserData)(BaseModel_1.ModelType.Folder, folder.id, 'foldertest', 'folderkey');
        expect(await (0, userData_1.getItemUserData)(BaseModel_1.ModelType.Folder, folder.id, 'foldertest', 'folderkey')).toBe(undefined);
        await (0, userData_1.setItemUserData)(BaseModel_1.ModelType.Tag, tag.id, 'tagtest', 'tagkey', 123);
        expect(await (0, userData_1.getItemUserData)(BaseModel_1.ModelType.Tag, tag.id, 'tagtest', 'tagkey')).toBe(123);
        await (0, userData_1.deleteItemUserData)(BaseModel_1.ModelType.Tag, tag.id, 'tagtest', 'tagkey');
        expect(await (0, userData_1.getItemUserData)(BaseModel_1.ModelType.Tag, tag.id, 'tagtest', 'tagkey')).toBe(undefined);
        await (0, userData_1.setItemUserData)(BaseModel_1.ModelType.Resource, resource.id, 'resourcetest', 'resourcekey', 123);
        expect(await (0, userData_1.getItemUserData)(BaseModel_1.ModelType.Resource, resource.id, 'resourcetest', 'resourcekey')).toBe(123);
        await (0, userData_1.deleteItemUserData)(BaseModel_1.ModelType.Resource, resource.id, 'resourcetest', 'resourcekey');
        expect(await (0, userData_1.getItemUserData)(BaseModel_1.ModelType.Resource, resource.id, 'resourcetest', 'resourcekey')).toBe(undefined);
    });
    it('should delete user data', async () => {
        const folder = await Folder_1.default.save({});
        let note = await Note_1.default.save({ parent_id: folder.id });
        note = await Note_1.default.load(note.id, loadOptions);
        await (0, userData_1.setNoteUserData)(note, 'org.joplin', 'my-key', 'something');
        let noteReloaded = await Note_1.default.load(note.id);
        expect(await (0, userData_1.getNoteUserData)(noteReloaded, 'org.joplin', 'my-key')).toBe('something');
        noteReloaded = await (0, userData_1.deleteNoteUserData)(noteReloaded, 'org.joplin', 'my-key');
        expect(await (0, userData_1.getNoteUserData)(noteReloaded, 'org.joplin', 'my-key')).toBe(undefined);
        // Check that it works if we set it again
        await (0, userData_1.setNoteUserData)(note, 'org.joplin', 'my-key', 'something else');
        noteReloaded = await Note_1.default.load(noteReloaded.id, loadOptions);
        expect(await (0, userData_1.getNoteUserData)(noteReloaded, 'org.joplin', 'my-key')).toBe('something else');
    });
    it('should merge user data', async () => {
        const testCases = [
            [
                {
                    'org.joplin': {
                        'k1': {
                            v: 123,
                            t: 0,
                        },
                        'k3': {
                            v: 789,
                            t: 5,
                        },
                        'k4': {
                            v: 789,
                            t: 5,
                        },
                    },
                    'com.example': {},
                },
                {
                    'org.joplin': {
                        'k1': {
                            v: 456,
                            t: 1,
                        },
                        'k2': {
                            v: 'abc',
                            t: 5,
                        },
                        'k4': {
                            v: 111,
                            t: 0,
                        },
                    },
                },
                {
                    'org.joplin': {
                        'k1': {
                            v: 456,
                            t: 1,
                        },
                        'k2': {
                            v: 'abc',
                            t: 5,
                        },
                        'k3': {
                            v: 789,
                            t: 5,
                        },
                        'k4': {
                            v: 789,
                            t: 5,
                        },
                    },
                    'com.example': {},
                },
            ],
            [
                // Client 2 delete a prop
                // Later, client 1 update that prop
                // Then data is merged
                // => In that case, the data is restored using client 1 data
                {
                    'org.joplin': {
                        'k1': {
                            v: 123,
                            t: 10,
                        },
                    },
                },
                {
                    'org.joplin': {
                        'k1': {
                            v: 0,
                            t: 0,
                            d: 1,
                        },
                    },
                },
                {
                    'org.joplin': {
                        'k1': {
                            v: 123,
                            t: 10,
                        },
                    },
                },
            ],
            [
                // Client 1 update a prop
                // Later, client 2 delete a prop
                // Then data is merged
                // => In that case, the data is deleted and the update from client 1 is lost
                {
                    'org.joplin': {
                        'k1': {
                            v: 123,
                            t: 0,
                        },
                    },
                },
                {
                    'org.joplin': {
                        'k1': {
                            v: 0,
                            t: 10,
                            d: 1,
                        },
                    },
                },
                {
                    'org.joplin': {
                        'k1': {
                            v: 0,
                            t: 10,
                            d: 1,
                        },
                    },
                },
            ],
        ];
        for (const [target, source, expected] of testCases) {
            const actual = (0, userData_1.mergeUserData)(target, source);
            expect(actual).toEqual(expected);
        }
    });
});
//# sourceMappingURL=userData.test.js.map