import React from 'react';
import { shallow, mount } from 'enzyme';
import Masthead from './masthead';

describe('<Masthead />', () => {
  const defaultWindowWidth = window.innerWidth;
  describe('menu closed', () => {
    const masthead = shallow(<Masthead />);
    it('should not apply the inverse styles', () => {
      expect(masthead.find('MastheadLinks').props().inverse).toEqual(false);
      expect(masthead.find('MenuDisclosure').props().inverse).toEqual(false);
      expect(masthead.find('CallToAction').props().inverse).toEqual(false);
      expect(masthead.find('NavigationDisclosureIcon').props().inverse).toEqual(
        false,
      );
      expect(masthead.find('SkipToContent').props().inverse).toEqual(false);
    });
  });

  describe('menu open', () => {
    const masthead = mount(<Masthead />);
    masthead.find('.ds-menu-disclosure').simulate('click');

    it('should apply the inverse styles', () => {
      expect(
        masthead
          .find('MastheadLinks')
          .first()
          .props().inverse,
      ).toEqual(true);
      expect(masthead.find('MenuDisclosure').props().inverse).toEqual(true);
      expect(
        masthead
          .find('CallToAction')
          .first()
          .props().inverse,
      ).toEqual(true);
      expect(
        masthead
          .find('NavigationLink')
          .first()
          .props().inverse,
      ).toEqual(true);
      expect(masthead.find('SkipToContent').props().inverse).toEqual(true);
    });
  });

  describe('user login', () => {
    const loginUrl = 'www.test.com';
    const masthead = shallow(<Masthead isLoggedIn loginUrl={loginUrl} />);

    it('should pass the users login status to AccountLogin', () => {
      expect(masthead.find('AccountLogin').props().isLoggedIn).toEqual(true);
    });

    it('should pass the login url to AccountLogin', () => {
      expect(masthead.find('AccountLogin').props().loginUrl).toEqual(loginUrl);
    });
  });

  describe('subscribe', () => {
    const subscribeUrl = 'www.testsubscribe.com';

    it('should use the default subscribe url', () => {
      const masthead = shallow(<Masthead isLoggedIn />);
      expect(masthead.find('CallToAction').props().href).toEqual(
        'https://subscription.economist.com/DE/EngCore/Ecom/Masthead',
      );
    });

    it('should use a custom subscribe url if passed as a prop', () => {
      const masthead = shallow(
        <Masthead isLoggedIn subscribeUrl={subscribeUrl} />,
      );
      expect(masthead.find('CallToAction').props().href).toEqual(subscribeUrl);
    });

    it('should use "Subscribe" for text on CTA if subscribeCtaText not passed', () => {
      const masthead = shallow(<Masthead showSubscribe />);
      expect(masthead.find('CallToAction').props().text).toEqual('Subscribe');
    });

    it('should use "Upgrade" for text on CTA if passed via subscribeCtaText', () => {
      const masthead = shallow(
        <Masthead showSubscribe subscribeCtaText='Upgrade' />,
      );
      expect(masthead.find('CallToAction').props().text).toEqual('Upgrade');
    });
  });

  describe('selected link', () => {
    it('should pass the selected link to MastheadLinks if passed as a prop', () => {
      const masthead = shallow(<Masthead selectedLink='weekly-edition' />);
      expect(masthead.find('MastheadLinks').props().selectedLink).toEqual(
        'weekly-edition',
      );
    });
  });

  describe('skip to content', () => {
    it('should pass default target ID', () => {
      const wrapper = shallow(<Masthead />);
      expect(wrapper.find('SkipToContent').props().targetId).toEqual(
        'skip-to-content-target',
      );
    });

    it('should pass custom skip target ID', () => {
      const wrapper = shallow(<Masthead skipTargetId='proper-content' />);
      expect(wrapper.find('SkipToContent').props().targetId).toEqual(
        'proper-content',
      );
    });
  });

  describe('extra item', () => {
    it('should render a react component passed as props', () => {
      const expectedText = 'hello';
      const wrapper = shallow(
        <Masthead temporaryExtraItem={<>{expectedText}</>} />,
      );
      expect(
        wrapper.find('.ds-masthead-nav-beta__item--extra-item').text(),
      ).toEqual(expectedText);
    });
  });

  describe('temporary extra item', () => {
    it('should render a react component passed as props', () => {
      const expectedText = 'hello';
      const wrapper = shallow(
        <Masthead temporaryExtraItem={<>{expectedText}</>} />,
      );
      expect(
        wrapper.find('.ds-masthead-nav-beta__item--extra-item').text(),
      ).toEqual(expectedText);
    });

    it('should not add anything to the DOM if nothing is passed (or undefined)', () => {
      const wrapper = shallow(<Masthead />);
      expect(
        wrapper.find('.ds-masthead-nav-beta__item--extra-item').exists(),
      ).toEqual(false);
    });
  });

  describe('AccountNavigation component', () => {
    it('should use the correct data for registered user', () => {
      const masthead = shallow(
        <Masthead
          isLoggedIn
          showSubscribe
          logoutUrl='/log-out'
          gsClientAdminUrl='/client-admin'
          mySubscriptionUrl='/my-subscription'
          personalInfoUrl='/personal-info'
          billingUrl='/billing'
          newslettersAndPreferencesUrl='/newsletters-and-preferences'
          giftSubscriptionsUrl='/gift-subscriptions'
          helpUrl='/help'
        />,
      );
      const accountNavigationAccountData = masthead
        .find('AccountNavigation')
        .props().accountData['account-logged-in'];
      const accountNavigationAccountMainData = masthead
        .find('AccountNavigation')
        .props().accountData['account-logged-in-main'];

      expect(masthead.find('AccountLogin').props().isLoggedIn).toEqual(true);

      expect(accountNavigationAccountData.length).toEqual(8);
      expect(accountNavigationAccountData[0].name).toEqual('My Economist');
      expect(accountNavigationAccountData[0].url).toEqual('/my-economist');
      expect(accountNavigationAccountData[1].name).toEqual('Saved stories');
      expect(accountNavigationAccountData[1].url).toEqual('/saved-stories');
      expect(accountNavigationAccountData[2].name).toEqual('My subscription');
      expect(accountNavigationAccountData[2].url).toEqual('/my-subscription');
      expect(accountNavigationAccountData[3].name).toEqual(
        'Personal information',
      );
      expect(accountNavigationAccountData[3].url).toEqual('/personal-info');
      expect(accountNavigationAccountData[4].name).toEqual(
        'Newsletters & preferences',
      );
      expect(accountNavigationAccountData[4].url).toEqual(
        '/newsletters-and-preferences',
      );
      expect(accountNavigationAccountData[5].name).toEqual(
        'Gift subscriptions',
      );
      expect(accountNavigationAccountData[5].url).toEqual(
        '/gift-subscriptions',
      );
      expect(accountNavigationAccountData[6].name).toEqual('Help');
      expect(accountNavigationAccountData[6].url).toEqual('/help');
      expect(accountNavigationAccountData[7].name).toEqual('Log out');
      expect(accountNavigationAccountData[7].url).toEqual('/log-out');

      expect(accountNavigationAccountMainData.length).toEqual(3);
      expect(accountNavigationAccountMainData[0].name).toEqual('Saved stories');
      expect(accountNavigationAccountMainData[0].url).toEqual('/saved-stories');
      expect(accountNavigationAccountMainData[1].name).toEqual('Account');
      expect(accountNavigationAccountMainData[1].url).toEqual('/my-economist');
      expect(accountNavigationAccountMainData[2].name).toEqual('Log out');
      expect(accountNavigationAccountMainData[2].url).toEqual('/log-out');
    });

    it('should use the correct data for b2c user', () => {
      const masthead = shallow(
        <Masthead
          isLoggedIn
          showSubscribe={false}
          logoutUrl='/log-out'
          gsClientAdminUrl='/client-admin'
          mySubscriptionUrl='/my-subscription'
          personalInfoUrl='/personal-info'
          billingUrl='/billing'
          newslettersAndPreferencesUrl='/newsletters-and-preferences'
          giftSubscriptionsUrl='/gift-subscriptions'
          helpUrl='/help'
        />,
      );
      const accountNavigationAccountData = masthead
        .find('AccountNavigation')
        .props().accountData['account-logged-in'];
      const accountNavigationAccountMainData = masthead
        .find('AccountNavigation')
        .props().accountData['account-logged-in-main'];

      expect(masthead.find('AccountLogin').props().isLoggedIn).toEqual(true);

      expect(accountNavigationAccountData.length).toEqual(9);
      expect(accountNavigationAccountData[0].name).toEqual('My Economist');
      expect(accountNavigationAccountData[0].url).toEqual('/my-economist');
      expect(accountNavigationAccountData[1].name).toEqual('Saved stories');
      expect(accountNavigationAccountData[1].url).toEqual('/saved-stories');
      expect(accountNavigationAccountData[2].name).toEqual('My subscription');
      expect(accountNavigationAccountData[2].url).toEqual('/my-subscription');
      expect(accountNavigationAccountData[3].name).toEqual(
        'Personal information',
      );
      expect(accountNavigationAccountData[3].url).toEqual('/personal-info');
      expect(accountNavigationAccountData[4].name).toEqual('Billing');
      expect(accountNavigationAccountData[4].url).toEqual('/billing');

      expect(accountNavigationAccountData[5].name).toEqual(
        'Newsletters & preferences',
      );
      expect(accountNavigationAccountData[5].url).toEqual(
        '/newsletters-and-preferences',
      );
      expect(accountNavigationAccountData[6].name).toEqual(
        'Gift subscriptions',
      );
      expect(accountNavigationAccountData[6].url).toEqual(
        '/gift-subscriptions',
      );
      expect(accountNavigationAccountData[7].name).toEqual('Help');
      expect(accountNavigationAccountData[7].url).toEqual('/help');
      expect(accountNavigationAccountData[8].name).toEqual('Log out');
      expect(accountNavigationAccountData[8].url).toEqual('/log-out');

      expect(accountNavigationAccountMainData.length).toEqual(3);
      expect(accountNavigationAccountMainData[0].name).toEqual('Saved stories');
      expect(accountNavigationAccountMainData[0].url).toEqual('/saved-stories');
      expect(accountNavigationAccountMainData[1].name).toEqual('Account');
      expect(accountNavigationAccountMainData[1].url).toEqual('/my-economist');
      expect(accountNavigationAccountMainData[2].name).toEqual('Log out');
      expect(accountNavigationAccountMainData[2].url).toEqual('/log-out');
    });

    it('should use the correct data for b2b user', () => {
      const masthead = shallow(
        <Masthead
          isLoggedIn
          showSubscribe={false}
          logoutUrl='/log-out'
          gsClientAdminUrl='/client-admin'
          mySubscriptionUrl='/my-subscription'
          personalInfoUrl='/personal-info'
          billingUrl='/billing'
          newslettersAndPreferencesUrl='/newsletters-and-preferences'
          giftSubscriptionsUrl='/gift-subscriptions'
          helpUrl='/help'
          isGroupSubscriber
        />,
      );
      const accountNavigationAccountData = masthead
        .find('AccountNavigation')
        .props().accountData['account-logged-in'];
      const accountNavigationAccountMainData = masthead
        .find('AccountNavigation')
        .props().accountData['account-logged-in-main'];

      expect(masthead.find('AccountLogin').props().isLoggedIn).toEqual(true);

      expect(accountNavigationAccountData.length).toEqual(7);
      expect(accountNavigationAccountData[0].name).toEqual('My Economist');
      expect(accountNavigationAccountData[0].url).toEqual('/my-economist');
      expect(accountNavigationAccountData[1].name).toEqual('Saved stories');
      expect(accountNavigationAccountData[1].url).toEqual('/saved-stories');
      expect(accountNavigationAccountData[2].name).toEqual('My subscription');
      expect(accountNavigationAccountData[2].url).toEqual('/my-subscription');
      expect(accountNavigationAccountData[3].name).toEqual(
        'Personal information',
      );
      expect(accountNavigationAccountData[3].url).toEqual('/personal-info');

      expect(accountNavigationAccountData[4].name).toEqual(
        'Newsletters & preferences',
      );
      expect(accountNavigationAccountData[4].url).toEqual(
        '/newsletters-and-preferences',
      );
      expect(accountNavigationAccountData[5].name).toEqual('Help');
      expect(accountNavigationAccountData[5].url).toEqual('/help');
      expect(accountNavigationAccountData[6].name).toEqual('Log out');
      expect(accountNavigationAccountData[6].url).toEqual('/log-out');

      expect(accountNavigationAccountMainData.length).toEqual(3);
      expect(accountNavigationAccountMainData[0].name).toEqual('Saved stories');
      expect(accountNavigationAccountMainData[0].url).toEqual('/saved-stories');
      expect(accountNavigationAccountMainData[1].name).toEqual('Account');
      expect(accountNavigationAccountMainData[1].url).toEqual('/my-economist');
      expect(accountNavigationAccountMainData[2].name).toEqual('Log out');
      expect(accountNavigationAccountMainData[2].url).toEqual('/log-out');
    });

    it('should use the correct data for client admin user', () => {
      const masthead = shallow(
        <Masthead
          isLoggedIn
          logoutUrl='/log-out'
          gsClientAdminUrl='/client-admin'
          mySubscriptionUrl='/my-subscription'
          personalInfoUrl='/personal-info'
          billingUrl='/billing'
          newslettersAndPreferencesUrl='/newsletters-and-preferences'
          giftSubscriptionsUrl='/gift-subscriptions'
          helpUrl='/help'
          isClientAdmin
        />,
      );
      const accountNavigationAccountData = masthead
        .find('AccountNavigation')
        .props().accountData['account-logged-in'];
      const accountNavigationAccountMainData = masthead
        .find('AccountNavigation')
        .props().accountData['account-logged-in-main'];

      expect(masthead.find('AccountLogin').props().isLoggedIn).toEqual(true);

      expect(accountNavigationAccountData.length).toEqual(8);
      expect(accountNavigationAccountData[0].name).toEqual('My Economist');
      expect(accountNavigationAccountData[0].url).toEqual('/my-economist');
      expect(accountNavigationAccountData[1].name).toEqual('Saved stories');
      expect(accountNavigationAccountData[1].url).toEqual('/saved-stories');
      expect(accountNavigationAccountData[2].name).toEqual('Admin account');
      expect(accountNavigationAccountData[2].url).toEqual('/client-admin');
      expect(accountNavigationAccountData[3].name).toEqual('My subscription');
      expect(accountNavigationAccountData[3].url).toEqual('/my-subscription');
      expect(accountNavigationAccountData[4].name).toEqual(
        'Personal information',
      );
      expect(accountNavigationAccountData[4].url).toEqual('/personal-info');

      expect(accountNavigationAccountData[5].name).toEqual(
        'Newsletters & preferences',
      );
      expect(accountNavigationAccountData[5].url).toEqual(
        '/newsletters-and-preferences',
      );
      expect(accountNavigationAccountData[6].name).toEqual('Help');
      expect(accountNavigationAccountData[6].url).toEqual('/help');
      expect(accountNavigationAccountData[7].name).toEqual('Log out');
      expect(accountNavigationAccountData[7].url).toEqual('/log-out');

      expect(accountNavigationAccountMainData.length).toEqual(4);
      expect(accountNavigationAccountMainData[0].name).toEqual('Saved stories');
      expect(accountNavigationAccountMainData[0].url).toEqual('/saved-stories');
      expect(accountNavigationAccountMainData[1].name).toEqual('Admin account');
      expect(accountNavigationAccountMainData[1].url).toEqual('/client-admin');
      expect(accountNavigationAccountMainData[2].name).toEqual('Account');
      expect(accountNavigationAccountMainData[2].url).toEqual('/my-economist');
      expect(accountNavigationAccountMainData[3].name).toEqual('Log out');
      expect(accountNavigationAccountMainData[3].url).toEqual('/log-out');
    });
  });

  describe('small screen', () => {
    let masthead;
    beforeAll(() => {
      window.innerWidth = 500;
      masthead = mount(<Masthead />);
    });
    afterAll(() => {
      window.innerWidth = defaultWindowWidth;
    });

    it('should set the menu navigation toggle to true', () => {
      expect(
        masthead
          .find('NavigationList')
          .first()
          .props().showNavToggle,
      ).toEqual(true);
    });
  });

  describe('large screen', () => {
    let masthead;
    beforeAll(() => {
      window.innerWidth = 1200;
      masthead = mount(<Masthead isLoggedIn />);
    });
    afterAll(() => {
      window.innerWidth = defaultWindowWidth;
    });

    it('should set the menu navigation toggle to false', () => {
      expect(
        masthead
          .find('NavigationList')
          .first()
          .props().showNavToggle,
      ).toEqual(false);
    });
  });

  describe('search', () => {
    it('should default to economist.com/search', () => {
      const masthead = shallow(<Masthead />);
      expect(masthead.find('SearchForm').props().searchUrl).toEqual(
        'https://www.economist.com/search',
      );
    });

    it('should use overriding url if supplied', () => {
      const customSearchUrl = 'https://localhost:3110/search';
      const masthead = shallow(
        <Masthead
          overrideUrls={{
            search: customSearchUrl,
          }}
        />,
      );
      expect(masthead.find('SearchForm').props().searchUrl).toEqual(
        customSearchUrl,
      );
    });
  });

  describe('give a gift', () => {
    it('should show the give a gift button when showSubscribe is false and showGiftGivingButton is true', () => {
      const masthead = shallow(
        <Masthead showGiftGivingButton isLoggedIn showSubscribe={false} />,
      );
      expect(masthead.find('CallToAction').props().href).toEqual(
        'https://subscribenow.economist.com/gift',
      );
    });
  });
});
