Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changeset/smooth-corners-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/cli': patch
---

add warning and confirm with user before running theme doctor test suite
183 changes: 91 additions & 92 deletions packages/cli/oclif.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3063,98 +3063,6 @@
"strict": true,
"summary": "Trigger delivery of a sample webhook topic payload to a designated address."
},
"audit": {
"aliases": [
],
"args": {
},
"description": "Run CLI audit tests",
"enableJsonFlag": false,
"flags": {
},
"hasDynamicHelp": false,
"hidden": true,
"hiddenAliases": [
],
"id": "audit",
"pluginAlias": "@shopify/cli",
"pluginName": "@shopify/cli",
"pluginType": "core",
"strict": true
},
"audit:theme": {
"aliases": [
],
"args": {
},
"description": "Run all theme command audit tests",
"enableJsonFlag": false,
"flags": {
"environment": {
"char": "e",
"description": "The environment to use from shopify.theme.toml (required for store-connected tests).",
"env": "SHOPIFY_FLAG_ENVIRONMENT",
"hasDynamicHelp": false,
"multiple": false,
"name": "environment",
"required": true,
"type": "option"
},
"no-color": {
"allowNo": false,
"description": "Disable color output.",
"env": "SHOPIFY_FLAG_NO_COLOR",
"hidden": false,
"name": "no-color",
"type": "boolean"
},
"password": {
"description": "Password from Theme Access app (overrides environment).",
"env": "SHOPIFY_FLAG_PASSWORD",
"hasDynamicHelp": false,
"multiple": false,
"name": "password",
"type": "option"
},
"path": {
"char": "p",
"default": ".",
"description": "The path to run tests in. Defaults to current directory.",
"env": "SHOPIFY_FLAG_PATH",
"hasDynamicHelp": false,
"multiple": false,
"name": "path",
"type": "option"
},
"store": {
"char": "s",
"description": "Store URL (overrides environment).",
"env": "SHOPIFY_FLAG_STORE",
"hasDynamicHelp": false,
"multiple": false,
"name": "store",
"type": "option"
},
"verbose": {
"allowNo": false,
"description": "Increase the verbosity of the output.",
"env": "SHOPIFY_FLAG_VERBOSE",
"hidden": false,
"name": "verbose",
"type": "boolean"
}
},
"hasDynamicHelp": false,
"hidden": true,
"hiddenAliases": [
"audit theme"
],
"id": "audit:theme",
"pluginAlias": "@shopify/cli",
"pluginName": "@shopify/cli",
"pluginType": "core",
"strict": true
},
"auth:login": {
"aliases": [
],
Expand Down Expand Up @@ -3501,6 +3409,97 @@
"pluginType": "core",
"strict": true
},
"doctor": {
"aliases": [
],
"args": {
},
"description": "Run CLI doctor tests",
"enableJsonFlag": false,
"flags": {
},
"hasDynamicHelp": false,
"hidden": true,
"hiddenAliases": [
],
"id": "doctor",
"pluginAlias": "@shopify/cli",
"pluginName": "@shopify/cli",
"pluginType": "core",
"strict": true
},
"doctor:theme": {
"aliases": [
],
"args": {
},
"description": "Run all theme command doctor tests",
"enableJsonFlag": false,
"flags": {
"environment": {
"char": "e",
"description": "The environment to use from shopify.theme.toml (required for store-connected tests).",
"env": "SHOPIFY_FLAG_ENVIRONMENT",
"hasDynamicHelp": false,
"multiple": false,
"name": "environment",
"required": true,
"type": "option"
},
"no-color": {
"allowNo": false,
"description": "Disable color output.",
"env": "SHOPIFY_FLAG_NO_COLOR",
"hidden": false,
"name": "no-color",
"type": "boolean"
},
"password": {
"description": "Password from Theme Access app (overrides environment).",
"env": "SHOPIFY_FLAG_PASSWORD",
"hasDynamicHelp": false,
"multiple": false,
"name": "password",
"type": "option"
},
"path": {
"char": "p",
"default": ".",
"description": "The path to run tests in. Defaults to current directory.",
"env": "SHOPIFY_FLAG_PATH",
"hasDynamicHelp": false,
"multiple": false,
"name": "path",
"type": "option"
},
"store": {
"char": "s",
"description": "Store URL (overrides environment).",
"env": "SHOPIFY_FLAG_STORE",
"hasDynamicHelp": false,
"multiple": false,
"name": "store",
"type": "option"
},
"verbose": {
"allowNo": false,
"description": "Increase the verbosity of the output.",
"env": "SHOPIFY_FLAG_VERBOSE",
"hidden": false,
"name": "verbose",
"type": "boolean"
}
},
"hasDynamicHelp": false,
"hidden": true,
"hiddenAliases": [
],
"id": "doctor:theme",
"pluginAlias": "@shopify/cli",
"pluginName": "@shopify/cli",
"pluginType": "core",
"strict": true
},
"help": {
"aliases": [
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import Command from '@shopify/cli-kit/node/base-command'
import {renderInfo} from '@shopify/cli-kit/node/ui'

export default class Audit extends Command {
static description = 'Run CLI audit tests'
export default class Doctor extends Command {
static description = 'Run CLI doctor tests'
static hidden = true

async run(): Promise<void> {
renderInfo({
headline: 'Shopify CLI Audit.',
headline: 'Shopify CLI Doctor.',
body: [
'Available audit commands:',
'Available doctor commands:',
'',
' shopify audit theme -e <environment> Run all theme command tests',
' shopify doctor theme -e <environment> Run all theme command tests',
'',
'The -e/--environment flag is required to specify the store configuration.',
'Use --help with any command for more options.',
Expand Down
30 changes: 30 additions & 0 deletions packages/cli/src/cli/commands/doctor/theme/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import DoctorTheme from './index.js'
import {runThemeDoctor} from '../../../services/doctor/theme/runner.js'
import {renderConfirmationPrompt} from '@shopify/cli-kit/node/ui'
import {test, expect, vi} from 'vitest'

vi.mock('@shopify/cli-kit/node/ui')
vi.mock('../../../services/doctor/theme/runner.js')

test('does not run theme doctor when user cancels', async () => {
// Given
vi.mocked(renderConfirmationPrompt).mockResolvedValue(false)

// When
await DoctorTheme.run(['--environment', 'test'])

// Then
expect(runThemeDoctor).not.toHaveBeenCalled()
})

test('runs theme doctor when user confirms', async () => {
// Given
vi.mocked(renderConfirmationPrompt).mockResolvedValue(true)
vi.mocked(runThemeDoctor).mockResolvedValue([])

// When
await DoctorTheme.run(['--environment', 'test'])

// Then
expect(runThemeDoctor).toHaveBeenCalled()
})
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {runThemeAudit} from '../../../services/audit/theme/runner.js'
import {runThemeDoctor} from '../../../services/doctor/theme/runner.js'
import Command from '@shopify/cli-kit/node/base-command'
import {globalFlags} from '@shopify/cli-kit/node/cli'
import {Flags} from '@oclif/core'
import {resolvePath, cwd} from '@shopify/cli-kit/node/path'
import {renderConfirmationPrompt, RenderConfirmationPromptOptions} from '@shopify/cli-kit/node/ui'

export default class AuditTheme extends Command {
static description = 'Run all theme command audit tests'
export default class DoctorTheme extends Command {
static description = 'Run all theme command doctor tests'
static hidden = true
static hiddenAliases = ['audit theme']

static flags = {
...globalFlags,
Expand Down Expand Up @@ -36,9 +36,19 @@ export default class AuditTheme extends Command {
}

async run(): Promise<void> {
const {flags} = await this.parse(AuditTheme)
const {flags} = await this.parse(DoctorTheme)
const promptOptions: RenderConfirmationPromptOptions = {
message: `This command will call theme commands that will interact with your remote shop. Please confirm before running.`,
confirmationMessage: 'Yes I understand',
cancellationMessage: 'No, cancel the command',
}
const confirmed = await renderConfirmationPrompt(promptOptions)

if (!confirmed) {
return
}

const results = await runThemeAudit({
const results = await runThemeDoctor({
path: flags.path,
environment: flags.environment,
store: flags.store,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {cwd} from '@shopify/cli-kit/node/path'
import type {AuditContext, ThemeAuditOptions} from './types.js'
import type {DoctorContext, ThemeDoctorOptions} from './types.js'

export function createAuditContext(options: ThemeAuditOptions): AuditContext {
export function createDoctorContext(options: ThemeDoctorOptions): DoctorContext {
return {
workingDirectory: options.path ?? cwd(),
environment: options.environment,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {AuditSuite} from './framework.js'
import {DoctorSuite} from './framework.js'
import {describe, expect, test, vi, beforeEach} from 'vitest'
import type {AuditContext} from './types.js'
import type {DoctorContext} from './types.js'

vi.mock('@shopify/cli-kit/node/fs')
vi.mock('@shopify/cli-kit/node/system')

/**
* Creates a minimal AuditContext for testing
* Creates a minimal DoctorContext for testing
*/
function createTestContext(overrides?: Partial<AuditContext>): AuditContext {
function createTestContext(overrides?: Partial<DoctorContext>): DoctorContext {
return {
workingDirectory: '/test/dir',
environment: 'test',
Expand All @@ -18,9 +18,9 @@ function createTestContext(overrides?: Partial<AuditContext>): AuditContext {
}

/**
* Concrete test suite for testing AuditSuite behavior
* Concrete test suite for testing DoctorSuite behavior
*/
class TestSuite extends AuditSuite {
class TestSuite extends DoctorSuite {
static description = 'Test suite for framework testing'

private readonly testDefinitions: {name: string; fn: () => Promise<void>}[] = []
Expand All @@ -45,9 +45,9 @@ class TestSuite extends AuditSuite {
}
}

describe('AuditSuite', () => {
describe('DoctorSuite', () => {
let suite: TestSuite
let context: AuditContext
let context: DoctorContext

beforeEach(() => {
suite = new TestSuite()
Expand Down
Loading