/**
 * atk_caching.spec.js
 *
 * Caching tests.
 *
 */

// Set up Playwright.
import { expect, test } from '@playwright/test'

/** ESLint directives */
/* eslint-disable import/first */
/* eslint-disable no-await-in-loop */

import * as atkCommands from '../support/atk_commands'
import * as atkUtilities from '../support/atk_utilities'

import playwrightConfig from '../../playwright.config'

const baseUrl = playwrightConfig.use.baseURL

// Import ATK Configuration.
import atkConfig from '../../playwright.atk.config'

// 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'

test.describe('Caching tests.', () => {
  const ctx = {
    tmpNid: [],
    adminPage: null,
  }

  test.beforeEach(async ({ browser }) => {
    ctx.adminPage = await atkCommands.getUserPage(browser, qaUserAccounts.admin)
  })

  //
  // Validate Caching.
  //
  test('(ATK-PW-1090) Verify block caching and cache tag functionality. @ATK-PW-1090 @caching @smoke @alters-db', async ({ page }) => {
    const testId = 'ATK-PW-1090'
    const uniqueToken = atkUtilities.createRandomString(6)
    const blockContent = `Block content state ${uniqueToken}`
    const uniqueToken1 = atkUtilities.createRandomString(6)
    const blockContent1 = `Block content state ${uniqueToken1}`

    // Log in as admin.
    const { adminPage } = ctx

    // Create a page.
    await adminPage.goto(baseUrl + atkConfig.pageAddUrl)
    const titleTextField = await adminPage.locator('input[name="title[0][value]"]')
    await titleTextField.fill(`${testId}: A Title`)
    await atkCommands.inputTextIntoCKEditor(adminPage, 'Page to include a block')
    await adminPage.getByRole('button', { name: 'Save' }).first().click()
    await adminPage.waitForEvent('domcontentloaded')
    const pageUrl = adminPage.url()

    // Get the nid.
    const nid = await atkCommands.getNid(adminPage)
    ctx.tmpNid.push(nid)

    // Create a block.
    await adminPage.goto(baseUrl + atkConfig.blockAddUrl)
    await adminPage.getByRole('textbox', { name: 'Block description' }).fill(`${testId}: Custom block`)
    await atkCommands.inputTextIntoCKEditor(adminPage, blockContent)
    await adminPage.getByRole('button', { name: 'Save' }).first().click()

    // Place the block to the content layout.
    // Set the content.
    await adminPage.goto(`${baseUrl}admin/structure/block`)
    await adminPage.getByRole('link', { name: 'Place block in the Content region' }).click()
    await adminPage.locator('tr', { hasText: testId }).first()
      .getByRole('link', { name: 'Place block' }).click()
    await adminPage.locator('#drupal-modal li', { hasText: 'Pages' }).click()
    await adminPage.getByRole('textbox', { name: 'Pages' }).fill(new URL(pageUrl).pathname)
    await adminPage.locator('button', { hasText: 'Save block' }).click()

    // Monitor the page response.
    let responsePromise
    responsePromise = page.waitForResponse(pageUrl)

    // Open the page (now as an original anonymous user).
    await page.goto(pageUrl)
    let response = await responsePromise
    expect(response.headers()['x-drupal-cache']).toEqual('MISS')

    // Open the page again.
    responsePromise = page.waitForResponse(pageUrl)
    await page.goto(pageUrl)
    response = await responsePromise
    expect(response.headers()['x-drupal-cache']).toEqual('HIT')

    // Change the block content.
    await adminPage.goto(`${baseUrl}admin/structure/block`)
    const blockRowLocator = adminPage.locator('tr', { hasText: testId })
    await blockRowLocator.locator('.dropbutton__toggle').click()
    await blockRowLocator.getByText('Edit').click()
    await atkCommands.inputTextIntoCKEditor(adminPage, blockContent1)
    await adminPage.getByRole('button', { name: 'Save' }).first().click()

    // Open the page (as an anonymous user).
    responsePromise = page.waitForResponse(pageUrl)
    await page.goto(pageUrl)
    response = await responsePromise
    expect(response.headers()['x-drupal-cache']).toEqual('MISS')

    // Open the page again.
    responsePromise = page.waitForResponse(pageUrl)
    await page.goto(pageUrl)
    response = await responsePromise
    expect(response.headers()['x-drupal-cache']).toEqual('HIT')
  })

  test.afterEach(async () => {
    // Delete the page.
    ctx.tmpNid.forEach((nid) => {
      atkCommands.deleteNodeWithNid(nid)
    })

    // Remove the block from the content layout.
    const { adminPage } = ctx
    await adminPage.goto(`${baseUrl}admin/structure/block`)
    const blockRowLocator = adminPage.locator('tr', { hasText: 'ATK' }).first()
    while (await blockRowLocator.isVisible()) {
      await blockRowLocator.locator('.dropbutton__toggle').click()
      await blockRowLocator.getByText('Remove').click()
      await adminPage.getByRole('button', { name: 'Remove' }).click()
    }

    // Delete the block.
    await adminPage.goto('admin/content/block')
    while (await blockRowLocator.isVisible()) {
      await blockRowLocator.locator('.dropbutton__toggle').click()
      await blockRowLocator.getByText('Delete').click()
      await adminPage.getByRole('button', { name: 'Delete' }).click()
    }
  })
})
