Skip to content

Commit 081988e

Browse files
committed
update Create Object action, add utils tests
1 parent 8c80e25 commit 081988e

File tree

7 files changed

+329
-215
lines changed

7 files changed

+329
-215
lines changed

lib/actions/createObject.js

Lines changed: 19 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,34 @@
1-
const _ = require('lodash');
21
const { messages } = require('elasticio-node');
3-
const { SalesforceEntity } = require('../entry.js');
4-
const MetaLoader = require('../helpers/metaLoader');
5-
const sfConnection = require('../helpers/sfConnection.js');
2+
const { processMeta } = require('../helpers/utils');
63
const attachment = require('../helpers/attachment.js');
4+
const { callJSForceMethod } = require('../helpers/wrapper');
75

8-
exports.objectTypes = function objectTypes(configuration) {
9-
const metaLoader = new MetaLoader(configuration, this);
10-
return metaLoader.getCreateableObjectTypes();
6+
exports.objectTypes = async function objectTypes(configuration) {
7+
return callJSForceMethod.call(this, configuration, 'getCreateableObjectTypes');
8+
};
9+
10+
exports.getMetaModel = async function getMetaModel(configuration) {
11+
const meta = await callJSForceMethod.call(this, configuration, 'describe');
12+
return processMeta(meta, 'create');
1113
};
1214

1315
exports.process = async function createObject(message, configuration) {
1416
this.logger.info(`Preparing to create a ${configuration.sobject} object...`);
15-
16-
const sfConn = sfConnection.createConnection(configuration, this);
17-
18-
this.logger.debug('Creating message body: ', message.body);
19-
20-
const binaryField = await attachment.prepareBinaryData(message, configuration, sfConn, this);
17+
this.logger.info('Starting Upsert Object Action');
18+
const binaryField = await attachment.prepareBinaryData(message, configuration, this);
2119

2220
this.logger.info('Sending request to SalesForce...');
21+
const response = await callJSForceMethod.call(this, configuration, 'sobjectCreate', message);
2322

24-
try {
25-
const response = await sfConn.sobject(configuration.sobject).create(message.body);
23+
this.logger.debug('SF response: ', response);
24+
this.logger.info(`${configuration.sobject} has been successfully created (ID = ${response.id}).`);
25+
// eslint-disable-next-line no-param-reassign
26+
message.body.id = response.id;
2627

27-
this.logger.debug('SF response: ', response);
28-
this.logger.info(`${configuration.sobject} has been successfully created (ID = ${response.id}).`);
28+
if (binaryField) {
2929
// eslint-disable-next-line no-param-reassign
30-
message.body.id = response.id;
31-
32-
if (binaryField) {
33-
// eslint-disable-next-line no-param-reassign
34-
delete message.body[binaryField.name];
35-
}
36-
37-
return messages.newMessageWithBody(message.body);
38-
} catch (err) {
39-
return this.emit('error', err);
30+
delete message.body[binaryField.name];
4031
}
41-
};
4232

43-
exports.getMetaModel = function getMetaModel(cfg, cb) {
44-
const entity = new SalesforceEntity(this);
45-
entity.getInMetaModel(cfg, (err, data) => {
46-
if (err) {
47-
return cb(err);
48-
}
49-
// eslint-disable-next-line no-param-reassign
50-
data.out = _.cloneDeep(data.in);
51-
// eslint-disable-next-line no-param-reassign
52-
data.out.properties.id = {
53-
type: 'string',
54-
required: true,
55-
readonly: true,
56-
title: 'ObjectID',
57-
};
58-
return cb(null, data);
59-
});
33+
return messages.newMessageWithBody(message.body);
6034
};

lib/actions/upsert.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ module.exports.process = async function upsertObject(message, configuration) {
5454
if (lookupResults.length === 1) {
5555
this.logger.info('sobject=%s was successfully upserted by %s=%s', sobject, configuration.lookupField, message.body[configuration.lookupField]);
5656
this.logger.debug('Emitting data: %j', lookupResults[0]);
57-
this.emit('data', messages.newMessageWithBody(lookupResults[0]));
57+
await this.emit('data', messages.newMessageWithBody(lookupResults[0]));
5858
return;
5959
}
6060
if (lookupResults.length > 1) {

lib/helpers/utils.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ const TYPES_MAP = {
2929
url: 'string',
3030
};
3131

32+
const META_TYPES_MAP = {
33+
lookup: 'lookup',
34+
upsert: 'upsert',
35+
create: 'create',
36+
};
37+
3238
/**
3339
* This method returns a property description for e.io proprietary schema
3440
*
@@ -102,18 +108,18 @@ exports.processMeta = async function processMeta(meta, metaType, lookupField) {
102108
const outProp = result.out.properties;
103109
let fields = await meta.fields.filter(field => !field.deprecatedAndHidden);
104110

105-
if (metaType !== 'lookup') {
111+
if (metaType === META_TYPES_MAP.create || metaType === META_TYPES_MAP.upsert) {
106112
fields = await fields.filter(field => field.updateable && field.createable);
107113
}
108114
await fields.forEach((field) => {
109-
if (metaType === 'lookup' && field.name === lookupField) {
115+
if (metaType === META_TYPES_MAP.lookup && field.name === lookupField) {
110116
inProp[field.name] = createProperty(field);
111-
} else if (metaType !== 'lookup' && field.createable) {
117+
} else if (metaType !== META_TYPES_MAP.lookup && field.createable) {
112118
inProp[field.name] = createProperty(field);
113119
}
114120
outProp[field.name] = createProperty(field);
115121
});
116-
if (metaType === 'upsert') {
122+
if (metaType === META_TYPES_MAP.upsert) {
117123
Object.keys(inProp).forEach((key) => {
118124
inProp[key].required = false;
119125
});
@@ -123,5 +129,11 @@ exports.processMeta = async function processMeta(meta, metaType, lookupField) {
123129
title: 'Id',
124130
};
125131
}
132+
if (metaType === META_TYPES_MAP.create) {
133+
outProp.id = {
134+
type: 'string',
135+
required: true,
136+
};
137+
}
126138
return result;
127139
};

lib/salesForceClient.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class SalesForceClient {
4343
return this.getSObjectList('updateable/createable sobject', object => object.updateable && object.createable);
4444
}
4545

46+
async getCreateableObjectTypes() {
47+
return this.getSObjectList('createable sobject', object => object.createable);
48+
}
49+
4650
async queryEmitAll(query) {
4751
const result = [];
4852
await new Promise((resolve, reject) => {
@@ -122,6 +126,12 @@ class SalesForceClient {
122126
return results;
123127
}
124128

129+
async sobjectCreate(options) {
130+
const sobject = options.sobject || this.configuration.sobject;
131+
const { body } = options;
132+
return this.connection.sobject(sobject).create(body);
133+
}
134+
125135
async sobjectUpdate(options) {
126136
const sobject = options.sobject || this.configuration.sobject;
127137
const { body } = options;
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* eslint-disable no-return-assign */
2+
const fs = require('fs');
3+
const logger = require('@elastic.io/component-logger')();
4+
const { expect } = require('chai');
5+
const sinon = require('sinon');
6+
const nock = require('nock');
7+
const action = require('../../lib/actions/createObject');
8+
9+
describe('creare object action', async () => {
10+
let emitter;
11+
const secretId = 'secretId';
12+
let configuration;
13+
let secret;
14+
15+
before(async () => {
16+
emitter = {
17+
emit: sinon.spy(),
18+
logger,
19+
};
20+
if (fs.existsSync('.env')) {
21+
// eslint-disable-next-line global-require
22+
require('dotenv').config();
23+
}
24+
process.env.ELASTICIO_API_URI = 'https://app.example.io';
25+
process.env.ELASTICIO_API_USERNAME = 'user';
26+
process.env.ELASTICIO_API_KEY = 'apiKey';
27+
process.env.ELASTICIO_WORKSPACE_ID = 'workspaceId';
28+
secret = {
29+
data: {
30+
attributes: {
31+
credentials: {
32+
access_token: process.env.ACCESS_TOKEN,
33+
instance_url: process.env.INSTANCE_URL,
34+
},
35+
},
36+
},
37+
};
38+
39+
configuration = {
40+
secretId,
41+
};
42+
43+
nock(process.env.ELASTICIO_API_URI)
44+
.get(`/v2/workspaces/${process.env.ELASTICIO_WORKSPACE_ID}/secrets/${secretId}`)
45+
.times(10)
46+
.reply(200, secret);
47+
});
48+
afterEach(() => {
49+
emitter.emit.resetHistory();
50+
});
51+
52+
it('should succeed selectModel objectTypes', async () => {
53+
const result = await action.objectTypes.call(emitter, configuration);
54+
expect(result.Contact).to.eql('Contact');
55+
});
56+
57+
it('should succeed process create sobject=Contact', async () => {
58+
const cfg = {
59+
...configuration,
60+
sobject: 'Contact',
61+
};
62+
const message = {
63+
body: {
64+
LastName: 'IntegrationTest',
65+
},
66+
};
67+
const result = await action.process.call(emitter, message, cfg);
68+
expect(result.body.LastName).to.eql('IntegrationTest');
69+
expect(Object.prototype.hasOwnProperty.call(result.body, 'id')).to.eql(true);
70+
});
71+
});

0 commit comments

Comments
 (0)