Skip to content

Commit

Permalink
fix(amplify-util-uibuilder): make studio app check static
Browse files Browse the repository at this point in the history
problem: having the admin check as a part of the studio client instance assumes
the app is already studio enabled

solution: move out studio app check into static function and also don't
throw error on failed app check this is so other flows are not blocked
  • Loading branch information
SwaySway committed Oct 19, 2022
1 parent 9a1c725 commit edd830b
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
$TSContext, AmplifyCategories, AmplifySupportedService, CloudformationProviderFacade,
} from 'amplify-cli-core';
import aws from 'aws-sdk'; // eslint-disable-line import/no-extraneous-dependencies
import { AmplifyStudioClient } from '../clients';
import { shouldRenderComponents } from '../commands/utils/shouldRenderComponents';

const awsMock = aws as any;
Expand Down Expand Up @@ -34,7 +33,6 @@ CloudformationProviderFacade.isAmplifyAdminApp = jest.fn().mockReturnValue({

describe('should render components', () => {
let context: $TSContext | any;
let client: AmplifyStudioClient;

beforeAll(async () => {
// set metadata response
Expand Down Expand Up @@ -69,31 +67,29 @@ describe('should render components', () => {
},
},
};

client = await AmplifyStudioClient.setClientInfo(context);
});
it('works with a valid config', async () => {
const shouldIt = await shouldRenderComponents(context, client);
const shouldIt = await shouldRenderComponents(context);
expect(shouldIt).toBe(true);
});
it("doesn't work if --no-codegen flag is set", async () => {
context.input.options['no-codegen'] = true;
const shouldIt = await shouldRenderComponents(context, client);
const shouldIt = await shouldRenderComponents(context);
expect(shouldIt).toBe(false);
});
it("doesn't work if provider is not awscloudformation", async () => {
context.exeInfo.projectConfig.providers = [];
const shouldIt = await shouldRenderComponents(context, client);
const shouldIt = await shouldRenderComponents(context);
expect(shouldIt).toBe(false);
});
it('should return false if frontend is ios', async () => {
context.exeInfo.projectConfig.frontend = 'ios';
const shouldIt = await shouldRenderComponents(context, client);
const shouldIt = await shouldRenderComponents(context);
expect(shouldIt).toBe(false);
});
it('should return false if frontend is vue', async () => {
context.exeInfo.projectConfig.javascript.framework = 'vue';
const shouldIt = await shouldRenderComponents(context, client);
const shouldIt = await shouldRenderComponents(context);
expect(shouldIt).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
import { AmplifyStudioClient } from '../clients';
import * as createUiBuilderComponentDependency from '../commands/utils/codegenResources';
import { exampleSchema } from './utils';
import { GenericDataModel, GenericDataSchema } from '@aws-amplify/codegen-ui';

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

const awsMock = aws as any;
Expand Down Expand Up @@ -259,8 +258,11 @@ describe('should sync amplify ui builder components', () => {
});

it('should not autogen forms for join tables or unsupported models', async () => {
expect(Object.keys(exampleSchema.models)).toStrictEqual(['Author', 'JoinTable', 'EmptyModel' ])
createUiBuilderComponentDependencyMock.createUiBuilderForm = jest.fn().mockImplementation((context, schema, dataSchema) => ({name: schema.dataType.dataTypeName}));
expect(Object.keys(exampleSchema.models)).toStrictEqual(['Author', 'JoinTable', 'EmptyModel']);
createUiBuilderComponentDependencyMock.createUiBuilderForm = jest.fn().mockImplementation(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(_ctx, schema, _dataSchema) => ({ name: schema.dataType.dataTypeName }),
);
const forms = generateUiBuilderForms(context, [], exampleSchema, true);
expect(forms.every(form => form.resultType === 'SUCCESS')).toBeTruthy();
// only create & update form for author model
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@ export default class AmplifyStudioClient {
#envName: string;
metadata: StudioMetadata;
isGraphQLSupported = false;

/**
* static function meant to check if given appId is studio enabled
*/
static isAmplifyApp = async (context: $TSContext, appId: string): Promise<boolean> => {
try {
const { isAdminApp } = await CloudformationProviderFacade.isAmplifyAdminApp(context, appId);
return isAdminApp;
} catch (err) {
// return false is admin app failed check
// this means we wont run codegen-ui
printer.debug(`Failed admin app check: ${err.message}`);
return false;
}
}

/**
* Used to configure the AWS Amplify clients.
*/
Expand Down Expand Up @@ -230,13 +246,4 @@ export default class AmplifyStudioClient {
throw new Error(`Models not found in AmplifyBackend:GetBackendAPIModels response: ${err.message}`);
}
};

isAmplifyApp = async (context: $TSContext): Promise<boolean> => {
try {
const { isAdminApp } = await CloudformationProviderFacade.isAmplifyAdminApp(context, this.#appId);
return isAdminApp;
} catch (err) {
throw new Error(`Failed admin app check: ${err.message}`);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import {
* Pulls ui components from Studio backend and generates the code in the user's file system
*/
export const run = async (context: $TSContext): Promise<void> => {
const studioClient = await AmplifyStudioClient.setClientInfo(context);
if (!(await shouldRenderComponents(context, studioClient))) {
if (!(await shouldRenderComponents(context))) {
return;
}
const spinner = ora('');
try {
const studioClient = await AmplifyStudioClient.setClientInfo(context);
const [componentSchemas, themeSchemas, formSchemas, dataSchema] = await Promise.all([
studioClient.listComponents(),
studioClient.listThemes(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import { $TSContext } from 'amplify-cli-core';
import { printer } from 'amplify-prompts';
import { AmplifyStudioClient } from '../../clients';
import { getAppId } from './environmentHelpers';

/**
* process to decide if we should render components
*/
export const shouldRenderComponents = async (context: $TSContext, studioClient: AmplifyStudioClient): Promise<boolean> => {
export const shouldRenderComponents = async (context: $TSContext): Promise<boolean> => {
if (process.env.FORCE_RENDER) {
printer.debug('Forcing component render since environment variable flag is set.');
return true;
Expand Down Expand Up @@ -36,7 +37,7 @@ export const shouldRenderComponents = async (context: $TSContext, studioClient:
return false;
}

if (!(await studioClient.isAmplifyApp(context))) {
if (!(await AmplifyStudioClient.isAmplifyApp(context, getAppId(context)))) {
printer.debug('Not pulling components because this project is not Amplify Studio enabled.');
return false;
}
Expand Down

0 comments on commit edd830b

Please sign in to comment.