content: /**
   * Copyright (c) 2016 - 2022 Alex Grant (@localnerve), LocalNerve LLC
   * Copyrights licensed under the BSD License. See the accompanying LICENSE file
   * for terms.
   */
  /* global afterEach, describe, it, beforeEach */
  import { expect } from 'chai';
  import React from 'react';
  import testUtils from 'react-dom/test-utils';
  import { RouteStore } from 'application/stores/RouteStore';
  import { BackgroundStore } from 'application/stores/BackgroundStore';
  import html from 'application/components/Html';
  import { createMockComponentContext } from 'fluxible/utils';
  // HtmlComponent never renders on the client, so dont make dom until test render
  import { start as testDomStart, stop as testDomStop } from 'test/utils/testdom';
  
  describe('html component', () => {
    let htmlComponent;
  
    const testProps = {
      mainScript: 'path/to/mainScript',
      polyfills: [
        'somefeature'
      ],
      trackingSnippet: 'window["SomeTrackingCode"] = 0;',
      inlineStyles: '@charset "UTF-8";',
      inlineScript: 'window["MyTest"] = 0;',
      state: '123456789',
      markup: 'Hello World',
      appManifest: 'path/to/manifest.json',
      otherStyles: [
        'path/to/otherstyles1.css'
      ],
      browserConfig: 'path/to/browserConfig.xml',
      swRegistrationScript: 'path/to/service-worker-registration.js',
      swMainScript: 'service-worker.js',
      revAsset: (asset) => asset
    };
  
    /**
     * renderIntoDocument for html element.
     *
     * Replaces testUtils.renderIntoDocument.
     * renderIntoDocument no longer supports React html components as it wraps
     * everything in a div.
     * https://github.com/facebook/react/issues/5128
     *
     * Must start testDom (jsdom) first.
     *
     * @param {ReactElement} el - the html element.
     * @returns {ReactComponent} The html component.
     */
    function renderHtmlIntoDocument (el) {
      const ReactDOM = require('react-dom');
      const ReactDOMServer = require('react-dom/server');
  
      const iframe = global.document.createElement('iframe');
  
      global.document.body.appendChild(iframe);
      iframe.src = 'about:blank';
      iframe.contentWindow.document.open();
      iframe.contentWindow.document.write(ReactDOMServer.renderToString(el));
      iframe.contentWindow.document.close();
  
      /* eslint-disable react/no-render-return-value */
      return ReactDOM.render(el, iframe.contentWindow.document);
      /* eslint-enable react/no-render-return-value */
    }
  
    beforeEach(() => {
      testProps.context = createMockComponentContext({
        stores: [RouteStore, BackgroundStore]
      });
      const htmlElement = React.createFactory(html)(testProps);
  
      // This enables dom render after HtmlComponent factory call.
      // This mimics what really happens.
      // Suppress JSDOM errors b/c resources do not really exist.
      testDomStart(null, {
        suppressJSDOMError: true
      });
  
      // Create the htmlComponent for use in tests.
      htmlComponent = renderHtmlIntoDocument(htmlElement);
    });
  
    afterEach(() => {
      // Remove the dom for the next HtmlComponent factory call.
      testDomStop();
    });
  
    it('should render inline styles', () => {
      const component =
        testUtils.findRenderedDOMComponentWithTag(htmlComponent, 'style');
      expect(component.textContent).to.equal(testProps.inlineStyles);
    });
  
    it('should render a title', () => {
      const component =
        testUtils.scryRenderedDOMComponentsWithTag(htmlComponent, 'title');
      expect(component[0].textContent).to.be.empty;
    });
  
    it('should render a section', () => {
      const component =
        testUtils.findRenderedDOMComponentWithTag(htmlComponent, 'section');
      expect(component.textContent).to.equal(testProps.markup);
    });
  
    it('should render a standard app manifest', () => {
      const links =
        testUtils.scryRenderedDOMComponentsWithTag(htmlComponent, 'link');
      const manifestLink = links.filter((link) => {
        return link.getAttribute('rel') === 'manifest';
      });
  
      expect(manifestLink.length).to.equal(1);
      expect(testProps.appManifest)
        .to.contain(manifestLink[0].getAttribute('href'));
    });
  
    it('should render css meta holders for external stylesheet loads', () => {
      const metas =
        testUtils.scryRenderedDOMComponentsWithTag(htmlComponent, 'meta');
      const cssMetas = metas.filter((meta) => {
        return meta.getAttribute('itemprop') === 'stylesheet';
      });
  
      expect(cssMetas.length).to.equal(1);
      expect(
        testProps.otherStyles[0]
      ).to.contain(cssMetas[0].getAttribute('content'));
    });
  
    it('should render multiple scripts', () => {
      const component =
        testUtils.scryRenderedDOMComponentsWithTag(htmlComponent, 'script');
  
      expect(component.length).to.equal(4);
      expect(component[0].textContent).to.equal(testProps.trackingSnippet);
      expect(
        component[1].getAttribute('src')
      ).to.equal(testProps.swRegistrationScript);
      expect(
        component[1].getAttribute('data-service-worker')
      ).to.equal(testProps.swMainScript);
      expect(component[2].textContent).to.equal(testProps.inlineScript);
      expect(
        component[2].getAttribute('data-main-script')
      ).to.equal(testProps.mainScript);
      expect(
        component[2].getAttribute('data-polyfills')
      ).to.equal(testProps.polyfills[0]);
      expect(component[3].textContent).to.equal(testProps.state);
    });
  });
  