highlight-share
Version:
Medium-like text selection sharing without dependencies
151 lines (139 loc) • 5.73 kB
JavaScript
/* eslint-disable consistent-return, no-undef, no-unused-expressions */
import chai, { expect } from "chai";
import { spy } from "sinon";
import sinonChai from "sinon-chai";
import { env } from "jsdom";
import * as popover from "../src/popover";
chai.use(sinonChai);
const fakeHTML = "<ul><li data-share-via=\"foo\">Hello, world!</li></ul>";
describe("Popover methods", () => {
describe("lifeCycleFactory", () => {
it("must be a factory function", () => {
expect(popover.lifeCycleFactory).to.be.a("function");
const result = popover.lifeCycleFactory(null);
expect(result).to.be.an("object");
});
it("must create an object with a createPopover method", (done) => {
initLifeCycle((result) => {
expect(result.createPopover).to.be.a("function");
done();
});
});
it("must create an object with an attachPopover method", (done) => {
initLifeCycle((result) => {
expect(result.attachPopover).to.be.a("function");
done();
});
});
it("must create an object with a removePopover method", (done) => {
initLifeCycle((result) => {
expect(result.removePopover).to.be.a("function");
done();
});
});
describe("createPopover", () => {
it("must create a DOM element", (done) => {
initLifeCycle((result, _window) => {
const element = result.createPopover();
expect(element instanceof _window.HTMLElement).to.be.true;
done();
});
});
it("must attach an onclick event listener to the created element", (done) => {
let attached = false;
const fakeElement = {
addEventListener(type, fn) {
expect(attached).to.be.false;
expect(type).to.equal("click");
expect(fn).to.be.a("function");
attached = true;
}
};
const fakeDocument = {
createElement(tagName) {
expect(tagName).to.be.a("string");
return fakeElement;
}
};
const { createPopover } = popover.lifeCycleFactory(fakeDocument);
const fakePopover = createPopover();
expect(fakePopover).to.equal(fakeElement);
done();
});
});
describe("attachPopover", () => {
it("must append the given element to document.body", (done) => {
initLifeCycle((result, _window) => {
const fakePopover = _window.document.createElement("foo");
result.attachPopover(fakePopover);
expect(fakePopover.parentNode).to.equal(_window.document.body);
done();
});
});
});
describe("removePopover", () => {
it("must detach the given element from document.body", (done) => {
initLifeCycle((result, _window) => {
const body = _window.document.body;
const fakePopover = body.firstChild;
result.removePopover(fakePopover);
expect(body.childNodes.length).to.equal(0);
expect(fakePopover.parentNode).to.be.null;
done();
});
});
});
});
describe("popoverClick", () => {
it("must call the sharer's `action` method", (done) => {
env(fakeHTML, (err, _window) => {
const sharer = {
name: "foo",
action: spy()
};
const target = _window.document.body.firstChild.firstChild;
const event = new _window.Event("click");
target.dispatchEvent(event);
popover.popoverClick([ sharer ], event);
expect(sharer.action).to.be.calledOnce;
done();
});
});
it("must get out soon if the sharer isn't found", (done) => {
env(fakeHTML, (err, _window) => {
const sharer = {
name: "bar",
action: spy()
};
const target = _window.document.body.firstChild.firstChild;
const event = new _window.Event("click");
target.dispatchEvent(event);
popover.popoverClick([ sharer ], event);
expect(sharer.action).to.not.be.called;
done();
});
});
it("must get out soon if the element isn't found", (done) => {
env(fakeHTML, (err, _window) => {
const sharer = {
name: "foo",
action: spy()
};
const target = _window.document.body.firstChild.firstChild;
target.removeAttribute("data-share-via");
const event = new _window.Event("click");
target.dispatchEvent(event);
popover.popoverClick([ sharer ], event);
expect(sharer.action).to.not.be.called;
done();
});
});
});
});
function initLifeCycle(callback) {
env(fakeHTML, (err, _window) => {
expect(err).to.be.null;
const result = popover.lifeCycleFactory(_window.document);
callback(result, _window);
});
}