/**
 * atk_simple_sitemap.cy.js
 *
 * Validate sitemap.xml.
 *
 */

/** ESLint directives */
/* eslint-disable import/first */

/// <reference types='Cypress' />

// Set up ATK.
import X2JS from 'x2js'
import * as atkCommands from '../../support/atk_commands' // eslint-disable-line no-unused-vars
import * as atkUtilities from '../../support/atk_utilities' // eslint-disable-line no-unused-vars
import atkConfig from '../../../cypress.atk.config' // eslint-disable-line no-unused-vars

// Standard accounts that use user accounts created
// by QA Accounts. QA Accounts are created when the QA
// Accounts module is enabled.
import qaUserAccounts from '../../data/qaUsers.json'

describe('Simple Sitemap tests.', () => {
  //
  // Confirm at least one sitemap exists; report total number of sitemaps.
  // Based on https://glebbahmutov.com/blog/test-sitemap/.
  //
  it('(ATK-CY-1080) Check if there is a sitemap file; fail if not.', { tags: ['@ATK-CY-1080', '@simple-sitemap', '@smoke'] }, () => {
    // eslint-disable-next-line no-unused-vars
    const testId = 'ATK-CY-1080'
    // If there isn't at least one sitemap, this will fail.
    cy.request('/sitemap.xml')
      .its('body')
      .then((body) => {
        const x2js = new X2JS()
        const json = x2js.xml2js(body)
        // Sitemap with one record only is a legitimate sitemap as well.
        expect(json.urlset.url).not.to.be.undefined
        if (!(json.urlset.url instanceof Array)) {
          json.urlset.url = [json.urlset.url]
        }
        // Get all URLs from the sitemap
        expect(json.urlset.url).to.be.an('array').and.have.length.gt(0)
        json.urlset.url.forEach((url) => {
          const parsed = new URL(url.loc)
          cy.log(parsed.pathname)

          // check if the resource exists
          cy.request('HEAD', url.loc).its('status').should('eq', 200)
          // visit the page to check if it loads in the browser
          // disable to speed up the test, if there are many nodes
          // eslint-disable-next-line cypress/no-unnecessary-waiting
          cy.visit(url.loc).wait(1000, { log: false })
        })
      })
  })

  //
  // Regenerate sitemap files.
  // 1. Identify if there are sitemap items.
  // 2. Fetch the sitemap.xml header date timestamp.
  // 3. Use drush simple-sitemap:generate to create a fresh sitemap.xml file.
  // 4. Compare header timestamps.
  //
  it('(ATK-CY-1081) Regenerate sitemap files.', { tags: ['@ATK-CY-1081', '@simple-sitemap', '@smoke'] }, () => {
    const testId = 'ATK-CY-1081' // eslint-disable-line no-unused-vars

    //
    // Step 1. Identify if there are sitemap items.
    //
    cy.logInViaForm(qaUserAccounts.admin)
    cy.visit(atkConfig.simpleSitemapUrl)

    // Check for sitemap items.
    let found = false
    const siteMapItems = []
    // eslint-disable-next-line cypress/unsafe-to-chain-command
    cy.get('table tbody tr')
      .each(($tr) => {
        const site = $tr.find('td:nth-child(1)').text()
        siteMapItems.push(site)
        if (site) {
          cy.wrap($tr.find('td:nth-child(1)').text()).as('siteMapItem')
          found = true
        }
      })
      .then(() => {
        assert(found, `At least one entry has ${found ? '' : '**not** '}been found in the table, actual sitemap items are [${siteMapItems.join(',')}]`)
      })

    //
    // Step 2. Fetch the date property for the sitemap xml file header.
    //
    cy.request('/sitemap.xml').its('headers').its('date').as('firstDate')

    //
    // Step 3. Regenerate the sitemap files, which will change the timestamp.
    //
    cy.execDrush('simple-sitemap:generate')

    cy.request('/sitemap.xml').its('headers').its('date').as('secondDate')

    //
    // Step 4. Compare the timestamps. They should be different.
    //
    // Verify timestamps changed.
    cy.get('@firstDate').should('not.be.undefined')
    cy.get('@secondDate').should('not.be.undefined')
    cy.get('@firstDate').then((firstDate) => {
      cy.get('@secondDate').should('not.eq', firstDate)
    })
  })
})
