Skip to content

Commit

Permalink
Wr/nuts check deploy (#180)
Browse files Browse the repository at this point in the history
* chore: current work towards validating deploy

* chore: the NUTs passing with filesToBeDeployedViaResult

* chore: bump source-testkit

* chore: fix test lintnig by forcing types

* chore: update typings to pass yarn test

* chore: working through NUT failures locally

* chore: the NUTS pass locally

* chore: hopefully fix source-testkit for windows NUTs

* chore: fix import pointing to locally linked SDR

* chore: attempt at fixing async NUTs
  • Loading branch information
WillieRuemmele authored Sep 8, 2021
1 parent bb58605 commit 72a452a
Show file tree
Hide file tree
Showing 18 changed files with 273 additions and 236 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@salesforce/plugin-config": "^1.2.13",
"@salesforce/plugin-user": "^1.4.0",
"@salesforce/prettier-config": "^0.0.2",
"@salesforce/source-testkit": "^0.0.5",
"@salesforce/source-testkit": "^0.0.14",
"@salesforce/ts-sinon": "1.3.21",
"@types/debug": "^4.1.7",
"@types/jsforce": "^1.9.33",
Expand Down
7 changes: 1 addition & 6 deletions test/commands/source/deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,12 +392,7 @@ describe('force:source:deploy', () => {

it('should emit predeploy hooks for async deploys', async () => {
const sourcepath = ['somepath'];
try {
await runDeployCmd(['--sourcepath', sourcepath[0], '--wait', '0']);
} catch (e) {
// TODO: once async deploys supported remove the try/catch
expect((e as Error).message).to.include('NOT IMPLEMENTED YET');
}
await runDeployCmd(['--sourcepath', sourcepath[0], '--wait', '0']);
expect(lifecycleEmitStub.firstCall.args[0]).to.equal('predeploy');
});
});
Expand Down
96 changes: 64 additions & 32 deletions test/nuts/REST/deploy.mpd.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

import * as path from 'path';
import { SourceTestkit } from '@salesforce/source-testkit';
import { get } from '@salesforce/ts-types';
import { FileResponse } from '@salesforce/source-deploy-retrieve';
import { expect } from 'chai';
import { DeployCommandResult } from '../../../lib/formatters/deployResultFormatter';

const EXECUTABLE = path.join(process.cwd(), 'bin', 'run');

Expand All @@ -15,32 +19,52 @@ const repo = {
gitUrl: 'https://github.com/salesforcecli/sample-project-multiple-packages.git',
deploy: {
sourcepath: [
{ toDeploy: '"force-app, my-app, foo-bar"', toVerify: ['force-app/**/*', 'my-app/**/*', 'foo-bar/**/*'] },
{
toDeploy: '"force-app, my-app, foo-bar"',
toVerify: ['force-app/**/*', 'my-app/**/*', 'foo-bar/**/*'],
toIgnore: [],
},
{
toDeploy:
'force-app/main/default/labels/CustomLabels.labels-meta.xml,my-app/labels/CustomLabels.labels-meta.xml',
toVerify: [
'force-app/main/default/labels/CustomLabels.labels-meta.xml',
'my-app/labels/CustomLabels.labels-meta.xml',
],
toIgnore: [],
},
{
toDeploy: 'force-app/main/default/labels/CustomLabels.labels-meta.xml',
toVerify: ['force-app/main/default/labels/CustomLabels.labels-meta.xml'],
toIgnore: [],
},
],
metadata: [
{ toDeploy: 'CustomObject', toVerify: ['force-app/main/default/objects/*__c/*', 'my-app/objects/*__c/*'] },
{
toDeploy: 'CustomObject',
toVerify: ['force-app/main/default/objects/**/*', 'my-app/objects/**/*'],
toIgnore: [],
},
{
toDeploy: 'CustomLabels',
toVerify: [
'force-app/main/default/labels/CustomLabels.labels-meta.xml',
'my-app/labels/CustomLabels.labels-meta.xml',
],
toIgnore: [],
},
],
manifest: [
{ toDeploy: 'force-app', toVerify: ['force-app/**/*'] },
{
toDeploy: 'force-app',
toVerify: [
'force-app/**/*',
'force-app/main/default/labels/CustomLabels.labels-meta.xml',
'my-app/labels/CustomLabels.labels-meta.xml',
'my-app/objects/MyObj__c/fields/MyField__c.field-meta.xml',
],
toIgnore: [],
},
// { toDeploy: '"force-app, my-app"', toVerify: ['force-app/**/*', 'my-app/**/*'] }, SDR BUG
],
},
Expand Down Expand Up @@ -73,31 +97,37 @@ context(`MPD REST Deploy NUTs [name: ${repo.name}] [exec: ${EXECUTABLE} ]`, () =
for (const sourcepath of repo.deploy.sourcepath) {
const toDeploy = path.normalize(sourcepath.toDeploy);
it(`should deploy ${toDeploy}`, async () => {
await testkit.deploy({ args: `--sourcepath ${toDeploy}` });
await testkit.expect.filesToBeChanged(sourcepath.toVerify);
const res = await testkit.deploy({ args: `--sourcepath ${toDeploy}` });
const fileResponse = get(res, 'result.deployedSource') as FileResponse[];

await testkit.expect.filesToBeDeployedViaResult(sourcepath.toVerify, sourcepath.toIgnore, fileResponse);
});
}
});

describe('--sourcepath ', () => {
describe('--metadata ', () => {
for (const metadata of repo.deploy.metadata) {
const toDeploy = path.normalize(metadata.toDeploy);
it(`should deploy ${toDeploy}`, async () => {
await testkit.deploy({ args: `--metadata ${toDeploy}` });
await testkit.expect.filesToBeChanged(metadata.toVerify);
const res = await testkit.deploy({ args: `--metadata ${toDeploy}` });
const fileResponse = get(res, 'result.deployedSource') as FileResponse[];

await testkit.expect.filesToBeDeployedViaResult(metadata.toVerify, metadata.toIgnore, fileResponse);
});
}
});

describe('--manifest flag', () => {
for (const testCase of repo.deploy.manifest) {
const toDeploy = path.normalize(testCase.toDeploy);
for (const manifest of repo.deploy.manifest) {
const toDeploy = path.normalize(manifest.toDeploy);
it(`should deploy ${toDeploy}`, async () => {
await testkit.convert({ args: `--sourcepath ${toDeploy} --outputdir out` });
const packageXml = path.join('out', 'package.xml');

await testkit.deploy({ args: `--manifest ${packageXml}` });
await testkit.expect.filesToBeChanged(testCase.toVerify);
const res = await testkit.deploy({ args: `--manifest ${packageXml}` });
const fileResponse = get(res, 'result.deployedSource') as FileResponse[];

await testkit.expect.filesToBeDeployedViaResult(manifest.toVerify, manifest.toIgnore, fileResponse);
});
}
});
Expand All @@ -123,24 +153,26 @@ context(`MPD REST Deploy NUTs [name: ${repo.name}] [exec: ${EXECUTABLE} ]`, () =
await testkit.expect.apexTestsToBeRun();
});

// TODO: once SDR v3 with async polling - update validateddeployrequestid polling
// describe('--validateddeployrequestid', () => {
// it('should return an id immediately when --wait is set to 0 and deploy:report should report results', async () => {
// // deploy all metadata to the org so that we can run tests
// await testkit.deploy({ args: '--sourcepath force-app' });
// // running tests requires a special permission in the 'dreamhouse' permission set
// await testkit.assignPermissionSet({ args: '--permsetname dreamhouse' });
//
// const checkOnly = await testkit.deploy({
// args: '--sourcepath force-app/main/default/classes --testlevel RunLocalTests --checkonly --ignoreerrors',
// });
// testkit.expect.toHaveProperty(checkOnly.result, 'id');
//
// const quickDeploy = await testkit.deploy({
// args: `--validateddeployrequestid ${checkOnly.result.id}`,
// });
// testkit.expect.toHavePropertyAndValue(quickDeploy.result, 'status', 'Succeeded');
// await testkit.expect.filesToBeChanged(testkit.packageGlobs);
// });
// });
describe('--validateddeployrequestid', () => {
it('should return an id immediately when --wait is set to 0 and deploy:report should report results', async () => {
// deploy all metadata to the org so that we can run tests
await testkit.deploy({ args: '--sourcepath force-app' });
// running tests requires a special permission in the 'dreamhouse' permission set
await testkit.assignPermissionSet({ args: '--permsetname dreamhouse' });

const classes = path.join('foo-bar', 'app', 'classes');

const checkOnly = (await testkit.deploy({
args: `--sourcepath ${classes} --testlevel RunLocalTests --checkonly --ignoreerrors`,
})) as { id: string; result: DeployCommandResult };

const quickDeploy = (await testkit.deploy({
args: `--validateddeployrequestid ${checkOnly.result.id}`,
})) as { id: string; result: DeployCommandResult };
const fileResponse = get(quickDeploy, 'result.deployedSource') as FileResponse[];

expect(quickDeploy.result.status).to.equal('Succeeded');
await testkit.expect.filesToBeDeployedViaResult(testkit.packageGlobs, [], fileResponse);
});
});
});
74 changes: 43 additions & 31 deletions test/nuts/REST/deploy.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,37 @@

import * as path from 'path';
import { SourceTestkit } from '@salesforce/source-testkit';

import { get } from '@salesforce/ts-types';
import { FileResponse } from '@salesforce/source-deploy-retrieve';
import { expect } from 'chai';
import { DeployCommandResult } from '../../../lib/formatters/deployResultFormatter';
const EXECUTABLE = path.join(process.cwd(), 'bin', 'run');

const repo = {
name: 'dreamhouse-lwc',
gitUrl: 'https://github.com/trailheadapps/dreamhouse-lwc.git',
deploy: {
sourcepath: [
{ toDeploy: 'force-app/main/default/objects', toVerify: ['force-app/main/default/objects/**/*'] },
{ toDeploy: 'force-app/main/default/objects', toVerify: ['force-app/main/default/objects/**/*'], toIgnore: [] },
{
toDeploy: 'force-app/main/default/classes,force-app/main/default/objects',
toVerify: ['force-app/main/default/classes/*', 'force-app/main/default/objects/**/*'],
toIgnore: [],
},
],
metadata: [
{ toDeploy: 'ApexClass', toVerify: ['force-app/main/default/classes/*'] },
{ toDeploy: 'ApexClass', toVerify: ['force-app/main/default/classes/*'], toIgnore: [] },
{
toDeploy: 'ApexClass,CustomObject:Broker__c',
toVerify: ['force-app/main/default/classes/*', 'force-app/main/default/objects/Broker__c/*'],
toVerify: ['force-app/main/default/classes/*', 'force-app/main/default/objects/Broker__c/**/*'],
toIgnore: [],
},
],
manifest: [
{
toDeploy: 'force-app/main/default/classes,force-app/main/default/objects',
toVerify: ['force-app/main/default/classes/*', 'force-app/main/default/objects/*'],
toVerify: ['force-app/main/default/classes/*', 'force-app/main/default/objects/**/*'],
toIgnore: [],
},
],
},
Expand Down Expand Up @@ -64,8 +70,10 @@ context(`REST Deploy NUTs [name: ${repo.name}] [exec: ${EXECUTABLE} ]`, () => {
for (const sourcepath of repo.deploy.sourcepath) {
const toDeploy = path.normalize(sourcepath.toDeploy);
it(`should deploy ${toDeploy}`, async () => {
await testkit.deploy({ args: `--sourcepath ${toDeploy}` });
await testkit.expect.filesToBeChanged(sourcepath.toVerify);
const res = await testkit.deploy({ args: `--sourcepath ${toDeploy}` });
const fileResponse = get(res, 'result.deployedSource') as FileResponse[];

await testkit.expect.filesToBeDeployedViaResult(sourcepath.toVerify, sourcepath.toIgnore, fileResponse);
});
}
});
Expand All @@ -74,8 +82,10 @@ context(`REST Deploy NUTs [name: ${repo.name}] [exec: ${EXECUTABLE} ]`, () => {
for (const metadata of repo.deploy.metadata) {
const toDeploy = path.normalize(metadata.toDeploy);
it(`should deploy ${toDeploy}`, async () => {
await testkit.deploy({ args: `--metadata ${toDeploy}` });
await testkit.expect.filesToBeChanged(metadata.toVerify);
const res = await testkit.deploy({ args: `--metadata ${toDeploy}` });
const fileResponse = get(res, 'result.deployedSource') as FileResponse[];

await testkit.expect.filesToBeDeployedViaResult(metadata.toVerify, metadata.toIgnore, fileResponse);
});
}
});
Expand All @@ -87,8 +97,10 @@ context(`REST Deploy NUTs [name: ${repo.name}] [exec: ${EXECUTABLE} ]`, () => {
await testkit.convert({ args: `--sourcepath ${toDeploy} --outputdir out` });
const packageXml = path.join('out', 'package.xml');

await testkit.deploy({ args: `--manifest ${packageXml}` });
await testkit.expect.filesToBeChanged(testCase.toVerify);
const res = await testkit.deploy({ args: `--manifest ${packageXml}` });
const fileResponse = get(res, 'result.deployedSource') as FileResponse[];

await testkit.expect.filesToBeDeployedViaResult(testCase.toVerify, testCase.toIgnore, fileResponse);
});
}
});
Expand All @@ -103,24 +115,24 @@ context(`REST Deploy NUTs [name: ${repo.name}] [exec: ${EXECUTABLE} ]`, () => {
});
});

// TODO: once SDR v3 with async polling - update validateddeployrequestid polling
// describe('--validateddeployrequestid', () => {
// it('should return an id immediately when --wait is set to 0 and deploy:report should report results', async () => {
// // deploy all metadata to the org so that we can run tests
// await testkit.deploy({ args: '--sourcepath force-app' });
// // running tests requires a special permission in the 'dreamhouse' permission set
// await testkit.assignPermissionSet({ args: '--permsetname dreamhouse' });
//
// const checkOnly = await testkit.deploy({
// args: '--sourcepath force-app/main/default/classes --testlevel RunLocalTests --checkonly --ignoreerrors',
// });
// testkit.expect.toHaveProperty(checkOnly.result, 'id');
//
// const quickDeploy = await testkit.deploy({
// args: `--validateddeployrequestid ${checkOnly.result.id}`,
// });
// testkit.expect.toHavePropertyAndValue(quickDeploy.result, 'status', 'Succeeded');
// await testkit.expect.filesToBeChanged(testkit.packageGlobs);
// });
// });
describe('--validateddeployrequestid', () => {
it('should return an id immediately when --wait is set to 0 and deploy:report should report results', async () => {
// deploy all metadata to the org so that we can run tests
await testkit.deploy({ args: '--sourcepath force-app' });
// running tests requires a special permission in the 'dreamhouse' permission set
await testkit.assignPermissionSet({ args: '--permsetname dreamhouse' });

const checkOnly = (await testkit.deploy({
args: '--sourcepath force-app/main/default/classes --testlevel RunLocalTests --checkonly --ignoreerrors',
})) as { id: string; result: DeployCommandResult };

const quickDeploy = (await testkit.deploy({
args: `--validateddeployrequestid ${checkOnly.result.id}`,
})) as { id: string; result: DeployCommandResult };
const fileResponse = get(quickDeploy, 'result.deployedSource') as FileResponse[];

expect(quickDeploy.result.status).to.equal('Succeeded');
await testkit.expect.filesToBeDeployedViaResult(testkit.packageGlobs, [], fileResponse);
});
});
});
32 changes: 24 additions & 8 deletions test/nuts/seeds/convert.seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

import * as path from 'path';
import * as shelljs from 'shelljs';
import { asString } from '@salesforce/ts-types';
import { getString } from '@salesforce/ts-types';
import { SourceTestkit } from '@salesforce/source-testkit';
import { fs } from '@salesforce/core';
import { Result } from '@salesforce/source-testkit/lib/types';
import { TEST_REPOS_MAP } from '../testMatrix';

// DO NOT TOUCH. generateNuts.ts will insert these values
Expand Down Expand Up @@ -105,7 +106,10 @@ context('Convert NUTs [name: %REPO_NAME%] [exec: %EXECUTABLE%]', () => {
}

it('should throw an error if the package.xml is not valid', async () => {
const convert = await testkit.convert({ args: '--manifest DOES_NOT_EXIST.xml', exitCode: 1 });
const convert = (await testkit.convert({ args: '--manifest DOES_NOT_EXIST.xml', exitCode: 1 })) as Result<{
id: string;
result: { id: string };
}>;
testkit.expect.errorToHaveName(convert, 'Error');
});
});
Expand All @@ -115,9 +119,12 @@ context('Convert NUTs [name: %REPO_NAME%] [exec: %EXECUTABLE%]', () => {

for (const testCase of REPO.convert.metadata) {
it(`should convert ${testCase.toConvert}`, async () => {
const res = await testkit.convert({ args: `--metadata ${testCase.toConvert} --outputdir out`, exitCode: 0 });
const res = await testkit.convert({
args: `--metadata ${testCase.toConvert} --outputdir out`,
exitCode: 0,
});

convertDir = path.relative(process.cwd(), asString(res.result?.location));
convertDir = path.relative(process.cwd(), getString(res, 'result.location') || '');
await testkit.expect.directoryToHaveSomeFiles(convertDir);
await testkit.expect.fileToExist(path.join(convertDir, 'package.xml'));
await testkit.expect.filesToBeConverted(convertDir, testCase.toVerify);
Expand All @@ -131,7 +138,10 @@ context('Convert NUTs [name: %REPO_NAME%] [exec: %EXECUTABLE%]', () => {
});

it('should throw an error if the metadata is not valid', async () => {
const convert = await testkit.convert({ args: '--metadata DOES_NOT_EXIST', exitCode: 1 });
const convert = (await testkit.convert({ args: '--metadata DOES_NOT_EXIST', exitCode: 1 })) as Result<{
id: string;
result: { id: string };
}>;
const expectedError = testkit.isLocalExecutable() ? 'SfdxError' : 'UnsupportedType';
testkit.expect.errorToHaveName(convert, expectedError);
});
Expand All @@ -143,9 +153,12 @@ context('Convert NUTs [name: %REPO_NAME%] [exec: %EXECUTABLE%]', () => {
for (const testCase of REPO.convert.sourcepath) {
it(`should convert ${testCase.toConvert}`, async () => {
const toConvert = path.normalize(testCase.toConvert);
const res = await testkit.convert({ args: `--sourcepath ${toConvert} --outputdir out`, exitCode: 0 });
const res = await testkit.convert({
args: `--sourcepath ${toConvert} --outputdir out`,
exitCode: 0,
});

convertDir = path.relative(process.cwd(), asString(res.result?.location));
convertDir = path.relative(process.cwd(), getString(res, 'result.location'));
await testkit.expect.directoryToHaveSomeFiles(convertDir);
await testkit.expect.fileToExist(path.join(convertDir, 'package.xml'));
await testkit.expect.filesToBeConverted(convertDir, testCase.toVerify);
Expand All @@ -159,7 +172,10 @@ context('Convert NUTs [name: %REPO_NAME%] [exec: %EXECUTABLE%]', () => {
});

it('should throw an error if the sourcepath is not valid', async () => {
const convert = await testkit.convert({ args: '--sourcepath DOES_NOT_EXIST', exitCode: 1 });
const convert = (await testkit.convert({ args: '--sourcepath DOES_NOT_EXIST', exitCode: 1 })) as Result<{
id: string;
result: { id: string };
}>;
const expectedError = testkit.isLocalExecutable() ? 'SfdxError' : 'SourcePathInvalid';
testkit.expect.errorToHaveName(convert, expectedError);
});
Expand Down
Loading

0 comments on commit 72a452a

Please sign in to comment.