import {
    checkDesignElementRestrictions,
    checkDesignElementRestrictionsWithRemovalCount,
    getDesignElementAvailability,
    getDesignElementCount,
} from '../DesignElementSelectors';

describe('Reducers/DesignArea/DesignElementSelectors', () => {
    test('getDesignElementCount returns the count of elements from the given designdata', () => {
        const designData = {
            canvasData: {
                objects: [
                    { type: 'Image' },
                    { type: 'Text' },
                    { type: 'Image' },
                    { type: 'Image' },
                    { type: 'Text' },
                    { type: 'Image' },
                    { type: 'Text' },
                    { type: 'Text' },
                    { type: 'Text' },
                ],
            },
        };
        expect(getDesignElementCount(designData)).toEqual({
            imagesCount: 4,
            textsCount: 5,
            totalCount: 9,
        });
    });
    test('checkDesignElementRestrictions matches the maxElements rule', () => {
        const designProductionMethodSubset = { maxElements: 2 };
        const designData = {
            canvasData: {
                objects: [{ type: 'Image' }, { type: 'Text' }],
            },
        };
        expect(checkDesignElementRestrictions(designData, designProductionMethodSubset)).toEqual({
            type: 'maxElements',
            max: 2,
        });
        const designDataWithSpace = {
            canvasData: {
                objects: [{ type: 'Image' }],
            },
        };
        expect(checkDesignElementRestrictions(designDataWithSpace, designProductionMethodSubset)).toBe(null);
    });
    test('checkDesignElementRestrictions matches the maxImages rule', () => {
        const designProductionMethodSubset = { maxImages: 1 };
        const designData = {
            canvasData: {
                objects: [{ type: 'Image' }, { type: 'Text' }],
            },
        };
        expect(checkDesignElementRestrictions(designData, designProductionMethodSubset)).toEqual({
            type: 'maxImages',
            max: 1,
        });
        const designDataWithSpace = {
            canvasData: {
                objects: [{ type: 'Text' }],
            },
        };
        expect(checkDesignElementRestrictions(designDataWithSpace, designProductionMethodSubset)).toBe(null);
    });
    test('checkDesignElementRestrictions matches the maxTexts rule', () => {
        const designProductionMethodSubset = { maxTexts: 1 };
        const designData = {
            canvasData: {
                objects: [{ type: 'Image' }, { type: 'Text' }],
            },
        };
        expect(checkDesignElementRestrictions(designData, designProductionMethodSubset)).toEqual({
            type: 'maxTexts',
            max: 1,
        });
        const designDataWithSpace = {
            canvasData: {
                objects: [{ type: 'Image' }],
            },
        };
        expect(checkDesignElementRestrictions(designDataWithSpace, designProductionMethodSubset)).toBe(null);
    });
    test('checkDesignElementRestrictions matches only the specified type', () => {
        const designProductionMethodSubset = { maxTexts: 1, maxImages: 2 };
        const designData = {
            canvasData: {
                objects: [{ type: 'Image' }, { type: 'Image' }],
            },
        };
        expect(checkDesignElementRestrictions(designData, designProductionMethodSubset, 'text')).toBe(null);
        expect(checkDesignElementRestrictions(designData, designProductionMethodSubset, 'image')).toEqual({
            type: 'maxImages',
            max: 2,
        });
    });
    test('checkDesignElementRestrictionsWithRemovalCount matches the maxElements rule', () => {
        const designProductionMethodSubset = { maxElements: 2 };
        const designData = {
            canvasData: {
                objects: [{ type: 'Image' }, { type: 'Text' }, { type: 'Text' }],
            },
        };
        expect(
            checkDesignElementRestrictionsWithRemovalCount(designData, designProductionMethodSubset)
        ).toEqual({
            type: 'maxElements',
            max: 2,
            toBeRemovedCount: 1,
        });
        const designDataWithSpace = {
            canvasData: {
                objects: [{ type: 'Image' }, { type: 'Text' }],
            },
        };
        expect(
            checkDesignElementRestrictionsWithRemovalCount(designDataWithSpace, designProductionMethodSubset)
        ).toBe(null);
    });
    test('checkDesignElementRestrictionsWithRemovalCount matches the maxImages rule', () => {
        const designProductionMethodSubset = { maxImages: 1 };
        const designData = {
            canvasData: {
                objects: [{ type: 'Image' }, { type: 'Image' }, { type: 'Image' }],
            },
        };
        expect(
            checkDesignElementRestrictionsWithRemovalCount(designData, designProductionMethodSubset)
        ).toEqual({
            type: 'maxImages',
            max: 1,
            toBeRemovedCount: 2,
        });
        const designDataWithSpace = {
            canvasData: {
                objects: [{ type: 'Image' }],
            },
        };
        expect(
            checkDesignElementRestrictionsWithRemovalCount(designDataWithSpace, designProductionMethodSubset)
        ).toBe(null);
    });
    test('checkDesignElementRestrictionsWithRemovalCount matches the maxTexts rule', () => {
        const designProductionMethodSubset = { maxTexts: 1 };
        const designData = {
            canvasData: {
                objects: [{ type: 'Text' }, { type: 'Text' }, { type: 'Text' }],
            },
        };
        expect(
            checkDesignElementRestrictionsWithRemovalCount(designData, designProductionMethodSubset)
        ).toEqual({
            type: 'maxTexts',
            max: 1,
            toBeRemovedCount: 2,
        });
        const designDataWithSpace = {
            canvasData: {
                objects: [{ type: 'Image' }],
            },
        };
        expect(
            checkDesignElementRestrictionsWithRemovalCount(designDataWithSpace, designProductionMethodSubset)
        ).toBe(null);
    });
    test('getDesignElementAvailability returns the correct result', () => {
        const createConfigurationWithProductionMethod = identifier => ({
            configurator: {
                configuration: {
                    designdata: {
                        front: {
                            designProductionMethodIdentifier: identifier,
                        },
                    },
                },
            },
        });
        const state = {
            designArea: {
                selectedDesignArea: {
                    identifier: 'front',
                    designProductionMethods: [
                        {
                            identifier: 'print0',
                        },
                        {
                            identifier: 'print1',
                            maxTexts: 0,
                        },
                        {
                            identifier: 'print2',
                            maxImages: 0,
                        },
                    ],
                },
            },
        };
        expect(
            getDesignElementAvailability({
                ...createConfigurationWithProductionMethod('print0'),
                ...state,
            })
        ).toEqual({
            image: true,
            text: true,
        });
        expect(
            getDesignElementAvailability({
                ...createConfigurationWithProductionMethod('print1'),
                ...state,
            })
        ).toEqual({
            image: true,
            text: false,
        });
        expect(
            getDesignElementAvailability({
                ...createConfigurationWithProductionMethod('print2'),
                ...state,
            })
        ).toEqual({
            image: false,
            text: true,
        });
    });
});
