From 40f8104cdc62d1eeaf0b0a79ff9de44b45b156c4 Mon Sep 17 00:00:00 2001 From: Piotr Szeremeta Date: Wed, 18 Sep 2024 16:07:44 +0200 Subject: [PATCH] Add tests to EnvironmentVariableGet --- .../__tests__/EnvironmentVariableGet.test.ts | 109 ++++++++++++++++++ packages/eas-cli/src/commands/env/get.ts | 56 ++++++--- .../queries/EnvironmentVariablesQuery.ts | 2 + 3 files changed, 149 insertions(+), 18 deletions(-) create mode 100644 packages/eas-cli/src/commands/env/__tests__/EnvironmentVariableGet.test.ts diff --git a/packages/eas-cli/src/commands/env/__tests__/EnvironmentVariableGet.test.ts b/packages/eas-cli/src/commands/env/__tests__/EnvironmentVariableGet.test.ts new file mode 100644 index 0000000000..77f91f542c --- /dev/null +++ b/packages/eas-cli/src/commands/env/__tests__/EnvironmentVariableGet.test.ts @@ -0,0 +1,109 @@ +import { Config } from '@oclif/core'; + +import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient'; +import { testProjectId } from '../../../credentials/__tests__/fixtures-constants'; +import { + EnvironmentVariableEnvironment, + EnvironmentVariableScope, + EnvironmentVariableVisibility, +} from '../../../graphql/generated'; +import { EnvironmentVariablesQuery } from '../../../graphql/queries/EnvironmentVariablesQuery'; +import Log from '../../../log'; +import { promptVariableEnvironmentAsync, promptVariableNameAsync } from '../../../utils/prompts'; +import EnvironmentVariableGet from '../get'; + +jest.mock('../../../graphql/mutations/EnvironmentVariableMutation'); +jest.mock('../../../graphql/queries/AppQuery'); +jest.mock('../../../graphql/queries/EnvironmentVariablesQuery'); +jest.mock('../../../utils/prompts'); + +describe(EnvironmentVariableGet, () => { + const graphqlClient = {} as any as ExpoGraphqlClient; + const mockConfig = {} as unknown as Config; + const mockVariables = [ + { + id: 'var1', + name: 'TEST_VAR_1', + value: 'value1', + environments: [EnvironmentVariableEnvironment.Production], + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + scope: EnvironmentVariableScope.Project, + visibility: EnvironmentVariableVisibility.Public, + }, + ]; + + it('retrieves environment variables successfully', async () => { + jest + .mocked(EnvironmentVariablesQuery.byAppIdWithSensitiveAsync) + .mockResolvedValueOnce(mockVariables); + jest.spyOn(Log, 'log').mockImplementation(() => {}); + + const command = new EnvironmentVariableGet(['--name', 'TEST_VAR_1'], mockConfig); + + // @ts-expect-error + jest.spyOn(command, 'getContextAsync').mockReturnValue({ + loggedIn: { graphqlClient }, + privateProjectConfig: { projectId: testProjectId }, + }); + + await command.runAsync(); + + expect(EnvironmentVariablesQuery.byAppIdWithSensitiveAsync).toHaveBeenCalledWith( + graphqlClient, + { + appId: testProjectId, + environment: undefined, + filterNames: ['TEST_VAR_1'], + } + ); + expect(Log.log).toHaveBeenCalledWith(expect.stringContaining('TEST_VAR_1')); + }); + + it('handles errors during retrieval', async () => { + const errorMessage = + "Variable name is required. Run the command with '--name VARIABLE_NAME' flag"; + + const command = new EnvironmentVariableGet([], mockConfig); + + // @ts-expect-error + jest.spyOn(command, 'getContextAsync').mockReturnValue({ + loggedIn: { graphqlClient }, + privateProjectConfig: { projectId: testProjectId }, + }); + + await expect(command.runAsync()).rejects.toThrow(errorMessage); + }); + + it('prompts for variable name and environment if the name is ambigous', async () => { + jest + .mocked(promptVariableEnvironmentAsync) + .mockResolvedValueOnce(EnvironmentVariableEnvironment.Production); + jest.mocked(promptVariableNameAsync).mockResolvedValueOnce('TEST_VAR_1'); + + const command = new EnvironmentVariableGet([], mockConfig); + + // @ts-expect-error + jest.spyOn(command, 'getContextAsync').mockReturnValue({ + loggedIn: { graphqlClient }, + privateProjectConfig: { projectId: testProjectId }, + }); + jest.mocked(EnvironmentVariablesQuery.byAppIdWithSensitiveAsync).mockResolvedValueOnce([ + ...mockVariables, + { + id: 'var2', + name: 'TEST_VAR_1', + value: 'value1', + environments: [EnvironmentVariableEnvironment.Development], + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + scope: EnvironmentVariableScope.Project, + visibility: EnvironmentVariableVisibility.Public, + }, + ]); + await command.runAsync(); + + expect(promptVariableEnvironmentAsync).toHaveBeenCalled(); + expect(promptVariableNameAsync).toHaveBeenCalled(); + }); +}); diff --git a/packages/eas-cli/src/commands/env/get.ts b/packages/eas-cli/src/commands/env/get.ts index 4963d57ee0..aaccaf75a0 100644 --- a/packages/eas-cli/src/commands/env/get.ts +++ b/packages/eas-cli/src/commands/env/get.ts @@ -1,4 +1,5 @@ import { Flags } from '@oclif/core'; +import assert from 'assert'; import chalk from 'chalk'; import EasCommand from '../../commandUtils/EasCommand'; @@ -69,15 +70,41 @@ export default class EnvironmentVariableGet extends EasCommand { name = await promptVariableNameAsync(nonInteractive); } - if (!environment && scope === EnvironmentVariableScope.Project) { - environment = await promptVariableEnvironmentAsync({ nonInteractive }); - } - const variable = await getVariableAsync(graphqlClient, scope, projectId, name, environment); + const variables = await getVariablesAsync(graphqlClient, scope, projectId, name, environment); - if (!variable) { + if (variables.length === 0) { Log.error(`Variable with name "${name}" not found`); return; } + + let variable; + + if (variables.length > 1) { + if (!environment) { + const availableEnvironments = variables.reduce( + (acc, v) => [...acc, ...(v.environments ?? [])], + [] as EnvironmentVariableEnvironment[] + ); + + environment = await promptVariableEnvironmentAsync({ + nonInteractive, + multiple: false, + availableEnvironments, + }); + } + + assert(environment, 'Environment is required.'); + + const variableInEnvironment = variables.find(v => v.environments?.includes(environment!)); + if (!variableInEnvironment) { + throw new Error(`Variable with name "${name}" not found in environment "${environment}"`); + } + + variable = variableInEnvironment; + } else { + variable = variables[0]; + } + if (!variable.value) { throw new Error( `${chalk.bold( @@ -112,29 +139,24 @@ export default class EnvironmentVariableGet extends EasCommand { } } -async function getVariableAsync( +async function getVariablesAsync( graphqlClient: ExpoGraphqlClient, scope: string, projectId: string, name: string | undefined, environment: EnvironmentVariableEnvironment | undefined -): Promise { - if (!environment && scope === EnvironmentVariableScope.Project) { - throw new Error('Environment is required.'); - } +): Promise { if (!name) { throw new Error("Variable name is required. Run the command with '--name VARIABLE_NAME' flag."); } - if (environment && scope === EnvironmentVariableScope.Project) { + if (scope === EnvironmentVariableScope.Project) { const appVariables = await EnvironmentVariablesQuery.byAppIdWithSensitiveAsync(graphqlClient, { appId: projectId, environment, filterNames: [name], }); - return appVariables[0]; - } - - if (scope === EnvironmentVariableScope.Shared) { + return appVariables; + } else { const sharedVariables = await EnvironmentVariablesQuery.sharedWithSensitiveAsync( graphqlClient, { @@ -142,8 +164,6 @@ async function getVariableAsync( filterNames: [name], } ); - return sharedVariables[0]; + return sharedVariables; } - - return null; } diff --git a/packages/eas-cli/src/graphql/queries/EnvironmentVariablesQuery.ts b/packages/eas-cli/src/graphql/queries/EnvironmentVariablesQuery.ts index 5a273c1547..99e3151ca7 100644 --- a/packages/eas-cli/src/graphql/queries/EnvironmentVariablesQuery.ts +++ b/packages/eas-cli/src/graphql/queries/EnvironmentVariablesQuery.ts @@ -44,6 +44,7 @@ export const EnvironmentVariablesQuery = { id name value + environments } } } @@ -167,6 +168,7 @@ export const EnvironmentVariablesQuery = { id name value + environments } } }