Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: skip automatic form generation when datastore is not enabled #12713

Merged
merged 3 commits into from
Jun 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/amplify-util-uibuilder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"access": "public"
},
"dependencies": {
"@aws-amplify/amplify-category-api": "^5.4.0",
"@aws-amplify/amplify-cli-core": "4.0.8",
"@aws-amplify/amplify-prompts": "2.7.0",
"@aws-amplify/codegen-ui": "2.14.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import aws from 'aws-sdk'; // eslint-disable-line import/no-extraneous-dependencies
import * as extractArgsDependency from '../commands/utils/extractArgs';
import { run } from '../commands/cloneComponentsFromEnv';
import { isDataStoreEnabled } from '@aws-amplify/amplify-category-api';

const extractArgsDependencyMock = extractArgsDependency as any;
const awsMock = aws as any;

jest.mock('../commands/utils/featureFlags', () => ({
getTransformerVersion: jest.fn().mockReturnValue(2),
}));
jest.mock('@aws-amplify/amplify-category-api', () => ({
...jest.requireActual('@aws-amplify/amplify-category-api'),
isDataStoreEnabled: jest.fn(),
}));
jest.mock('../commands/utils/extractArgs');
jest.mock('@aws-amplify/amplify-cli-core');

const isDataStoreEnabledMocked = jest.mocked(isDataStoreEnabled);

const mockedComponentExport = jest.fn((envName: string) => {
if (envName === 'newEnvName') {
return {
Expand All @@ -26,6 +33,7 @@ const mockedComponentCreate = jest.fn().mockReturnValue({ entity: {} });
describe('can clone components to new environment', () => {
let context: any;
beforeEach(() => {
isDataStoreEnabledMocked.mockResolvedValue(true);
context = {
amplify: {
invokePluginMethod: () => ({}),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import aws from 'aws-sdk'; // eslint-disable-line import/no-extraneous-dependencies
import * as utils from '../commands/utils';
import { run } from '../commands/generateComponents';
import { isDataStoreEnabled } from '@aws-amplify/amplify-category-api';
import { getTransformerVersion } from '../commands/utils/featureFlags';

jest.mock('../commands/utils');
jest.mock('@aws-amplify/amplify-cli-core');
jest.mock('@aws-amplify/amplify-category-api', () => ({
...jest.requireActual('@aws-amplify/amplify-category-api'),
isDataStoreEnabled: jest.fn(),
}));
jest.mock('../commands/utils/featureFlags', () => ({
...jest.requireActual('../commands/utils/featureFlags'),
getTransformerVersion: jest.fn(),
}));
const awsMock = aws as any;
const utilsMock = utils as any;

const isDataStoreEnabledMocked = jest.mocked(isDataStoreEnabled);
const getTransformerVersionMocked = jest.mocked(getTransformerVersion);
utilsMock.shouldRenderComponents = jest.fn().mockReturnValue(true);
utilsMock.notifyMissingPackages = jest.fn().mockReturnValue(true);
utilsMock.getAmplifyDataSchema = jest.fn().mockReturnValue({});
Expand All @@ -19,7 +31,19 @@ describe('can generate components', () => {
let context: any;
let schemas: any;
let mockedExport: jest.Mock<any, any>;
const getMetadataPromise = jest.fn().mockReturnValue({
features: {
autoGenerateForms: 'true',
autoGenerateViews: 'true',
formFeatureFlags: {
isRelationshipSupported: 'false',
isNonModelSupported: 'false',
},
},
});
beforeEach(() => {
isDataStoreEnabledMocked.mockResolvedValue(true);
getTransformerVersionMocked.mockResolvedValue(2);
context = {
amplify: {
invokePluginMethod: () => ({}),
Expand Down Expand Up @@ -65,16 +89,7 @@ describe('can generate components', () => {
promise: () => mockedExport(),
}),
getMetadata: jest.fn().mockReturnValue({
promise: jest.fn().mockReturnValue({
features: {
autoGenerateForms: 'true',
autoGenerateViews: 'true',
formFeatureFlags: {
isRelationshipSupported: 'false',
isNonModelSupported: 'false',
},
},
}),
promise: getMetadataPromise,
}),
});
utilsMock.generateUiBuilderComponents = jest.fn().mockReturnValue(schemas.entities);
Expand All @@ -94,4 +109,88 @@ describe('can generate components', () => {
expect(utilsMock.generateUiBuilderForms).toBeCalledTimes(1);
expect(utilsMock.deleteDetachedForms).toBeCalledTimes(1);
});

it('should autogenerate forms if transformer v2 and datastore and feature flag are enabled', async () => {
isDataStoreEnabledMocked.mockResolvedValue(true);
getTransformerVersionMocked.mockResolvedValue(2);
getMetadataPromise.mockReturnValue({
features: {
autoGenerateForms: 'true',
autoGenerateViews: 'true',
formFeatureFlags: {
isRelationshipSupported: 'false',
isNonModelSupported: 'false',
},
},
});
await run(context, 'PostPull');
expect(utilsMock.generateUiBuilderForms).toHaveBeenCalledWith(expect.anything(), expect.anything(), undefined, true, expect.anything());
});

it('should not autogenerate forms if transformer v1', async () => {
isDataStoreEnabledMocked.mockResolvedValue(true);
getTransformerVersionMocked.mockResolvedValue(1);
getMetadataPromise.mockReturnValue({
features: {
autoGenerateForms: 'true',
autoGenerateViews: 'true',
formFeatureFlags: {
isRelationshipSupported: 'false',
isNonModelSupported: 'false',
},
},
});
await run(context, 'PostPull');
expect(utilsMock.generateUiBuilderForms).toHaveBeenCalledWith(
expect.anything(),
expect.anything(),
undefined,
false,
expect.anything(),
);
});

it('should not autogenerate forms if datastore is not enabled', async () => {
isDataStoreEnabledMocked.mockResolvedValue(false);
getMetadataPromise.mockReturnValue({
features: {
autoGenerateForms: 'true',
autoGenerateViews: 'true',
formFeatureFlags: {
isRelationshipSupported: 'false',
isNonModelSupported: 'false',
},
},
});
await run(context, 'PostPull');
expect(utilsMock.generateUiBuilderForms).toHaveBeenCalledWith(
expect.anything(),
expect.anything(),
undefined,
false,
expect.anything(),
);
});

it('should not autogenerate forms if feature flag isnot enabled', async () => {
isDataStoreEnabledMocked.mockResolvedValue(true);
getMetadataPromise.mockReturnValue({
features: {
autoGenerateForms: 'false',
autoGenerateViews: 'true',
formFeatureFlags: {
isRelationshipSupported: 'false',
isNonModelSupported: 'false',
},
},
});
await run(context, 'PostPull');
expect(utilsMock.generateUiBuilderForms).toHaveBeenCalledWith(
expect.anything(),
expect.anything(),
undefined,
false,
expect.anything(),
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ import { Form } from 'aws-sdk/clients/amplifyuibuilder'; // eslint-disable-line
import { printer } from '@aws-amplify/amplify-prompts'; // eslint-disable-line import/no-extraneous-dependencies
import * as utils from '../commands/utils';
import { prePushHandler } from '../utils/prePushHandler';
import { isDataStoreEnabled } from '@aws-amplify/amplify-category-api';

jest.mock('../commands/utils');
jest.mock('@aws-amplify/amplify-cli-core');
jest.mock('../commands/utils/featureFlags', () => ({
getTransformerVersion: jest.fn().mockImplementation(() => 2),
}));
jest.mock('@aws-amplify/amplify-category-api', () => ({
...jest.requireActual('@aws-amplify/amplify-category-api'),
isDataStoreEnabled: jest.fn(),
}));

const awsMock = aws as any;
const utilsMock = utils as any;
const isDataStoreEnabledMocked = jest.mocked(isDataStoreEnabled);

utilsMock.shouldRenderComponents = jest.fn().mockImplementation(() => true);

Expand All @@ -22,6 +28,7 @@ describe('handlePrePush', () => {
let exportedForms: Form[];

beforeEach(() => {
isDataStoreEnabledMocked.mockResolvedValue(true);
context = {
amplify: {
invokePluginMethod: jest.fn().mockResolvedValue({ models: { Comment: {} } }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { AmplifyStudioClient } from '../clients';
import * as createUiBuilderComponentDependency from '../commands/utils/codegenResources';
import { exampleSchema } from './utils';
import { isDataStoreEnabled } from '@aws-amplify/amplify-category-api';

jest.mock('@aws-amplify/amplify-cli-core', () => ({
...jest.requireActual('@aws-amplify/amplify-cli-core'),
Expand All @@ -24,12 +25,20 @@ jest.mock('../commands/utils/featureFlags', () => ({
getTransformerVersion: jest.fn().mockReturnValue(2),
}));

jest.mock('@aws-amplify/amplify-category-api', () => ({
...jest.requireActual('@aws-amplify/amplify-category-api'),
isDataStoreEnabled: jest.fn(),
}));

const awsMock = aws as any;
const stateManagerMock = stateManager as any;
const createUiBuilderComponentDependencyMock = createUiBuilderComponentDependency as any;
const isDataStoreEnabledMocked = jest.mocked(isDataStoreEnabled);

describe('should sync amplify ui builder components', () => {
let context: any;
beforeEach(() => {
isDataStoreEnabledMocked.mockResolvedValue(true);
context = {
exeInfo: {
projectConfig: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { AmplifyUIBuilder, AmplifyBackend } from 'aws-sdk';
import { printer } from '@aws-amplify/amplify-prompts';
import { getAppId, getEnvName } from '../commands/utils/environmentHelpers';
import { getTransformerVersion } from '../commands/utils/featureFlags';
import { isDataStoreEnabled } from '@aws-amplify/amplify-category-api';

/**
* studio client metadata
Expand Down Expand Up @@ -60,6 +61,7 @@ export default class AmplifyStudioClient {
#envName: string;
metadata: StudioMetadata;
isGraphQLSupported = false;
isDataStoreEnabled = false;

/**
* static function meant to check if given appId is studio enabled
Expand All @@ -82,11 +84,14 @@ export default class AmplifyStudioClient {
static async setClientInfo(context: $TSContext, envName?: string, appId?: string): Promise<AmplifyStudioClient> {
const resolvedEnvName = getEnvName(context, envName);
const resolvedAppId = getAppId(context, appId);
const awsConfigInfo = (await context.amplify.invokePluginMethod(context, 'awscloudformation', undefined, 'loadConfigurationForEnv', [
context,
resolvedEnvName,
resolvedAppId,
])) as ServiceConfigurationOptions;
const [awsConfigInfo, dataStoreStatus] = await Promise.all([
context.amplify.invokePluginMethod(context, 'awscloudformation', undefined, 'loadConfigurationForEnv', [
context,
resolvedEnvName,
resolvedAppId,
]) as ServiceConfigurationOptions,
isDataStoreEnabled(context),
]);

const client = new AmplifyStudioClient(awsConfigInfo, resolvedAppId, resolvedEnvName);

Expand All @@ -97,6 +102,8 @@ export default class AmplifyStudioClient {
client.isGraphQLSupported = false;
}

client.isDataStoreEnabled = dataStoreStatus;

return client;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ export const run = async (context: $TSContext, eventType: 'PostPush' | 'PostPull
studioClient.isGraphQLSupported ? getAmplifyDataSchema(context) : Promise.resolve(undefined),
]);

const nothingWouldAutogenerate = !dataSchema || !studioClient.metadata.autoGenerateForms || !studioClient.isGraphQLSupported;
const nothingWouldAutogenerate =
!dataSchema || !studioClient.metadata.autoGenerateForms || !studioClient.isGraphQLSupported || !studioClient.isDataStoreEnabled;

if (nothingWouldAutogenerate && [componentSchemas, themeSchemas, formSchemas].every((group) => !group.entities.length)) {
printer.debug('Skipping UI component generation since none are found.');
Expand All @@ -52,7 +53,7 @@ export const run = async (context: $TSContext, eventType: 'PostPush' | 'PostPull
context,
formSchemas.entities,
dataSchema,
studioClient.metadata.autoGenerateForms && studioClient.isGraphQLSupported,
studioClient.metadata.autoGenerateForms && studioClient.isGraphQLSupported && studioClient.isDataStoreEnabled,
studioClient.metadata.formFeatureFlags,
),
};
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@aws-amplify/amplify-util-uibuilder@workspace:packages/amplify-util-uibuilder"
dependencies:
"@aws-amplify/amplify-category-api": ^5.4.0
"@aws-amplify/amplify-cli-core": 4.0.8
"@aws-amplify/amplify-prompts": 2.7.0
"@aws-amplify/appsync-modelgen-plugin": ^2.4.4
Expand Down