Skip to content

Commit

Permalink
Rename locator to integrationConfigLocator (#8776)
Browse files Browse the repository at this point in the history
  • Loading branch information
twschiller authored Jul 9, 2024
1 parent 150d658 commit a98eb0e
Show file tree
Hide file tree
Showing 53 changed files with 382 additions and 282 deletions.
4 changes: 2 additions & 2 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@
"filename": "src/runtime/pipelineTests/validateInput.test.ts",
"hashed_secret": "0ba9927dc8deb33a61c711371f7ace3407591191",
"is_verified": false,
"line_number": 274
"line_number": 276
}
],
"src/testUtils/factories/authFactories.ts": [
Expand All @@ -264,5 +264,5 @@
}
]
},
"generated_at": "2024-06-20T16:25:50Z"
"generated_at": "2024-07-08T21:14:43Z"
}
14 changes: 8 additions & 6 deletions src/analysis/analysisVisitors/varAnalysis/varAnalysis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
type ListElement,
} from "@/pageEditor/documentBuilder/documentBuilderTypes";
import { type Schema } from "@/types/schemaTypes";
import { services } from "@/background/messenger/api";
import { integrationConfigLocator } from "@/background/messenger/api";
import { modMetadataFactory } from "@/testUtils/factories/modComponentFactories";
import {
formStateFactory,
Expand All @@ -58,11 +58,13 @@ import IdentityTransformer from "@/bricks/transformers/IdentityTransformer";
import { createNewConfiguredBrick } from "@/bricks/exampleBrickConfigs";
import pixiebrixIntegrationDependencyFactory from "@/integrations/util/pixiebrixIntegrationDependencyFactory";

jest.mocked(services.locate).mockResolvedValue(
sanitizedIntegrationConfigFactory({
serviceId: validateRegistryId("@test/service"),
}),
);
jest
.mocked(integrationConfigLocator.findSanitizedIntegrationConfig)
.mockResolvedValue(
sanitizedIntegrationConfigFactory({
serviceId: validateRegistryId("@test/service"),
}),
);

// XXX: should be using actual bricks instead of a single outputSchema across all tests in order to test
// different outputSchema scenarios
Expand Down
4 changes: 2 additions & 2 deletions src/background/auth/launchInteractiveOAuth2Flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/

import type { UUID } from "@/types/stringTypes";
import { locator } from "@/background/locator";
import { integrationConfigLocator } from "@/background/integrationConfigLocator";
import { BusinessError } from "@/errors/businessErrors";
import integrationRegistry from "@/integrations/registry";
import launchOAuth2Flow from "@/background/auth/launchOAuth2Flow";
Expand All @@ -33,7 +33,7 @@ import launchOAuth2Flow from "@/background/auth/launchOAuth2Flow";
// Currently in its own file because launchOAuth2Flow has strict null checks enabled and this file references the
// integration registry and configuration locator
async function launchInteractiveOAuth2Flow(configId: UUID): Promise<void> {
const config = await locator.findIntegrationConfig(configId);
const config = await integrationConfigLocator.findIntegrationConfig(configId);

if (!config) {
throw new BusinessError(`Integration config not found: ${configId}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { appApiMock } from "@/testUtils/appApiMock";
import tokenIntegrationDefinition from "@contrib/integrations/automation-anywhere.yaml";
import oauthIntegrationDefinition from "@contrib/integrations/automation-anywhere-oauth2.yaml";
import { syncRemotePackages } from "@/registry/memoryRegistry";
import { locator as serviceLocator } from "@/background/locator";
import { integrationConfigLocator as serviceLocator } from "@/background/integrationConfigLocator";
import { getPartnerPrincipals } from "@/background/auth/partnerIntegrations/getPartnerPrincipals";
import {
integrationConfigFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
CONTROL_ROOM_TOKEN_INTEGRATION_ID,
} from "@/integrations/constants";
import { compact, flatten } from "lodash";
import { locator as serviceLocator } from "@/background/locator";
import { integrationConfigLocator as serviceLocator } from "@/background/integrationConfigLocator";
import { canParseUrl } from "@/utils/urlUtils";

/**
Expand All @@ -40,7 +40,7 @@ export async function getPartnerPrincipals(): Promise<PartnerPrincipal[]> {
await Promise.all(
partnerIds.map(async (id) => {
try {
return await serviceLocator.locateAllForService(id);
return await serviceLocator.findAllSanitizedConfigsForIntegration(id);
} catch {
// `serviceLocator` throws if the user doesn't have the service definition. Handle case where the brick
// definition for CONTROL_ROOM_OAUTH_SERVICE_ID hasn't been made available on the server yet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import type { RegistryId } from "@/types/registryTypes";
import { expectContext } from "@/utils/expectContext";
import serviceRegistry from "@/integrations/registry";
import { locator as serviceLocator } from "@/background/locator";
import { integrationConfigLocator as serviceLocator } from "@/background/integrationConfigLocator";
import { assertNotNullish } from "@/utils/nullishUtils";
import launchOAuth2Flow from "@/background/auth/launchOAuth2Flow";
import { CONTROL_ROOM_OAUTH_INTEGRATION_ID } from "@/integrations/constants";
Expand Down Expand Up @@ -47,7 +47,8 @@ export async function launchAuthIntegration({
const integration = await serviceRegistry.lookup(integrationId);

await serviceLocator.refreshLocal();
const allAuths = await serviceLocator.locateAllForService(integrationId);
const allAuths =
await serviceLocator.findAllSanitizedConfigsForIntegration(integrationId);
const localAuths = allAuths.filter((x) => !x.proxy);

if (localAuths.length === 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/background/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import "@/background/axiosFetch";
import { initMessengerLogging } from "@/development/messengerLogging";
import registerMessenger from "@/background/messenger/registration";
import registerExternalMessenger from "@/background/messenger/external/registration";
import initLocator from "@/background/locator";
import initLocator from "@/background/integrationConfigLocator";
import initContextMenus from "@/background/contextMenus/initContextMenus";
import initBrowserAction from "@/background/browserAction";
import initInstaller from "@/background/installer";
Expand Down
14 changes: 8 additions & 6 deletions src/background/deploymentUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ import {
} from "@/utils/deploymentUtils";
import { selectUpdatePromptState } from "@/store/settings/settingsSelectors";
import settingsSlice from "@/store/settings/settingsSlice";
import { locator } from "@/background/locator";
import { getEditorState, saveEditorState } from "@/store/editorStorage";
import { type EditorState } from "@/pageEditor/store/editor/pageEditorTypes";
import { editorSlice } from "@/pageEditor/store/editor/editorSlice";
Expand All @@ -73,7 +72,7 @@ import { allSettled } from "@/utils/promiseUtils";
import type { Manifest } from "webextension-polyfill";
import { getRequestHeadersByAPIVersion } from "@/data/service/apiVersioning";
import { fetchDeploymentModDefinitions } from "@/modDefinitions/modDefinitionRawApiCalls";
import { services } from "@/background/messenger/api";
import { integrationConfigLocator } from "@/background/messenger/api";
import type { ActivatableDeployment } from "@/types/deploymentTypes";
import { isAxiosError } from "@/errors/networkErrorHelpers";
import type { components } from "@/types/swagger";
Expand All @@ -89,7 +88,10 @@ const { reducer: optionsReducer, actions: optionsActions } = extensionsSlice;
const { reducer: editorReducer, actions: editorActions } = editorSlice;

// eslint-disable-next-line local-rules/persistBackgroundData -- Function
const locateAllForService = locator.locateAllForService.bind(locator);
const findAllSanitizedIntegrationConfigs =
integrationConfigLocator.findAllSanitizedConfigsForIntegration.bind(
integrationConfigLocator,
);

/**
* Heartbeat frequency for reporting/checking deployments from the server.
Expand Down Expand Up @@ -319,7 +321,7 @@ async function activateDeployment({
deployment,
configuredDependencies: await mergeDeploymentIntegrationDependencies(
activatableDeployment,
services.locateAllForId,
integrationConfigLocator.findAllSanitizedConfigsForIntegration,
),
// Assume backend properly validates the options
optionsArgs: deployment.options_config as OptionsArgs,
Expand Down Expand Up @@ -397,7 +399,7 @@ async function canAutoActivate({
const personalConfigs =
await findLocalDeploymentConfiguredIntegrationDependencies(
activatableDeployment,
locateAllForService,
findAllSanitizedIntegrationConfigs,
);
return personalConfigs.every(({ configs }) => configs.length === 1);
}
Expand Down Expand Up @@ -682,7 +684,7 @@ async function activateDeploymentsInBackground({
activatableDeployment,
...(await checkDeploymentPermissions({
activatableDeployment,
locate: locateAllForService,
locate: findAllSanitizedIntegrationConfigs,
optionalPermissions,
})),
})),
Expand Down
16 changes: 9 additions & 7 deletions src/background/installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
setAvailableVersion,
} from "@/background/installer";
import * as auth from "@/auth/authStorage";
import { locator } from "@/background/locator";
import { integrationConfigLocator } from "@/background/integrationConfigLocator";
import { uuidv4 } from "@/types/helpers";
import { waitForEffect } from "@/testUtils/testHelpers";
import { INTERNAL_reset as resetManagedStorage } from "@/store/enterprise/managedStorage";
Expand All @@ -45,9 +45,9 @@ jest.mock("@/auth/authStorage", () => ({

jest.mock("@/background/telemetry");

jest.mock("@/background/locator", () => ({
locator: {
locateAllForService: jest.fn().mockResolvedValue([]),
jest.mock("@/background/integrationConfigLocator", () => ({
integrationConfigLocator: {
findAllSanitizedConfigsForIntegration: jest.fn().mockResolvedValue([]),
},
}));

Expand All @@ -57,7 +57,9 @@ const queryTabsMock = jest.mocked(browser.tabs.query);
const isLinkedMock = jest.mocked(auth.isLinked);
const getExtensionTokenMock = jest.mocked(auth.getExtensionToken);
const getUserData = jest.mocked(auth.getUserData);
const locateAllForServiceMock = jest.mocked(locator.locateAllForService);
const findAllSanitizedConfigsForIntegrationMock = jest.mocked(
integrationConfigLocator.findAllSanitizedConfigsForIntegration,
);
const browserManagedStorageMock = jest.mocked(browser.storage.managed.get);

beforeEach(async () => {
Expand Down Expand Up @@ -159,7 +161,7 @@ describe("checkPartnerAuth", () => {
queryTabsMock.mockResolvedValue([]);
isLinkedMock.mockResolvedValue(true);
getExtensionTokenMock.mockResolvedValue("abc123");
locateAllForServiceMock.mockResolvedValue([
findAllSanitizedConfigsForIntegrationMock.mockResolvedValue([
// Include a cloud configuration to clarify that local integration is still required
{ id: uuidv4(), serviceId: "automation-anywhere", proxy: true } as any,
]);
Expand Down Expand Up @@ -203,7 +205,7 @@ describe("checkPartnerAuth", () => {
queryTabsMock.mockResolvedValue([]);
isLinkedMock.mockResolvedValue(true);
getExtensionTokenMock.mockResolvedValue("abc123");
locateAllForServiceMock.mockResolvedValue([
findAllSanitizedConfigsForIntegrationMock.mockResolvedValue([
{ id: uuidv4(), serviceId: "automation-anywhere" } as any,
]);
getUserData.mockResolvedValue({
Expand Down
9 changes: 5 additions & 4 deletions src/background/installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { locator as serviceLocator } from "@/background/locator";
import { integrationConfigLocator as serviceLocator } from "@/background/integrationConfigLocator";
import { type Runtime } from "webextension-polyfill";
import { initTelemetry, recordEvent } from "@/background/telemetry";
import { getUUID } from "@/telemetry/telemetryHelpers";
Expand Down Expand Up @@ -195,9 +195,10 @@ export async function requirePartnerAuth(): Promise<void> {
console.debug("requirePartnerAuth", userData);

if (userData.partner?.partnerTheme === "automation-anywhere") {
const configs = await serviceLocator.locateAllForService(
CONTROL_ROOM_TOKEN_INTEGRATION_ID,
);
const configs =
await serviceLocator.findAllSanitizedConfigsForIntegration(
CONTROL_ROOM_TOKEN_INTEGRATION_ID,
);

if (!configs.some((x) => !x.proxy)) {
const extensionConsoleUrl = getExtensionConsoleUrl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,44 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import LazyLocatorFactory from "@/integrations/locator";
import IntegrationConfigLocator from "@/integrations/integrationConfigLocator";
import { expectContext } from "@/utils/expectContext";
import { memoizeUntilSettled } from "@/utils/promiseUtils";

export const locator = new LazyLocatorFactory();
/**
* Singleton IntegrationConfigLocator instance.
*/
export const integrationConfigLocator = new IntegrationConfigLocator();

export default async function initLocator() {
// Service locator cannot run in contentScript due to CSP and wanting to isolate local secrets.
// IntegrationConfigLocator cannot run in contentScript due to CSP and wanting to isolate local secrets.
// Force use of background page to ensure there's a singleton locator instance across all frames/pages.
expectContext(
"background",
"The service locator must run in the background worker",
"The integration configuration locator must run in the background worker",
);

console.debug("Eagerly initializing service locator");
await locator.refresh();
console.debug("Eagerly initializing integration configuration locator");
await integrationConfigLocator.refresh();
}

async function _refreshServices({
async function _refreshIntegrationConfigs({
local = true,
remote = true,
} = {}): Promise<void> {
// Service locator cannot run in contentScript due to CSP and wanting to isolate local secrets.
// Integration configuration locator cannot run in contentScript due to CSP and wanting to isolate local secrets.
// Force use of background page to ensure there's a singleton locator instance across all frames/pages.
expectContext(
"background",
"The service locator must run in the background worker",
"The integration configuration locator must run in the background worker",
);

if (remote && local) {
await locator.refresh();
await integrationConfigLocator.refresh();
} else if (remote) {
await locator.refreshRemote();
await integrationConfigLocator.refreshRemote();
} else if (local) {
await locator.refreshLocal();
await integrationConfigLocator.refreshLocal();
} else {
// Prevent buggy call sites from silently causing issues
throw new Error("Either local or remote must be set to true");
Expand All @@ -62,6 +65,9 @@ async function _refreshServices({
*/
// Memoize while running, because multiple elements on the page might be trying to refresh services. But can't
// memoize completely, as that would prevent future refreshes
export const refreshServices = memoizeUntilSettled(_refreshServices, {
cacheKey: JSON.stringify,
});
export const refreshIntegrationConfigs = memoizeUntilSettled(
_refreshIntegrationConfigs,
{
cacheKey: JSON.stringify,
},
);
19 changes: 14 additions & 5 deletions src/background/messenger/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,16 @@ export const fetchFeatureFlagsInBackground = getMethod(
bg,
);

export const services = {
locateAllForId: getMethod("LOCATE_SERVICES_FOR_ID", bg),
locate: getMethod("LOCATE_SERVICE", bg),
refresh: getMethod("REFRESH_SERVICES", bg),
export const integrationConfigLocator = {
findAllSanitizedConfigsForIntegration: getMethod(
"LOCATOR_FIND_ALL_SANITIZED_CONFIGS_FOR_INTEGRATION",
bg,
),
findSanitizedIntegrationConfig: getMethod(
"LOCATOR_FIND_SANITIZED_INTEGRATION_CONFIG",
bg,
),
refresh: getMethod("LOCATOR_REFRESH", bg),
refreshLocal: getMethod("LOCATOR_REFRESH_LOCAL", bg),
};

Expand Down Expand Up @@ -147,7 +153,10 @@ export const removeModComponentForEveryTab = getNotifier(
"REMOVE_MOD_COMPONENT_EVERY_TAB",
bg,
);
export const clearServiceCache = getMethod("CLEAR_SERVICE_CACHE", bg);
export const clearIntegrationRegistry = getMethod(
"INTEGRATION_REGISTRY_CLEAR",
bg,
);
export const getUserData = getMethod("GET_USER_DATA", bg);
export const installStarterBlueprints = getMethod(
"INSTALL_STARTER_BLUEPRINTS",
Expand Down
Loading

0 comments on commit a98eb0e

Please sign in to comment.