Skip to content

Commit

Permalink
Merge pull request #589 from gadget-inc/mill/throwErrorForAutoFormAct…
Browse files Browse the repository at this point in the history
…ionsWithNoTriggers

Added error for using actions without the API trigger in autoforms
  • Loading branch information
MillanWangGadget authored Aug 13, 2024
2 parents dad559c + f09dc2e commit 536da60
Show file tree
Hide file tree
Showing 26 changed files with 3,249 additions and 263 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
import { api } from "../../../support/api.js";
import { describeForEachAutoAdapter } from "../../../support/auto.js";

Expand All @@ -24,6 +25,7 @@ describeForEachAutoAdapter("AutoForm", ({ name, adapter: { AutoForm }, wrapper }
modelName: "Widget",
action: { apiIdentifier: "update", operatesWithRecordIdentity: true },
inputFields: getInputFieldsWithCustomValidations(),
triggers: apiTriggerOnly,
});
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
import { api } from "../../../support/api.js";
import { describeForEachAutoAdapter } from "../../../support/auto.js";

Expand Down Expand Up @@ -135,6 +136,7 @@ const modelActionMetadataResponse = {
name: "Create",
apiIdentifier: "create",
operatesWithRecordIdentity: false,
triggers: apiTriggerOnly,
inputFields: [
{
name: "Widget",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import React from "react";
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
import { PolarisAutoBelongsToInput } from "../../../../src/auto/polaris/inputs/relationships/PolarisAutoBelongsToInput.js";
import { PolarisAutoSubmit } from "../../../../src/auto/polaris/submit/PolarisAutoSubmit.js";
import { PolarisSubmitResultBanner } from "../../../../src/auto/polaris/submit/PolarisSubmitResultBanner.js";
import { api } from "../../../support/api.js";
import { PolarisWrapper } from "../../../support/auto.js";

describe("PolarisAutoBelongsToInput", () => {
const interceptModelUpdateActionMetadata = () => {
cy.mockModelActionMetadata(api, {
modelApiIdentifier: "widget",
modelName: "Widget",
action: { apiIdentifier: "update", operatesWithRecordIdentity: true },
triggers: apiTriggerOnly,
inputFields: getInputFieldsWithCustomValidations(),
});
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { format } from "date-fns";
import { utcToZonedTime } from "date-fns-tz";
import React, { useState } from "react";
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
import { PolarisAutoDateTimePicker } from "../../../../src/auto/polaris/inputs/PolarisAutoDateTimePicker.js";
import { api } from "../../../support/api.js";
Expand Down Expand Up @@ -110,6 +111,8 @@ describe("PolarisDateTimePicker", () => {
apiIdentifier: "create",
operatesWithRecordIdentity: false,
},

triggers: apiTriggerOnly,
inputFields: [
{
name: "Widget",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
import { getStadiumRecord } from "../../../../spec/auto/support/stadiumModel.js";
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
import { api } from "../../../support/api.js";
Expand Down Expand Up @@ -327,6 +328,7 @@ const baseModelActionMetadata = {
apiIdentifier: "create",
operatesWithRecordIdentity: false,
},
triggers: apiTriggerOnly,
inputFields: [
{
name: "Stadium",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
import { getStadiumRecord } from "../../../../spec/auto/support/stadiumModel.js";
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
import { PolarisAutoFileInput } from "../../../../src/auto/polaris/inputs/PolarisAutoFileInput.js";
Expand All @@ -15,6 +16,7 @@ describe("PolarisFileInput", () => {
operatesWithRecordIdentity: false,
},
inputFields: getInputFieldsWithCustomValidations(validations),
triggers: apiTriggerOnly,
});
};

Expand All @@ -27,6 +29,7 @@ describe("PolarisFileInput", () => {
operatesWithRecordIdentity: true,
},
inputFields: getInputFieldsWithCustomValidations(validations),
triggers: apiTriggerOnly,
});
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
import { PolarisAutoHasManyInput } from "../../../../src/auto/polaris/inputs/relationships/PolarisAutoHasManyInput.js";
import { PolarisAutoSubmit } from "../../../../src/auto/polaris/submit/PolarisAutoSubmit.js";
Expand All @@ -14,6 +15,7 @@ describe("PolarisAutoHasManyInput", () => {
modelName: "Widget",
action: { apiIdentifier: "update", operatesWithRecordIdentity: true },
inputFields: getInputFieldsWithCustomValidations(),
triggers: apiTriggerOnly,
});
};

Expand Down
2 changes: 2 additions & 0 deletions packages/react/cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { AnyClient } from "@gadgetinc/api-client-core";
import "cypress-each";
import { apiTriggerOnly } from "../../spec/auto/support/Triggers.js";
import { recordIdInputField } from "../../spec/auto/support/shared.js";

Cypress.Commands.add("mockModelActionMetadata", (api: AnyClient, props) => {
Expand All @@ -19,6 +20,7 @@ Cypress.Commands.add("mockModelActionMetadata", (api: AnyClient, props) => {
action: {
...action,
name: action.apiIdentifier,
triggers: apiTriggerOnly,
inputFields: action.operatesWithRecordIdentity ? [recordIdInputField, ...inputFields] : inputFields,
__typename: "GadgetAction",
},
Expand Down
1 change: 1 addition & 0 deletions packages/react/cypress/support/cypress-commands.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ declare namespace Cypress {
operatesWithRecordIdentity: boolean;
};
inputFields: any[];
triggers: any[];
defaultRecord?: Record<string, any>;
}
): Chainable<void>;
Expand Down
64 changes: 58 additions & 6 deletions packages/react/spec/auto/PolarisAutoForm.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { PolarisAutoSubmit } from "../../src/auto/polaris/submit/PolarisAutoSubm
import { testApi as api } from "../apis.js";
import { MockClientProvider, mockUrqlClient } from "../testWrappers.js";
import { getGizmoModelMetadata } from "./support/gizmoModel.js";
import { getGlobalActionMetadata } from "./support/globalActions.js";
import { getWidgetModelMetadata, getWidgetRecord } from "./support/widgetModel.js";

const PolarisMockedProviders = (props: { children: ReactNode }) => {
Expand Down Expand Up @@ -676,6 +677,36 @@ describe("PolarisAutoForm", () => {
}).toThrow("Bulk actions are not supported in AutoForms");
});
});
describe("Actions without triggers", () => {
describe("No triggers in the api client", () => {
it("throws an error when a model action without triggers", () => {
expect(() => {
render(<PolarisAutoForm action={api.autoTableTest.noTriggerAction as any} />, { wrapper: PolarisMockedProviders });
}).toThrow("Actions must have API triggers to be used in AutoForms");
});

it("throws an error when a global action without triggers", () => {
expect(() => {
render(<PolarisAutoForm action={api.noTriggerGlobalAction as any} />, { wrapper: PolarisMockedProviders });
}).toThrow("Actions must have API triggers to be used in AutoForms");
});
});
describe("Has triggers in api client but no triggers in action metadata", () => {
it("throws an error when a model action without triggers", () => {
expect(() => {
render(<PolarisAutoForm action={api.widget.create as any} />, { wrapper: PolarisMockedProviders });
loadMockWidgetCreateMetadata({ triggers: [{ specID: "non/api/trigger", __typename: "GadgetTrigger" }] });
}).toThrow("Actions must have API triggers to be used in AutoForms");
});

it("throws an error when a global action without triggers", () => {
expect(() => {
render(<PolarisAutoForm action={api.flipAll as any} />, { wrapper: PolarisMockedProviders });
loadMockFlipAllMetadata({ triggers: [{ specID: "non/api/trigger", __typename: "GadgetTrigger" }] });
}).toThrow("Actions must have API triggers to be used in AutoForms");
});
});
});
});

function loadMockGizmoCreateMetadata() {
Expand All @@ -697,7 +728,7 @@ function loadMockGizmoCreateMetadata() {
});
}

function loadMockWidgetCreateMetadata() {
function loadMockWidgetCreateMetadata(opts?: { inputFields?: any[]; triggers?: any[] }) {
expect(mockUrqlClient.executeQuery.mock.calls[0][0].variables).toEqual({
modelApiIdentifier: "widget",
modelNamespace: null,
Expand All @@ -708,11 +739,15 @@ function loadMockWidgetCreateMetadata() {
mockUrqlClient.executeQuery.pushResponse("ModelActionMetadata", {
stale: false,
hasNext: false,
data: getWidgetModelMetadata({
name: "Create",
apiIdentifier: "create",
operatesWithRecordIdentity: false,
}),
data: getWidgetModelMetadata(
{
name: "Create",
apiIdentifier: "create",
operatesWithRecordIdentity: false,
},
opts?.inputFields,
opts?.triggers
),
});
}

Expand Down Expand Up @@ -780,3 +815,20 @@ function loadMockWidgetDeleteMetadata() {
),
});
}

function loadMockFlipAllMetadata(opts?: { triggers?: any[] }) {
expect(mockUrqlClient.executeQuery.mock.calls[0][0].variables).toEqual({
namespace: null,
apiIdentifier: "flipAll",
includeRelatedFields: false,
});

mockUrqlClient.executeQuery.pushResponse("GlobalActionMetadata", {
stale: false,
hasNext: false,
data: getGlobalActionMetadata({
apiIdentifier: "flipAll",
triggers: opts?.triggers,
}),
});
}
6 changes: 0 additions & 6 deletions packages/react/spec/auto/PolarisAutoForm.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,3 @@ export const onFailureCallback = {
},
},
};
export const FieldNameCustomParamCollisionError = {
args: {
findBy: "1",
action: api.autoTableTest.updateWithCustomParams,
},
};
49 changes: 49 additions & 0 deletions packages/react/spec/auto/form/PolarisAutoFormErrors.stories.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { AppProvider, Card, Page } from "@shopify/polaris";
import translations from "@shopify/polaris/locales/en.json";
import React from "react";
import { FormProvider, useForm } from "react-hook-form";
import { Provider } from "../../../src/GadgetProvider.tsx";
import { PolarisAutoForm } from "../../../src/auto/polaris/PolarisAutoForm.tsx";
import { testApi as api } from "../../apis.ts";

export default {
title: "Polaris/AutoForm/Errors",
component: PolarisAutoForm,
decorators: [
(Story) => {
return (
<Provider api={api}>
<AppProvider i18n={translations}>
<FormProvider {...useForm()}>
<Page>
<Card>
<Story />
</Card>
</Page>
</FormProvider>
</AppProvider>
</Provider>
);
},
],
};

export const FieldNameCustomParamCollisionError = {
args: {
findBy: "1",
action: api.autoTableTest.updateWithCustomParams,
},
};

export const ModelActionWithoutApiTrigger = {
args: {
findBy: "70",
action: api.autoTableTest.noTriggerAction,
},
};

export const GlobalActionWithoutApiTrigger = {
args: {
action: api.noTriggerGlobalAction,
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React from "react";
import { PolarisAutoEncryptedStringInput } from "../../../src/auto/polaris/inputs/PolarisAutoEncryptedStringInput.js";
import type { ActionMetadata } from "../../../src/metadata.js";
import { MockForm } from "../MockForm.js";
import { apiTriggerOnly } from "../support/Triggers.js";

describe("PolarisEncryptedStringInput", () => {
let result: RenderResult;
Expand Down Expand Up @@ -39,6 +40,7 @@ const metadata: ActionMetadata = {
action: {
name: "Create",
apiIdentifier: "create",
triggers: apiTriggerOnly,
inputFields: [
{
name: "Widget",
Expand Down
3 changes: 3 additions & 0 deletions packages/react/spec/auto/inputs/PolarisAutoTextInput.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { ActionMetadata } from "../../../src/metadata.js";
import { testApi as api } from "../../apis.js";
import { MockClientProvider, mockUrqlClient } from "../../testWrappers.js";
import { MockForm } from "../MockForm.js";
import { apiTriggerOnly } from "../support/Triggers.js";

describe("PolarisAutoTextInput", () => {
let result: RenderResult;
Expand Down Expand Up @@ -147,6 +148,7 @@ describe("PolarisAutoTextInput", () => {
apiIdentifier: "create",
operatesWithRecordIdentity: false,
isDeleteAction: false,
triggers: apiTriggerOnly,
inputFields: [
{
name: "Widget",
Expand Down Expand Up @@ -209,6 +211,7 @@ const metadata = {
apiIdentifier: "create",
operatesWithRecordIdentity: false,
isDeleteAction: false,
triggers: apiTriggerOnly,
inputFields: [
{
name: "Widget",
Expand Down
1 change: 1 addition & 0 deletions packages/react/spec/auto/support/Triggers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const apiTriggerOnly = [{ specID: "gadget/trigger/graphql_api", __typename: "GadgetTrigger" }];
2 changes: 2 additions & 0 deletions packages/react/spec/auto/support/gameCityModel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { recordIdInputField } from "./shared.js";
import { apiTriggerOnly } from "./Triggers.js";

export const gameCityModelInputFields = {
name: "City",
Expand Down Expand Up @@ -65,6 +66,7 @@ export const getGameCityModelMetadata = (action: { name: string; apiIdentifier:
action: {
...action,
inputFields: [recordIdInputField, gameCityModelInputFields],
triggers: apiTriggerOnly,
__typename: "GadgetAction",
},
__typename: "GadgetModel",
Expand Down
2 changes: 2 additions & 0 deletions packages/react/spec/auto/support/gizmoModel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { recordIdInputField } from "./shared.js";
import { apiTriggerOnly } from "./Triggers.js";

export const gizmoModelInputFields = {
name: "Gizmo",
Expand Down Expand Up @@ -74,6 +75,7 @@ export const getGizmoModelMetadata = (
action: {
...action,
inputFields: action.operatesWithRecordIdentity ? [recordIdInputField, ...inputFields] : inputFields,
triggers: apiTriggerOnly,
__typename: "GadgetAction",
},
__typename: "GadgetModel",
Expand Down
Loading

0 comments on commit 536da60

Please sign in to comment.