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 { DCRChangeRequestState, DCRTypes } from '@reltio/mdm-sdk';
import { buildDCRSavePlan, concatEntityRelationsObjects, createEntityRelationsObjectByEntity, createEntityRelationsObjectByRelation, extractObjectsFromChangeRequest, getEntityUriForChangeRequest, isCreateEntityOperation } from './dcr';
describe('dcr helpers tests', function () {
    it('extractObjectsFromChangeRequest behaviour', function () {
        var objectsInfo = { id1: {}, id2: {}, id3: {} };
        var changes = { id1: {}, id3: {} };
        expect(extractObjectsFromChangeRequest(changes, objectsInfo)).toEqual([{ uri: 'id1' }, { uri: 'id3' }]);
        expect(extractObjectsFromChangeRequest({}, {})).toEqual([]);
    });
    it('createEntityRelationsObjectByEntity behaviour', function () {
        var objectsWithChanges = [
            { uri: 'entities/1Hhdq6PW' },
            { uri: 'relations/ja6cDI2', startObjectUri: 'entities/10f6JMNk' },
            { uri: 'relations/10f6Jdz', startObjectUri: 'entities/1Hhdq6PW' }
        ];
        var entity = { uri: 'entities/1Hhdq6PW' };
        expect(createEntityRelationsObjectByEntity(objectsWithChanges, entity)).toEqual({
            entity: objectsWithChanges[0],
            relations: [objectsWithChanges[2]]
        });
    });
    it('createEntityRelationsObjectByRelation behaviour', function () {
        var objectsInfo = {
            'entities/1Hhdq6PW': { uri: 'entities/1Hhdq6PW' },
            'relations/ja6cDI2': { uri: 'relations/ja6cDI2', startObjectUri: 'entities/10f6JMNk' },
            'relations/10f6Jdz': { uri: 'relations/10f6Jdz', startObjectUri: 'entities/1Hhdq6PW' }
        };
        expect(createEntityRelationsObjectByRelation(objectsInfo, objectsInfo['relations/ja6cDI2'])).toEqual({
            relations: [objectsInfo['relations/ja6cDI2']]
        });
        expect(createEntityRelationsObjectByRelation(objectsInfo, objectsInfo['relations/10f6Jdz'])).toEqual({
            entity: objectsInfo['entities/1Hhdq6PW'],
            relations: [objectsInfo['relations/10f6Jdz']]
        });
    });
    it('concatEntityRelationsObjects behaviour', function () {
        var objects = [
            {
                entity: {
                    uri: 'entities/10f6JMNk',
                    isExist: true,
                    label: 'Test Label',
                    secondaryLabel: '',
                    type: 'configuration/entityTypes/Type'
                },
                relations: [
                    {
                        uri: 'relations/ja6cDI2',
                        type: 'configuration/relationTypes/HasAddress',
                        startObjectUri: 'entities/10f6JMNk',
                        startObjectLabel: 'label 1',
                        endObjectUri: 'entities/1MXzYxGR',
                        endObjectLabel: 'label 2',
                        isExist: true
                    }
                ]
            },
            {
                entity: {
                    uri: 'entities/1Hhdq6PW',
                    isExist: true,
                    label: 'Test Label 2',
                    secondaryLabel: '',
                    type: 'configuration/entityTypes/Type'
                },
                relations: [
                    {
                        uri: 'relations/10f6Jdz',
                        type: 'configuration/relationTypes/HasAddress',
                        startObjectUri: 'entities/1Hhdq6PW',
                        startObjectLabel: 'label 3',
                        endObjectUri: 'entities/1MXzYxGR',
                        endObjectLabel: 'label 2',
                        isExist: true
                    }
                ]
            },
            {
                entity: {
                    uri: 'entities/10f6JMNk',
                    isExist: true,
                    label: 'Test Label',
                    secondaryLabel: '',
                    type: 'configuration/entityTypes/Type'
                },
                relations: [
                    {
                        uri: 'relations/ja6caxc',
                        type: 'configuration/relationTypes/HasAddress',
                        startObjectUri: 'entities/10f6JMNk',
                        startObjectLabel: 'label 1',
                        endObjectUri: 'entities/1MXzYxGR',
                        endObjectLabel: 'label 2',
                        isExist: true
                    }
                ]
            },
            {
                entity: {
                    uri: 'entities/10f6Jabc',
                    isExist: true,
                    label: 'Test Label',
                    secondaryLabel: '',
                    type: 'configuration/entityTypes/Type'
                },
                relations: []
            }
        ];
        expect(objects.reduce(function (acc, object) { return concatEntityRelationsObjects(acc, object); }, {})).toEqual({
            'entities/10f6JMNk': {
                entity: objects[0].entity,
                relations: [objects[2].relations[0], objects[0].relations[0]]
            },
            'entities/1Hhdq6PW': objects[1],
            'entities/10f6Jabc': objects[3]
        });
    });
    it('concatEntityRelationsObjects preserves existing entity when duplicate uri appears', function () {
        var originalEntity = {
            uri: 'entities/10f6JMNk',
            isExist: true,
            label: 'Test Label',
            secondaryLabel: '',
            type: 'configuration/entityTypes/Type'
        };
        var fetchedEntity = {
            uri: 'entities/10f6JMNk',
            type: 'configuration/entityTypes/Type',
            label: 'Test Label',
            secondaryLabel: '',
            roles: ['configuration/roles/Admin']
        };
        var objects = [
            {
                entity: originalEntity,
                relations: [
                    {
                        uri: 'relations/rel1',
                        type: 'configuration/relationTypes/HasAddress',
                        startObjectUri: 'entities/10f6JMNk',
                        startObjectLabel: 'label 1',
                        endObjectUri: 'entities/abc',
                        endObjectLabel: 'label 2',
                        isExist: true
                    }
                ]
            },
            {
                entity: fetchedEntity,
                relations: [
                    {
                        uri: 'relations/rel2',
                        type: 'configuration/relationTypes/HasAddress',
                        startObjectUri: 'entities/10f6JMNk',
                        startObjectLabel: 'label 1',
                        endObjectUri: 'entities/def',
                        endObjectLabel: 'label 3',
                        isExist: true
                    }
                ]
            }
        ];
        var result = objects.reduce(function (acc, object) { return concatEntityRelationsObjects(acc, object); }, {});
        expect(result['entities/10f6JMNk'].entity).toBe(originalEntity);
        expect(result['entities/10f6JMNk'].relations).toEqual([objects[1].relations[0], objects[0].relations[0]]);
    });
    it('getEntityUriForChangeRequest behaviour', function () {
        expect(getEntityUriForChangeRequest('dcrUri', 'entityUri')).toBe('dcrUri/changes/entityUri');
    });
    it('isCreateEntityOperation behaviour', function () {
        var change = {
            type: DCRTypes.CREATE_ENTITY,
            changes: {},
            uri: 'changeRequestUri',
            createdBy: 'somebody',
            objectsInfo: {},
            createdTime: 1,
            state: DCRChangeRequestState.APPLIED,
            updatedBy: 'somebody2',
            updatedTime: 2
        };
        expect(isCreateEntityOperation(change)).toBe(true);
        expect(isCreateEntityOperation(__assign(__assign({}, change), { type: DCRTypes.CREATE_RELATIONSHIP }))).toBe(false);
    });
    describe('buildDCRSavePlan', function () {
        var emptyMetadata = { entityTypes: [], relationTypes: [] };
        var noLineData = function () { return []; };
        var emptyPlan = {
            rejectedChangeIds: [],
            updatedChanges: {},
            deleteEntityAttributes: {},
            deleteRelationAttributes: {},
            insertEntityAttributes: {},
            insertRelationAttributes: {}
        };
        it('should include added attribute with defaultValue when no lineData exists', function () {
            var changes = {
                'entities/456': [
                    {
                        id: 'added|simple1',
                        type: DCRTypes.INSERT_ATTRIBUTE,
                        attributePath: 'Surname',
                        attributeType: 'configuration/entityTypes/HCP/attributes/Surname',
                        newValue: { value: 'DefaultSurname' }
                    }
                ]
            };
            var result = buildDCRSavePlan(changes, noLineData, emptyMetadata);
            expect(result).toEqual(__assign(__assign({}, emptyPlan), { insertEntityAttributes: {
                    'entities/456': [
                        {
                            type: 'INSERT_ATTRIBUTE',
                            uri: 'entities/456/attributes/Surname',
                            newValue: [{ value: 'DefaultSurname' }]
                        }
                    ]
                } }));
        });
        it('should include added lookup attribute with lookupCode when no lineData exists', function () {
            var changes = {
                'entities/456': [
                    {
                        id: 'added|lookup1',
                        type: DCRTypes.INSERT_ATTRIBUTE,
                        attributePath: 'Country',
                        attributeType: 'configuration/entityTypes/HCP/attributes/Country',
                        newValue: { value: '', lookupCode: 'ALBY' }
                    }
                ]
            };
            var result = buildDCRSavePlan(changes, noLineData, emptyMetadata);
            expect(result).toEqual(__assign(__assign({}, emptyPlan), { insertEntityAttributes: {
                    'entities/456': [
                        {
                            type: 'INSERT_ATTRIBUTE',
                            uri: 'entities/456/attributes/Country',
                            newValue: [{ value: '', lookupCode: 'ALBY' }]
                        }
                    ]
                } }));
        });
        it('should remove lookupRawValue when new lookup value does not have it', function () {
            var changes = {
                'entities/456': [
                    {
                        id: 'change1',
                        type: DCRTypes.UPDATE_ATTRIBUTE,
                        attributePath: 'Country',
                        attributeType: 'configuration/entityTypes/HCP/attributes/Country',
                        newValue: { value: 'Albania', lookupCode: 'ALBY', lookupRawValue: 'ALBY' },
                        oldValue: { value: 'France', lookupCode: 'FRA' }
                    }
                ]
            };
            var lineData = [
                ['456/change1/newValue', { value: { value: 'Germany', lookupCode: 'DEU' } }]
            ];
            var result = buildDCRSavePlan(changes, function (changeId) { return (changeId === 'change1' ? lineData : []); }, emptyMetadata);
            expect(result).toEqual(__assign(__assign({}, emptyPlan), { rejectedChangeIds: ['change1'], updatedChanges: {
                    'entities/456': [
                        {
                            id: 'change1',
                            type: DCRTypes.UPDATE_ATTRIBUTE,
                            attributePath: 'Country',
                            attributeType: 'configuration/entityTypes/HCP/attributes/Country',
                            newValue: { value: 'Germany', lookupCode: 'DEU' },
                            oldValue: { value: 'France', lookupCode: 'FRA' }
                        }
                    ]
                } }));
        });
        it('should preserve primitive boolean defaultValue for added attribute when no lineData exists', function () {
            var changes = {
                'entities/456': [
                    {
                        id: 'added|bool1',
                        type: DCRTypes.INSERT_ATTRIBUTE,
                        attributePath: 'PrimaryAffiliationIndicator',
                        attributeType: 'configuration/entityTypes/HCP/attributes/PrimaryAffiliationIndicator',
                        newValue: { value: false }
                    }
                ]
            };
            var result = buildDCRSavePlan(changes, noLineData, emptyMetadata);
            expect(result).toEqual(__assign(__assign({}, emptyPlan), { insertEntityAttributes: {
                    'entities/456': [
                        {
                            type: 'INSERT_ATTRIBUTE',
                            uri: 'entities/456/attributes/PrimaryAffiliationIndicator',
                            newValue: [{ value: false }]
                        }
                    ]
                } }));
        });
        it('should send user-edited boolean value for added attribute', function () {
            var changes = {
                'entities/456': [
                    {
                        id: 'added|bool2',
                        type: DCRTypes.INSERT_ATTRIBUTE,
                        attributePath: 'PrimaryAffiliationIndicator',
                        attributeType: 'configuration/entityTypes/HCP/attributes/PrimaryAffiliationIndicator',
                        newValue: { value: false }
                    }
                ]
            };
            var lineData = [['456/added|bool2/newValue', { value: { value: 'true' } }]];
            var result = buildDCRSavePlan(changes, function (changeId) { return (changeId === 'added|bool2' ? lineData : []); }, emptyMetadata);
            expect(result).toEqual(__assign(__assign({}, emptyPlan), { insertEntityAttributes: {
                    'entities/456': [
                        {
                            type: 'INSERT_ATTRIBUTE',
                            uri: 'entities/456/attributes/PrimaryAffiliationIndicator',
                            newValue: [{ value: 'true' }]
                        }
                    ]
                } }));
        });
        it('should preserve lookup sub-attribute with lookupCode inside nested parent', function () {
            var metadata = {
                entityTypes: [
                    {
                        uri: 'configuration/entityTypes/HCP',
                        attributes: [
                            {
                                uri: 'configuration/entityTypes/HCP/attributes/Details',
                                name: 'Details',
                                type: 'Nested',
                                attributes: [
                                    {
                                        uri: 'configuration/entityTypes/HCP/attributes/Details/attributes/Country',
                                        name: 'Country',
                                        type: 'String'
                                    },
                                    {
                                        uri: 'configuration/entityTypes/HCP/attributes/Details/attributes/Notes',
                                        name: 'Notes',
                                        type: 'String'
                                    }
                                ]
                            }
                        ]
                    }
                ]
            };
            var changes = {
                'entities/456': [
                    {
                        id: 'added|nested1',
                        type: DCRTypes.INSERT_ATTRIBUTE,
                        attributePath: 'Details',
                        attributeType: 'configuration/entityTypes/HCP/attributes/Details',
                        newValue: {
                            value: {
                                Country: [{ value: '', lookupCode: 'ALBY' }],
                                Notes: [{ value: '' }]
                            }
                        }
                    }
                ]
            };
            var notesLineData = [
                ['456/added|nested1/newValue/value/Notes/0', { value: { value: 'User typed note' } }]
            ];
            var result = buildDCRSavePlan(changes, function (changeId) { return (changeId === 'added|nested1' ? notesLineData : []); }, metadata);
            expect(result).toEqual(__assign(__assign({}, emptyPlan), { insertEntityAttributes: {
                    'entities/456': [
                        {
                            type: 'INSERT_ATTRIBUTE',
                            uri: 'entities/456/attributes/Details',
                            newValue: [
                                {
                                    value: {
                                        Country: [{ value: '', lookupCode: 'ALBY' }],
                                        Notes: [{ value: 'User typed note' }]
                                    }
                                }
                            ]
                        }
                    ]
                } }));
        });
    });
});
