Skip to content

Commit 340c0ad

Browse files
committed
test: bundle installed list plugin test
1 parent c9f2c01 commit 340c0ad

1 file changed

Lines changed: 263 additions & 0 deletions

File tree

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/*
2+
* Copyright 2025, Salesforce, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { Config } from '@oclif/core';
17+
import { TestContext, MockTestOrgData } from '@salesforce/core/testSetup';
18+
import { expect } from 'chai';
19+
import { PackageBundleInstalledList } from '@salesforce/packaging';
20+
import { stubSfCommandUx } from '@salesforce/sf-plugins-core';
21+
import sinon from 'sinon';
22+
import { PackageBundleInstalledListCommand } from '../../../src/commands/package/bundle/installed/list.js';
23+
24+
describe('package:bundle:installed:list - tests', () => {
25+
const $$ = new TestContext();
26+
const testOrg = new MockTestOrgData();
27+
let sfCommandStubs: ReturnType<typeof stubSfCommandUx>;
28+
let getInstalledBundlesStub: sinon.SinonStub;
29+
const config = new Config({ root: import.meta.url });
30+
31+
beforeEach(async () => {
32+
await $$.stubAuths(testOrg);
33+
await config.load();
34+
sfCommandStubs = stubSfCommandUx($$.SANDBOX);
35+
36+
getInstalledBundlesStub = $$.SANDBOX.stub(PackageBundleInstalledList, 'getInstalledBundles');
37+
});
38+
39+
afterEach(() => {
40+
$$.restore();
41+
});
42+
43+
it('should list installed bundles with components', async () => {
44+
const mockInstalledBundles = [
45+
{
46+
Id: '1aE000000000001',
47+
BundleName: 'TestBundle',
48+
BundleId: '0Kz000000000001',
49+
BundleVersionId: '05i000000000001',
50+
BundleVersionName: 'ver 1.0',
51+
MajorVersion: 1,
52+
MinorVersion: 0,
53+
Description: 'Test Description',
54+
InstalledDate: '2024-01-01T00:00:00.000+0000',
55+
LastUpgradedDate: '2024-01-01T00:00:00.000+0000',
56+
Components: [
57+
{
58+
ExpectedPackageName: 'TestPackage',
59+
ExpectedPackageVersionNumber: '1.0.0.1',
60+
ActualPackageName: 'TestPackage',
61+
ActualPackageVersionNumber: '1.0.0.1',
62+
},
63+
],
64+
},
65+
];
66+
67+
const cmd = new PackageBundleInstalledListCommand(['-o', testOrg.username], config);
68+
69+
getInstalledBundlesStub.resolves(mockInstalledBundles);
70+
71+
await cmd.run();
72+
73+
expect(getInstalledBundlesStub.calledOnce).to.be.true;
74+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
75+
expect(sfCommandStubs.table.called).to.be.true;
76+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
77+
expect(sfCommandStubs.table.callCount).to.equal(2); // One for bundle info, one for components
78+
});
79+
80+
it('should list multiple installed bundles', async () => {
81+
const mockInstalledBundles = [
82+
{
83+
Id: '1aE000000000001',
84+
BundleName: 'TestBundle1',
85+
BundleId: '0Kz000000000001',
86+
BundleVersionId: '05i000000000001',
87+
BundleVersionName: 'ver 1.0',
88+
MajorVersion: 1,
89+
MinorVersion: 0,
90+
Description: '',
91+
InstalledDate: '2024-01-01T00:00:00.000+0000',
92+
LastUpgradedDate: '2024-01-01T00:00:00.000+0000',
93+
Components: [
94+
{
95+
ExpectedPackageName: 'Package1',
96+
ExpectedPackageVersionNumber: '1.0.0.1',
97+
ActualPackageName: 'Package1',
98+
ActualPackageVersionNumber: '1.0.0.1',
99+
},
100+
],
101+
},
102+
{
103+
Id: '1aE000000000002',
104+
BundleName: 'TestBundle2',
105+
BundleId: '0Kz000000000002',
106+
BundleVersionId: '05i000000000002',
107+
BundleVersionName: 'ver 2.0',
108+
MajorVersion: 2,
109+
MinorVersion: 0,
110+
Description: '',
111+
InstalledDate: '2024-01-02T00:00:00.000+0000',
112+
LastUpgradedDate: '2024-01-02T00:00:00.000+0000',
113+
Components: [
114+
{
115+
ExpectedPackageName: 'Package2',
116+
ExpectedPackageVersionNumber: '2.0.0.1',
117+
ActualPackageName: 'Package2',
118+
ActualPackageVersionNumber: '2.0.0.1',
119+
},
120+
],
121+
},
122+
];
123+
124+
const cmd = new PackageBundleInstalledListCommand(['-o', testOrg.username], config);
125+
126+
getInstalledBundlesStub.resolves(mockInstalledBundles);
127+
128+
await cmd.run();
129+
130+
expect(getInstalledBundlesStub.calledOnce).to.be.true;
131+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
132+
expect(sfCommandStubs.table.called).to.be.true;
133+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
134+
expect(sfCommandStubs.table.callCount).to.equal(4); // Two bundles × (info + components)
135+
});
136+
137+
it('should handle bundles with version mismatches', async () => {
138+
const mockInstalledBundles = [
139+
{
140+
Id: '1aE000000000001',
141+
BundleName: 'TestBundle',
142+
BundleId: '0Kz000000000001',
143+
BundleVersionId: '05i000000000001',
144+
BundleVersionName: 'ver 1.0',
145+
MajorVersion: 1,
146+
MinorVersion: 0,
147+
Description: '',
148+
InstalledDate: '2024-01-01T00:00:00.000+0000',
149+
LastUpgradedDate: '2024-01-01T00:00:00.000+0000',
150+
Components: [
151+
{
152+
ExpectedPackageName: 'TestPackage',
153+
ExpectedPackageVersionNumber: '1.0.0.1',
154+
ActualPackageName: 'TestPackage',
155+
ActualPackageVersionNumber: '2.0.0.1',
156+
},
157+
],
158+
},
159+
];
160+
161+
const cmd = new PackageBundleInstalledListCommand(['-o', testOrg.username], config);
162+
163+
getInstalledBundlesStub.resolves(mockInstalledBundles);
164+
165+
await cmd.run();
166+
167+
expect(getInstalledBundlesStub.calledOnce).to.be.true;
168+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
169+
expect(sfCommandStubs.table.called).to.be.true;
170+
});
171+
172+
it('should handle bundles with uninstalled packages', async () => {
173+
const mockInstalledBundles = [
174+
{
175+
Id: '1aE000000000001',
176+
BundleName: 'TestBundle',
177+
BundleId: '0Kz000000000001',
178+
BundleVersionId: '05i000000000001',
179+
BundleVersionName: 'ver 1.0',
180+
MajorVersion: 1,
181+
MinorVersion: 0,
182+
Description: '',
183+
InstalledDate: '2024-01-01T00:00:00.000+0000',
184+
LastUpgradedDate: '2024-01-01T00:00:00.000+0000',
185+
Components: [
186+
{
187+
ExpectedPackageName: 'TestPackage',
188+
ExpectedPackageVersionNumber: '1.0.0.1',
189+
ActualPackageName: 'Uninstalled',
190+
ActualPackageVersionNumber: 'N/A',
191+
},
192+
],
193+
},
194+
];
195+
196+
const cmd = new PackageBundleInstalledListCommand(['-o', testOrg.username], config);
197+
198+
getInstalledBundlesStub.resolves(mockInstalledBundles);
199+
200+
await cmd.run();
201+
202+
expect(getInstalledBundlesStub.calledOnce).to.be.true;
203+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
204+
expect(sfCommandStubs.table.called).to.be.true;
205+
});
206+
207+
it('should show warning when no installed bundles found', async () => {
208+
const cmd = new PackageBundleInstalledListCommand(['-o', testOrg.username], config);
209+
210+
getInstalledBundlesStub.resolves([]);
211+
212+
await cmd.run();
213+
214+
expect(getInstalledBundlesStub.calledOnce).to.be.true;
215+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
216+
expect(sfCommandStubs.warn.calledOnce).to.be.true;
217+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
218+
expect(sfCommandStubs.warn.firstCall.args[0]).to.include('No installed package bundles found');
219+
});
220+
221+
it('should handle bundles without components', async () => {
222+
const mockInstalledBundles = [
223+
{
224+
Id: '1aE000000000001',
225+
BundleName: 'TestBundle',
226+
BundleId: '0Kz000000000001',
227+
BundleVersionId: '05i000000000001',
228+
BundleVersionName: 'ver 1.0',
229+
MajorVersion: 1,
230+
MinorVersion: 0,
231+
Description: '',
232+
InstalledDate: '2024-01-01T00:00:00.000+0000',
233+
LastUpgradedDate: '2024-01-01T00:00:00.000+0000',
234+
Components: [],
235+
},
236+
];
237+
238+
const cmd = new PackageBundleInstalledListCommand(['-o', testOrg.username], config);
239+
240+
getInstalledBundlesStub.resolves(mockInstalledBundles);
241+
242+
await cmd.run();
243+
244+
expect(getInstalledBundlesStub.calledOnce).to.be.true;
245+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
246+
expect(sfCommandStubs.table.called).to.be.true;
247+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
248+
expect(sfCommandStubs.table.callCount).to.equal(1); // Only bundle info, no components table
249+
});
250+
251+
it('should throw error when target org flag is missing', async () => {
252+
const cmd = new PackageBundleInstalledListCommand([], config);
253+
254+
getInstalledBundlesStub.resolves([]);
255+
256+
try {
257+
await cmd.run();
258+
expect.fail('Expected error was not thrown');
259+
} catch (error) {
260+
expect((error as Error).message).to.include('No default environment found');
261+
}
262+
});
263+
});

0 commit comments

Comments
 (0)