Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

W-17545444 fix: match on loginUrl/instanceUrl of ScratchOrgInfo if username does not match #1311

Merged
merged 2 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
22 changes: 13 additions & 9 deletions src/commands/org/display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ export class OrgDisplayCommand extends SfCommand<OrgDisplayReturn> {
const fields = authInfo.getFields(true) as AuthFieldsFromFS;

const isScratchOrg = Boolean(fields.devHubUsername);
const scratchOrgInfo =
isScratchOrg && fields.orgId ? await this.getScratchOrgInformation(fields.orgId, fields.username) : {};
const scratchOrgInfo = isScratchOrg && fields.orgId ? await this.getScratchOrgInformation(fields) : {};

const returnValue: OrgDisplayReturn = {
// renamed properties
Expand Down Expand Up @@ -105,14 +104,17 @@ export class OrgDisplayCommand extends SfCommand<OrgDisplayReturn> {
});
}

private async getScratchOrgInformation(orgId: string, username: string): Promise<ScratchOrgFields> {
private async getScratchOrgInformation(fields: AuthFieldsFromFS): Promise<ScratchOrgFields> {
const hubOrg = await this.org.getDevHubOrg();
// we know this is a scratch org so it must have a hubOrg and that'll have a username
const hubUsername = hubOrg?.getUsername() as string;
// this query can return multiple records that match the 15 char ID because `ScratchOrgInfo.ScratchOrg` isn't a case-sensitive field
// Prefer the scratch org admin username if it's on the auth fields
const username = fields.scratchAdminUsername ?? fields.username;
// This query can return multiple records that match the 15 char ID because `ScratchOrgInfo.ScratchOrg` isn't a case-sensitive field
// so we look for the record that matches the scratch org username in the auth file.
const result = (await OrgListUtil.retrieveScratchOrgInfoFromDevHub(hubUsername, [trimTo15(orgId)])).find(
(rec) => rec.SignupUsername === username
// 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
const result = (await OrgListUtil.retrieveScratchOrgInfoFromDevHub(hubUsername, [trimTo15(fields.orgId)])).find(
(rec) => rec.SignupUsername === username || rec.LoginUrl === fields.instanceUrl
);

if (result) {
Expand All @@ -128,8 +130,10 @@ export class OrgDisplayCommand extends SfCommand<OrgDisplayReturn> {
signupUsername: result.SignupUsername,
};
}
throw new SfError(messages.getMessage('noScratchOrgInfoError', [trimTo15(orgId), hubUsername]), 'NoScratchInfo', [
messages.getMessage('noScratchOrgInfoAction'),
]);
throw new SfError(
messages.getMessage('noScratchOrgInfoError', [trimTo15(fields.orgId), hubUsername]),
'NoScratchInfo',
[messages.getMessage('noScratchOrgInfoAction')]
);
}
}
1 change: 1 addition & 0 deletions src/shared/orgListUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ export class OrgListUtil {
'OrgName',
'CreatedBy.Username',
'SignupUsername',
'LoginUrl',
];

try {
Expand Down
1 change: 1 addition & 0 deletions src/shared/orgTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export type ScratchOrgInfoSObject = {
Namespace?: string;
OrgName: string;
SignupUsername: string;
LoginUrl: string;
};

/** fields in the */
Expand Down
47 changes: 42 additions & 5 deletions test/unit/org/display.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ describe('org:display', () => {
Username: '[email protected]',
SignupUsername: '[email protected]',
devHubOrgId: testHub.orgId,
LoginUrl: testHub.instanceUrl,
},
{
CreatedDate: '2024-06-16T05:52:42.000+0000',
Expand All @@ -124,6 +125,7 @@ describe('org:display', () => {
Username: testOrg.username,
SignupUsername: testOrg.username,
devHubOrgId: testHub.orgId,
LoginUrl: testHub.instanceUrl,
},
]);
const result = await OrgDisplayCommand.run(['--targetusername', testOrg.username]);
Expand All @@ -132,6 +134,40 @@ describe('org:display', () => {
expect(result.orgName).to.equal('Dreamhouse');
});

it('gets the correct org when username is not the scratch org username and instanceUrl matches', async () => {
const testHub = new MockTestOrgData();
const scratchOrgAdminUser = '[email protected]';
testOrg.devHubUsername = testHub.username;
testOrg.isScratchOrg = true;

await $$.stubAuths(testOrg, testHub);

$$.SANDBOX.stub(OrgListUtil, 'retrieveScratchOrgInfoFromDevHub').resolves([
{
CreatedDate: '2024-06-15T05:52:42.000+0000',
Edition: 'Developer',
Status: 'Active',
ExpirationDate: '2024-06-16',
Namespace: 'null',
OrgName: 'ACME',
CreatedBy: {
Username: '[email protected]',
},
Username: scratchOrgAdminUser,
SignupUsername: scratchOrgAdminUser, // This won't match but the LoginUrl/instanceUrl will
devHubOrgId: testHub.orgId,
LoginUrl: testOrg.instanceUrl,
},
]);
const result = await OrgDisplayCommand.run(['--targetusername', testOrg.username]);
expect(commonAssert(result));
// check specifically `orgName` because it's one of the fields that comes from the payload instead of the auth file
expect(result.orgName).to.equal('ACME');
expect(result.username).to.equal(testOrg.username);
expect(result.signupUsername).to.equal(scratchOrgAdminUser);
expect(result.instanceUrl).to.equal(testOrg.instanceUrl);
});

it('gets an org from local auth files by alias', async () => {
await $$.stubAuths(testOrg);
$$.stubAliases({ nonscratchalias: testOrg.username });
Expand Down Expand Up @@ -201,6 +237,7 @@ describe('org:display', () => {
OrgName: 'MyOrg',
CreatedDate: '2020-12-24T15:18:55.000+0000',
SignupUsername: testOrg.username,
LoginUrl: testOrg.instanceUrl,
},
]),
});
Expand All @@ -210,9 +247,9 @@ describe('org:display', () => {
expect(result.status).to.equal('Active');
});

// it('gets non-scratch org connectedStatus');
// it('handles properly when username is an accessToken?');
// it('displays good error when org is not connectable due to DNS');
// it('displays scratch-org-only properties for scratch orgs');
// it('displays no scratch-org-only properties for non-scratch orgs');
it('gets non-scratch org connectedStatus');
it('handles properly when username is an accessToken?');
it('displays good error when org is not connectable due to DNS');
it('displays scratch-org-only properties for scratch orgs');
it('displays no scratch-org-only properties for non-scratch orgs');
});
Loading