/**
 * @jest-environment jsdom
 */

import { getByLabelText } from '@testing-library/dom';
import { getRenderFn } from './testHelpers';

it('renders a list', async () => {
  const render = await getRenderFn('{% for item in items %}<div>{{ item }}</div>{% endfor %}');
  let result = render({ items: [1, 2, 3, 4] });
  expect(result).toHaveTextContent('1234');
  result = render({ items: [4, 3, 2, 1] });
  expect(result).toHaveTextContent('4321');
});

it('renders a keyed list', async () => {
  const render = await getRenderFn(
    `{% for item in items | key %}
      <label for="item-{{item.public_id}}">{{ item.value }}</label>
      <input type="checkbox" value={{item.value}} id="item-{{ item.public_id }}">
    {% endfor %}`
  );
  let result = render({
    items: [
      { public_id: 1, value: 'one' },
      { public_id: 2, value: 'two' }
    ]
  });

  expect(getByLabelText(result, 'one')).not.toBeChecked();
  expect(getByLabelText(result, 'two')).not.toBeChecked();

  getByLabelText(result, 'one').checked = true;

  // reorder the items - the checkbox state should be preserved
  result = render({
    items: [
      { public_id: 2, value: 'two' },
      { public_id: 1, value: 'one' }
    ]
  });

  // by keying the loop, checkbox "one" stays checked
  // if we didn't key the loop, then checkbox two would be checked instead
  expect(getByLabelText(result, 'one')).toBeChecked();
  expect(getByLabelText(result, 'two')).not.toBeChecked();
});

it('renders an else', async () => {
  const render = await getRenderFn(
    `{% for item in items %}
      <div>{{ item }}</div>
    {% else %}
      <div>No items</div>
    {% endfor %}`
  );
  let result = render({ items: [] });
  expect(result).toHaveTextContent('No items');

  result = render({ items: [1] });
  expect(result).toHaveTextContent('1');

  result = render({});
  expect(result).toHaveTextContent('No items');
});

it('renders nested lists', async () => {
  const render = await getRenderFn(
    `{% for row in table %}
      <div class="row">
        {% for cell in row %}
          <span class="cell">{{ cell }}</span>
        {% endfor %}
      </div>
    {% endfor %}`
  );

  let result = render({
    table: [
      [1, 2, 3],
      [4, 5, 6]
    ]
  });

  const rows = result.querySelectorAll('.row');
  expect(rows).toHaveLength(2);
  expect(rows[0]).toHaveTextContent('1 2 3');
  expect(rows[1]).toHaveTextContent('4 5 6');
});

it('handles select', async () => {
  const render = await getRenderFn(
    `{% for item in items | select(type="fruit") %}
      <div>{{ item.name }}</div>
    {% endfor %}
    `
  );

  let result = render({
    items: [
      { name: 'Apple', type: 'fruit' },
      { name: 'Carrot', type: 'vegetable' },
      { name: 'Banana', type: 'fruit' }
    ]
  });

  expect(result).toHaveTextContent('Apple');
  expect(result).toHaveTextContent('Banana');
  expect(result).not.toHaveTextContent('Carrot');
});
