Winston/sobject fetch (#96)
* SObject describe and integration tests @W-4252302@ * Update path for mac builds * Refactor and address issues from PR * Cleanup code and add describeSObject test * Add permset for FLS in integration test * Update to dependencies to 40.9 * Buffer output to only return when stdout finishes streaming * Enable jwt auth for CI tests * Fail fast for now for truncated JSON * Rename to use devhub.key * Try Ascii encoding * Fix some logging calls * Debug autobuilds * Validate key through openssl * Extract jwt key location to env variable * Give absolute path for appveyor * Extract appveyor keylocation to web * Remove key env variable * Use absolute path for keyfile * Escape character in appveyor path * Change travis key path * Distinguish key path for linux vs mac * Update to 40.10.0
This commit is contained in:
Родитель
61e407fafa
Коммит
5b9e10e067
|
@ -25,9 +25,8 @@ install:
|
|||
- sfdx update
|
||||
- npm install -g codecov
|
||||
# the JWT key should be stored base 64 encoded in AppVeyor settings
|
||||
- ps: "[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($env:SFDX_CI_DEVHUB_JWTKEY)) | Out-File -Encoding \"ASCII\" devhub.key"
|
||||
- sfdx force:auth:jwt:grant --clientid %SFDX_CI_DEVHUB_CLIENTID% --username %SFDX_CI_DEVHUB_USERNAME% --jwtkeyfile devhub.key --setdefaultdevhubusername --setalias devhub
|
||||
- del devhub.key
|
||||
- ps: "[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($env:SFDX_CI_DEVHUB_JWTKEY)) | Out-File -Encoding \"ASCII\" C:\\projects\\devhub.key"
|
||||
- sfdx force:auth:jwt:grant --clientid %SFDX_CI_DEVHUB_CLIENTID% --username %SFDX_CI_DEVHUB_USERNAME% --jwtkeyfile C:\projects\devhub.key --setdefaultdevhubusername --setalias devhub
|
||||
|
||||
|
||||
build_script:
|
||||
|
@ -41,5 +40,6 @@ test_script:
|
|||
- npm run coverage:system-tests
|
||||
|
||||
on_finish:
|
||||
- del C:\projects\devhub.key
|
||||
- codecov
|
||||
|
10
.travis.yml
10
.travis.yml
|
@ -40,6 +40,7 @@ before_install:
|
|||
"./sfdx/install"
|
||||
export PATH=./sfdx/$(pwd):$PATH
|
||||
sfdx update
|
||||
export SFDX_CI_KEY_LOCATION=/home/travis/devhub.key
|
||||
fi
|
||||
- |
|
||||
if [[ $TRAVIS_OS_NAME == "osx" ]]; then
|
||||
|
@ -50,12 +51,12 @@ before_install:
|
|||
wget -q $SFDX_URL_OSX
|
||||
sudo installer -pkg sfdx-osx.pkg -target /
|
||||
sfdx update
|
||||
export SFDX_CI_KEY_LOCATION=/Users/travis/devhub.key
|
||||
fi
|
||||
- |
|
||||
# the key should be stored in Travis Repository Setting, wrapped in quotes and newlines replaced with \n
|
||||
echo -e $SFDX_CI_DEVHUB_JWTKEY > devhub.key
|
||||
sfdx force:auth:jwt:grant --clientid $SFDX_CI_DEVHUB_CLIENTID --username $SFDX_CI_DEVHUB_USERNAME --jwtkeyfile devhub.key --setdefaultdevhubusername --setalias devhub
|
||||
rm devhub.key
|
||||
echo -e $SFDX_CI_DEVHUB_JWTKEY > $SFDX_CI_KEY_LOCATION
|
||||
sfdx force:auth:jwt:grant --clientid $SFDX_CI_DEVHUB_CLIENTID --username $SFDX_CI_DEVHUB_USERNAME --jwtkeyfile $SFDX_CI_KEY_LOCATION --setdefaultdevhubusername --setalias devhub
|
||||
curl -sL https://raw.githubusercontent.com/travis-ci/artifacts/master/install | bash
|
||||
|
||||
install:
|
||||
|
@ -77,3 +78,6 @@ script:
|
|||
npm run test:without-system-tests
|
||||
fi
|
||||
- codecov
|
||||
|
||||
after_script:
|
||||
- rm $SFDX_CI_KEY_LOCATION
|
|
@ -166,6 +166,28 @@
|
|||
],
|
||||
"preLaunchTask": "Compile",
|
||||
"internalConsoleOptions": "openOnSessionStart"
|
||||
},
|
||||
{
|
||||
"name": "Launch SObject Generator Tests",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceRoot}/packages/salesforcedx-sobjects-faux-generator",
|
||||
"program":
|
||||
"${workspaceRoot}/packages/salesforcedx-sobjects-faux-generator/node_modules/mocha/bin/_mocha",
|
||||
"args": [
|
||||
"-u",
|
||||
"tdd",
|
||||
"--timeout",
|
||||
"100000",
|
||||
"--colors",
|
||||
"--recursive",
|
||||
"${workspaceRoot}/packages/salesforcedx-sobjects-faux-generator/out/test/"
|
||||
],
|
||||
"sourceMaps": true,
|
||||
"outFiles": [
|
||||
"${workspaceRoot}/packages/salesforcedx-sobjects-faux-generator/out/test/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "Compile"
|
||||
}
|
||||
],
|
||||
"compounds": [
|
||||
|
|
|
@ -6,6 +6,9 @@ describes them and give pointers on how to run/debug them.
|
|||
These tests are described in the order in which we prefer to write them. Always
|
||||
prefer unit tests, integration tests, and system tests, in that order.
|
||||
|
||||
Ensure that you have set a default dev hub through the `sfdx force:auth:*` commands,
|
||||
passing in `--setdefaultdevhubusername`.
|
||||
|
||||
To run all tests, execute `npm run compile && npm run test` from the top-level
|
||||
folder.
|
||||
|
||||
|
@ -88,7 +91,7 @@ There are some optional environment variables to configure the test runner:
|
|||
| ------------|-------------------|
|
||||
| `CODE_VERSION` | Version of VS Code to run the tests against (e.g. `0.10.10`) |
|
||||
| `CODE_DOWNLOAD_URL` | Full URL of a VS Code drop to use for running tests against |
|
||||
| `CODE_TESTS_PATH` | Location of the tests to execute (default is `proces.cwd()/out/test` or `process.cwd()/test`) |
|
||||
| `CODE_TESTS_PATH` | Location of the tests to execute (default is `process.cwd()/out/test` or `process.cwd()/test`) |
|
||||
| `CODE_EXTENSIONS_PATH` | Location of the extensions to load (default is `proces.cwd()`) |
|
||||
| `CODE_TESTS_WORKSPACE` | Location of a workspace to open for the test instance (default is CODE_TESTS_PATH) |
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# salesforcedx-sobjects-faux-generator
|
||||
This repository contains a generator that transforms Salesforce objects and their fields
|
||||
into faux classes understood by the Apex Language Server.
|
||||
|
||||
## Resources
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "@salesforce/salesforcedx-sobjects-faux-generator",
|
||||
"displayName": "Salesforce SObject Faux Generator",
|
||||
"description":
|
||||
"Fetches sobjects and generates their faux apex class to be used for Apex Language Server",
|
||||
"version": "40.10.0",
|
||||
"publisher": "salesforce",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"vscode": "^1.15.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@salesforce/salesforcedx-utils-vscode": "40.10.0",
|
||||
"jsforce": "1.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.0.0",
|
||||
"@types/jsforce": "^1.7.1",
|
||||
"@types/mocha": "2.2.38",
|
||||
"@types/node": "^6.0.40",
|
||||
"@types/rimraf": "^2.0.2",
|
||||
"@types/sinon": "^2.3.2",
|
||||
"chai": "^4.0.2",
|
||||
"cross-env": "5.0.4",
|
||||
"jsforce": "1.7.1",
|
||||
"mocha": "3.2.0",
|
||||
"mock-spawn": "0.2.6",
|
||||
"nyc": "^11.0.2",
|
||||
"sinon": "^2.3.6",
|
||||
"typescript": "2.4.0",
|
||||
"vscode": "1.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:package": "npm prune --production",
|
||||
"compile": "tsc -p ./",
|
||||
"lint": "tslint --project .",
|
||||
"watch": "tsc -watch -p .",
|
||||
"clean": "shx rm -rf node_modules && shx rm -rf out",
|
||||
"test":
|
||||
"./node_modules/.bin/cross-env VSCODE_NLS_CONFIG={} ./node_modules/.bin/nyc ./node_modules/.bin/_mocha --recursive out/test"
|
||||
},
|
||||
"nyc": {
|
||||
"reporter": ["text-summary", "lcov"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright (c) 2017, salesforce.com, inc.
|
||||
* All rights reserved.
|
||||
* Licensed under the BSD 3-Clause license.
|
||||
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
export { SObjectCategory, SObjectDescribe } from './sObjectDescribe';
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (c) 2017, salesforce.com, inc.
|
||||
* All rights reserved.
|
||||
* Licensed under the BSD 3-Clause license.
|
||||
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
import {
|
||||
CliCommandExecutor,
|
||||
CommandOutput,
|
||||
SfdxCommandBuilder
|
||||
} from '@salesforce/salesforcedx-utils-vscode/out/src/cli';
|
||||
|
||||
export interface SObject {
|
||||
actionOverrides: any[];
|
||||
activateable: boolean;
|
||||
childRelationships: ChildRelationship[];
|
||||
compactLayoutable: boolean;
|
||||
createable: boolean;
|
||||
custom: boolean;
|
||||
customSetting: boolean;
|
||||
deletable: boolean;
|
||||
deprecatedAndHidden: boolean;
|
||||
feedEnabled: boolean;
|
||||
fields: Field[];
|
||||
hasSubtypes: boolean;
|
||||
isSubtype: boolean;
|
||||
keyPrefix: string;
|
||||
label: string;
|
||||
labelPlural: string;
|
||||
layoutable: boolean;
|
||||
listviewable?: any;
|
||||
lookupLayoutable?: any;
|
||||
mergeable: boolean;
|
||||
mruEnabled: boolean;
|
||||
name: string;
|
||||
namedLayoutInfos: any[];
|
||||
networkScopeFieldName?: any;
|
||||
queryable: boolean;
|
||||
recordTypeInfos: RecordTypeInfo[];
|
||||
replicateable: boolean;
|
||||
retrieveable: boolean;
|
||||
searchLayoutable: boolean;
|
||||
searchable: boolean;
|
||||
supportedScopes: SupportedScope[];
|
||||
triggerable: boolean;
|
||||
undeletable: boolean;
|
||||
updateable: boolean;
|
||||
urls: Urls2;
|
||||
}
|
||||
|
||||
export interface ChildRelationship {
|
||||
cascadeDelete: boolean;
|
||||
childSObject: string;
|
||||
deprecatedAndHidden: boolean;
|
||||
field: string;
|
||||
junctionIdListNames: any[];
|
||||
junctionReferenceTo: any[];
|
||||
relationshipName: string;
|
||||
restrictedDelete: boolean;
|
||||
}
|
||||
|
||||
export interface Field {
|
||||
aggregatable: boolean;
|
||||
autoNumber: boolean;
|
||||
byteLength: number;
|
||||
calculated: boolean;
|
||||
calculatedFormula?: any;
|
||||
cascadeDelete: boolean;
|
||||
caseSensitive: boolean;
|
||||
compoundFieldName?: any;
|
||||
controllerName?: any;
|
||||
createable: boolean;
|
||||
custom: boolean;
|
||||
defaultValue?: boolean;
|
||||
defaultValueFormula?: any;
|
||||
defaultedOnCreate: boolean;
|
||||
dependentPicklist: boolean;
|
||||
deprecatedAndHidden: boolean;
|
||||
digits: number;
|
||||
displayLocationInDecimal: boolean;
|
||||
encrypted: boolean;
|
||||
externalId: boolean;
|
||||
extraTypeInfo?: any;
|
||||
filterable: boolean;
|
||||
filteredLookupInfo?: any;
|
||||
groupable: boolean;
|
||||
highScaleNumber: boolean;
|
||||
htmlFormatted: boolean;
|
||||
idLookup: boolean;
|
||||
inlineHelpText?: any;
|
||||
label: string;
|
||||
length: number;
|
||||
mask?: any;
|
||||
maskType?: any;
|
||||
name: string;
|
||||
nameField: boolean;
|
||||
namePointing: boolean;
|
||||
nillable: boolean;
|
||||
permissionable: boolean;
|
||||
picklistValues: any[];
|
||||
polymorphicForeignKey: boolean;
|
||||
precision: number;
|
||||
queryByDistance: boolean;
|
||||
referenceTargetField?: any;
|
||||
referenceTo: string[];
|
||||
relationshipName: string;
|
||||
relationshipOrder?: any;
|
||||
restrictedDelete: boolean;
|
||||
restrictedPicklist: boolean;
|
||||
scale: number;
|
||||
searchPrefilterable: boolean;
|
||||
soapType: string;
|
||||
sortable: boolean;
|
||||
type: string;
|
||||
unique: boolean;
|
||||
updateable: boolean;
|
||||
writeRequiresMasterRead: boolean;
|
||||
}
|
||||
|
||||
export interface Urls {
|
||||
layout: string;
|
||||
}
|
||||
|
||||
export interface RecordTypeInfo {
|
||||
active: boolean;
|
||||
available: boolean;
|
||||
defaultRecordTypeMapping: boolean;
|
||||
master: boolean;
|
||||
name: string;
|
||||
recordTypeId: string;
|
||||
urls: Urls;
|
||||
}
|
||||
|
||||
export interface SupportedScope {
|
||||
label: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface Urls2 {
|
||||
compactLayouts: string;
|
||||
rowTemplate: string;
|
||||
approvalLayouts: string;
|
||||
uiDetailTemplate: string;
|
||||
uiEditTemplate: string;
|
||||
defaultValues: string;
|
||||
describe: string;
|
||||
uiNewRecord: string;
|
||||
quickActions: string;
|
||||
layouts: string;
|
||||
sobject: string;
|
||||
}
|
||||
|
||||
export interface DescribeSObjectResult {
|
||||
result: SObject;
|
||||
}
|
||||
|
||||
export enum SObjectCategory {
|
||||
ALL = 'ALL',
|
||||
STANDARD = 'STANDARD',
|
||||
CUSTOM = 'CUSTOM'
|
||||
}
|
||||
|
||||
export class SObjectDescribe {
|
||||
public async describeSObject(
|
||||
projectPath: string,
|
||||
type: string,
|
||||
username?: string
|
||||
): Promise<SObject> {
|
||||
const builder = new SfdxCommandBuilder()
|
||||
.withArg('force:schema:sobject:describe')
|
||||
.withFlag('--sobjecttype', type);
|
||||
if (username) {
|
||||
builder.args.push('--targetusername', username);
|
||||
}
|
||||
const command = builder.withJson().build();
|
||||
const execution = new CliCommandExecutor(command, {
|
||||
cwd: projectPath
|
||||
}).execute();
|
||||
|
||||
const cmdOutput = new CommandOutput();
|
||||
const result = await cmdOutput.getCmdResult(execution);
|
||||
try {
|
||||
const sobject = JSON.parse(result).result as SObject;
|
||||
return Promise.resolve(sobject);
|
||||
} catch (e) {
|
||||
return Promise.reject(result);
|
||||
}
|
||||
}
|
||||
|
||||
public async describeGlobal(
|
||||
projectPath: string,
|
||||
type: SObjectCategory,
|
||||
username?: string
|
||||
): Promise<string[]> {
|
||||
const builder = new SfdxCommandBuilder()
|
||||
.withArg('force:schema:sobject:list')
|
||||
.withFlag('--sobjecttypecategory', type.toString());
|
||||
if (username) {
|
||||
builder.args.push('--targetusername', username);
|
||||
}
|
||||
const command = builder.withJson().build();
|
||||
const execution = new CliCommandExecutor(command, {
|
||||
cwd: projectPath
|
||||
}).execute();
|
||||
|
||||
const cmdOutput = new CommandOutput();
|
||||
const result = await cmdOutput.getCmdResult(execution);
|
||||
try {
|
||||
const sobjects = JSON.parse(result).result as string[];
|
||||
return Promise.resolve(sobjects);
|
||||
} catch (e) {
|
||||
return Promise.reject(result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2017, salesforce.com, inc.
|
||||
* All rights reserved.
|
||||
* Licensed under the BSD 3-Clause license.
|
||||
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { SObjectCategory, SObjectDescribe } from '../describe';
|
||||
|
||||
export class FauxClassGenerator {
|
||||
public async generate(projectPath: string, type: SObjectCategory) {
|
||||
const describe = new SObjectDescribe();
|
||||
const sobjects = await describe.describeGlobal(projectPath, type);
|
||||
console.log(sobjects.length);
|
||||
for (let i = 0; i < sobjects.length; i++) {
|
||||
const sobject = await describe.describeSObject(projectPath, sobjects[i]);
|
||||
console.log(sobject.name);
|
||||
this.generateFauxClass(projectPath, sobject);
|
||||
}
|
||||
}
|
||||
|
||||
private async generateFauxClass(
|
||||
projectPath: string,
|
||||
sobject: any
|
||||
): Promise<void> {
|
||||
const folderPath = path.join(projectPath, '.sfdx', 'sobjects');
|
||||
if (!fs.existsSync(folderPath)) {
|
||||
//fs.mkdirSync(folderPath);
|
||||
}
|
||||
//const isCustom = sobject.custom;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright (c) 2017, salesforce.com, inc.
|
||||
* All rights reserved.
|
||||
* Licensed under the BSD 3-Clause license.
|
||||
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
export { FauxClassGenerator } from './fauxClassGenerator';
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2017, salesforce.com, inc.
|
||||
* All rights reserved.
|
||||
* Licensed under the BSD 3-Clause license.
|
||||
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
// tslint:disable-next-line:no-var-requires
|
||||
// tslint:disable-next-line:variable-name
|
||||
import Mocha = require('mocha');
|
||||
|
||||
// You can directly control Mocha options by uncommenting the following lines
|
||||
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
|
||||
|
||||
const mocha = new Mocha({
|
||||
ui: 'bdd',
|
||||
timeout: 100000
|
||||
});
|
||||
mocha.useColors(true);
|
||||
|
||||
module.exports = mocha;
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<actionOverrides>
|
||||
<actionName>Accept</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>CancelEdit</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>Clone</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>Delete</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>Edit</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>List</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>New</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>SaveEdit</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>Tab</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<actionOverrides>
|
||||
<actionName>View</actionName>
|
||||
<type>Default</type>
|
||||
</actionOverrides>
|
||||
<allowInChatterGroups>false</allowInChatterGroups>
|
||||
<compactLayoutAssignment>SYSTEM</compactLayoutAssignment>
|
||||
<deploymentStatus>Deployed</deploymentStatus>
|
||||
<enableActivities>false</enableActivities>
|
||||
<enableBulkApi>true</enableBulkApi>
|
||||
<enableChangeDataCapture>false</enableChangeDataCapture>
|
||||
<enableFeeds>false</enableFeeds>
|
||||
<enableHistory>false</enableHistory>
|
||||
<enableReports>false</enableReports>
|
||||
<enableSearch>false</enableSearch>
|
||||
<enableSharing>true</enableSharing>
|
||||
<enableStreamingApi>true</enableStreamingApi>
|
||||
<externalSharingModel>ReadWrite</externalSharingModel>
|
||||
<label>MyCustomObject</label>
|
||||
<nameField>
|
||||
<label>MyCustomObject Name</label>
|
||||
<type>Text</type>
|
||||
</nameField>
|
||||
<pluralLabel>MyCustomObjects</pluralLabel>
|
||||
<searchLayouts/>
|
||||
<sharingModel>ReadWrite</sharingModel>
|
||||
<visibility>Public</visibility>
|
||||
</CustomObject>
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>MyCustomField__c</fullName>
|
||||
<externalId>false</externalId>
|
||||
<label>MyCustomField</label>
|
||||
<precision>18</precision>
|
||||
<required>false</required>
|
||||
<scale>0</scale>
|
||||
<trackTrending>false</trackTrending>
|
||||
<type>Number</type>
|
||||
<unique>false</unique>
|
||||
</CustomField>
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2017, salesforce.com, inc.
|
||||
* All rights reserved.
|
||||
* Licensed under the BSD 3-Clause license.
|
||||
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
import {
|
||||
CliCommandExecutor,
|
||||
CommandOutput,
|
||||
SfdxCommandBuilder
|
||||
} from '@salesforce/salesforcedx-utils-vscode/out/src/cli';
|
||||
import childProcess = require('child_process');
|
||||
import * as path from 'path';
|
||||
import * as util from 'util';
|
||||
|
||||
// Used only for CI purposes. Must call delete if you call create
|
||||
export async function createSFDXProject(projectName: string): Promise<void> {
|
||||
const execution = new CliCommandExecutor(
|
||||
new SfdxCommandBuilder()
|
||||
.withArg('force:project:create')
|
||||
.withFlag('--projectname', projectName)
|
||||
.withJson()
|
||||
.build(),
|
||||
{ cwd: process.cwd() }
|
||||
).execute();
|
||||
const cmdOutput = new CommandOutput();
|
||||
await cmdOutput.getCmdResult(execution);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
export async function createScratchOrg(projectName: string): Promise<string> {
|
||||
const scratchDefFilePath = path.join(
|
||||
process.cwd(),
|
||||
projectName,
|
||||
'config',
|
||||
'project-scratch-def.json'
|
||||
);
|
||||
const execution = new CliCommandExecutor(
|
||||
new SfdxCommandBuilder()
|
||||
.withArg('force:org:create')
|
||||
.withFlag('--definitionfile', scratchDefFilePath)
|
||||
.withJson()
|
||||
.build(),
|
||||
{ cwd: path.join(process.cwd(), projectName) }
|
||||
).execute();
|
||||
const cmdOutput = new CommandOutput();
|
||||
const result = await cmdOutput.getCmdResult(execution);
|
||||
const username = JSON.parse(result).result.username;
|
||||
return Promise.resolve(username);
|
||||
}
|
||||
|
||||
export async function push(
|
||||
sourceFolder: string,
|
||||
projectName: string,
|
||||
username: string
|
||||
): Promise<string> {
|
||||
const targetFolder = path.join(
|
||||
process.cwd(),
|
||||
projectName,
|
||||
'force-app',
|
||||
'main',
|
||||
'default'
|
||||
);
|
||||
childProcess.execSync('cp -R ' + sourceFolder + ' ' + targetFolder);
|
||||
const execution = new CliCommandExecutor(
|
||||
new SfdxCommandBuilder()
|
||||
.withArg('force:source:push')
|
||||
.withFlag('--targetusername', username)
|
||||
.withJson()
|
||||
.build(),
|
||||
{ cwd: path.join(process.cwd(), projectName) }
|
||||
).execute();
|
||||
const cmdOutput = new CommandOutput();
|
||||
const result = await cmdOutput.getCmdResult(execution);
|
||||
const source = JSON.parse(result).result.pushedSource;
|
||||
return Promise.resolve(source);
|
||||
}
|
||||
|
||||
export async function createPermissionSet(
|
||||
permissionSetName: string,
|
||||
username: string
|
||||
): Promise<string> {
|
||||
const execution = new CliCommandExecutor(
|
||||
new SfdxCommandBuilder()
|
||||
.withArg('force:data:record:create')
|
||||
.withFlag('--sobjecttype', 'PermissionSet')
|
||||
.withFlag('--targetusername', username)
|
||||
.withFlag(
|
||||
'--values',
|
||||
'Name=' + permissionSetName + " Label='Give FLS Read'"
|
||||
)
|
||||
.withJson()
|
||||
.build(),
|
||||
{ cwd: process.cwd() }
|
||||
).execute();
|
||||
const cmdOutput = new CommandOutput();
|
||||
const result = await cmdOutput.getCmdResult(execution);
|
||||
const permissionSetId = JSON.parse(result).result.id as string;
|
||||
return Promise.resolve(permissionSetId);
|
||||
}
|
||||
|
||||
export async function createFieldPermissions(
|
||||
permissionSetId: string,
|
||||
sobjectType: string,
|
||||
fieldName: string,
|
||||
username: string
|
||||
): Promise<void> {
|
||||
const execution = new CliCommandExecutor(
|
||||
new SfdxCommandBuilder()
|
||||
.withArg('force:data:record:create')
|
||||
.withFlag('--sobjecttype', 'FieldPermissions')
|
||||
.withFlag('--targetusername', username)
|
||||
.withFlag(
|
||||
'--values',
|
||||
util.format(
|
||||
'ParentId=%s SobjectType=%s Field=%s PermissionsRead=true',
|
||||
permissionSetId,
|
||||
sobjectType,
|
||||
fieldName
|
||||
)
|
||||
)
|
||||
.withJson()
|
||||
.build(),
|
||||
{ cwd: process.cwd() }
|
||||
).execute();
|
||||
const cmdOutput = new CommandOutput();
|
||||
await cmdOutput.getCmdResult(execution);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
export async function assignPermissionSet(
|
||||
permissionSetName: string,
|
||||
username: string
|
||||
): Promise<void> {
|
||||
const execution = new CliCommandExecutor(
|
||||
new SfdxCommandBuilder()
|
||||
.withArg('force:user:permset:assign')
|
||||
.withFlag('--permsetname', permissionSetName)
|
||||
.withFlag('--targetusername', username)
|
||||
.withJson()
|
||||
.build(),
|
||||
{ cwd: process.cwd() }
|
||||
).execute();
|
||||
const cmdOutput = new CommandOutput();
|
||||
await cmdOutput.getCmdResult(execution);
|
||||
return Promise.resolve();
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 2017, salesforce.com, inc.
|
||||
* All rights reserved.
|
||||
* Licensed under the BSD 3-Clause license.
|
||||
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
|
||||
import rimraf = require('rimraf');
|
||||
import { expect } from 'chai';
|
||||
import * as path from 'path';
|
||||
import {
|
||||
SObjectCategory,
|
||||
SObjectDescribe
|
||||
} from '../../src/describe/sObjectDescribe';
|
||||
import * as util from './integrationTestUtil';
|
||||
|
||||
const PROJECT_NAME = `project_${new Date().getTime()}`;
|
||||
const CUSTOM_OBJECT_NAME = 'MyCustomObject__c';
|
||||
const CUSTOM_FIELD_FULLNAME = CUSTOM_OBJECT_NAME + '.MyCustomField__c';
|
||||
const SIMPLE_OBJECT_DIR = path.join(
|
||||
'test',
|
||||
'integration',
|
||||
'config',
|
||||
'simpleObjectAndField',
|
||||
'objects'
|
||||
);
|
||||
|
||||
const sobjectdescribe = new SObjectDescribe();
|
||||
|
||||
// tslint:disable:no-unused-expression
|
||||
describe('Fetch sObjects', function() {
|
||||
// tslint:disable-next-line:no-invalid-this
|
||||
this.timeout(60000);
|
||||
let username: string;
|
||||
|
||||
before(async function() {
|
||||
await util.createSFDXProject(PROJECT_NAME);
|
||||
username = await util.createScratchOrg(PROJECT_NAME);
|
||||
|
||||
const sourceFolder = path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
'..',
|
||||
'..',
|
||||
SIMPLE_OBJECT_DIR
|
||||
);
|
||||
await util.push(sourceFolder, PROJECT_NAME, username);
|
||||
|
||||
const permSetName = 'AllowRead';
|
||||
const permissionSetId = await util.createPermissionSet(
|
||||
permSetName,
|
||||
username
|
||||
);
|
||||
|
||||
await util.createFieldPermissions(
|
||||
permissionSetId,
|
||||
CUSTOM_OBJECT_NAME,
|
||||
CUSTOM_FIELD_FULLNAME,
|
||||
username
|
||||
);
|
||||
|
||||
await util.assignPermissionSet(permSetName, username);
|
||||
});
|
||||
|
||||
after(function() {
|
||||
const projectPath = path.join(process.cwd(), PROJECT_NAME);
|
||||
rimraf.sync(projectPath);
|
||||
});
|
||||
|
||||
it('Should be able to call describeGlobal', async function() {
|
||||
const cmdOutput = await sobjectdescribe.describeGlobal(
|
||||
process.cwd(),
|
||||
SObjectCategory.CUSTOM,
|
||||
username
|
||||
);
|
||||
expect(cmdOutput.length).to.be.equal(1);
|
||||
expect(cmdOutput[0]).to.be.equal(CUSTOM_OBJECT_NAME);
|
||||
});
|
||||
|
||||
it('Should be able to call describeSObject on custom object', async function() {
|
||||
const cmdOutput = await sobjectdescribe.describeSObject(
|
||||
process.cwd(),
|
||||
CUSTOM_OBJECT_NAME,
|
||||
username
|
||||
);
|
||||
expect(cmdOutput.name).to.be.equal(CUSTOM_OBJECT_NAME);
|
||||
expect(cmdOutput.custom).to.be.true;
|
||||
expect(cmdOutput.fields.length).to.be.least(9);
|
||||
const customField = cmdOutput.fields[cmdOutput.fields.length - 1];
|
||||
expect(customField.custom).to.be.true;
|
||||
expect(customField.precision).to.be.equal(18);
|
||||
expect(customField.scale).to.be.equal(0);
|
||||
expect(customField.name).to.be.equal('MyCustomField__c');
|
||||
});
|
||||
|
||||
it('Should be able to call describeSObject on standard object', async function() {
|
||||
// const cmdOutput = await sobjectdescribe.describeSObject(
|
||||
// process.cwd(),
|
||||
// 'Account',
|
||||
// username
|
||||
// );
|
||||
// expect(cmdOutput.name).to.be.equal('Account');
|
||||
// expect(cmdOutput.custom).to.be.false;
|
||||
// expect(cmdOutput.fields.length).to.be.least(59);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"lib": ["dom", "es6"],
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": true,
|
||||
"rootDir": ".",
|
||||
"outDir": "out",
|
||||
"preserveConstEnums": true,
|
||||
"strict": true
|
||||
},
|
||||
"exclude": ["node_modules", "out"]
|
||||
}
|
|
@ -80,6 +80,7 @@
|
|||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@salesforce/salesforcedx-sobjects-faux-generator": "40.9.0",
|
||||
"@salesforce/salesforcedx-utils-vscode": "^40.10.0",
|
||||
"expand-home-dir": "0.0.3",
|
||||
"find-java-home": "0.2.0",
|
||||
|
|
Загрузка…
Ссылка в новой задаче