Skip to content

Commit

Permalink
Merge pull request #4256 from Shopify/add-domain-to-stores-list
Browse files Browse the repository at this point in the history
Show domain for stores list (app management client only)
  • Loading branch information
gracejychang authored Aug 2, 2024
2 parents c7b83d8 + c7677bb commit b9c5253
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 15 deletions.
26 changes: 23 additions & 3 deletions packages/app/src/cli/prompts/dev.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,13 @@ describe('selectApp', () => {
})

describe('selectStore', () => {
const defaultShowDomainOnPrompt = false
test('returns undefined if store list is empty', async () => {
// Given
const stores: OrganizationStore[] = []

// When
const got = await selectStorePrompt(stores)
const got = await selectStorePrompt(stores, defaultShowDomainOnPrompt)

// Then
expect(got).toEqual(undefined)
Expand All @@ -153,7 +154,7 @@ describe('selectStore', () => {
const outputMock = mockAndCaptureOutput()

// When
const got = await selectStorePrompt(stores)
const got = await selectStorePrompt(stores, defaultShowDomainOnPrompt)

// Then
expect(got).toEqual(STORE1)
Expand All @@ -167,7 +168,7 @@ describe('selectStore', () => {
vi.mocked(renderAutocompletePrompt).mockResolvedValue('2')

// When
const got = await selectStorePrompt(stores)
const got = await selectStorePrompt(stores, defaultShowDomainOnPrompt)

// Then
expect(got).toEqual(STORE2)
Expand All @@ -179,6 +180,25 @@ describe('selectStore', () => {
],
})
})

test('renders stores list with domain if showDomainOnPrompt is true ', async () => {
// Given
const stores: OrganizationStore[] = [STORE1, STORE2]
vi.mocked(renderAutocompletePrompt).mockResolvedValue('2')

// When
const got = await selectStorePrompt(stores, true)

// Then
expect(got).toEqual(STORE2)
expect(renderAutocompletePrompt).toHaveBeenCalledWith({
message: 'Which store would you like to use to view your project?',
choices: [
{label: 'store1 (domain1)', value: '1'},
{label: 'store2 (domain2)', value: '2'},
],
})
})
})

describe('appName', () => {
Expand Down
14 changes: 12 additions & 2 deletions packages/app/src/cli/prompts/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,23 @@ export async function selectAppPrompt(
return currentAppChoices.find((app) => app.apiKey === apiKey)!
}

export async function selectStorePrompt(stores: OrganizationStore[]): Promise<OrganizationStore | undefined> {
export async function selectStorePrompt(
stores: OrganizationStore[],
showDomainOnPrompt: boolean,
): Promise<OrganizationStore | undefined> {
if (stores.length === 0) return undefined
if (stores.length === 1) {
outputCompleted(`Using your default dev store, ${stores[0]!.shopName}, to preview your project.`)
return stores[0]
}
const storeList = stores.map((store) => ({label: store.shopName, value: store.shopId}))

const storeList = stores.map((store) => {
let label = store.shopName
if (showDomainOnPrompt && store.shopDomain) {
label = `${store.shopName} (${store.shopDomain})`
}
return {label, value: store.shopId}
})

const id = await renderAutocompletePrompt({
message: 'Which store would you like to use to view your project?',
Expand Down
26 changes: 21 additions & 5 deletions packages/app/src/cli/services/dev/select-store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
confirmConversionToTransferDisabledStorePrompt,
} from '../../prompts/dev.js'
import {testDeveloperPlatformClient} from '../../models/app/app.test-data.js'
import {ClientName} from '../../utilities/developer-platform-client.js'
import {beforeEach, describe, expect, vi, test} from 'vitest'
import {isSpinEnvironment} from '@shopify/cli-kit/node/context/spin'
import {firstPartyDev} from '@shopify/cli-kit/node/context/local'
Expand Down Expand Up @@ -47,6 +48,8 @@ const STORE3: OrganizationStore = {
convertableToPartnerTest: false,
}

const defaultShowDomainOnPrompt = false

beforeEach(() => {
vi.mocked(isSpinEnvironment).mockReturnValue(false)
})
Expand All @@ -61,7 +64,20 @@ describe('selectStore', async () => {

// Then
expect(got).toEqual(STORE1)
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2])
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2], defaultShowDomainOnPrompt)
})

test('selectStorePrompt is called with showDomainOnPrompt = true if clientName is app-management', async () => {
// Given
vi.mocked(selectStorePrompt).mockResolvedValueOnce(STORE1)
const developerPlatformClient = testDeveloperPlatformClient({clientName: ClientName.AppManagement})

// When
const got = await selectStore([STORE1, STORE2], ORG1, developerPlatformClient)

// Then
expect(got).toEqual(STORE1)
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2], true)
})

test('prompts user to convert store to non-transferable if selection is invalid', async () => {
Expand All @@ -74,7 +90,7 @@ describe('selectStore', async () => {

// Then
expect(got).toEqual(STORE2)
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2])
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2], defaultShowDomainOnPrompt)
expect(confirmConversionToTransferDisabledStorePrompt).toHaveBeenCalled()
})

Expand All @@ -89,7 +105,7 @@ describe('selectStore', async () => {

// Then
expect(got).toEqual(STORE1)
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2])
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2], defaultShowDomainOnPrompt)
expect(confirmConversionToTransferDisabledStorePrompt).toHaveBeenCalled()
})

Expand All @@ -106,7 +122,7 @@ describe('selectStore', async () => {
// Then
expect(got).toEqual(STORE2)
expect(developerPlatformClient.convertToTransferDisabledStore).not.toHaveBeenCalled()
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2])
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2], defaultShowDomainOnPrompt)
})

test('throws if store is non convertible', async () => {
Expand All @@ -130,7 +146,7 @@ describe('selectStore', async () => {

// Then
await expect(got).rejects.toThrowError()
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2])
expect(selectStorePrompt).toHaveBeenCalledWith([STORE1, STORE2], defaultShowDomainOnPrompt)
})

test('prompts user to create & reload, fetches 10 times and tries again if reload is true', async () => {
Expand Down
7 changes: 4 additions & 3 deletions packages/app/src/cli/services/dev/select-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
ConvertDevToTransferDisabledSchema,
ConvertDevToTransferDisabledStoreVariables,
} from '../../api/graphql/convert_dev_to_transfer_disabled_store.js'
import {DeveloperPlatformClient} from '../../utilities/developer-platform-client.js'
import {ClientName, DeveloperPlatformClient} from '../../utilities/developer-platform-client.js'
import {sleep} from '@shopify/cli-kit/node/system'
import {renderTasks} from '@shopify/cli-kit/node/ui'
import {partnersFqdn} from '@shopify/cli-kit/node/context/fqdn'
Expand Down Expand Up @@ -39,9 +39,10 @@ export async function selectStore(
org: Organization,
developerPlatformClient: DeveloperPlatformClient,
): Promise<OrganizationStore> {
const showDomainOnPrompt = developerPlatformClient.clientName === ClientName.AppManagement
// If no stores, guide the developer through creating one
// Then, with a store selected, make sure its transfer-disabled, prompting to convert if needed
let store = await selectStorePrompt(stores)
let store = await selectStorePrompt(stores, showDomainOnPrompt)
if (!store) {
outputInfo(`\n${await CreateStoreLink(org.id)}`)
await sleep(5)
Expand All @@ -63,7 +64,7 @@ export async function selectStore(
)
while (!storeIsValid) {
// eslint-disable-next-line no-await-in-loop
store = await selectStorePrompt(stores)
store = await selectStorePrompt(stores, showDomainOnPrompt)
if (!store) {
throw new CancelExecution()
}
Expand Down
5 changes: 5 additions & 0 deletions packages/app/src/cli/utilities/developer-platform-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ import {DevSessionDeleteMutation} from '../api/graphql/app-dev/generated/dev-ses
import {FunctionUploadUrlGenerateResponse} from '@shopify/cli-kit/node/api/partners'
import {isTruthy} from '@shopify/cli-kit/node/context/utilities'

export enum ClientName {
AppManagement = 'app-management',
Partners = 'partners',
}

export type Paginateable<T> = T & {
hasMorePages: boolean
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
AppVersionIdentifiers,
DevSessionOptions,
filterDisabledFlags,
ClientName,
} from '../developer-platform-client.js'
import {PartnersSession} from '../../services/context/partner-account-info.js'
import {
Expand Down Expand Up @@ -145,7 +146,7 @@ export interface GatedExtensionTemplate extends ExtensionTemplate {
}

export class AppManagementClient implements DeveloperPlatformClient {
public clientName = 'app-management'
public clientName = ClientName.AppManagement
public webUiName = 'Developer Dashboard'
public requiresOrganization = true
public supportsAtomicDeployments = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Paginateable,
DevSessionOptions,
filterDisabledFlags,
ClientName,
} from '../developer-platform-client.js'
import {fetchCurrentAccountInformation, PartnersSession} from '../../../cli/services/context/partner-account-info.js'
import {
Expand Down Expand Up @@ -209,7 +210,7 @@ interface OrgAndAppsResponse {
}

export class PartnersClient implements DeveloperPlatformClient {
public clientName = 'partners'
public clientName = ClientName.Partners
public webUiName = 'Partner Dashboard'
public supportsAtomicDeployments = false
public requiresOrganization = false
Expand Down

0 comments on commit b9c5253

Please sign in to comment.