@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
1,164 lines (1,102 loc) • 33.6 kB
JavaScript
import * as R from "ramda";
import {
findFocusableNode,
getLastFocusedItems,
getPreferableItems,
getPriorityItems,
getSelectedItems,
hasPriorityInDirection,
} from "../../Utils";
import { FocusDirection } from "../../../../directionHelper";
import { Tree } from "../../Tree";
const directionMocks = {
right: { axis: "x", isHorizontal: true, isVertical: false, value: "right" },
left: { axis: "x", isHorizontal: true, isVertical: false, value: "left" },
up: { axis: "x", isHorizontal: false, isVertical: true, value: "up" },
down: { axis: "x", isHorizontal: false, isVertical: true, value: "down" },
};
const screenMock1 = {
root: {
id: "root",
children: [
{
id: "menu",
parent: {
id: "root",
},
children: [
{
id: "1dfa32eb-c1b6-4056-b566-ae001978d9eb",
parent: {
id: "menu",
},
component: {
props: {
id: "1dfa32eb-c1b6-4056-b566-ae001978d9eb",
groupId: "menu",
preferredFocus: false,
},
selected: false,
getRect: jest.fn(() => ({
top: 60,
left: 678,
right: 931,
bottom: 90,
width: 253,
height: 30,
x: 0,
y: 0,
})),
},
},
{
id: "a892edf2-ceb6-425f-8fdb-3e58b38b233e",
parent: {
id: "menu",
},
component: {
props: {
id: "a892edf2-ceb6-425f-8fdb-3e58b38b233e",
groupId: "menu",
preferredFocus: true,
},
selected: true,
getRect: jest.fn(() => ({
top: 60,
left: 931,
right: 1130,
bottom: 90,
width: 199,
height: 30,
x: 0,
y: 0,
})),
},
},
],
component: {
props: {
id: "menu",
preferredFocus: true,
},
getRect: jest.fn(() => ({
top: 0,
left: 0,
right: 1920,
bottom: 100,
width: 1920,
height: 100,
x: 0,
y: 0,
})),
},
},
{
id: "ScreenPicker",
parent: {
id: "root",
},
children: [
{
id: "ScreenPicker.ScreenSelector",
parent: {
id: "ScreenPicker",
},
children: [
{
id: 14948,
parent: {
id: "ScreenPicker.ScreenSelector",
},
component: {
props: {
id: 14948,
groupId: "ScreenPicker.ScreenSelector",
preferredFocus: true,
},
selected: false,
getRect: jest.fn(() => ({
top: 131,
left: 112,
right: 412,
bottom: 188,
width: 300,
height: 57,
x: 0,
y: 0,
})),
},
},
{
id: 14949,
parent: {
id: "ScreenPicker.ScreenSelector",
},
component: {
props: {
id: 14949,
groupId: "ScreenPicker.ScreenSelector",
preferredFocus: false,
},
selected: false,
getRect: jest.fn(() => ({
top: 188,
left: 112,
right: 412,
bottom: 245,
width: 300,
height: 57,
x: 0,
y: 0,
})),
},
},
{
id: 14950,
parent: {
id: "ScreenPicker.ScreenSelector",
},
component: {
props: {
id: 14950,
groupId: "ScreenPicker.ScreenSelector",
preferredFocus: false,
},
selected: true,
getRect: jest.fn(() => ({
top: 245,
left: 112,
right: 412,
bottom: 302,
width: 300,
height: 57,
x: 0,
y: 0,
})),
},
},
{
id: 16270,
parent: {
id: "ScreenPicker.ScreenSelector",
},
component: {
props: {
id: 16270,
groupId: "ScreenPicker.ScreenSelector",
preferredFocus: false,
},
selected: false,
getRect: jest.fn(() => ({
top: 302,
left: 112,
right: 412,
bottom: 359,
width: 300,
height: 57,
x: 0,
y: 0,
})),
},
},
],
component: {
props: {
id: "ScreenPicker.ScreenSelector",
groupId: "ScreenPicker",
preferredFocus: true,
},
getRect: jest.fn(() => ({
top: 101,
left: 112,
right: 412,
bottom: 2186,
width: 300,
height: 2085,
x: 0,
y: 0,
})),
},
},
{
id: "ScreenPicker.ScreenContainer",
parent: {
id: "ScreenPicker",
},
children: [
{
id: "Grid",
parent: {
id: "ScreenPicker.ScreenContainer",
},
children: [
{
id: "Grid+5bc7813a8c1abc222700000e",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+5bc7813a8c1abc222700000e",
groupId: "Grid",
preferredFocus: true,
},
getRect: jest.fn(() => ({
top: 758,
left: 526,
right: 955,
bottom: 1245,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+5af0a05a841c4b344c00002a",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+5af0a05a841c4b344c00002a",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 758,
left: 955,
right: 1384,
bottom: 1245,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+5ae9f107dbc8585711000011",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+5ae9f107dbc8585711000011",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 758,
left: 1384,
right: 1813,
bottom: 1245,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+5ad6451a841c4b3168000017",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+5ad6451a841c4b3168000017",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 1245,
left: 526,
right: 955,
bottom: 1732,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+5ad50977dbc8580f24000002",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+5ad50977dbc8580f24000002",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 1245,
left: 955,
right: 1384,
bottom: 1732,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+5abbb261841c4b026d00001b",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+5abbb261841c4b026d00001b",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 1245,
left: 1384,
right: 1813,
bottom: 1732,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+5a553591148bb0623f00000b",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+5a553591148bb0623f00000b",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 1732,
left: 526,
right: 955,
bottom: 2219,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+5a284cb8148bb006e3000002",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+5a284cb8148bb006e3000002",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 1732,
left: 955,
right: 1384,
bottom: 2219,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+59dd327b2d1ca033d3000027",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+59dd327b2d1ca033d3000027",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 1732,
left: 1384,
right: 1813,
bottom: 2219,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+594d8085fd2e611a7600002a",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+594d8085fd2e611a7600002a",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 2219,
left: 526,
right: 955,
bottom: 2706,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+594ad354fd2e61585c000019",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+594ad354fd2e61585c000019",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 2219,
left: 955,
right: 1384,
bottom: 2706,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
{
id: "Grid+59405d44b57ac32c80000014",
parent: {
id: "Grid",
},
component: {
props: {
id: "Grid+59405d44b57ac32c80000014",
groupId: "Grid",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 2219,
left: 1384,
right: 1813,
bottom: 2706,
width: 429,
height: 487,
x: 0,
y: 0,
})),
},
},
],
component: {
props: {
id: "Grid",
groupId: "ScreenPicker.ScreenContainer",
preferredFocus: true,
},
getRect: jest.fn(() => ({
top: 661,
left: 412,
right: 1912,
bottom: 2706,
width: 1500,
height: 2045,
x: 0,
y: 0,
})),
},
},
{
id: "Hero",
parent: {
id: "ScreenPicker.ScreenContainer",
},
children: [
{
id: "Hero+5ad6451a841c4b3168000017",
parent: {
id: "Hero",
},
component: {
props: {
id: "Hero+5ad6451a841c4b3168000017",
groupId: "Hero",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 180,
left: -596,
right: 558,
bottom: 661,
width: 1154,
height: 481,
x: 0,
y: 0,
})),
},
},
{
id: "Hero+5bc7813a8c1abc222700000e",
parent: {
id: "Hero",
},
component: {
props: {
id: "Hero+5bc7813a8c1abc222700000e",
groupId: "Hero",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 180,
left: 558,
right: 1712,
bottom: 661,
width: 1154,
height: 481,
x: 0,
y: 0,
})),
},
},
{
id: "Hero+5af0a05a841c4b344c00002a",
parent: {
id: "Hero",
},
component: {
props: {
id: "Hero+5af0a05a841c4b344c00002a",
groupId: "Hero",
preferredFocus: true,
},
getRect: jest.fn(() => ({
top: 180,
left: 1712,
right: 2866,
bottom: 661,
width: 1154,
height: 481,
x: 0,
y: 0,
})),
},
},
{
id: "Hero+5ae9f107dbc8585711000011",
parent: {
id: "Hero",
},
component: {
props: {
id: "Hero+5ae9f107dbc8585711000011",
groupId: "Hero",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 180,
left: 2866,
right: 4020,
bottom: 661,
width: 1154,
height: 481,
x: 0,
y: 0,
})),
},
},
],
component: {
props: {
id: "Hero",
groupId: "ScreenPicker.ScreenContainer",
preferredFocus: true,
},
getRect: jest.fn(() => ({
top: 131,
left: 412,
right: 1912,
bottom: 661,
width: 1500,
height: 530,
x: 0,
y: 0,
})),
},
},
],
component: {
props: {
id: "ScreenPicker.ScreenContainer",
groupId: "ScreenPicker",
preferredFocus: false,
},
getRect: jest.fn(() => ({
top: 101,
left: 412,
right: 1912,
bottom: 2186,
width: 1500,
height: 2085,
x: 0,
y: 0,
})),
},
},
],
component: {
props: {
id: "ScreenPicker",
preferredFocus: true,
},
getRect: jest.fn(() => ({
top: 100,
left: 0,
right: 1920,
bottom: 2186,
width: 1920,
height: 2086,
x: 0,
y: 0,
})),
},
},
],
},
};
const priorityMock = [
{
id: "child1",
parent: {
id: "parent1",
lastFocusedItem: "child5",
component: { isWithMemory: R.T },
},
component: {
props: { id: "child1", preferredFocus: false, selected: false },
},
},
{
id: "child2",
parent: {
id: "parent1",
lastFocusedItem: "child5",
component: { isWithMemory: R.T },
},
component: {
props: { id: "child2", preferredFocus: true, selected: false },
},
},
{
id: "child3",
parent: {
id: "parent1",
lastFocusedItem: "child5",
component: { isWithMemory: R.T },
},
component: {
props: { id: "child3", preferredFocus: false, selected: false },
},
},
{
id: "child4",
parent: {
id: "parent1",
lastFocusedItem: "child5",
component: { isWithMemory: R.T },
},
component: {
props: { id: "child4", preferredFocus: false, selected: true },
},
},
{
id: "child5",
parent: {
id: "parent1",
lastFocusedItem: "child5",
component: { isWithMemory: R.T },
},
component: {
props: { id: "child5", preferredFocus: false, selected: false },
},
},
];
const priorityMock2 = [
{
id: "child1",
parent: {
id: "parent1",
lastFocusedItem: "child5",
component: { isWithMemory: R.T },
},
component: {
props: { id: "child1", preferredFocus: false, selected: false },
},
},
{
id: "child2",
parent: {
id: "parent1",
lastFocusedItem: "child5",
component: { isWithMemory: R.T },
},
component: {
props: { id: "child2", preferredFocus: true, selected: false },
},
},
{
id: "child3",
parent: {
id: "parent1",
lastFocusedItem: "child5",
component: { isWithMemory: R.T },
},
component: {
props: { id: "child3", preferredFocus: false, selected: false },
},
},
{
id: "child4",
parent: {
id: "parent1",
lastFocusedItem: "child5",
component: { isWithMemory: R.T },
},
component: {
props: { id: "child4", preferredFocus: false, selected: false },
},
},
{
id: "child5",
parent: {
id: "parent1",
lastFocusedItem: "child5",
component: { isWithMemory: R.T },
},
component: {
props: { id: "child5", preferredFocus: false, selected: false },
},
},
];
const priorityMock3 = [
{
id: "child1",
parent: {
id: "parent1",
lastFocusedItem: null,
component: { isWithMemory: R.T },
},
component: {
props: { id: "child1", preferredFocus: false, selected: false },
},
},
{
id: "child2",
parent: {
id: "parent1",
lastFocusedItem: null,
component: { isWithMemory: R.T },
},
component: {
props: { id: "child2", preferredFocus: true, selected: false },
},
},
{
id: "child3",
parent: {
id: "parent1",
lastFocusedItem: null,
component: { isWithMemory: R.T },
},
component: {
props: { id: "child3", preferredFocus: false, selected: false },
},
},
{
id: "child4",
parent: {
id: "parent1",
lastFocusedItem: null,
component: { isWithMemory: R.T },
},
component: {
props: { id: "child4", preferredFocus: false, selected: false },
},
},
{
id: "child5",
parent: {
id: "parent1",
lastFocusedItem: null,
component: { isWithMemory: R.T },
},
component: {
props: { id: "child5", preferredFocus: false, selected: false },
},
},
];
const priorityMock4 = [
{
id: "child1",
parent: {
id: "parent1",
lastFocusedItem: null,
component: { isWithMemory: R.T },
},
component: {
props: { id: "child1", preferredFocus: false, selected: false },
},
},
{
id: "child2",
parent: {
id: "parent1",
lastFocusedItem: null,
component: { isWithMemory: R.T },
},
component: {
props: { id: "child2", preferredFocus: false, selected: false },
},
},
{
id: "child3",
parent: {
id: "parent1",
lastFocusedItem: null,
component: { isWithMemory: R.T },
},
component: {
props: { id: "child3", preferredFocus: false, selected: false },
},
},
{
id: "child4",
parent: {
id: "parent1",
lastFocusedItem: null,
component: { isWithMemory: R.T },
},
component: {
props: { id: "child4", preferredFocus: false, selected: false },
},
},
{
id: "child5",
parent: {
id: "parent1",
lastFocusedItem: null,
component: { isWithMemory: R.T },
},
component: {
props: { id: "child5", preferredFocus: false, selected: false },
},
},
];
function prepareMock(node) {
if (node.children) {
node.children.forEach((child) => {
child.parent = node;
prepareMock(child);
});
}
}
function treeLoaded() {}
describe("findFocusableNode", () => {
const mockScreen = screenMock1;
prepareMock(mockScreen.root);
const tree = new Tree(treeLoaded);
tree.root = mockScreen.root;
const selectedHero = tree.findInTree("Hero+5bc7813a8c1abc222700000e");
const expectedOnRight = tree.findInTree("Hero+5af0a05a841c4b344c00002a");
it("return expectedOnRight component when moving right direction", () => {
const foundNode = findFocusableNode(directionMocks.right, selectedHero);
expect(foundNode).toEqual(expectedOnRight);
});
// TODO this should change with new functionality of screen picker selector on left.
const expectedOnLeft = tree.findInTree("Hero+5ad6451a841c4b3168000017");
it("return expectedOnLeft component when moving left direction", () => {
const foundNode = findFocusableNode(directionMocks.left, selectedHero);
expect(foundNode).toEqual(expectedOnLeft);
});
it("return preferred menu id a892edf2-ceb6-425f-8fdb-3e58b38b233e component when moving up direction", () => {
const foundNode = findFocusableNode(directionMocks.up, selectedHero);
expect(foundNode.id).toEqual("a892edf2-ceb6-425f-8fdb-3e58b38b233e");
});
it("return preferred grid id Grid+5bc7813a8c1abc222700000e component when moving down direction", () => {
const foundNode = findFocusableNode(directionMocks.down, selectedHero);
expect(foundNode.id).toEqual("Grid+5bc7813a8c1abc222700000e");
});
});
describe("getSelectedItems", () => {
it("return size 1 of array and child4 for first item.id if parent currently selected item is child4", () => {
const selectedItems = getSelectedItems(priorityMock);
expect(selectedItems.length).toEqual(1);
expect(selectedItems[0].id).toEqual("child4");
});
});
describe("getLastFocusedItems", () => {
it("return size 1 of array and child5 for first item.id if parent last focused item is child5", () => {
const lastFocusedItems = getLastFocusedItems(priorityMock);
expect(lastFocusedItems.length).toEqual(1);
expect(lastFocusedItems[0].id).toEqual("child5");
});
});
describe("getPreferableItems", () => {
it("return size 1 of array and child2 for first item.id for preferable item", () => {
const preferableItems = getPreferableItems(priorityMock);
expect(preferableItems.length).toEqual(1);
expect(preferableItems[0].id).toEqual("child2");
});
});
describe("getPriorityItems", () => {
it("return size 1 of array and child4 for first item.id for currently selected item.", () => {
const priorityItems = getPriorityItems(priorityMock);
expect(priorityItems.length).toEqual(1);
expect(priorityItems[0].id).toEqual("child4");
});
it(`return size 1 of array and child5 for first item.id
if there is no currently selected item is child4`, () => {
const priorityItems = getPriorityItems(priorityMock2);
expect(priorityItems.length).toEqual(1);
expect(priorityItems[0].id).toEqual("child5");
});
it(`return size 1 of array and child2 for first item.id
if there is no last focused or currently selected item.`, () => {
const priorityItems = getPriorityItems(priorityMock3);
expect(priorityItems.length).toEqual(1);
expect(priorityItems[0].id).toEqual("child2");
});
it(`return size 1 of array and child1 for first item.id
if there is no last focused, preferable or currently selected item.`, () => {
const priorityItems = getPriorityItems(priorityMock4);
expect(priorityItems.length).toEqual(1);
expect(priorityItems[0].id).toEqual("child1");
});
});
const componentMock1 = {
id: "componentMock",
parent: { id: "parent1", lastFocusedItem: null },
component: {
props: {
id: "componentMock",
prioritiseFocusOn: FocusDirection.UP | FocusDirection.LEFT,
preferredFocus: false,
selected: false,
},
},
};
const componentMock2 = {
id: "componentMock",
parent: { id: "parent1", lastFocusedItem: null },
component: {
props: {
id: "componentMock",
prioritiseFocusOn:
FocusDirection.UP |
FocusDirection.LEFT |
FocusDirection.DOWN |
FocusDirection.RIGHT,
preferredFocus: false,
selected: false,
},
},
};
const componentMock3 = {
id: "componentMock",
parent: { id: "parent1", lastFocusedItem: null },
component: {
props: {
id: "componentMock",
preferredFocus: false,
selected: false,
},
},
};
describe("hasPriorityInDirection", () => {
it(`return true for up and left directions and return false for right and bottom,
when input prioritiseFocusOn is .TOP or .LEFT`, () => {
const hasPriorityInUpDirection = hasPriorityInDirection(
directionMocks.up,
componentMock1.component
);
expect(hasPriorityInUpDirection).toEqual(true);
const hasPriorityInDownDirection = hasPriorityInDirection(
directionMocks.down,
componentMock1.component
);
expect(hasPriorityInDownDirection).toEqual(false);
const hasPriorityInLeftDirection = hasPriorityInDirection(
directionMocks.left,
componentMock1.component
);
expect(hasPriorityInLeftDirection).toEqual(true);
const hasPriorityInRightDirection = hasPriorityInDirection(
directionMocks.right,
componentMock1.component
);
expect(hasPriorityInRightDirection).toEqual(false);
});
it(`return true for in any direction, when input
prioritiseFocusOn is .TOP or .LEFT or .BOTTOM or .RIGHT`, () => {
const hasPriorityInUpDirection = hasPriorityInDirection(
directionMocks.up,
componentMock2.component
);
expect(hasPriorityInUpDirection).toEqual(true);
const hasPriorityInDownDirection = hasPriorityInDirection(
directionMocks.down,
componentMock2.component
);
expect(hasPriorityInDownDirection).toEqual(true);
const hasPriorityInLeftDirection = hasPriorityInDirection(
directionMocks.left,
componentMock2.component
);
expect(hasPriorityInLeftDirection).toEqual(true);
const hasPriorityInRightDirection = hasPriorityInDirection(
directionMocks.right,
componentMock2.component
);
expect(hasPriorityInRightDirection).toEqual(true);
});
it("return false for in any direction, when input prioritiseFocusOn is not defined", () => {
const hasPriorityInUpDirection = hasPriorityInDirection(
directionMocks.up,
componentMock3.component
);
expect(hasPriorityInUpDirection).toEqual(false);
const hasPriorityInDownDirection = hasPriorityInDirection(
directionMocks.down,
componentMock3.component
);
expect(hasPriorityInDownDirection).toEqual(false);
const hasPriorityInLeftDirection = hasPriorityInDirection(
directionMocks.left,
componentMock3.component
);
expect(hasPriorityInLeftDirection).toEqual(false);
const hasPriorityInRightDirection = hasPriorityInDirection(
directionMocks.right,
componentMock3.component
);
expect(hasPriorityInRightDirection).toEqual(false);
});
});