Skip to content

Commit dca0d31

Browse files
committed
chore: refactor usage of connection object. fix more tests
1 parent c8d2672 commit dca0d31

File tree

5 files changed

+76
-35
lines changed

5 files changed

+76
-35
lines changed

src/commands/lightning/preview/app.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import chalk from 'chalk';
2121
import { OrgUtils } from '../../../shared/orgUtils.js';
2222
import { startLWCServer } from '../../../lwc-dev-server/index.js';
2323
import { PreviewUtils } from '../../../shared/previewUtils.js';
24-
import { ConfigUtils } from '../../../shared/configUtils.js';
24+
import { AppServerIdentityTokenService, ConfigUtils } from '../../../shared/configUtils.js';
2525

2626
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2727
const messages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'lightning.preview.app');
@@ -165,7 +165,8 @@ export default class LightningPreviewApp extends SfCommand<void> {
165165
return Promise.reject(new Error(messages.getMessage('error.username')));
166166
}
167167

168-
const token = await ConfigUtils.getOrCreateIdentityToken(username, connection);
168+
const tokenService = new AppServerIdentityTokenService(connection);
169+
const token = await ConfigUtils.getOrCreateIdentityToken(username, tokenService);
169170

170171
let appId: string | undefined;
171172
if (appName) {

src/shared/configUtils.ts

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,27 @@ import { CryptoUtils, SSLCertificateData } from '@salesforce/lwc-dev-mobile-core
1010
import { Config, ConfigAggregator, Connection } from '@salesforce/core';
1111
import configMeta, { ConfigVars, SerializedSSLCertificateData } from './../configMeta.js';
1212

13+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
14+
export interface IdentityTokenService {
15+
saveTokenToServer(token: string): Promise<string>;
16+
}
17+
18+
export class AppServerIdentityTokenService implements IdentityTokenService {
19+
private connection: Connection;
20+
public constructor(connection: Connection) {
21+
this.connection = connection;
22+
}
23+
24+
public async saveTokenToServer(token: string): Promise<string> {
25+
const sobject = this.connection.sobject('UserLocalWebServerIdentity');
26+
const result = await sobject.insert({ LocalWebServerIdentityToken: token });
27+
if (result.success) {
28+
return result.id;
29+
}
30+
throw new Error('Could not save the token to the server');
31+
}
32+
}
33+
1334
export const LOCAL_DEV_SERVER_DEFAULT_PORT = 8081;
1435
export const LOCAL_DEV_SERVER_DEFAULT_WORKSPACE = Workspace.SfCli;
1536

@@ -40,11 +61,11 @@ export class ConfigUtils {
4061
return this.#globalConfig;
4162
}
4263

43-
public static async getOrCreateIdentityToken(username: string, connection: Connection): Promise<string> {
64+
public static async getOrCreateIdentityToken(username: string, tokenService: IdentityTokenService): Promise<string> {
4465
let identityData = await this.getIdentityData();
4566
if (!identityData) {
4667
const token = CryptoUtils.generateIdentityToken();
47-
const entityId = await this.saveIdentityTokenToServer(token, connection);
68+
const entityId = await tokenService.saveTokenToServer(token);
4869
identityData = {
4970
identityToken: token,
5071
usernameToServerEntityIdMap: {},
@@ -53,7 +74,7 @@ export class ConfigUtils {
5374
await this.writeIdentityData(identityData);
5475
return token;
5576
} else {
56-
const entityId = await this.saveIdentityTokenToServer(identityData.identityToken, connection);
77+
const entityId = await tokenService.saveTokenToServer(identityData.identityToken);
5778
identityData.usernameToServerEntityIdMap[username] = entityId;
5879
await this.writeIdentityData(identityData);
5980
return identityData.identityToken;
@@ -62,7 +83,9 @@ export class ConfigUtils {
6283

6384
public static async writeIdentityData(identityData: LocalWebServerIdentityData): Promise<void> {
6485
const config = await this.getConfig();
65-
config.set(ConfigVars.LOCAL_WEB_SERVER_IDENTITY_DATA, identityData);
86+
// TODO: JSON needs to be stringified in order for config.write to encrypt. When config.write()
87+
// can encrypt JSON data to write it into config we shall remove stringify().
88+
config.set(ConfigVars.LOCAL_WEB_SERVER_IDENTITY_DATA, JSON.stringify(identityData));
6689
await config.write();
6790
}
6891

@@ -116,17 +139,8 @@ export class ConfigUtils {
116139
const identityJson = config.getPropertyValue(ConfigVars.LOCAL_WEB_SERVER_IDENTITY_DATA);
117140

118141
if (identityJson) {
119-
return identityJson as LocalWebServerIdentityData;
142+
return JSON.parse(identityJson as string) as LocalWebServerIdentityData;
120143
}
121144
return undefined;
122145
}
123-
124-
private static async saveIdentityTokenToServer(token: string, connection: Connection): Promise<string> {
125-
const sobject = connection.sobject('UserLocalWebServerIdentity');
126-
const result = await sobject.insert({ LocalWebServerIdentityToken: token });
127-
if (result.success) {
128-
return result.id;
129-
}
130-
throw new Error('Could not save the token to the server');
131-
}
132146
}

test/commands/lightning/preview/app.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import path from 'node:path';
99
import { Config as OclifConfig } from '@oclif/core';
10-
import { Config as SfConfig, Messages } from '@salesforce/core';
10+
import { Config as SfConfig, Messages, Connection } from '@salesforce/core';
1111
import { MockTestOrgData, TestContext } from '@salesforce/core/testSetup';
1212
import {
1313
AndroidVirtualDevice,
@@ -98,6 +98,16 @@ describe('lightning preview app', () => {
9898
}
9999
});
100100

101+
it('throws when username not found', async () => {
102+
try {
103+
$$.SANDBOX.stub(OrgUtils, 'getAppId').resolves(undefined);
104+
$$.SANDBOX.stub(Connection.prototype, 'getUsername').returns(undefined);
105+
await MockedLightningPreviewApp.run(['--name', 'blah', '-o', testOrgData.username]);
106+
} catch (err) {
107+
expect(err).to.be.an('error').with.property('message', messages.getMessage('error.username'));
108+
}
109+
});
110+
101111
it('throws when cannot determine ldp server url', async () => {
102112
try {
103113
$$.SANDBOX.stub(OrgUtils, 'getAppId').resolves(testAppId);

test/shared/configUtils.test.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,22 @@ import { Workspace } from '@lwc/lwc-dev-server';
1010
import { Config, ConfigAggregator, Connection } from '@salesforce/core';
1111
import { TestContext } from '@salesforce/core/testSetup';
1212
import { CryptoUtils } from '@salesforce/lwc-dev-mobile-core';
13-
import { ConfigUtils, LocalWebServerIdentityData } from '../../src/shared/configUtils.js';
13+
import { ConfigUtils, LocalWebServerIdentityData, IdentityTokenService } from '../../src/shared/configUtils.js';
1414
import { ConfigVars } from '../../src/configMeta.js';
1515

1616
describe('configUtils', () => {
1717
const $$ = new TestContext();
1818
const fakeIdentityToken = 'PFT1vw8v65aXd2b9HFvZ3Zu4OcKZwjI60bq7BEjj5k4=';
1919
const username = 'SalesforceDeveloper';
20+
const fakeEntityId = 'entityId';
21+
22+
class TestIdentityTokenService implements IdentityTokenService {
23+
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars
24+
public saveTokenToServer(token: string): Promise<string> {
25+
return Promise.resolve(fakeEntityId);
26+
}
27+
}
28+
const testTokenService = new TestIdentityTokenService();
2029

2130
afterEach(() => {
2231
$$.restore();
@@ -27,27 +36,22 @@ describe('configUtils', () => {
2736
identityToken: fakeIdentityToken,
2837
usernameToServerEntityIdMap: {},
2938
};
30-
identityData.usernameToServerEntityIdMap[username] = 'entityId';
31-
const stubConnection = $$.SANDBOX.createStubInstance(Connection);
39+
identityData.usernameToServerEntityIdMap[username] = fakeEntityId;
3240
$$.SANDBOX.stub(ConfigUtils, 'getIdentityData').resolves(identityData);
3341
$$.SANDBOX.stub(Connection, 'create').resolves(Connection.prototype);
42+
$$.SANDBOX.stub(ConfigUtils, 'writeIdentityData').resolves();
3443

35-
const resolved = await ConfigUtils.getOrCreateIdentityToken(username, stubConnection);
44+
const resolved = await ConfigUtils.getOrCreateIdentityToken(username, testTokenService);
3645

3746
expect(resolved).to.equal(fakeIdentityToken);
3847
});
3948

4049
it('getOrCreateIdentityToken resolves and writeIdentityData is called when there is no identity data', async () => {
41-
const stubConnection = $$.SANDBOX.createStubInstance(Connection);
4250
$$.SANDBOX.stub(ConfigUtils, 'getIdentityData').resolves(undefined);
4351
$$.SANDBOX.stub(CryptoUtils, 'generateIdentityToken').resolves(fakeIdentityToken);
44-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
45-
$$.SANDBOX.stub(ConfigUtils as any, 'saveIdentityTokenToServer')
46-
.withArgs(fakeIdentityToken, stubConnection)
47-
.resolves('entityId');
4852
const writeIdentityTokenStub = $$.SANDBOX.stub(ConfigUtils, 'writeIdentityData').resolves();
4953

50-
const resolved = await ConfigUtils.getOrCreateIdentityToken(username, stubConnection);
54+
const resolved = await ConfigUtils.getOrCreateIdentityToken(username, testTokenService);
5155

5256
expect(resolved).to.equal(fakeIdentityToken);
5357
expect(writeIdentityTokenStub.calledOnce).to.be.true;
@@ -63,12 +67,17 @@ describe('configUtils', () => {
6367
});
6468

6569
it('getIdentityData resolves when identity data is available', async () => {
70+
const identityData: LocalWebServerIdentityData = {
71+
identityToken: fakeIdentityToken,
72+
usernameToServerEntityIdMap: {},
73+
};
74+
const stringifiedData = JSON.stringify(identityData);
6675
$$.SANDBOX.stub(ConfigAggregator, 'create').resolves(ConfigAggregator.prototype);
6776
$$.SANDBOX.stub(ConfigAggregator.prototype, 'reload').resolves();
68-
$$.SANDBOX.stub(ConfigAggregator.prototype, 'getPropertyValue').returns(fakeIdentityToken);
77+
$$.SANDBOX.stub(ConfigAggregator.prototype, 'getPropertyValue').returns(stringifiedData);
6978

7079
const resolved = await ConfigUtils.getIdentityData();
71-
expect(resolved).to.equal(fakeIdentityToken);
80+
expect(resolved).to.deep.equal(identityData);
7281
});
7382

7483
it('writeIdentityData resolves', async () => {

test/shared/previewUtils.test.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@ describe('previewUtils', () => {
112112
it('generateDesktopPreviewLaunchArguments', async () => {
113113
// eslint-disable-next-line @typescript-eslint/no-explicit-any
114114
$$.SANDBOX.stub(PreviewUtils as any, 'getEntityId')
115-
.withArgs([username])
115+
.withArgs(username)
116116
.resolves(entityId);
117117

118118
expect(
119-
PreviewUtils.generateDesktopPreviewLaunchArguments(
119+
await PreviewUtils.generateDesktopPreviewLaunchArguments(
120120
'MyLdpServerUrl',
121121
username,
122122
'MyAppId',
@@ -130,7 +130,7 @@ describe('previewUtils', () => {
130130
'MyTargetOrg',
131131
]);
132132

133-
expect(PreviewUtils.generateDesktopPreviewLaunchArguments('MyLdpServerUrl', username)).to.deep.equal([
133+
expect(await PreviewUtils.generateDesktopPreviewLaunchArguments('MyLdpServerUrl', username)).to.deep.equal([
134134
'--path',
135135
`lightning?0.aura.ldpServerUrl=MyLdpServerUrl&0.aura.ldpServerId=${entityId}&0.aura.mode=DEVPREVIEW`,
136136
]);
@@ -139,19 +139,26 @@ describe('previewUtils', () => {
139139
it('generateMobileAppPreviewLaunchArguments', async () => {
140140
// eslint-disable-next-line @typescript-eslint/no-explicit-any
141141
$$.SANDBOX.stub(PreviewUtils as any, 'getEntityId')
142-
.withArgs([username])
142+
.withArgs(username)
143143
.resolves(entityId);
144144

145145
expect(
146-
PreviewUtils.generateMobileAppPreviewLaunchArguments('MyLdpServerUrl', 'MyAppName', 'MyAppId', 'MyAuraMode')
146+
await PreviewUtils.generateMobileAppPreviewLaunchArguments(
147+
'MyLdpServerUrl',
148+
username,
149+
'MyAppName',
150+
'MyAppId',
151+
'MyAuraMode'
152+
)
147153
).to.deep.equal([
148154
{ name: 'LightningExperienceAppName', value: 'MyAppName' },
149155
{ name: 'LightningExperienceAppID', value: 'MyAppId' },
150156
{ name: '0.aura.ldpServerUrl', value: 'MyLdpServerUrl' },
151157
{ name: '0.aura.mode', value: 'MyAuraMode' },
158+
{ name: '0.aura.ldpServerId', value: entityId },
152159
]);
153160

154-
expect(PreviewUtils.generateMobileAppPreviewLaunchArguments('MyLdpServerUrl', username)).to.deep.equal([
161+
expect(await PreviewUtils.generateMobileAppPreviewLaunchArguments('MyLdpServerUrl', username)).to.deep.equal([
155162
{ name: '0.aura.ldpServerUrl', value: 'MyLdpServerUrl' },
156163
{ name: '0.aura.mode', value: 'DEVPREVIEW' },
157164
{ name: '0.aura.ldpServerId', value: entityId },

0 commit comments

Comments
 (0)