From aa92de40c3e6f19341294aee41b5401301bf831b Mon Sep 17 00:00:00 2001 From: Ben Loe Date: Thu, 30 Mar 2023 21:44:03 -0400 Subject: [PATCH] handle legacy sheets service usage (#5446) Co-authored-by: Ben Loe --- .../sheets/getSheetServiceOutputKey.test.ts | 52 +++++++++++++++++++ .../google/sheets/getSheetServiceOutputKey.ts | 41 +++++++++++++++ .../google/sheets/useSpreadsheetId.test.ts | 19 +++++++ src/contrib/google/sheets/useSpreadsheetId.ts | 14 ++--- 4 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 src/contrib/google/sheets/getSheetServiceOutputKey.test.ts create mode 100644 src/contrib/google/sheets/getSheetServiceOutputKey.ts diff --git a/src/contrib/google/sheets/getSheetServiceOutputKey.test.ts b/src/contrib/google/sheets/getSheetServiceOutputKey.test.ts new file mode 100644 index 0000000000..72a44834e1 --- /dev/null +++ b/src/contrib/google/sheets/getSheetServiceOutputKey.test.ts @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2023 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 . + */ + +import { getSheetServiceOutputKey } from "@/contrib/google/sheets/getSheetServiceOutputKey"; +import { makeVariableExpression } from "@/runtime/expressionCreators"; + +describe("getSheetServiceOutputKey", () => { + test("abc", () => { + expect(getSheetServiceOutputKey(makeVariableExpression("abc"))).toEqual( + "abc" + ); + }); + test("@abc", () => { + expect(getSheetServiceOutputKey(makeVariableExpression("@abc"))).toEqual( + "abc" + ); + }); + test("@abc.def", () => { + expect( + getSheetServiceOutputKey(makeVariableExpression("@abc.def")) + ).toBeUndefined(); + }); + test("@abc.spreadsheetId", () => { + expect( + getSheetServiceOutputKey(makeVariableExpression("@abc.spreadsheetId")) + ).toEqual("abc"); + }); + test("@abc.spreadsheetId.def", () => { + expect( + getSheetServiceOutputKey(makeVariableExpression("@abc.spreadsheetId.def")) + ).toBeUndefined(); + }); + test("@abc.def.spreadsheetId", () => { + expect( + getSheetServiceOutputKey(makeVariableExpression("@abc.def.spreadsheetId")) + ).toBeUndefined(); + }); +}); diff --git a/src/contrib/google/sheets/getSheetServiceOutputKey.ts b/src/contrib/google/sheets/getSheetServiceOutputKey.ts new file mode 100644 index 0000000000..2a351f9063 --- /dev/null +++ b/src/contrib/google/sheets/getSheetServiceOutputKey.ts @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 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 . + */ + +import { type Expression } from "@/core"; + +export function getSheetServiceOutputKey( + fieldValue: Expression +): string | undefined { + const parts = fieldValue.__value__ + // Remove the leading @ + .replace(/^@/, "") + .split("."); + + switch (parts.length) { + case 1: { + return parts[0]; + } + + case 2: { + return parts[1] === "spreadsheetId" ? parts[0] : undefined; + } + + default: { + return undefined; + } + } +} diff --git a/src/contrib/google/sheets/useSpreadsheetId.test.ts b/src/contrib/google/sheets/useSpreadsheetId.test.ts index 69a683d3f2..ba1402038c 100644 --- a/src/contrib/google/sheets/useSpreadsheetId.test.ts +++ b/src/contrib/google/sheets/useSpreadsheetId.test.ts @@ -73,6 +73,25 @@ describe("useSpreadsheetId", () => { expect(result.current).toBe(TEST_SPREADSHEET_ID); }); + test("works with legacy service usage", async () => { + const { result, waitForEffect } = renderHook(() => useSpreadsheetId(""), { + initialValues: { + spreadsheetId: makeVariableExpression("@sheet.spreadsheetId"), + services: [ + { + id: GOOGLE_SHEET_SERVICE_ID, + outputKey: "sheet", + config: uuidSequence(2), + }, + ], + }, + }); + + await waitForEffect(); + + expect(result.current).toBe(TEST_SPREADSHEET_ID); + }); + test("works with mod input", async () => { const { result, waitForEffect } = renderHook(() => useSpreadsheetId(""), { initialValues: { diff --git a/src/contrib/google/sheets/useSpreadsheetId.ts b/src/contrib/google/sheets/useSpreadsheetId.ts index 67c51c5f70..b00743ae25 100644 --- a/src/contrib/google/sheets/useSpreadsheetId.ts +++ b/src/contrib/google/sheets/useSpreadsheetId.ts @@ -19,18 +19,16 @@ import { useField, useFormikContext } from "formik"; import { type Expression, type UserOptions } from "@/core"; import { joinName } from "@/utils"; import { useReducer } from "react"; -import { - keyToFieldValue, - type ServiceSlice, -} from "@/components/fields/schemaFields/serviceFieldUtils"; +import { type ServiceSlice } from "@/components/fields/schemaFields/serviceFieldUtils"; import { isServiceValueFormat } from "@/components/fields/schemaFields/fieldTypeCheckers"; -import { isEmpty, isEqual } from "lodash"; +import { isEmpty } from "lodash"; import { pickDependency } from "@/services/useDependency"; import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; import { useAsyncEffect } from "use-async-effect"; import { services } from "@/background/messenger/api"; import { getErrorMessage } from "@/errors/errorHelpers"; import { getOptionsArgForFieldValue } from "@/utils/getOptionsArgForFieldValue"; +import { getSheetServiceOutputKey } from "@/contrib/google/sheets/getSheetServiceOutputKey"; type SpreadsheetState = { spreadsheetId: string | null; @@ -115,9 +113,11 @@ function useSpreadsheetId(basePath: string): string | null { } try { - const sheetsService = servicesValue.find((service) => - isEqual(keyToFieldValue(service.outputKey), fieldValue) + const serviceOutputKey = getSheetServiceOutputKey(fieldValue); + const sheetsService = servicesValue.find( + (service) => service.outputKey === serviceOutputKey ); + if (!sheetsService) { throw new Error( "Could not find service for spreadsheetId field value: " +