var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
import { renderHook, act } from '@testing-library/react';
import * as useAttributesActionsImport from './useAttributeActions';
import { useModifiedEntity } from './useModifiedEntity';
describe('useModifiedEntity', function () {
    var attributeActions = {
        pinAttribute: jest.fn(),
        deleteAttribute: jest.fn(),
        ignoreAttribute: jest.fn(),
        updateAttribute: jest.fn(),
        createAttribute: jest.fn()
    };
    var useAttributeActionsMock = jest
        .spyOn(useAttributesActionsImport, 'useAttributeActions')
        .mockReturnValue(attributeActions);
    var entity = {
        uri: 'entities/1',
        type: 'configuration/entityTypes/HCP',
        attributes: {
            Simple: [
                {
                    uri: 'entities/1/attributes/Simple/1',
                    value: 'simple value'
                }
            ],
            Nested: [
                {
                    uri: 'entities/1/attributes/Nested/1',
                    value: {
                        SubNested: [
                            {
                                uri: 'entities/1/attributes/Nested/1/SubNested/1',
                                value: 'subnested value'
                            }
                        ]
                    }
                }
            ],
            Reference: [
                {
                    uri: 'entities/1/attributes/Reference/1',
                    refRelation: {
                        uri: 'relations/1',
                        crosswalks: [
                            {
                                uri: 'relations/1/crosswalks/1',
                                type: 'configuration/sources/AHA',
                                value: 'cw3',
                                attributeURIs: ['entities/1/attributes/Reference/1/RefSimple/1']
                            }
                        ]
                    },
                    value: {
                        RefSimple: [
                            {
                                uri: 'entities/1/attributes/Reference/1/RefSimple/1',
                                value: 'ref simple value'
                            }
                        ]
                    }
                }
            ]
        },
        crosswalks: [
            {
                uri: 'entities/1/crosswalks/1',
                type: 'configuration/sources/Reltio',
                value: 'cw1',
                attributes: ['entities/1/attributes/Simple/1']
            },
            {
                uri: 'entities/1/crosswalks/2',
                type: 'configuration/sources/FB',
                value: 'cw2',
                attributes: ['entities/1/attributes/Nested/1', 'entities/1/attributes/Nested/1/SubNested/1']
            }
        ]
    };
    var initCrosswalksMap = {
        entity: {
            'entities/1/attributes/Simple/1': [entity.crosswalks[0]],
            'entities/1/attributes/Nested/1': [entity.crosswalks[1]],
            'entities/1/attributes/Nested/1/SubNested/1': [entity.crosswalks[1]]
        },
        relation: {
            'entities/1/attributes/Reference/1/RefSimple/1': [entity.attributes.Reference[0].refRelation.crosswalks[0]]
        }
    };
    var initialProps = {
        entity: entity,
        onModify: jest.fn(),
        onError: jest.fn(),
        onLoad: jest.fn()
    };
    var getModifiedEntity = function () {
        var _a = renderHook(useModifiedEntity, { initialProps: initialProps }), result = _a.result, rerender = _a.rerender;
        return __assign({ result: result, rerender: rerender }, result.current);
    };
    afterEach(function () {
        jest.clearAllMocks();
    });
    it('should use attribute actions correctly', function () {
        getModifiedEntity();
        var _a = useAttributeActionsMock.mock.calls[0][0], onSuccess = _a.onSuccess, onError = _a.onError, onLoad = _a.onLoad;
        expect(onLoad).toBe(initialProps.onLoad);
        expect(onSuccess).toBe(initialProps.onModify);
        var error = new Error();
        onError === null || onError === void 0 ? void 0 : onError(error);
        expect(initialProps.onError).toHaveBeenCalledWith(error);
    });
    it('should return unmodified entity on first render', function () {
        var modifiedEntity = getModifiedEntity().modifiedEntity;
        expect(modifiedEntity).toBe(entity);
    });
    it('should return correct crosswalks map on first render', function () {
        var crosswalksMap = getModifiedEntity().crosswalksMap;
        expect(crosswalksMap).toEqual(initCrosswalksMap);
    });
    it('should return correct pin handler', function () {
        var onPinAttribute = getModifiedEntity().onPinAttribute;
        expect(onPinAttribute).toBe(attributeActions.pinAttribute);
    });
    it('should return correct ignore handler', function () {
        var onIgnoreAttribute = getModifiedEntity().onIgnoreAttribute;
        expect(onIgnoreAttribute).toBe(attributeActions.ignoreAttribute);
    });
    it('should return correct add handler for simple attribute', function () {
        var _a;
        var _b;
        var _c = getModifiedEntity(), onAddAttribute = _c.onAddAttribute, result = _c.result;
        var crosswalk = {
            uri: 'entities/1/crosswalks/1',
            type: 'configuration/sources/Reltio',
            value: 'cw1',
            attributes: ['entities/1/attributes/Simple/1'],
            ownerType: 'entity'
        };
        act(function () {
            onAddAttribute({
                attributeType: {
                    uri: 'configuration/entityTypes/HCP/attributes/Simple',
                    type: 'Simple',
                    label: 'Simple',
                    name: 'Simple'
                },
                parentUri: 'entities/1',
                crosswalk: crosswalk,
                index: 1
            });
        });
        expect(result.current.modifiedEntity).toEqual(__assign(__assign({}, entity), { attributes: __assign(__assign({}, entity.attributes), { Simple: [
                    {
                        uri: 'entities/1/attributes/Simple/1',
                        value: 'simple value'
                    },
                    {
                        uri: expect.stringContaining('entities/1/attributes/Simple/uri$$'),
                        type: 'configuration/entityTypes/HCP/attributes/Simple',
                        value: ''
                    }
                ] }) }));
        expect(result.current.crosswalksMap).toEqual(__assign(__assign({}, initCrosswalksMap), { entity: __assign(__assign({}, initCrosswalksMap.entity), (_a = {}, _a[(_b = result.current.modifiedEntity.attributes) === null || _b === void 0 ? void 0 : _b.Simple[1].uri] = [crosswalk], _a)) }));
    });
    it('should return correct add handler for nested attribute', function () {
        var _a = getModifiedEntity(), onAddAttribute = _a.onAddAttribute, result = _a.result;
        act(function () {
            onAddAttribute({
                attributeType: {
                    uri: 'configuration/entityTypes/HCP/attributes/Nested',
                    type: 'Nested',
                    label: 'Nested',
                    name: 'Nested',
                    attributes: [
                        {
                            uri: 'configuration/entityTypes/HCP/attributes/Nested/attributes/SubNested',
                            type: 'String',
                            name: 'SubNested',
                            label: 'SubNested'
                        }
                    ]
                },
                parentUri: 'entities/1'
            });
        });
        expect(result.current.modifiedEntity).toEqual(__assign(__assign({}, entity), { attributes: __assign(__assign({}, entity.attributes), { Nested: [
                    {
                        uri: 'entities/1/attributes/Nested/1',
                        value: {
                            SubNested: [
                                {
                                    uri: 'entities/1/attributes/Nested/1/SubNested/1',
                                    value: 'subnested value'
                                }
                            ]
                        }
                    },
                    {
                        type: 'configuration/entityTypes/HCP/attributes/Nested',
                        uri: expect.stringContaining('entities/1/attributes/Nested/uri$$'),
                        value: {}
                    }
                ] }) }));
        expect(result.current.crosswalksMap).toEqual(initCrosswalksMap);
    });
    it('should return correct delete handler for existing attribute', function () {
        var onDeleteAttribute = getModifiedEntity().onDeleteAttribute;
        var deleteEvent = {
            attributeValue: entity.attributes.Simple[0],
            attributeType: {
                uri: 'configuration/entityTypes/HCP/attributes/Simple',
                type: 'Simple',
                label: 'Simple',
                name: 'Simple'
            },
            crosswalks: [entity.crosswalks[0]]
        };
        act(function () {
            onDeleteAttribute(deleteEvent);
        });
        expect(attributeActions.deleteAttribute).toHaveBeenCalledWith(deleteEvent);
    });
    it('should return correct delete handler for temporary attribute', function () {
        var _a = getModifiedEntity(), onAddAttribute = _a.onAddAttribute, onDeleteAttribute = _a.onDeleteAttribute, result = _a.result;
        var crosswalk = {
            uri: 'entities/1/crosswalks/1',
            type: 'configuration/sources/Reltio',
            value: 'cw1',
            attributes: ['entities/1/attributes/Simple/1'],
            ownerType: 'entity'
        };
        var attributeType = {
            uri: 'configuration/entityTypes/HCP/attributes/Simple',
            type: 'Simple',
            label: 'Simple',
            name: 'Simple'
        };
        act(function () {
            onAddAttribute({
                attributeType: attributeType,
                parentUri: 'entities/1',
                crosswalk: crosswalk,
                index: 1
            });
        });
        act(function () {
            var _a;
            onDeleteAttribute({
                attributeValue: (_a = result.current.modifiedEntity.attributes) === null || _a === void 0 ? void 0 : _a.Simple[1],
                attributeType: attributeType,
                crosswalks: [crosswalk]
            });
        });
        expect(attributeActions.deleteAttribute).not.toHaveBeenCalled();
        expect(result.current.modifiedEntity).toEqual(entity);
        expect(result.current.crosswalksMap).toEqual(initCrosswalksMap);
    });
    it('should return correct edit handler for existing attribute', function () {
        var onEditAttribute = getModifiedEntity().onEditAttribute;
        var editEvent = {
            attributeValue: __assign(__assign({}, entity.attributes.Simple[0]), { value: 'new value' }),
            attributeType: {
                uri: 'configuration/entityTypes/HCP/attributes/Simple',
                type: 'Simple',
                label: 'Simple',
                name: 'Simple'
            },
            crosswalk: entity.crosswalks[0]
        };
        act(function () {
            onEditAttribute(editEvent);
        });
        expect(attributeActions.updateAttribute).toHaveBeenCalledWith(editEvent);
    });
    it('should return correct edit handler for temporary simple attribute', function () {
        var _a, _b;
        var _c = getModifiedEntity(), onEditAttribute = _c.onEditAttribute, onAddAttribute = _c.onAddAttribute, result = _c.result;
        var crosswalk = {
            uri: 'entities/1/crosswalks/1',
            type: 'configuration/sources/Reltio',
            value: 'cw1',
            attributes: ['entities/1/attributes/Simple/1'],
            ownerType: 'entity'
        };
        var attributeType = {
            uri: 'configuration/entityTypes/HCP/attributes/Simple',
            type: 'Simple',
            label: 'Simple',
            name: 'Simple'
        };
        act(function () {
            onAddAttribute({
                attributeType: attributeType,
                parentUri: 'entities/1',
                crosswalk: crosswalk,
                index: 1
            });
        });
        var editEvent = {
            attributeValue: __assign(__assign({}, (_a = result.current.modifiedEntity.attributes) === null || _a === void 0 ? void 0 : _a.Simple[1]), { value: 'new value' }),
            attributeType: attributeType,
            crosswalk: crosswalk
        };
        act(function () {
            onEditAttribute(editEvent);
        });
        expect(attributeActions.updateAttribute).not.toHaveBeenCalled();
        expect(attributeActions.createAttribute).toHaveBeenCalledWith({
            attributeValue: __assign(__assign({}, (_b = result.current.modifiedEntity.attributes) === null || _b === void 0 ? void 0 : _b.Simple[1]), { value: 'new value' }),
            crosswalk: crosswalk
        });
    });
    it('should return correct edit handler for temporary subnested attribute', function () {
        var _a, _b;
        var _c = getModifiedEntity(), onEditAttribute = _c.onEditAttribute, onAddAttribute = _c.onAddAttribute, result = _c.result;
        var crosswalk = {
            uri: 'entities/1/crosswalks/1',
            type: 'configuration/sources/Reltio',
            value: 'cw1',
            attributes: ['entities/1/attributes/Simple/1'],
            ownerType: 'entity'
        };
        var attributeType = {
            uri: 'configuration/entityTypes/HCP/attributes/Nested',
            type: 'Nested',
            label: 'Nested',
            name: 'Nested',
            attributes: [
                {
                    uri: 'configuration/entityTypes/HCP/attributes/Nested/attributes/SubNested',
                    type: 'String',
                    name: 'SubNested',
                    label: 'SubNested'
                }
            ]
        };
        act(function () {
            onAddAttribute({
                attributeType: attributeType,
                parentUri: 'entities/1',
                index: 1
            });
        });
        act(function () {
            var _a;
            onAddAttribute({
                attributeType: attributeType.attributes[0],
                parentUri: (_a = result.current.modifiedEntity.attributes) === null || _a === void 0 ? void 0 : _a.Nested[1].uri,
                crosswalk: crosswalk,
                index: 0
            });
        });
        act(function () {
            var _a;
            onEditAttribute({
                attributeType: attributeType.attributes[0],
                crosswalk: crosswalk,
                attributeValue: __assign(__assign({}, (_a = result.current.modifiedEntity.attributes) === null || _a === void 0 ? void 0 : _a.Nested[1].value.SubNested[0]), { value: 'new value' })
            });
        });
        expect(attributeActions.updateAttribute).not.toHaveBeenCalled();
        expect(attributeActions.createAttribute).toHaveBeenCalledWith({
            attributeValue: __assign(__assign({}, (_a = result.current.modifiedEntity.attributes) === null || _a === void 0 ? void 0 : _a.Nested[1]), { value: {
                    SubNested: [
                        __assign(__assign({}, (_b = result.current.modifiedEntity.attributes) === null || _b === void 0 ? void 0 : _b.Nested[1].value.SubNested[0]), { value: 'new value' })
                    ]
                } }),
            crosswalk: crosswalk
        });
    });
    it('should reset data on entity change', function () {
        var _a = getModifiedEntity(), onAddAttribute = _a.onAddAttribute, result = _a.result, rerender = _a.rerender;
        var crosswalk = {
            uri: 'entities/1/crosswalks/1',
            type: 'configuration/sources/Reltio',
            value: 'cw1',
            attributes: ['entities/1/attributes/Simple/1'],
            ownerType: 'entity'
        };
        act(function () {
            onAddAttribute({
                attributeType: {
                    uri: 'configuration/entityTypes/HCP/attributes/Simple',
                    type: 'Simple',
                    label: 'Simple',
                    name: 'Simple'
                },
                parentUri: 'entities/1',
                crosswalk: crosswalk,
                index: 1
            });
        });
        expect(result.current.modifiedEntity).not.toEqual(entity);
        expect(result.current.crosswalksMap).not.toEqual(initCrosswalksMap);
        rerender(__assign(__assign({}, initialProps), { entity: __assign({}, entity) }));
        expect(result.current.modifiedEntity).toEqual(entity);
        expect(result.current.crosswalksMap).toEqual(initCrosswalksMap);
    });
    it('should return newlyCreatedAttributes correctly', function () {
        var _a = getModifiedEntity(), onEditAttribute = _a.onEditAttribute, onAddAttribute = _a.onAddAttribute, result = _a.result, rerender = _a.rerender;
        var crosswalk = {
            uri: 'entities/1/crosswalks/1',
            type: 'configuration/sources/Reltio',
            value: 'cw1',
            attributes: ['entities/1/attributes/Simple/1'],
            ownerType: 'entity'
        };
        var attributeType = {
            uri: 'configuration/entityTypes/HCP/attributes/Nested',
            type: 'Nested',
            label: 'Nested',
            name: 'Nested',
            attributes: [
                {
                    uri: 'configuration/entityTypes/HCP/attributes/Nested/attributes/SubNested',
                    type: 'String',
                    name: 'SubNested',
                    label: 'SubNested'
                }
            ]
        };
        act(function () {
            onAddAttribute({
                attributeType: attributeType,
                parentUri: 'entities/1',
                index: 1
            });
        });
        act(function () {
            var _a;
            onAddAttribute({
                attributeType: attributeType.attributes[0],
                parentUri: (_a = result.current.modifiedEntity.attributes) === null || _a === void 0 ? void 0 : _a.Nested[1].uri,
                crosswalk: crosswalk,
                index: 0
            });
        });
        act(function () {
            var _a;
            onEditAttribute({
                attributeType: attributeType.attributes[0],
                crosswalk: crosswalk,
                attributeValue: __assign(__assign({}, (_a = result.current.modifiedEntity.attributes) === null || _a === void 0 ? void 0 : _a.Nested[1].value.SubNested[0]), { value: 'new value' })
            });
        });
        expect(result.current.newlyCreatedAttributes).toEqual([]);
        rerender(__assign(__assign({}, initialProps), { entity: __assign(__assign({}, entity), { attributes: __assign(__assign({}, entity.attributes), { Nested: [
                        {
                            uri: 'entities/1/attributes/Nested/2',
                            value: {
                                SubNested: [
                                    {
                                        uri: 'entities/1/attributes/Nested/2/SubNested/1',
                                        value: 'new value'
                                    }
                                ]
                            }
                        },
                        {
                            uri: 'entities/1/attributes/Nested/1',
                            value: {
                                SubNested: [
                                    {
                                        uri: 'entities/1/attributes/Nested/1/SubNested/1',
                                        value: 'subnested value'
                                    }
                                ]
                            }
                        }
                    ] }), crosswalks: [
                    {
                        uri: 'entities/1/crosswalks/1',
                        type: 'configuration/sources/Reltio',
                        value: 'cw1',
                        attributes: [
                            'entities/1/attributes/Simple/1',
                            'entities/1/attributes/Nested/2',
                            'entities/1/attributes/Nested/2/SubNested/1'
                        ]
                    },
                    entity.crosswalks[1]
                ] }) }));
        expect(result.current.newlyCreatedAttributes).toEqual([
            'entities/1/attributes/Nested/2',
            'entities/1/attributes/Nested/2/SubNested/1'
        ]);
    });
});
