Skip to content

Commit 409191a

Browse files
committed
feat: adds DR version check as a prerequisite for migrate and assess
1 parent c395979 commit 409191a

File tree

6 files changed

+317
-3
lines changed

6 files changed

+317
-3
lines changed

messages/assess.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
"fileImplementsVlocityOpenInterface": "The %s file implements VlocityOpenInterface. Changes will be applied.",
9393
"methodCallBundleNameUpdated": "Method call bundle name will be updated in %s for the %s class and %s method.",
9494
"cardNameChangeMessage": "The Flexcard name will be changed from %s to %s to adhere to the API naming standards.",
95-
"authordNameChangeMessage": "The Flexcard author name will be changed from %s to %s to adhere to the naming rules: %s",
95+
"authordNameChangeMessage": "The Flexcard author name will be changed from %s to %s to adhere to the naming rules",
9696
"cardLWCNameChangeMessage": "The Flexcard generated LWC name will be changed from %s to %s to align with Flexcard name change.",
9797
"omniScriptNameChangeMessage": "The Omniscript reference name %s will be changed to %s during migration.",
9898
"dataRaptorNameChangeMessage": "The Data Mapper name will be changed from %s to %s during migration.",
@@ -201,5 +201,9 @@
201201
"dmNameReferenceNotFound": "Data Mapper reference can’t be updated",
202202
"invalidTypeAssessErrorMessage": "We couldn't assess your Omnistudio components in the %s namespace. Select the correct namespace and try again",
203203
"assessmentSuccessfulMessage": "Migration assessment for org %s is complete and reports are ready for review in the folder %s",
204-
"missingMandatoryField": "Missing mandatory field: %s for %s"
204+
"missingMandatoryField": "Missing mandatory field: %s for %s",
205+
"validatingDrVersioningDisabled": "Checking Data mapper versioning org preference",
206+
"drVersioningDisabled": "Data mapper versioning is disabled. Ok to proceed with the assessment",
207+
"drVersioningEnabled": "Data mapper versioning is enabled. Cannot proceed with the assessment",
208+
"errorValidatingDrVersioning": "Failed to read Data mapper versioning"
205209
}

messages/migrate.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,5 +286,9 @@
286286
"deploymentTriggeredSuccessfully": "Please monitor your Deployment: %s using deployment status page in Org",
287287
"omniscriptPackageDeploymentFailedReturnedFalse": "Omniscript package deployment failed - deployment returned false. This may be due to missing package, permissions, or deployment timeout.",
288288
"omniscriptPackageDeploymentFailedWithMessage": "Omniscript package deployment failed: %s",
289-
"customLWCFlexCardReferenceUpdated": "Updated Custom LWC FlexCard reference: %s -> cf%s"
289+
"customLWCFlexCardReferenceUpdated": "Updated Custom LWC FlexCard reference: %s -> cf%s",
290+
"validatingDrVersioningDisabled": "Checking Data mapper versioning org preference",
291+
"drVersioningDisabled": "Data mapper versioning is disabled. Ok to proceed with the migration",
292+
"drVersioningEnabled": "Data mapper versioning is enabled. Cannot proceed with the migration",
293+
"errorValidatingDrVersioning": "Failed to read Data mapper versioning"
290294
}

src/utils/orgPreferences.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
ExperienceBundleSettingsMetadata,
55
QueryResult,
66
ExperienceBundleSettingsReadMetadata,
7+
MetadataInfo,
78
} from './interfaces';
89
import { Logger } from './logger';
910

@@ -49,6 +50,17 @@ export class OrgPreferences {
4950
}
5051
}
5152

53+
public static async readDrVersion(connection: Connection): Promise<boolean> {
54+
try {
55+
const result = await connection.metadata.read('OmniStudioSettings', ['OmniStudioDrVersionOrgPreference']);
56+
const metadata = result as MetadataInfo;
57+
Logger.logVerbose(`DR version response: ${metadata.enableOmniStudioDrVersion}`);
58+
return metadata.enableOmniStudioDrVersion === 'true';
59+
} catch (error) {
60+
throw new Error(`Failed to read DR version: ${error instanceof Error ? error.message : String(error)}`);
61+
}
62+
}
63+
5264
/**
5365
* Checks which rollback flags are enabled in OmniInteractionConfig
5466
*

src/utils/validatorService.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Connection, Messages } from '@salesforce/core';
22
import { Logger } from '../utils/logger';
33
import { OmnistudioOrgDetails } from './orgUtils';
4+
import { OrgPreferences } from './orgPreferences';
45

56
export class ValidatorService {
67
private readonly connection: Connection;
@@ -18,6 +19,7 @@ export class ValidatorService {
1819
this.validateNamespace() &&
1920
this.validatePackageInstalled() &&
2021
this.validateOmniStudioOrgPermissionEnabled() &&
22+
(await this.validateDrVersioningDisabled()) &&
2123
(await this.validateOmniStudioLicenses())
2224
);
2325
}
@@ -75,4 +77,19 @@ export class ValidatorService {
7577
return false;
7678
}
7779
}
80+
81+
public async validateDrVersioningDisabled(): Promise<boolean> {
82+
Logger.logVerbose(this.messages.getMessage('validatingDrVersioningDisabled'));
83+
try {
84+
const drVersion = await OrgPreferences.readDrVersion(this.connection);
85+
if (!drVersion) {
86+
Logger.logVerbose(this.messages.getMessage('drVersioningDisabled'));
87+
return true;
88+
}
89+
Logger.error(this.messages.getMessage('drVersioningEnabled'));
90+
} catch (error) {
91+
Logger.error(this.messages.getMessage('errorValidatingDrVersioning'));
92+
}
93+
return false;
94+
}
7895
}

test/utils/orgPreferences.test.ts

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,158 @@ describe('OrgPreferences', () => {
6161
});
6262
});
6363

64+
describe('readDrVersion', () => {
65+
it('should return true when DR versioning is enabled', async () => {
66+
// Arrange
67+
const metadataReadResult = {
68+
enableOmniStudioDrVersion: 'true',
69+
};
70+
const metadataReadStub = sandbox.stub().resolves(metadataReadResult);
71+
connection.metadata.read = metadataReadStub;
72+
73+
// Act
74+
const result = await OrgPreferences.readDrVersion(connection);
75+
76+
// Assert
77+
expect(result).to.be.true;
78+
expect(metadataReadStub.calledOnce).to.be.true;
79+
expect(metadataReadStub.firstCall.args[0]).to.equal('OmniStudioSettings');
80+
expect(metadataReadStub.firstCall.args[1]).to.deep.equal(['OmniStudioDrVersionOrgPreference']);
81+
});
82+
83+
it('should return false when DR versioning is disabled', async () => {
84+
// Arrange
85+
const metadataReadResult = {
86+
enableOmniStudioDrVersion: 'false',
87+
};
88+
const metadataReadStub = sandbox.stub().resolves(metadataReadResult);
89+
connection.metadata.read = metadataReadStub;
90+
91+
// Act
92+
const result = await OrgPreferences.readDrVersion(connection);
93+
94+
// Assert
95+
expect(result).to.be.false;
96+
expect(metadataReadStub.calledOnce).to.be.true;
97+
});
98+
99+
it('should return false when enableOmniStudioDrVersion is not "true"', async () => {
100+
// Arrange
101+
const metadataReadResult = {
102+
enableOmniStudioDrVersion: 'maybe',
103+
};
104+
const metadataReadStub = sandbox.stub().resolves(metadataReadResult);
105+
connection.metadata.read = metadataReadStub;
106+
107+
// Act
108+
const result = await OrgPreferences.readDrVersion(connection);
109+
110+
// Assert
111+
expect(result).to.be.false;
112+
expect(metadataReadStub.calledOnce).to.be.true;
113+
});
114+
115+
it('should return false when enableOmniStudioDrVersion is undefined', async () => {
116+
// Arrange
117+
const metadataReadResult = {};
118+
const metadataReadStub = sandbox.stub().resolves(metadataReadResult);
119+
connection.metadata.read = metadataReadStub;
120+
121+
// Act
122+
const result = await OrgPreferences.readDrVersion(connection);
123+
124+
// Assert
125+
expect(result).to.be.false;
126+
expect(metadataReadStub.calledOnce).to.be.true;
127+
});
128+
129+
it('should return false when enableOmniStudioDrVersion is null', async () => {
130+
// Arrange
131+
const metadataReadResult = {
132+
enableOmniStudioDrVersion: null,
133+
};
134+
const metadataReadStub = sandbox.stub().resolves(metadataReadResult);
135+
connection.metadata.read = metadataReadStub;
136+
137+
// Act
138+
const result = await OrgPreferences.readDrVersion(connection);
139+
140+
// Assert
141+
expect(result).to.be.false;
142+
expect(metadataReadStub.calledOnce).to.be.true;
143+
});
144+
145+
it('should throw error when metadata read fails', async () => {
146+
// Arrange
147+
const error = new Error('Metadata read failed');
148+
const metadataReadStub = sandbox.stub().rejects(error);
149+
connection.metadata.read = metadataReadStub;
150+
151+
// Act & Assert
152+
try {
153+
await OrgPreferences.readDrVersion(connection);
154+
expect.fail('Expected an error to be thrown');
155+
} catch (err: unknown) {
156+
if (err instanceof Error) {
157+
expect(err.message).to.equal('Failed to read DR version: Metadata read failed');
158+
} else {
159+
expect.fail('Expected an Error object');
160+
}
161+
}
162+
});
163+
164+
it('should throw error when metadata read fails with non-Error object', async () => {
165+
// Arrange
166+
const error = 'String error message';
167+
const metadataReadStub = sandbox.stub().rejects(error);
168+
connection.metadata.read = metadataReadStub;
169+
170+
// Act & Assert
171+
try {
172+
await OrgPreferences.readDrVersion(connection);
173+
expect.fail('Expected an error to be thrown');
174+
} catch (err: unknown) {
175+
if (err instanceof Error) {
176+
expect(err.message).to.equal('Failed to read DR version: ');
177+
} else {
178+
expect.fail('Expected an Error object');
179+
}
180+
}
181+
});
182+
183+
it('should handle boolean true value correctly', async () => {
184+
// Arrange
185+
const metadataReadResult = {
186+
enableOmniStudioDrVersion: true,
187+
};
188+
const metadataReadStub = sandbox.stub().resolves(metadataReadResult);
189+
connection.metadata.read = metadataReadStub;
190+
191+
// Act
192+
const result = await OrgPreferences.readDrVersion(connection);
193+
194+
// Assert
195+
expect(result).to.be.false; // Should be false because it's not the string 'true'
196+
expect(metadataReadStub.calledOnce).to.be.true;
197+
});
198+
199+
it('should handle boolean false value correctly', async () => {
200+
// Arrange
201+
const metadataReadResult = {
202+
enableOmniStudioDrVersion: false,
203+
};
204+
const metadataReadStub = sandbox.stub().resolves(metadataReadResult);
205+
connection.metadata.read = metadataReadStub;
206+
207+
// Act
208+
const result = await OrgPreferences.readDrVersion(connection);
209+
210+
// Assert
211+
expect(result).to.be.false;
212+
expect(metadataReadStub.calledOnce).to.be.true;
213+
});
214+
});
215+
64216
describe('checkRollbackFlags', () => {
65217
it('should return empty array when no flags are enabled', async () => {
66218
// Arrange

0 commit comments

Comments
 (0)