Skip to content

Commit

Permalink
[Resolver] SideEffectContext changes
Browse files Browse the repository at this point in the history
* `getBoundingClientRect` is now access through `SideEffectContext`.
* `writeText` from the `Clipboard` API is now accessed through the
`SideEffectContext`
* No longer using `@testing-library/react` and `@testing-library/react-hooks`
* No longer using `jest.spyOn` or `jest.clearAllMocks`
  • Loading branch information
oatkiller committed Oct 19, 2020
1 parent db14725 commit ba41788
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 102 deletions.
27 changes: 27 additions & 0 deletions x-pack/plugins/security_solution/public/resolver/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,26 @@ export interface SideEffectors {
* A function which returns the time since epoch in milliseconds. Injected because mocking Date is tedious.
*/
timestamp: () => number;
/**
* Use instead of `window.requestAnimationFrame`
**/
requestAnimationFrame: typeof window.requestAnimationFrame;
/**
* Use instead of `window.cancelAnimationFrame`
**/
cancelAnimationFrame: typeof window.cancelAnimationFrame;
/**
* Use instead of the `ResizeObserver` global.
*/
ResizeObserver: ResizeObserverConstructor;
/**
* Use this instead of the Clipboard API's `writeText` method.
*/
writeTextToClipboard(text: string): Promise<void>;
/**
* Use this instead of `Element.prototype.getBoundingClientRect` .
*/
getBoundingClientRect(element: Element): DOMRect;
}

export interface SideEffectSimulator {
Expand All @@ -512,6 +529,16 @@ export interface SideEffectSimulator {
* Trigger `ResizeObserver` callbacks for `element` and update the mocked value for `getBoundingClientRect`.
*/
simulateElementResize: (element: Element, contentRect: DOMRect) => void;

/**
* Get the most recently written clipboard text. This is only updated when `confirmTextWrittenToClipboard` is called.
*/
clipboardText: string;

/**
* Call this to resolve the promise returned by `writeText`.
*/
confirmTextWrittenToClipboard: () => void;
};
/**
* Mocked `SideEffectors`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ const sideEffectors: SideEffectors = {
return window.cancelAnimationFrame(...args);
},
ResizeObserver,
writeTextToClipboard(text: string): Promise<void> {
return navigator.clipboard.writeText(text);
},
getBoundingClientRect(element: Element): DOMRect {
return element.getBoundingClientRect();
},
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const sideEffectSimulatorFactory: () => SideEffectSimulator = () => {
/**
* Get the simulate `DOMRect` for `element`.
*/
const contentRectForElement: (target: Element) => DOMRect = (target) => {
const getBoundingClientRect: (target: Element) => DOMRect = (target) => {
if (contentRects.has(target)) {
return contentRects.get(target)!;
}
Expand All @@ -58,26 +58,33 @@ export const sideEffectSimulatorFactory: () => SideEffectSimulator = () => {
};

/**
* Change `Element.prototype.getBoundingClientRect` to return our faked values.
* Last value written to the clipboard, of '' if no text has been written. Returned by the `controls`.
*/
jest
.spyOn(Element.prototype, 'getBoundingClientRect')
.mockImplementation(function (this: Element) {
return contentRectForElement(this);
});
let clipboardText: string = ''; // the `readText` method of the Clipboard API returns an empty string if the clipboard is empty.

function confirmTextWrittenToClipboard() {
const next = clipboardWriteTextQueue.shift();
if (next) {
const [text, resolve] = next;
clipboardText = text;
resolve();
}
}

/**
* Mock the global writeText method as it is not available in jsDOM and alows us to track what was copied
* Queue of `text` waiting to be written to the clipboard. Calling `resolve` will resolve the promise returned by the mock `writeTextToClipboard` method.
*/
const MockClipboard: Clipboard = {
writeText: jest.fn(),
readText: jest.fn(),
addEventListener: jest.fn(),
dispatchEvent: jest.fn(),
removeEventListener: jest.fn(),
};
// @ts-ignore navigator doesn't natively exist on global
global.navigator.clipboard = MockClipboard;
const clipboardWriteTextQueue: Array<[text: string, resolve: () => void]> = [];

/**
* Mock `writeText` method of the `Clipboard` API.
*/
function writeTextToClipboard(text: string): Promise<void> {
return new Promise((resolve) => {
clipboardWriteTextQueue.push([text, resolve]);
});
}

/**
* A mock implementation of `ResizeObserver` that works with our fake `getBoundingClientRect` and `simulateElementResize`
*/
Expand Down Expand Up @@ -171,12 +178,20 @@ export const sideEffectSimulatorFactory: () => SideEffectSimulator = () => {
},

simulateElementResize,

get clipboardText() {
return clipboardText;
},

confirmTextWrittenToClipboard,
},
mock: {
requestAnimationFrame,
cancelAnimationFrame,
timestamp,
ResizeObserver: MockResizeObserver,
writeTextToClipboard,
getBoundingClientRect,
},
};
return retval;
Expand Down
Loading

0 comments on commit ba41788

Please sign in to comment.