Skip to content

Commit

Permalink
#4464 Temporary display info - Slice 1 (#4584)
Browse files Browse the repository at this point in the history
  • Loading branch information
BLoe committed Nov 3, 2022
1 parent 5ca79ec commit f3aba14
Show file tree
Hide file tree
Showing 31 changed files with 627 additions and 62 deletions.
2 changes: 2 additions & 0 deletions src/blocks/renderers/table.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe("parse compile error", () => {
root: null,
logger: new ConsoleLogger(),
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
}
);

Expand All @@ -49,6 +50,7 @@ describe("parse compile error", () => {
root: null,
logger: new ConsoleLogger(),
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
}
);

Expand Down
1 change: 1 addition & 0 deletions src/blocks/transformers/FormData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ describe("FormData block", () => {
logger: null,
root: null,
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
});

expect(result).toEqual({
Expand Down
5 changes: 5 additions & 0 deletions src/blocks/transformers/jq.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe("smoke tests", () => {
root: null,
logger: new ConsoleLogger(),
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
}
);

Expand All @@ -47,6 +48,7 @@ describe("ctxt", () => {
root: null,
logger: new ConsoleLogger(),
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
}
);

Expand All @@ -64,6 +66,7 @@ describe("parse compile error", () => {
root: null,
logger: new ConsoleLogger(),
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
}
);

Expand All @@ -82,6 +85,7 @@ describe("parse compile error", () => {
root: null,
logger: new ConsoleLogger(),
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
}
);

Expand All @@ -100,6 +104,7 @@ describe("parse compile error", () => {
root: null,
logger: new ConsoleLogger(),
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
}
);

Expand Down
4 changes: 4 additions & 0 deletions src/blocks/transformers/parseDate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ describe("ParseDate block", () => {
logger: null,
root: null,
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
});

expect(result).toEqual({
Expand Down Expand Up @@ -93,6 +94,7 @@ describe("ParseDate block", () => {
logger: null,
root: null,
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
});
}).rejects.toThrow(BusinessError);
});
Expand All @@ -106,6 +108,7 @@ describe("ParseDate block", () => {
logger: null,
root: null,
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
});
}).rejects.toThrow(BusinessError);
});
Expand All @@ -122,6 +125,7 @@ describe("ParseDate block", () => {
logger: null,
root: null,
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
});

expect(result).toEqual({
Expand Down
2 changes: 2 additions & 0 deletions src/blocks/transformers/parseJson.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe("ParseJson block", () => {
logger: null,
root: null,
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
});

expect(result).toEqual({
Expand All @@ -47,6 +48,7 @@ test("Throw BusinessError on invalid JSON", async () => {
logger: null,
root: null,
runPipeline: neverPromise,
runRendererPipeline: neverPromise,
});
}).rejects.toThrow(BusinessError);
});
4 changes: 4 additions & 0 deletions src/blocks/transformers/registerTransformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import TryExcept from "./controlFlow/TryExcept";
import ForEachElement from "@/blocks/transformers/controlFlow/ForEachElement";
import { RandomNumber } from "@/blocks/transformers/randomNumber";
import Retry from "@/blocks/transformers/controlFlow/Retry";
import DisplayTemporaryInfo from "@/blocks/transformers/temporaryInfo/DisplayTemporaryInfo";

function registerTransformers() {
registerBlock(new JQTransformer());
Expand Down Expand Up @@ -81,6 +82,9 @@ function registerTransformers() {
registerBlock(new TryExcept());
registerBlock(new ForEachElement());
registerBlock(new Retry());

// Render Pipelines
registerBlock(new DisplayTemporaryInfo());
}

export default registerTransformers;
125 changes: 125 additions & 0 deletions src/blocks/transformers/temporaryInfo/DisplayTemporaryInfo.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright (C) 2022 PixieBrix, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import DisplayTemporaryInfo from "@/blocks/transformers/temporaryInfo/DisplayTemporaryInfo";
import blockRegistry from "@/blocks/registry";
import {
simpleInput,
teapotBlock,
testOptions,
throwBlock,
} from "@/runtime/pipelineTests/pipelineTestHelpers";
import { makePipelineExpression } from "@/runtime/expressionCreators";
import { DocumentRenderer } from "@/blocks/renderers/document";
import { getExampleBlockConfig } from "@/pageEditor/exampleBlockConfigs";
import { reducePipeline } from "@/runtime/reducePipeline";
import { BusinessError } from "@/errors/businessErrors";
import {
PanelPayload,
RendererError,
TemporaryPanelEntry,
} from "@/sidebar/types";
import { showTemporarySidebarPanel } from "@/contentScript/sidebarController";

jest.mock("@/background/messenger/api", () => {
const actual = jest.requireActual("@/background/messenger/api");
return {
...actual,
getLoggingConfig: jest.fn().mockResolvedValue({
logValues: true,
}),
};
});

jest.mock("@/contentScript/sidebarController", () => ({
ensureSidebar: jest.fn(),
showTemporarySidebarPanel: jest.fn(),
}));

jest.mock("@/blocks/transformers/temporaryInfo/temporaryPanelProtocol", () => ({
waitForTemporaryPanel: jest.fn(),
stopWaitingForTemporaryPanels: jest.fn(),
}));

describe("DisplayTemporaryInfo", () => {
const displayTemporaryInfoBlock = new DisplayTemporaryInfo();
const renderer = new DocumentRenderer();

beforeEach(() => {
blockRegistry.clear();
blockRegistry.register(
teapotBlock,
throwBlock,
renderer,
displayTemporaryInfoBlock
);
});

test("it returns payload", async () => {
const config = getExampleBlockConfig(renderer.id);
const pipeline = {
id: displayTemporaryInfoBlock.id,
config: {
title: "Test Temp Panel",
body: makePipelineExpression([{ id: renderer.id, config }]),
},
};
let payload: PanelPayload;
(showTemporarySidebarPanel as jest.Mock).mockImplementation(
(entry: TemporaryPanelEntry) => {
payload = entry.payload;
}
);

await reducePipeline(pipeline, simpleInput({}), testOptions("v3"));

// Check structure for RendererPayload
expect(payload).toHaveProperty("blockId", renderer.id);
expect(payload).toHaveProperty("args");
expect(payload).toHaveProperty("ctxt");
});

test("it returns error", async () => {
const message = "display info test error";

const pipeline = {
id: displayTemporaryInfoBlock.id,
config: {
title: "Test Temp Panel",
body: makePipelineExpression([
{ id: throwBlock.id, config: { message } },
{ id: renderer.id, config: getExampleBlockConfig(renderer.id) },
]),
},
};

let payload: PanelPayload;
(showTemporarySidebarPanel as jest.Mock).mockImplementation(
(entry: TemporaryPanelEntry) => {
payload = entry.payload;
}
);

await reducePipeline(pipeline, simpleInput({}), testOptions("v3"));

// Check structure for RendererError
expect(payload).toHaveProperty("error");
const error = payload as RendererError;
const errorMessage = (error.error as BusinessError).message;
expect(errorMessage).toStrictEqual(message);
});
});
123 changes: 123 additions & 0 deletions src/blocks/transformers/temporaryInfo/DisplayTemporaryInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (C) 2022 PixieBrix, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { Transformer } from "@/types";
import { uuidv4, validateRegistryId } from "@/types/helpers";
import { BlockArg, BlockOptions, Schema } from "@/core";
import { PipelineExpression } from "@/runtime/mapArgs";
import { expectContext } from "@/utils/expectContext";
import {
ensureSidebar,
hideTemporarySidebarPanel,
PANEL_HIDING_EVENT,
showTemporarySidebarPanel,
} from "@/contentScript/sidebarController";
import { PanelPayload } from "@/sidebar/types";
import {
waitForTemporaryPanel,
stopWaitingForTemporaryPanels,
} from "@/blocks/transformers/temporaryInfo/temporaryPanelProtocol";

class DisplayTemporaryInfo extends Transformer {
static BLOCK_ID = validateRegistryId("@pixiebrix/display");
defaultOutputKey = "infoOutput";

constructor() {
super(
DisplayTemporaryInfo.BLOCK_ID,
"Display Temporary Information",
"A display title for the information, shown in the tab name"
);
}

inputSchema: Schema = {
type: "object",
properties: {
title: {
type: "string",
description: "A display title for the temporary document",
},
body: {
$ref: "https://app.pixiebrix.com/schemas/pipeline#",
description: "The render pipeline for the temporary document",
},
},
required: ["body"],
};

async transform(
{
title,
body: bodyPipeline,
}: BlockArg<{
title: string;
body: PipelineExpression;
}>,
{
logger: {
context: { extensionId },
},
ctxt,
runPipeline,
runRendererPipeline,
}: BlockOptions
): Promise<unknown> {
expectContext("contentScript");

const nonce = uuidv4();
const controller = new AbortController();

await ensureSidebar();

const payload = (await runRendererPipeline(bodyPipeline?.__value__ ?? [], {
key: "body",
counter: 0,
})) as PanelPayload;

showTemporarySidebarPanel({
extensionId,
nonce,
heading: title,
payload,
});

window.addEventListener(
PANEL_HIDING_EVENT,
() => {
controller.abort();
},
{
signal: controller.signal,
}
);

controller.signal.addEventListener("abort", () => {
hideTemporarySidebarPanel(nonce);
void stopWaitingForTemporaryPanels([nonce]);
});

try {
await waitForTemporaryPanel(nonce);
} finally {
controller.abort();
}

return {};
}
}

export default DisplayTemporaryInfo;

0 comments on commit f3aba14

Please sign in to comment.