Skip to content

Commit 0a9c0f2

Browse files
authored
fix: match on loginUrl/instanceUrl of ScratchOrgInfo if username does not match (#1311)
* fix: match on loginUrl/instanceUrl of ScratchOrgInfo if username does not match * fix: remove scratchAdminUsername
1 parent 1d49899 commit 0a9c0f2

File tree

4 files changed

+56
-14
lines changed

4 files changed

+56
-14
lines changed

src/commands/org/display.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ export class OrgDisplayCommand extends SfCommand<OrgDisplayReturn> {
5656
const fields = authInfo.getFields(true) as AuthFieldsFromFS;
5757

5858
const isScratchOrg = Boolean(fields.devHubUsername);
59-
const scratchOrgInfo =
60-
isScratchOrg && fields.orgId ? await this.getScratchOrgInformation(fields.orgId, fields.username) : {};
59+
const scratchOrgInfo = isScratchOrg && fields.orgId ? await this.getScratchOrgInformation(fields) : {};
6160

6261
const returnValue: OrgDisplayReturn = {
6362
// renamed properties
@@ -105,14 +104,16 @@ export class OrgDisplayCommand extends SfCommand<OrgDisplayReturn> {
105104
});
106105
}
107106

108-
private async getScratchOrgInformation(orgId: string, username: string): Promise<ScratchOrgFields> {
107+
private async getScratchOrgInformation(fields: AuthFieldsFromFS): Promise<ScratchOrgFields> {
109108
const hubOrg = await this.org.getDevHubOrg();
110109
// we know this is a scratch org so it must have a hubOrg and that'll have a username
111110
const hubUsername = hubOrg?.getUsername() as string;
112-
// this query can return multiple records that match the 15 char ID because `ScratchOrgInfo.ScratchOrg` isn't a case-sensitive field
111+
112+
// This query can return multiple records that match the 15 char ID because `ScratchOrgInfo.ScratchOrg` isn't a case-sensitive field
113113
// so we look for the record that matches the scratch org username in the auth file.
114-
const result = (await OrgListUtil.retrieveScratchOrgInfoFromDevHub(hubUsername, [trimTo15(orgId)])).find(
115-
(rec) => rec.SignupUsername === username
114+
// If that doesn't match (e.g., when calling `org display` with a username that is not the scratch org admin), use the instance URL
115+
const result = (await OrgListUtil.retrieveScratchOrgInfoFromDevHub(hubUsername, [trimTo15(fields.orgId)])).find(
116+
(rec) => rec.SignupUsername === fields.username || rec.LoginUrl === fields.instanceUrl
116117
);
117118

118119
if (result) {
@@ -128,8 +129,10 @@ export class OrgDisplayCommand extends SfCommand<OrgDisplayReturn> {
128129
signupUsername: result.SignupUsername,
129130
};
130131
}
131-
throw new SfError(messages.getMessage('noScratchOrgInfoError', [trimTo15(orgId), hubUsername]), 'NoScratchInfo', [
132-
messages.getMessage('noScratchOrgInfoAction'),
133-
]);
132+
throw new SfError(
133+
messages.getMessage('noScratchOrgInfoError', [trimTo15(fields.orgId), hubUsername]),
134+
'NoScratchInfo',
135+
[messages.getMessage('noScratchOrgInfoAction')]
136+
);
134137
}
135138
}

src/shared/orgListUtil.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ export class OrgListUtil {
240240
'OrgName',
241241
'CreatedBy.Username',
242242
'SignupUsername',
243+
'LoginUrl',
243244
];
244245

245246
try {

src/shared/orgTypes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export type ScratchOrgInfoSObject = {
6868
Namespace?: string;
6969
OrgName: string;
7070
SignupUsername: string;
71+
LoginUrl: string;
7172
};
7273

7374
/** fields in the */

test/unit/org/display.test.ts

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ describe('org:display', () => {
110110
Username: '[email protected]',
111111
SignupUsername: '[email protected]',
112112
devHubOrgId: testHub.orgId,
113+
LoginUrl: testHub.instanceUrl,
113114
},
114115
{
115116
CreatedDate: '2024-06-16T05:52:42.000+0000',
@@ -124,6 +125,7 @@ describe('org:display', () => {
124125
Username: testOrg.username,
125126
SignupUsername: testOrg.username,
126127
devHubOrgId: testHub.orgId,
128+
LoginUrl: testHub.instanceUrl,
127129
},
128130
]);
129131
const result = await OrgDisplayCommand.run(['--targetusername', testOrg.username]);
@@ -132,6 +134,40 @@ describe('org:display', () => {
132134
expect(result.orgName).to.equal('Dreamhouse');
133135
});
134136

137+
it('gets the correct org when username is not the scratch org username and instanceUrl matches', async () => {
138+
const testHub = new MockTestOrgData();
139+
const scratchOrgAdminUser = '[email protected]';
140+
testOrg.devHubUsername = testHub.username;
141+
testOrg.isScratchOrg = true;
142+
143+
await $$.stubAuths(testOrg, testHub);
144+
145+
$$.SANDBOX.stub(OrgListUtil, 'retrieveScratchOrgInfoFromDevHub').resolves([
146+
{
147+
CreatedDate: '2024-06-15T05:52:42.000+0000',
148+
Edition: 'Developer',
149+
Status: 'Active',
150+
ExpirationDate: '2024-06-16',
151+
Namespace: 'null',
152+
OrgName: 'ACME',
153+
CreatedBy: {
154+
Username: '[email protected]',
155+
},
156+
Username: scratchOrgAdminUser,
157+
SignupUsername: scratchOrgAdminUser, // This won't match but the LoginUrl/instanceUrl will
158+
devHubOrgId: testHub.orgId,
159+
LoginUrl: testOrg.instanceUrl,
160+
},
161+
]);
162+
const result = await OrgDisplayCommand.run(['--targetusername', testOrg.username]);
163+
expect(commonAssert(result));
164+
// check specifically `orgName` because it's one of the fields that comes from the payload instead of the auth file
165+
expect(result.orgName).to.equal('ACME');
166+
expect(result.username).to.equal(testOrg.username);
167+
expect(result.signupUsername).to.equal(scratchOrgAdminUser);
168+
expect(result.instanceUrl).to.equal(testOrg.instanceUrl);
169+
});
170+
135171
it('gets an org from local auth files by alias', async () => {
136172
await $$.stubAuths(testOrg);
137173
$$.stubAliases({ nonscratchalias: testOrg.username });
@@ -201,6 +237,7 @@ describe('org:display', () => {
201237
OrgName: 'MyOrg',
202238
CreatedDate: '2020-12-24T15:18:55.000+0000',
203239
SignupUsername: testOrg.username,
240+
LoginUrl: testOrg.instanceUrl,
204241
},
205242
]),
206243
});
@@ -210,9 +247,9 @@ describe('org:display', () => {
210247
expect(result.status).to.equal('Active');
211248
});
212249

213-
// it('gets non-scratch org connectedStatus');
214-
// it('handles properly when username is an accessToken?');
215-
// it('displays good error when org is not connectable due to DNS');
216-
// it('displays scratch-org-only properties for scratch orgs');
217-
// it('displays no scratch-org-only properties for non-scratch orgs');
250+
it('gets non-scratch org connectedStatus');
251+
it('handles properly when username is an accessToken?');
252+
it('displays good error when org is not connectable due to DNS');
253+
it('displays scratch-org-only properties for scratch orgs');
254+
it('displays no scratch-org-only properties for non-scratch orgs');
218255
});

0 commit comments

Comments
 (0)