Skip to content

Commit 536da60

Browse files
Merge pull request #589 from gadget-inc/mill/throwErrorForAutoFormActionsWithNoTriggers
Added error for using actions without the API trigger in autoforms
2 parents dad559c + f09dc2e commit 536da60

26 files changed

+3249
-263
lines changed

packages/react/cypress/component/auto/form/AutoFormDynamicFormInputChanges.cy.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react";
2+
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
23
import { api } from "../../../support/api.js";
34
import { describeForEachAutoAdapter } from "../../../support/auto.js";
45

@@ -24,6 +25,7 @@ describeForEachAutoAdapter("AutoForm", ({ name, adapter: { AutoForm }, wrapper }
2425
modelName: "Widget",
2526
action: { apiIdentifier: "update", operatesWithRecordIdentity: true },
2627
inputFields: getInputFieldsWithCustomValidations(),
28+
triggers: apiTriggerOnly,
2729
});
2830
};
2931

packages/react/cypress/component/auto/form/AutoRoleInput.cy.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react";
2+
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
23
import { api } from "../../../support/api.js";
34
import { describeForEachAutoAdapter } from "../../../support/auto.js";
45

@@ -135,6 +136,7 @@ const modelActionMetadataResponse = {
135136
name: "Create",
136137
apiIdentifier: "create",
137138
operatesWithRecordIdentity: false,
139+
triggers: apiTriggerOnly,
138140
inputFields: [
139141
{
140142
name: "Widget",

packages/react/cypress/component/auto/form/PolarisAutoBelongsToInput.cy.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import React from "react";
2+
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
23
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
34
import { PolarisAutoBelongsToInput } from "../../../../src/auto/polaris/inputs/relationships/PolarisAutoBelongsToInput.js";
45
import { PolarisAutoSubmit } from "../../../../src/auto/polaris/submit/PolarisAutoSubmit.js";
56
import { PolarisSubmitResultBanner } from "../../../../src/auto/polaris/submit/PolarisSubmitResultBanner.js";
67
import { api } from "../../../support/api.js";
78
import { PolarisWrapper } from "../../../support/auto.js";
8-
99
describe("PolarisAutoBelongsToInput", () => {
1010
const interceptModelUpdateActionMetadata = () => {
1111
cy.mockModelActionMetadata(api, {
1212
modelApiIdentifier: "widget",
1313
modelName: "Widget",
1414
action: { apiIdentifier: "update", operatesWithRecordIdentity: true },
15+
triggers: apiTriggerOnly,
1516
inputFields: getInputFieldsWithCustomValidations(),
1617
});
1718
};

packages/react/cypress/component/auto/form/PolarisAutoDateTimePicker.cy.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { format } from "date-fns";
22
import { utcToZonedTime } from "date-fns-tz";
33
import React, { useState } from "react";
4+
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
45
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
56
import { PolarisAutoDateTimePicker } from "../../../../src/auto/polaris/inputs/PolarisAutoDateTimePicker.js";
67
import { api } from "../../../support/api.js";
@@ -110,6 +111,8 @@ describe("PolarisDateTimePicker", () => {
110111
apiIdentifier: "create",
111112
operatesWithRecordIdentity: false,
112113
},
114+
115+
triggers: apiTriggerOnly,
113116
inputFields: [
114117
{
115118
name: "Widget",

packages/react/cypress/component/auto/form/PolarisAutoEnumInput.cy.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react";
2+
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
23
import { getStadiumRecord } from "../../../../spec/auto/support/stadiumModel.js";
34
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
45
import { api } from "../../../support/api.js";
@@ -327,6 +328,7 @@ const baseModelActionMetadata = {
327328
apiIdentifier: "create",
328329
operatesWithRecordIdentity: false,
329330
},
331+
triggers: apiTriggerOnly,
330332
inputFields: [
331333
{
332334
name: "Stadium",

packages/react/cypress/component/auto/form/PolarisAutoFileInput.cy.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react";
2+
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
23
import { getStadiumRecord } from "../../../../spec/auto/support/stadiumModel.js";
34
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
45
import { PolarisAutoFileInput } from "../../../../src/auto/polaris/inputs/PolarisAutoFileInput.js";
@@ -15,6 +16,7 @@ describe("PolarisFileInput", () => {
1516
operatesWithRecordIdentity: false,
1617
},
1718
inputFields: getInputFieldsWithCustomValidations(validations),
19+
triggers: apiTriggerOnly,
1820
});
1921
};
2022

@@ -27,6 +29,7 @@ describe("PolarisFileInput", () => {
2729
operatesWithRecordIdentity: true,
2830
},
2931
inputFields: getInputFieldsWithCustomValidations(validations),
32+
triggers: apiTriggerOnly,
3033
});
3134
};
3235

packages/react/cypress/component/auto/form/PolarisAutoHasManyInput.cy.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react";
2+
import { apiTriggerOnly } from "../../../../spec/auto/support/Triggers.js";
23
import { PolarisAutoForm } from "../../../../src/auto/polaris/PolarisAutoForm.js";
34
import { PolarisAutoHasManyInput } from "../../../../src/auto/polaris/inputs/relationships/PolarisAutoHasManyInput.js";
45
import { PolarisAutoSubmit } from "../../../../src/auto/polaris/submit/PolarisAutoSubmit.js";
@@ -14,6 +15,7 @@ describe("PolarisAutoHasManyInput", () => {
1415
modelName: "Widget",
1516
action: { apiIdentifier: "update", operatesWithRecordIdentity: true },
1617
inputFields: getInputFieldsWithCustomValidations(),
18+
triggers: apiTriggerOnly,
1719
});
1820
};
1921

packages/react/cypress/support/commands.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { AnyClient } from "@gadgetinc/api-client-core";
22
import "cypress-each";
3+
import { apiTriggerOnly } from "../../spec/auto/support/Triggers.js";
34
import { recordIdInputField } from "../../spec/auto/support/shared.js";
45

56
Cypress.Commands.add("mockModelActionMetadata", (api: AnyClient, props) => {
@@ -19,6 +20,7 @@ Cypress.Commands.add("mockModelActionMetadata", (api: AnyClient, props) => {
1920
action: {
2021
...action,
2122
name: action.apiIdentifier,
23+
triggers: apiTriggerOnly,
2224
inputFields: action.operatesWithRecordIdentity ? [recordIdInputField, ...inputFields] : inputFields,
2325
__typename: "GadgetAction",
2426
},

packages/react/cypress/support/cypress-commands.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ declare namespace Cypress {
1212
operatesWithRecordIdentity: boolean;
1313
};
1414
inputFields: any[];
15+
triggers: any[];
1516
defaultRecord?: Record<string, any>;
1617
}
1718
): Chainable<void>;

packages/react/spec/auto/PolarisAutoForm.spec.tsx

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { PolarisAutoSubmit } from "../../src/auto/polaris/submit/PolarisAutoSubm
1212
import { testApi as api } from "../apis.js";
1313
import { MockClientProvider, mockUrqlClient } from "../testWrappers.js";
1414
import { getGizmoModelMetadata } from "./support/gizmoModel.js";
15+
import { getGlobalActionMetadata } from "./support/globalActions.js";
1516
import { getWidgetModelMetadata, getWidgetRecord } from "./support/widgetModel.js";
1617

1718
const PolarisMockedProviders = (props: { children: ReactNode }) => {
@@ -676,6 +677,36 @@ describe("PolarisAutoForm", () => {
676677
}).toThrow("Bulk actions are not supported in AutoForms");
677678
});
678679
});
680+
describe("Actions without triggers", () => {
681+
describe("No triggers in the api client", () => {
682+
it("throws an error when a model action without triggers", () => {
683+
expect(() => {
684+
render(<PolarisAutoForm action={api.autoTableTest.noTriggerAction as any} />, { wrapper: PolarisMockedProviders });
685+
}).toThrow("Actions must have API triggers to be used in AutoForms");
686+
});
687+
688+
it("throws an error when a global action without triggers", () => {
689+
expect(() => {
690+
render(<PolarisAutoForm action={api.noTriggerGlobalAction as any} />, { wrapper: PolarisMockedProviders });
691+
}).toThrow("Actions must have API triggers to be used in AutoForms");
692+
});
693+
});
694+
describe("Has triggers in api client but no triggers in action metadata", () => {
695+
it("throws an error when a model action without triggers", () => {
696+
expect(() => {
697+
render(<PolarisAutoForm action={api.widget.create as any} />, { wrapper: PolarisMockedProviders });
698+
loadMockWidgetCreateMetadata({ triggers: [{ specID: "non/api/trigger", __typename: "GadgetTrigger" }] });
699+
}).toThrow("Actions must have API triggers to be used in AutoForms");
700+
});
701+
702+
it("throws an error when a global action without triggers", () => {
703+
expect(() => {
704+
render(<PolarisAutoForm action={api.flipAll as any} />, { wrapper: PolarisMockedProviders });
705+
loadMockFlipAllMetadata({ triggers: [{ specID: "non/api/trigger", __typename: "GadgetTrigger" }] });
706+
}).toThrow("Actions must have API triggers to be used in AutoForms");
707+
});
708+
});
709+
});
679710
});
680711

681712
function loadMockGizmoCreateMetadata() {
@@ -697,7 +728,7 @@ function loadMockGizmoCreateMetadata() {
697728
});
698729
}
699730

700-
function loadMockWidgetCreateMetadata() {
731+
function loadMockWidgetCreateMetadata(opts?: { inputFields?: any[]; triggers?: any[] }) {
701732
expect(mockUrqlClient.executeQuery.mock.calls[0][0].variables).toEqual({
702733
modelApiIdentifier: "widget",
703734
modelNamespace: null,
@@ -708,11 +739,15 @@ function loadMockWidgetCreateMetadata() {
708739
mockUrqlClient.executeQuery.pushResponse("ModelActionMetadata", {
709740
stale: false,
710741
hasNext: false,
711-
data: getWidgetModelMetadata({
712-
name: "Create",
713-
apiIdentifier: "create",
714-
operatesWithRecordIdentity: false,
715-
}),
742+
data: getWidgetModelMetadata(
743+
{
744+
name: "Create",
745+
apiIdentifier: "create",
746+
operatesWithRecordIdentity: false,
747+
},
748+
opts?.inputFields,
749+
opts?.triggers
750+
),
716751
});
717752
}
718753

@@ -780,3 +815,20 @@ function loadMockWidgetDeleteMetadata() {
780815
),
781816
});
782817
}
818+
819+
function loadMockFlipAllMetadata(opts?: { triggers?: any[] }) {
820+
expect(mockUrqlClient.executeQuery.mock.calls[0][0].variables).toEqual({
821+
namespace: null,
822+
apiIdentifier: "flipAll",
823+
includeRelatedFields: false,
824+
});
825+
826+
mockUrqlClient.executeQuery.pushResponse("GlobalActionMetadata", {
827+
stale: false,
828+
hasNext: false,
829+
data: getGlobalActionMetadata({
830+
apiIdentifier: "flipAll",
831+
triggers: opts?.triggers,
832+
}),
833+
});
834+
}

packages/react/spec/auto/PolarisAutoForm.stories.jsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,3 @@ export const onFailureCallback = {
126126
},
127127
},
128128
};
129-
export const FieldNameCustomParamCollisionError = {
130-
args: {
131-
findBy: "1",
132-
action: api.autoTableTest.updateWithCustomParams,
133-
},
134-
};
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { AppProvider, Card, Page } from "@shopify/polaris";
2+
import translations from "@shopify/polaris/locales/en.json";
3+
import React from "react";
4+
import { FormProvider, useForm } from "react-hook-form";
5+
import { Provider } from "../../../src/GadgetProvider.tsx";
6+
import { PolarisAutoForm } from "../../../src/auto/polaris/PolarisAutoForm.tsx";
7+
import { testApi as api } from "../../apis.ts";
8+
9+
export default {
10+
title: "Polaris/AutoForm/Errors",
11+
component: PolarisAutoForm,
12+
decorators: [
13+
(Story) => {
14+
return (
15+
<Provider api={api}>
16+
<AppProvider i18n={translations}>
17+
<FormProvider {...useForm()}>
18+
<Page>
19+
<Card>
20+
<Story />
21+
</Card>
22+
</Page>
23+
</FormProvider>
24+
</AppProvider>
25+
</Provider>
26+
);
27+
},
28+
],
29+
};
30+
31+
export const FieldNameCustomParamCollisionError = {
32+
args: {
33+
findBy: "1",
34+
action: api.autoTableTest.updateWithCustomParams,
35+
},
36+
};
37+
38+
export const ModelActionWithoutApiTrigger = {
39+
args: {
40+
findBy: "70",
41+
action: api.autoTableTest.noTriggerAction,
42+
},
43+
};
44+
45+
export const GlobalActionWithoutApiTrigger = {
46+
args: {
47+
action: api.noTriggerGlobalAction,
48+
},
49+
};

packages/react/spec/auto/inputs/PolarisAutoEncryptedStringInput.spec.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import React from "react";
55
import { PolarisAutoEncryptedStringInput } from "../../../src/auto/polaris/inputs/PolarisAutoEncryptedStringInput.js";
66
import type { ActionMetadata } from "../../../src/metadata.js";
77
import { MockForm } from "../MockForm.js";
8+
import { apiTriggerOnly } from "../support/Triggers.js";
89

910
describe("PolarisEncryptedStringInput", () => {
1011
let result: RenderResult;
@@ -39,6 +40,7 @@ const metadata: ActionMetadata = {
3940
action: {
4041
name: "Create",
4142
apiIdentifier: "create",
43+
triggers: apiTriggerOnly,
4244
inputFields: [
4345
{
4446
name: "Widget",

packages/react/spec/auto/inputs/PolarisAutoTextInput.spec.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type { ActionMetadata } from "../../../src/metadata.js";
1313
import { testApi as api } from "../../apis.js";
1414
import { MockClientProvider, mockUrqlClient } from "../../testWrappers.js";
1515
import { MockForm } from "../MockForm.js";
16+
import { apiTriggerOnly } from "../support/Triggers.js";
1617

1718
describe("PolarisAutoTextInput", () => {
1819
let result: RenderResult;
@@ -147,6 +148,7 @@ describe("PolarisAutoTextInput", () => {
147148
apiIdentifier: "create",
148149
operatesWithRecordIdentity: false,
149150
isDeleteAction: false,
151+
triggers: apiTriggerOnly,
150152
inputFields: [
151153
{
152154
name: "Widget",
@@ -209,6 +211,7 @@ const metadata = {
209211
apiIdentifier: "create",
210212
operatesWithRecordIdentity: false,
211213
isDeleteAction: false,
214+
triggers: apiTriggerOnly,
212215
inputFields: [
213216
{
214217
name: "Widget",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const apiTriggerOnly = [{ specID: "gadget/trigger/graphql_api", __typename: "GadgetTrigger" }];

packages/react/spec/auto/support/gameCityModel.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { recordIdInputField } from "./shared.js";
2+
import { apiTriggerOnly } from "./Triggers.js";
23

34
export const gameCityModelInputFields = {
45
name: "City",
@@ -65,6 +66,7 @@ export const getGameCityModelMetadata = (action: { name: string; apiIdentifier:
6566
action: {
6667
...action,
6768
inputFields: [recordIdInputField, gameCityModelInputFields],
69+
triggers: apiTriggerOnly,
6870
__typename: "GadgetAction",
6971
},
7072
__typename: "GadgetModel",

packages/react/spec/auto/support/gizmoModel.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { recordIdInputField } from "./shared.js";
2+
import { apiTriggerOnly } from "./Triggers.js";
23

34
export const gizmoModelInputFields = {
45
name: "Gizmo",
@@ -74,6 +75,7 @@ export const getGizmoModelMetadata = (
7475
action: {
7576
...action,
7677
inputFields: action.operatesWithRecordIdentity ? [recordIdInputField, ...inputFields] : inputFields,
78+
triggers: apiTriggerOnly,
7779
__typename: "GadgetAction",
7880
},
7981
__typename: "GadgetModel",

0 commit comments

Comments
 (0)