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
|
- sfdx update
|
||||||
- npm install -g codecov
|
- npm install -g codecov
|
||||||
# the JWT key should be stored base 64 encoded in AppVeyor settings
|
# 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"
|
- 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 devhub.key --setdefaultdevhubusername --setalias devhub
|
- sfdx force:auth:jwt:grant --clientid %SFDX_CI_DEVHUB_CLIENTID% --username %SFDX_CI_DEVHUB_USERNAME% --jwtkeyfile C:\projects\devhub.key --setdefaultdevhubusername --setalias devhub
|
||||||
- del devhub.key
|
|
||||||
|
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
|
@ -41,5 +40,6 @@ test_script:
|
||||||
- npm run coverage:system-tests
|
- npm run coverage:system-tests
|
||||||
|
|
||||||
on_finish:
|
on_finish:
|
||||||
|
- del C:\projects\devhub.key
|
||||||
- codecov
|
- codecov
|
||||||
|
|
10
.travis.yml
10
.travis.yml
|
@ -40,6 +40,7 @@ before_install:
|
||||||
"./sfdx/install"
|
"./sfdx/install"
|
||||||
export PATH=./sfdx/$(pwd):$PATH
|
export PATH=./sfdx/$(pwd):$PATH
|
||||||
sfdx update
|
sfdx update
|
||||||
|
export SFDX_CI_KEY_LOCATION=/home/travis/devhub.key
|
||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
if [[ $TRAVIS_OS_NAME == "osx" ]]; then
|
if [[ $TRAVIS_OS_NAME == "osx" ]]; then
|
||||||
|
@ -50,12 +51,12 @@ before_install:
|
||||||
wget -q $SFDX_URL_OSX
|
wget -q $SFDX_URL_OSX
|
||||||
sudo installer -pkg sfdx-osx.pkg -target /
|
sudo installer -pkg sfdx-osx.pkg -target /
|
||||||
sfdx update
|
sfdx update
|
||||||
|
export SFDX_CI_KEY_LOCATION=/Users/travis/devhub.key
|
||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
# the key should be stored in Travis Repository Setting, wrapped in quotes and newlines replaced with \n
|
# 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
|
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 devhub.key --setdefaultdevhubusername --setalias devhub
|
sfdx force:auth:jwt:grant --clientid $SFDX_CI_DEVHUB_CLIENTID --username $SFDX_CI_DEVHUB_USERNAME --jwtkeyfile $SFDX_CI_KEY_LOCATION --setdefaultdevhubusername --setalias devhub
|
||||||
rm devhub.key
|
|
||||||
curl -sL https://raw.githubusercontent.com/travis-ci/artifacts/master/install | bash
|
curl -sL https://raw.githubusercontent.com/travis-ci/artifacts/master/install | bash
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
@ -77,3 +78,6 @@ script:
|
||||||
npm run test:without-system-tests
|
npm run test:without-system-tests
|
||||||
fi
|
fi
|
||||||
- codecov
|
- codecov
|
||||||
|
|
||||||
|
after_script:
|
||||||
|
- rm $SFDX_CI_KEY_LOCATION
|
|
@ -166,6 +166,28 @@
|
||||||
],
|
],
|
||||||
"preLaunchTask": "Compile",
|
"preLaunchTask": "Compile",
|
||||||
"internalConsoleOptions": "openOnSessionStart"
|
"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": [
|
"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
|
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.
|
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
|
To run all tests, execute `npm run compile && npm run test` from the top-level
|
||||||
folder.
|
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_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_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_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) |
|
| `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": {
|
"dependencies": {
|
||||||
|
"@salesforce/salesforcedx-sobjects-faux-generator": "40.9.0",
|
||||||
"@salesforce/salesforcedx-utils-vscode": "^40.10.0",
|
"@salesforce/salesforcedx-utils-vscode": "^40.10.0",
|
||||||
"expand-home-dir": "0.0.3",
|
"expand-home-dir": "0.0.3",
|
||||||
"find-java-home": "0.2.0",
|
"find-java-home": "0.2.0",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче