Skip to content

Commit 5773981

Browse files
committed
Add InstanceCommand and MrtCommand integration tests
Integration tests provide API contract validation beyond code coverage: - Catch flag definition errors (wrong type, missing env var) - Validate baseFlags inheritance works correctly - Exercise full oclif command lifecycle (discovery, parse, init, run) - Test commands the way consumers actually use them New fixtures: - test-instance.js: Tests server, instance flags and hasServer check - test-mrt.js: Tests api-key, project, environment, cloud-origin flags New integration tests: - instance-command.integration.test.ts (5 tests) - mrt-command.integration.test.ts (8 tests) Total integration tests: 18 (BaseCommand + InstanceCommand + MrtCommand)
1 parent 09e3f9d commit 5773981

4 files changed

Lines changed: 249 additions & 0 deletions

File tree

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2025, Salesforce, Inc.
3+
* SPDX-License-Identifier: Apache-2
4+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
import {expect} from 'chai';
7+
import {runCommand} from '@oclif/test';
8+
import path from 'node:path';
9+
import {fileURLToPath} from 'node:url';
10+
11+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
12+
const fixtureRoot = path.join(__dirname, '../fixtures/test-cli');
13+
14+
interface TestInstanceResult {
15+
server?: string;
16+
hasServer: boolean;
17+
instance?: string;
18+
}
19+
20+
describe('InstanceCommand integration', () => {
21+
it('runs test-instance command without errors', async () => {
22+
const {error} = await runCommand(['test-instance'], {root: fixtureRoot});
23+
expect(error).to.be.undefined;
24+
});
25+
26+
it('handles --server flag', async () => {
27+
const {error, result} = await runCommand<TestInstanceResult>(
28+
['test-instance', '--server', 'test.demandware.net', '--json'],
29+
{root: fixtureRoot},
30+
);
31+
32+
expect(error).to.be.undefined;
33+
expect(result?.server).to.equal('test.demandware.net');
34+
expect(result?.hasServer).to.be.true;
35+
});
36+
37+
it('reports hasServer false when no server provided', async () => {
38+
const {error, result} = await runCommand<TestInstanceResult>(['test-instance', '--json'], {root: fixtureRoot});
39+
40+
expect(error).to.be.undefined;
41+
expect(result?.hasServer).to.be.false;
42+
expect(result?.server).to.be.undefined;
43+
});
44+
45+
it('creates instance when server is provided', async () => {
46+
const {error, result} = await runCommand<TestInstanceResult>(
47+
['test-instance', '--server', 'test.demandware.net', '--json'],
48+
{root: fixtureRoot},
49+
);
50+
51+
expect(error).to.be.undefined;
52+
expect(result?.instance).to.equal('test.demandware.net');
53+
});
54+
55+
it('handles --instance flag for config selection', async () => {
56+
// The --instance flag is for selecting a named instance from dw.json
57+
// Without a dw.json, it just sets the flag value
58+
const {error, result} = await runCommand<TestInstanceResult>(['test-instance', '--instance', 'staging', '--json'], {
59+
root: fixtureRoot,
60+
});
61+
62+
expect(error).to.be.undefined;
63+
// Instance flag is for config selection, not server name
64+
expect(result?.hasServer).to.be.false;
65+
});
66+
});
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (c) 2025, Salesforce, Inc.
3+
* SPDX-License-Identifier: Apache-2
4+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
import {expect} from 'chai';
7+
import {runCommand} from '@oclif/test';
8+
import path from 'node:path';
9+
import {fileURLToPath} from 'node:url';
10+
11+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
12+
const fixtureRoot = path.join(__dirname, '../fixtures/test-cli');
13+
14+
interface TestMrtResult {
15+
hasApiKey: boolean;
16+
project?: string;
17+
environment?: string;
18+
cloudOrigin?: string;
19+
credentialsFile?: string;
20+
hasMrtCredentials: boolean;
21+
}
22+
23+
describe('MrtCommand integration', () => {
24+
it('runs test-mrt command without errors', async () => {
25+
const {error} = await runCommand(['test-mrt'], {root: fixtureRoot});
26+
expect(error).to.be.undefined;
27+
});
28+
29+
it('handles --api-key flag', async () => {
30+
const {error, result} = await runCommand<TestMrtResult>(['test-mrt', '--api-key', 'test-api-key-123', '--json'], {
31+
root: fixtureRoot,
32+
});
33+
34+
expect(error).to.be.undefined;
35+
expect(result?.hasApiKey).to.be.true;
36+
expect(result?.hasMrtCredentials).to.be.true;
37+
});
38+
39+
it('handles --project flag', async () => {
40+
const {error, result} = await runCommand<TestMrtResult>(['test-mrt', '--project', 'my-project', '--json'], {
41+
root: fixtureRoot,
42+
});
43+
44+
expect(error).to.be.undefined;
45+
expect(result?.project).to.equal('my-project');
46+
});
47+
48+
it('handles --environment flag', async () => {
49+
const {error, result} = await runCommand<TestMrtResult>(['test-mrt', '--environment', 'staging', '--json'], {
50+
root: fixtureRoot,
51+
});
52+
53+
expect(error).to.be.undefined;
54+
expect(result?.environment).to.equal('staging');
55+
});
56+
57+
it('handles --cloud-origin flag', async () => {
58+
const {error, result} = await runCommand<TestMrtResult>(
59+
['test-mrt', '--cloud-origin', 'https://custom.mobify.com', '--json'],
60+
{root: fixtureRoot},
61+
);
62+
63+
expect(error).to.be.undefined;
64+
expect(result?.cloudOrigin).to.equal('https://custom.mobify.com');
65+
});
66+
67+
it('handles --credentials-file flag', async () => {
68+
const {error, result} = await runCommand<TestMrtResult>(
69+
['test-mrt', '--credentials-file', '/custom/path/.mobify', '--json'],
70+
{root: fixtureRoot},
71+
);
72+
73+
expect(error).to.be.undefined;
74+
expect(result?.credentialsFile).to.equal('/custom/path/.mobify');
75+
});
76+
77+
it('reports hasMrtCredentials false when no api-key provided', async () => {
78+
// Use --credentials-file to isolate from developer's ~/.mobify
79+
const {error, result} = await runCommand<TestMrtResult>(
80+
['test-mrt', '--credentials-file', '/dev/null', '--json'],
81+
{root: fixtureRoot},
82+
);
83+
84+
expect(error).to.be.undefined;
85+
expect(result?.hasApiKey).to.be.false;
86+
expect(result?.hasMrtCredentials).to.be.false;
87+
});
88+
89+
it('handles multiple flags together', async () => {
90+
const {error, result} = await runCommand<TestMrtResult>(
91+
['test-mrt', '--api-key', 'key123', '--project', 'proj', '--environment', 'prod', '--json'],
92+
{root: fixtureRoot},
93+
);
94+
95+
expect(error).to.be.undefined;
96+
expect(result?.hasApiKey).to.be.true;
97+
expect(result?.project).to.equal('proj');
98+
expect(result?.environment).to.equal('prod');
99+
expect(result?.hasMrtCredentials).to.be.true;
100+
});
101+
});
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2025, Salesforce, Inc.
3+
* SPDX-License-Identifier: Apache-2
4+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
// Use relative import since this fixture is inside the SDK's test folder
7+
import {InstanceCommand} from '../../../../../src/cli/index.js';
8+
9+
/**
10+
* Test command that extends InstanceCommand for integration testing.
11+
* Exercises instance command features like server flag and instance getter.
12+
*/
13+
export default class TestInstance extends InstanceCommand {
14+
static id = 'test-instance';
15+
static description = 'Test command for InstanceCommand integration testing';
16+
static enableJsonFlag = true;
17+
18+
async run() {
19+
// Check server via resolvedConfig (no hasServer method on InstanceCommand)
20+
const hasServer = Boolean(this.resolvedConfig.hostname);
21+
22+
// Return server/instance info without requiring server (for testing flags work)
23+
const result = {
24+
server: this.resolvedConfig.hostname,
25+
hasServer,
26+
};
27+
28+
// Only access instance if server is provided (avoids requireServer error)
29+
if (hasServer) {
30+
result.instance = this.instance.config.hostname;
31+
}
32+
33+
if (this.jsonEnabled()) {
34+
return result;
35+
}
36+
37+
this.log('Server: ' + (result.server || 'not set'));
38+
this.log('Has server: ' + result.hasServer);
39+
40+
return result;
41+
}
42+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2025, Salesforce, Inc.
3+
* SPDX-License-Identifier: Apache-2
4+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
// Use relative import since this fixture is inside the SDK's test folder
7+
import {MrtCommand} from '../../../../../src/cli/index.js';
8+
9+
/**
10+
* Test command that extends MrtCommand for integration testing.
11+
* Exercises MRT command features like api-key, project, and environment flags.
12+
*/
13+
export default class TestMrt extends MrtCommand {
14+
static id = 'test-mrt';
15+
static description = 'Test command for MrtCommand integration testing';
16+
static enableJsonFlag = true;
17+
18+
async run() {
19+
const result = {
20+
// Mask API key for security (just show if present)
21+
hasApiKey: Boolean(this.flags['api-key']),
22+
project: this.flags.project,
23+
environment: this.flags.environment,
24+
cloudOrigin: this.flags['cloud-origin'],
25+
credentialsFile: this.flags['credentials-file'],
26+
hasMrtCredentials: this.hasMrtCredentials(),
27+
};
28+
29+
if (this.jsonEnabled()) {
30+
return result;
31+
}
32+
33+
this.log('Has API key: ' + result.hasApiKey);
34+
this.log('Project: ' + (result.project || 'not set'));
35+
this.log('Environment: ' + (result.environment || 'not set'));
36+
this.log('Has MRT credentials: ' + result.hasMrtCredentials);
37+
38+
return result;
39+
}
40+
}

0 commit comments

Comments
 (0)