<commit_before>import sinon from 'sinon';
import '../../src/js/jquery-ui-wrapper.js';
import 'jquery.browser';
import '../../src/js/dragscrollable-br.js';
import 'jquery-colorbox';

import '../../src/js/BookReader.js';
import { BookreaderWithTextSelection, TextSelectionPlugin } from '../../src/js/plugins/plugin.text_selection.js';


/** @type {BookReader} */

// djvu.xml book infos copied from https://ia803103.us.archive.org/14/items/goodytwoshoes00newyiala/goodytwoshoes00newyiala_djvu.xml
const FAKE_XML_1WORD = `<OBJECT data="file://localhost//tmp/derive/goodytwoshoes00newyiala//goodytwoshoes00newyiala.djvu" height="3192" type="image/x.djvu" usemap="goodytwoshoes00newyiala_0001.djvu" width="2454">
<PARAGRAPH><LINE><WORD coords="1216,2768,1256,2640">test</WORD></LINE></PARAGRAPH>
</OBJECT>`;
const FAKE_XML_MULT_WORDS = `<OBJECT data="file://localhost//tmp/derive/goodytwoshoes00newyiala//goodytwoshoes00newyiala.djvu" height="3192" type="image/x.djvu" usemap="goodytwoshoes00newyiala_0001.djvu" width="2454">
<PARAGRAPH><LINE><WORD coords="1216,2768,1256,2640">test1</WORD>
<WORD coords="1400,2768,1500,2640">test2</WORD>
<WORD coords="1600,2768,1700,2640">test3</WORD></LINE></PARAGRAPH></OBJECT>`;
const FAKE_XML_5COORDS = `<OBJECT data="file://localhost//tmp/derive/goodytwoshoes00newyiala//goodytwoshoes00newyiala.djvu" height="3192" type="image/x.djvu" usemap="goodytwoshoes00newyiala_0001.djvu" width="2454">
<PARAGRAPH><LINE><WORD coords="1216,2768,1256,2640,2690">test</WORD></LINE></PARAGRAPH></OBJECT>`;

describe("Generic tests", () => {

  let br;
  beforeEach(() => {
    const parser = new DOMParser()
    document.body.innerHTML = '<div id="BookReader">';
    br = new BookreaderWithTextSelection({
      data: [
        [
          { width: 800, height: 1200,
            uri: '//archive.org/download/BookReader/img/page001.jpg' },
        ],
        [
          { width: 800, height: 1200,
            uri: '//archive.org/download/BookReader/img/page002.jpg' },
          { width: 800, height: 1200,
            uri: '//archive.org/download/BookReader/img/page003.jpg' },
        ],
        [
          { width: 800, height: 1200,
            uri: '//archive.org/download/BookReader/img/page004.jpg' },
          { width: 800, height: 1200,
            uri: '//archive.org/download/BookReader/img/page005.jpg' },
        ]
      ],
    });
    br.enableTextSelection = true;
    br.init();
    sinon.stub(br.textSelectionPlugin, "getPageText").callsFake(async (pageIndex) => {
      switch (pageIndex) {
      case 1: return $(parser.parseFromString(FAKE_XML_1WORD, "text/xml"));
      case 2: return $(parser.parseFromString(FAKE_XML_MULT_WORDS, "text/xml"));
      case 3: return $(parser.parseFromString(FAKE_XML_5COORDS, "text/xml"));
      }
    });
  });

  test("_createPageContainer overriden function still creates a BRpagecontainer element", () => {
    const spy = sinon.spy(br.textSelectionPlugin, 'createTextLayer');
    const $container = br._createPageContainer(1, {});
    expect($container.hasClass("BRpagecontainer")).toBe(true);
    expect(spy.callCount).toBe(1);
  });


  test("_createPageContainer handles index -1", () => {
    const spy = sinon.spy(br.textSelectionPlugin, 'createTextLayer');
    br._createPageContainer(-1, {});
    expect(spy.callCount).toBe(0);
  });

  test("createTextLayer creates an svg layer with paragraph with 1 word element", async () => {
    const $container = br.refs.$brContainer;
    await br.textSelectionPlugin.createTextLayer(1, $container);
    expect($container.find(".textSelectionSVG").length).toBe(1);
    expect($container.find(".BRparagElement").length).toBe(1);
    expect($container.find(".BRwordElement").length).toBe(1);
    expect($container.find(".BRwordElement").text()).toBe("test");
  });

  test("createTextLayer creates an svg layer with paragraph with multiple word elements", async () => {
    const $container = br.refs.$brContainer;
    await br.textSelectionPlugin.createTextLayer(2, $container);
    expect($container.find(".textSelectionSVG").length).toBe(1);
    expect($container.find(".BRparagElement").length).toBe(1);
    expect($container.find(".BRwordElement").length).toBe(5);
    expect($container.find(".BRwordElement").last()).not.toBe(" ");
  });

  test("createTextLayer creates an svg layer with paragraph with word with 5 params coordinates", async () => {
    const $container = br.refs.$brContainer;
    await br.textSelectionPlugin.createTextLayer(3, $container);
    expect($container.find(".textSelectionSVG").length).toBe(1);
    expect($container.find(".BRparagElement").length).toBe(1);
    expect($container.find(".BRwordElement").length).toBe(1);
  });

  const LONG_PRESS_DURATION = 500;
  test("calling stopPageFlip does not allow long click to flip the page", () => {
    const $container = br.refs.$brContainer;
    br.textSelectionPlugin.stopPageFlip($container);
    const currIndex = br.currentIndex();
    $container.find("BRwordElement").mousedown();
    // Waits for long press
    setTimeout(() => {
      $container.find("BRwordElement").mousedown();
      // Waits for flipping animation
      setTimeout(() => {
        expect(br.currentIndex()).toBe(currIndex);
      }, 2000);
    }, LONG_PRESS_DURATION);
  });
})

describe("textSelectionPlugin cosntructor", () => {
  test("textSelectionPlugin constructor with firefox browser", () => {
    const tsp = new TextSelectionPlugin({}, {}, true)
    expect(tsp.djvuPagesPromise).toBe(null);
    expect(tsp.svgParagraphElement).toBe("g");
    expect(tsp.svgWordElement).toBe("text");
  });

  test("textSelectionPlugin constructor not on firefox browser", () => {
    const tsp = new TextSelectionPlugin({}, {}, false)
    expect(tsp.djvuPagesPromise).toBe(null);
    expect(tsp.svgParagraphElement).toBe("text");
    expect(tsp.svgWordElement).toBe("tspan");<commit_msg>add unit test around empty xml<commit_after>import sinon from 'sinon';
import '../../src/js/jquery-ui-wrapper.js';
import 'jquery.browser';
import '../../src/js/dragscrollable-br.js';
import 'jquery-colorbox';

import '../../src/js/BookReader.js';
import { BookreaderWithTextSelection, TextSelectionPlugin } from '../../src/js/plugins/plugin.text_selection.js';


/** @type {BookReader} */

// djvu.xml book infos copied from https://ia803103.us.archive.org/14/items/goodytwoshoes00newyiala/goodytwoshoes00newyiala_djvu.xml
const FAKE_XML_1WORD = `<OBJECT data="file://localhost//tmp/derive/goodytwoshoes00newyiala//goodytwoshoes00newyiala.djvu" height="3192" type="image/x.djvu" usemap="goodytwoshoes00newyiala_0001.djvu" width="2454">
<PARAGRAPH><LINE><WORD coords="1216,2768,1256,2640">test</WORD></LINE></PARAGRAPH>
</OBJECT>`;
const FAKE_XML_MULT_WORDS = `<OBJECT data="file://localhost//tmp/derive/goodytwoshoes00newyiala//goodytwoshoes00newyiala.djvu" height="3192" type="image/x.djvu" usemap="goodytwoshoes00newyiala_0001.djvu" width="2454">
<PARAGRAPH><LINE><WORD coords="1216,2768,1256,2640">test1</WORD>
<WORD coords="1400,2768,1500,2640">test2</WORD>
<WORD coords="1600,2768,1700,2640">test3</WORD></LINE></PARAGRAPH></OBJECT>`;
const FAKE_XML_5COORDS = `<OBJECT data="file://localhost//tmp/derive/goodytwoshoes00newyiala//goodytwoshoes00newyiala.djvu" height="3192" type="image/x.djvu" usemap="goodytwoshoes00newyiala_0001.djvu" width="2454">
<PARAGRAPH><LINE><WORD coords="1216,2768,1256,2640,2690">test</WORD></LINE></PARAGRAPH></OBJECT>`;
const FAKE_XML_EMPTY = '';

describe("Generic tests", () => {

  let br;
  beforeEach(() => {
    const parser = new DOMParser()
    document.body.innerHTML = '<div id="BookReader">';
    br = new BookreaderWithTextSelection({
      data: [
        [
          { width: 800, height: 1200,
            uri: '//archive.org/download/BookReader/img/page001.jpg' },
        ],
        [
          { width: 800, height: 1200,
            uri: '//archive.org/download/BookReader/img/page002.jpg' },
          { width: 800, height: 1200,
            uri: '//archive.org/download/BookReader/img/page003.jpg' },
        ],
        [
          { width: 800, height: 1200,
            uri: '//archive.org/download/BookReader/img/page004.jpg' },
          { width: 800, height: 1200,
            uri: '//archive.org/download/BookReader/img/page005.jpg' },
        ]
      ],
    });
    br.enableTextSelection = true;
    br.init();
    sinon.stub(br.textSelectionPlugin, "getPageText").callsFake(async (pageIndex) => {
      switch (pageIndex) {
      case 1: return $(parser.parseFromString(FAKE_XML_1WORD, "text/xml"));
      case 2: return $(parser.parseFromString(FAKE_XML_MULT_WORDS, "text/xml"));
      case 3: return $(parser.parseFromString(FAKE_XML_5COORDS, "text/xml"));
      case 4: return $(parser.parseFromString(FAKE_XML_EMPTY, "text/xml"))
      }
    });
  });

  test("_createPageContainer overriden function still creates a BRpagecontainer element", () => {
    const spy = sinon.spy(br.textSelectionPlugin, 'createTextLayer');
    const $container = br._createPageContainer(1, {});
    expect($container.hasClass("BRpagecontainer")).toBe(true);
    expect(spy.callCount).toBe(1);
  });


  test("_createPageContainer handles index -1", () => {
    const spy = sinon.spy(br.textSelectionPlugin, 'createTextLayer');
    br._createPageContainer(-1, {});
    expect(spy.callCount).toBe(0);
  });

  test("createTextLayer creates an svg layer with paragraph with 1 word element", async () => {
    const $container = br.refs.$brContainer;
    await br.textSelectionPlugin.createTextLayer(1, $container);
    expect($container.find(".textSelectionSVG").length).toBe(1);
    expect($container.find(".BRparagElement").length).toBe(1);
    expect($container.find(".BRwordElement").length).toBe(1);
    expect($container.find(".BRwordElement").text()).toBe("test");
  });

  test("createTextLayer creates an svg layer with paragraph with multiple word elements", async () => {
    const $container = br.refs.$brContainer;
    await br.textSelectionPlugin.createTextLayer(2, $container);
    expect($container.find(".textSelectionSVG").length).toBe(1);
    expect($container.find(".BRparagElement").length).toBe(1);
    expect($container.find(".BRwordElement").length).toBe(5);
    expect($container.find(".BRwordElement").last()).not.toBe(" ");
  });

  test("createTextLayer creates an svg layer with paragraph with word with 5 params coordinates", async () => {
    const $container = br.refs.$brContainer;
    await br.textSelectionPlugin.createTextLayer(3, $container);
    expect($container.find(".textSelectionSVG").length).toBe(1);
    expect($container.find(".BRparagElement").length).toBe(1);
    expect($container.find(".BRwordElement").length).toBe(1);
  });

  test("createTextLayer can handle empty xml", async () => {
    const $container = br.refs.$brContainer;
    await br.textSelectionPlugin.createTextLayer(4, $container);
    expect($container.find(".textSelectionSVG").length).toBe(1);
    expect($container.find(".BRparagElement").length).toBe(0);
    expect($container.find(".BRwordElement").length).toBe(0);
  });

  const LONG_PRESS_DURATION = 500;
  test("calling stopPageFlip does not allow long click to flip the page", () => {
    const $container = br.refs.$brContainer;
    br.textSelectionPlugin.stopPageFlip($container);
    const currIndex = br.currentIndex();
    $container.find("BRwordElement").mousedown();
    // Waits for long press
    setTimeout(() => {
      $container.find("BRwordElement").mousedown();
      // Waits for flipping animation
      setTimeout(() => {
        expect(br.currentIndex()).toBe(currIndex);
      }, 2000);
    }, LONG_PRESS_DURATION);
  });
})

describe("textSelectionPlugin cosntructor", () => {
  test("textSelectionPlugin constructor with firefox browser", () => {
    const tsp = new TextSelectionPlugin({}, {}, true)
    expect(tsp.djvuPagesPromise).toBe(null);
    expect(tsp.svgParagraphElement).toBe("g");
    expect(tsp.svgWordElement).toBe("text");
  });

  test("textSelectionPlugin constructor not on firefox browser", () => {
    const tsp = new TextSelectionPlugin({}, {}, false)
    expect(tsp.djvuPagesPromise).toBe(null);
    expect(tsp.svgParagraphElement).toBe("text");
    expect(tsp.svgWordElement).toBe("tspan");
{'fraction_non_alphanumeric': 0.17055024119041778, 'fraction_numerical': 0.03899926416482708, 'mean_word_length': 4.254295532646048, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 90, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 13}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1550886', 'n_tokens_mistral': 4332, 'n_tokens_neox': 3956, 'n_words': 606}