import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'

import { singleLetterStringGenerator, goodError2, goodError1, goodComment4, goodComment6 } from './GoodEventLibrary';
import '../src/helpers/EventHelpers';
import { getContent, getFirstLettersofContent, getTag, getPreviousVersionNumber, getEventIcon, getLastCommentContent, getOriginalUsername } from '../src/helpers/EventHelpers.js';
import { goodComment1, goodComment2, badComment3, goodComment5 } from './GoodEventLibrary';
import { badComment1, badError1 } from './BadEventLibrary';



/**
 * This file tests the helper functions defined in helper.js
 */

describe('The helpers functions', () => {

    describe('getContent()', () => {
        it('return plain text when content is filled with plain text only', () => {
            let actualContent = [
                {
                    format: 'plainText',
                    text: "hello"
                }
            ]
            expect(getContent(actualContent, 'plainText')).toBe("hello");
        })

        it('returns null when content is null', () => {
            let actualContent = null
            expect(getContent(actualContent, 'plainText')).toBe(null);
        })

        it('returns null when content is an empty array', () => {
            let actualContent = []
            expect(getContent(actualContent, 'plainText')).toBe(null);
        })

        test('returns html text when content is filled with html text only', () => {
            let actualContent = [
                {
                    format: 'html',
                    text: "<p> hello </p>"
                }
            ]
            expect(getContent(actualContent, 'html')).toBe('<p> hello </p>');
        })

        test('returns null when text property is not defined', () => {
            let actualContent = [
                {
                    format: 'text'
                }
            ]
            expect(getContent(actualContent, 'plainText')).toBe(null);

        })

        test(' returns null when format property is not defined', () => {
            let actualContent = [
                {
                    text: 'hello'
                }
            ]
            expect(getContent(actualContent, 'plainText')).toBe(null);
        })

    })

    describe('getFirstLettersofContent()', () => {
        test('plainText contains more than 100 letters', () => {
            let actualContent = [
                {
                    format: 'plainText',
                    text: singleLetterStringGenerator(95) + "123456789"
                }
            ]
            let expectedText = singleLetterStringGenerator(95) + "12345 ...";
            expect(getFirstLettersofContent(actualContent, 100)).toBe(expectedText);
        })

        test('plainText contains less than 100 letters', () => {
            let actualContent = [
                {
                    format: 'plainText',
                    text: "This is some text"
                }
            ]
            let expectedText = "This is some text";
            expect(getFirstLettersofContent(actualContent, 100)).toBe(expectedText);
        })

        test('content is null', () => {
            let actualContent = null
            expect(getFirstLettersofContent(actualContent, 100)).toBe("");
        })

        test('content is an empty array', () => {
            let actualContent = []
            expect(getFirstLettersofContent(actualContent, 100)).toBe('');
        })

        test('content does not contain the plain text object', () => {
            let actualContent = [
                {
                    format: 'html',
                    text: "<p> hello </p>"
                }
            ]
            expect(getFirstLettersofContent(actualContent, 100)).toBe('');
        })

        test('text property is not defined in the object but format is there', () => {
            let actualContent = [
                {
                    format: 'text'
                }
            ]
            expect(getFirstLettersofContent(actualContent, 100)).toBe('');
        })

        test('format property is not defined in the object but text is there', () => {
            let actualContent = [
                {
                    text: 'hello'
                }
            ]
            expect(getFirstLettersofContent(actualContent, 100)).toBe('');
        })

        test('number of character is not provided', () => {
            let actualContent = [
                {
                    format: 'plainText',
                    text: 'ten characters should be displayed '
                }
            ]
            expect(getFirstLettersofContent(actualContent)).toBe('ten charac ...');
        })
    })

    describe('getTag', () => {
        test('it returns a tag list as a string', () => {
            let actualEvent = goodComment1;

            expect(getTag(actualEvent)).toBe("firstTag secondTag");
        })

        test('it returns an empty string when there is not tag', () => {
            let actualEvent = goodComment2;

            expect(getTag(actualEvent)).toBe("");
        })

        test('it returns an empty string when tag does not exist', () => {
            let actualEvent = badComment3;

            expect(getTag(actualEvent)).toBe("");
        })
    })

    describe('getPreviousVersionNumber', () => {
        test('it returns 0 when no event is provided', () => {
            let actualEvent;

            expect(getPreviousVersionNumber(actualEvent)).toBe(0);
        })

        test('it returns 0 when the event has a previousEventVersion of null', () => {
            let actualEvent = goodComment1;

            expect(getPreviousVersionNumber(actualEvent)).toBe(0);
        })

        test('it returns 0 when the event has a previousEventVersion of undefined', () => {
            let actualEvent = goodError1;

            expect(getPreviousVersionNumber(actualEvent)).toBe(0);
        })

        test('it returns the number of previous version an event has', () => {
            let actualEvent = goodError2;

            expect(getPreviousVersionNumber(actualEvent)).toBe(1);
        })
    })

    describe('getEventIcon', () => {
        it('returns an icon of size 25 when the size is not specified', () => {
            Enzyme.configure({ adapter: new Adapter() });

            let actualCategory = 'comment';
            expect(Enzyme.shallow(getEventIcon(actualCategory)).prop('width')).toBe("25px");
        })

        it('returns an icon which size corresponds to the specified one', () => {
            Enzyme.configure({ adapter: new Adapter() });

            let actualCategory = 'comment';
            let actualSize = "40";
            expect(Enzyme.shallow(getEventIcon(actualCategory, actualSize)).prop('width')).toBe("40px");
        })
    })

    describe('getLastCommentContent', () => {
        it('returns the last comment of an annotation without previous version', () => {
            let actualEvent = goodComment1;
            let expectedContent = [{
                format: 'plainText',
                text: 'plain text content 1'
            }, {
                format: 'html',
                text: '<p> html text content 1 </p>'
            }]

            expect(getLastCommentContent(actualEvent)).toEqual(expectedContent);
        })

        it('returns the last comment of an annotation with several versions', () => {
            let actualEvent = goodComment4;
            let expectedContent = [{
                format: 'plainText',
                text: 'new version of plain text'
            }, {
                format: 'html',
                text: '<p> new version of plain text </p>'
            }]

            expect(getLastCommentContent(actualEvent)).toEqual(expectedContent);
        })

        it('returns null for an uncommented notification', () => {
            let actualEvent = goodError1;
            let expectedContent = null;

            expect(getLastCommentContent(actualEvent)).toBe(null);
        })

        it('returns the last comment for a commented notification', () => {
            let actualEvent = goodError2;
            let expectedContent = [{
                format: "plainText",
                text: "this is a user comment on the error"
            }];

            expect(getLastCommentContent(actualEvent)).toEqual(expectedContent);
        })

        it('returns null when the event has no type', () => {
            let actualEvent = badComment3;
            let expectedContent = null;

            expect(getLastCommentContent(actualEvent)).toBe(null);
        })
    })

    describe('getOriginalUsername', () => {
        it('returns the original username for an event which has no previous version', () => {
            let actualEvent = goodComment1;
            expect(getOriginalUsername(actualEvent)).toBe('mchaille');
        })

        it('returns the original username for an event which has a previous version', () => {
            let actualEvent = goodComment5;
            expect(getOriginalUsername(actualEvent)).toBe('agoetz');
        })

        it('returns null when the original username does not exist', () => {
            let actualEvent = goodComment6;
            expect(getOriginalUsername(actualEvent)).toBe(null);
        })

    })
})