1 /*jshint trailing:true, white:true, indent:2, strict:true, curly:true,
2 immed:true, eqeqeq:true, forin:true, latedef:true,
3 newcap:true, noarg:true, undef:true */
4 /*global XT:true, describe:true, it:true, require:true, __dirname:true, before:true */
6 var _ = require("underscore"),
7 assert = require('chai').assert,
8 datasource = require('../../node-datasource/lib/ext/datasource').dataSource,
9 path = require('path');
13 describe('The database', function () {
14 this.timeout(10 * 1000);
16 var loginData = require(path.join(__dirname, "../lib/login_data.js")).data,
17 datasource = require('../../../xtuple/node-datasource/lib/ext/datasource').dataSource,
18 config = require(path.join(__dirname, "../../node-datasource/config.js")),
19 creds = config.databaseServer,
20 databaseName = loginData.org,
21 isCommercial = false; // this is awkward #refactor
24 before(function (done) {
25 var sql = "select metric_value from public.metric where metric_name = 'MultiWhs';";
26 creds.database = databaseName;
27 datasource.query(sql, creds, function (err, res) {
28 isCommercial = res.rows[0].metric_value === 't';
34 // these tests are pretty fragile to the exact numbers in the database, but have been invaluable to
35 // make sure I'm not breaking anything in the fetch refactor
36 it('should execute a query with a join filter', function (done) {
37 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ContactListItem","query":{"orderBy":[{"attribute":"lastName"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"owner.username","operator":"","isCharacteristic":false,"value":"admin"}]},"username":"admin","encryptionKey":"foo"}$$);';
39 datasource.query(sql, creds, function (err, res) {
42 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
43 results = JSON.parse(res.rows[1].get);
44 assert.isNumber(results.data.length);
49 it('should execute a query with an array', function (done) {
50 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ActivityListItem","query":{"orderBy":[{"attribute":"dueDate"},{"attribute":"name"},{"attribute":"uuid"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"isActive","operator":"=","value":true},{"attribute":["owner.username","assignedTo.username"],"operator":"","isCharacteristic":false,"value":"admin"},{"attribute":"activityType","operator":"ANY","value":["Incident","Opportunity","ToDo","SalesOrder","SalesOrderWorkflow","PurchaseOrder","PurchaseOrderWorkflow","Project","ProjectTask","ProjectWorkflow"]}]},"username":"admin","encryptionKey":"this is any content"}$$);';
52 datasource.query(sql, creds, function (err, res) {
55 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
56 results = JSON.parse(res.rows[1].get);
57 assert.isNumber(results.data.length);
62 it('should execute a query with an array with a path', function (done) {
63 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ContactListItem","query":{"orderBy":[{"attribute":"lastName"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"owner.username","operator":"ANY","isCharacteristic":false,"value":["admin","foo"]}]},"username":"admin","encryptionKey":"foo"}$$);';
65 datasource.query(sql, creds, function (err, res) {
68 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
69 results = JSON.parse(res.rows[1].get);
70 assert.equal(results.data.length, 5);
75 it('should execute a query with a simple filter', function (done) {
76 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ContactListItem","query":{"orderBy":[{"attribute":"lastName"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"isActive","operator":"=","value":true}]},"username":"admin","encryptionKey":"foo"}$$);';
78 datasource.query(sql, creds, function (err, res) {
81 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
82 results = JSON.parse(res.rows[1].get);
83 assert.isNumber(results.data.length);
88 it('should execute a query with a simple filter and a join filter', function (done) {
89 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ContactListItem","query":{"orderBy":[{"attribute":"lastName"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"isActive","operator":"=","value":true},{"attribute":"owner.username","operator":"","isCharacteristic":false,"value":"admin"}]},"username":"admin","encryptionKey":"foo"}$$);';
91 datasource.query(sql, creds, function (err, res) {
94 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
95 results = JSON.parse(res.rows[1].get);
96 assert.equal(results.data.length, 5);
101 it('should execute a query with a simple filter and two join filters', function (done) {
102 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ContactListItem","query":{"orderBy":[{"attribute":"lastName"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"isActive","operator":"=","value":true},{"attribute":"account.number","operator":"","isCharacteristic":false,"value":"admin"},{"attribute":"owner.username","operator":"","isCharacteristic":false,"value":"admin"}]},"username":"admin","encryptionKey":"foo"}$$);';
104 datasource.query(sql, creds, function (err, res) {
107 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
108 results = JSON.parse(res.rows[1].get);
109 assert.equal(results.length, 0);
114 it('should execute a query with an array of attributes', function (done) {
115 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ContactListItem","query":{"orderBy":[{"attribute":"lastName"},{"attribute":"firstName"},{"attribute":"primaryEmail"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":["number","name","firstName","lastName","jobTitle","phone","alternate","fax","primaryEmail","webAddress","accountParent"],"operator":"MATCHES","value":"coltraine"},{"attribute":"isActive","operator":"=","value":true}]},"username":"admin","encryptionKey":"this is any content"}$$);';
117 datasource.query(sql, creds, function (err, res) {
120 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
121 results = JSON.parse(res.rows[1].get);
122 assert.equal(results.data.length, 1);
127 it('should execute a query with two join filters on the same table', function (done) {
128 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"IncidentListItem","query":{"orderBy":[{"attribute":"priorityOrder"},{"attribute":"updated","descending":true},{"attribute":"number","descending":true,"numeric":true}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":["owner.username","assignedTo.username"],"operator":"","isCharacteristic":false,"value":"admin"}]},"username":"admin","encryptionKey":"this is any content"}$$);';
130 datasource.query(sql, creds, function (err, res) {
133 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
134 results = JSON.parse(res.rows[1].get);
135 assert.equal(results.data.length, 4);
140 it('should execute a query with an x.y join path when x.y.naturalKeyOfY is needed', function (done) {
141 var sql = 'select xt.js_init(true);select xt.post($${"nameSpace":"XM","type":"ItemSiteListItem","dispatch":{"functionName":"fetch","parameters":{"orderBy":[{"attribute":"item.number"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"isActive","operator":"=","value":true},{"attribute":"item.classCode","operator":"","isCharacteristic":false,"value":"TOYS-CARS"}]}},"encoding":"rjson","username":"admin","encryptionKey":"this is any content"}$$);';
143 datasource.query(sql, creds, function (err, res) {
146 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
147 results = JSON.parse(res.rows[1].post);
148 assert.isNumber(results.length);
153 it('should execute a query with ambiguous column filters', function (done) {
154 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ToDoListItem","query":{"orderBy":[{"attribute":"priorityOrder"},{"attribute":"dueDate"},{"attribute":"name"}],"parameters":[{"attribute":"isActive","operator":"=","value":true},{"attribute":["owner.username","assignedTo.username"],"operator":"","isCharacteristic":false,"value":"admin"},{"attribute":"uuid","operator":"=","value":"23eef809-2f7c-4289-9eab-a72d621a6adb"}],"rowOffset":0,"rowLimit":50},"username":"admin","encryptionKey":"this is any content"}$$);';
156 datasource.query(sql, creds, function (err, res) {
159 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
160 results = JSON.parse(res.rows[1].get);
165 it('should execute a query filtering on an orm-extended field', function (done) {
166 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ProspectRelation","query":{"orderBy":[{"attribute":"number"}],"parameters":[{"attribute":"isActive","operator":"=","value":true}],"rowOffset":0,"rowLimit":50},"username":"admin","encryptionKey":"this is any content"}$$);';
168 datasource.query(sql, creds, function (err, res) {
171 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
172 results = JSON.parse(res.rows[1].get);
173 assert.equal(results.data.length, 1);
178 it('should execute a simple item-site fetch', function (done) {
179 var sql = 'select xt.js_init(true);select xt.post($${"nameSpace":"XM","type":"ItemSiteListItem","dispatch":{"functionName":"fetch","parameters":{"orderBy":[{"attribute":"item.number"}],"parameters":[{"attribute":"isActive","operator":"=","value":true}],"rowOffset":0,"rowLimit":50}},"username":"admin"}$$);';
181 datasource.query(sql, creds, function (err, res) {
184 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
185 results = JSON.parse(res.rows[1].post);
186 assert.isNumber(results.length);
191 it('should execute an item-site fetch', function (done) {
192 var sql = 'select xt.js_init(true);select xt.post($${"nameSpace":"XM","type":"ItemSiteRelation","dispatch":{"functionName":"fetch","parameters":{"parameters":[{"attribute":"item.number","value":"BTRUCK1"},{"attribute":"site.code","value":"WH1"}]}},"username":"admin","encryptionKey":"this is any content"}$$);';
194 datasource.query(sql, creds, function (err, res) {
197 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
198 results = JSON.parse(res.rows[1].post);
199 assert.equal(results.length, 1);
204 it('should execute a complicated item-site fetch', function (done) {
205 var sql = 'select xt.js_init(true);select xt.post($${"nameSpace":"XM","type":"ItemSiteRelation","dispatch":{"functionName":"fetch","parameters":{"parameters":[{"attribute":"item.isSold","value":true},{"attribute":"item.isActive","value":true},{"attribute":"isSold","value":true},{"attribute":"isActive","value":true},{"attribute":"site.code","value":"WH1"},{"attribute":"customer","value":"TTOYS"},{"attribute":["number","barcode"],"operator":"BEGINS_WITH","value":"bt","keySearch":true}],"orderBy":[{"attribute":"number"},{"attribute":"barcode"}],"rowLimit":1}},"username":"admin","encryptionKey":"this is any content"}$$)';
207 datasource.query(sql, creds, function (err, res) {
210 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
211 results = JSON.parse(res.rows[1].post);
212 assert.equal(results.length, 1);
217 it('should be able to search item-site by number', function (done) {
218 var sql = 'select xt.js_init(true);select xt.post($${"nameSpace":"XM","type":"ItemSiteListItem","dispatch":{"functionName":"fetch","parameters":{"orderBy":[{"attribute":"item.number"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"isActive","operator":"=","value":true},{"attribute":"item.number","operator":"MATCHES","isCharacteristic":false,"value":"yt"}]}},"encoding":"rjson","username":"admin","encryptionKey":"foo"}$$);';
220 datasource.query(sql, creds, function (err, res) {
223 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
224 results = JSON.parse(res.rows[1].post);
225 assert.isNumber(results.length);
230 it('should be able to do an item-site search with a keysearch', function (done) {
231 var sql = 'select xt.js_init(true);select xt.post($${"nameSpace":"XM","type":"ItemSiteRelation","dispatch":{"functionName":"fetch","parameters":{"parameters":[{"attribute":["number","barcode"],"operator":"BEGINS_WITH","value":"BTR","keySearch":true}],"orderBy":[{"attribute":"number"},{"attribute":"barcode"}],"rowLimit":10}},"username":"admin","encryptionKey":"this is any content"}$$);';
233 datasource.query(sql, creds, function (err, res) {
236 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
237 results = JSON.parse(res.rows[1].post);
238 assert.isNumber(results.length);
243 it('should be able to do a complex item-site search with a keysearch and join table parameters', function (done) {
244 var sql = 'select xt.js_init(true);select xt.post($${"nameSpace":"XM","type":"ItemSiteRelation","dispatch":{"functionName":"fetch","parameters":{"parameters":[{"attribute":"item.isSold","value":true},{"attribute":"item.isActive","value":true},{"attribute":"isSold","value":true},{"attribute":"isActive","value":true},{"attribute":"site.code","value":"WH1"},{"attribute":"customer","value":"TTOYS"},{"attribute":["number","barcode"],"operator":"BEGINS_WITH","value":"btr","keySearch":true}],"orderBy":[{"attribute":"number"},{"attribute":"barcode"}],"rowLimit":10}},"username":"admin"}$$);';
246 datasource.query(sql, creds, function (err, res) {
249 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
250 results = JSON.parse(res.rows[1].post);
251 assert.isNumber(results.length);
256 it('should support a nested order-by', function (done) {
257 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ItemSource","query":{"orderBy":[{"attribute":"vendorItemNumber"},{"attribute":"vendor.name"}],"parameters":[{"attribute":"isActive","value":true},{"attribute":"effective","operator":"<=","value":"2014-03-20T04:00:00.000Z"},{"attribute":"expires","operator":">=","value":"2014-03-22T01:18:09.202Z"}],"rowOffset":0,"rowLimit":50},"username":"admin","encryptionKey":"this is any content"}$$);';
259 datasource.query(sql, creds, function (err, res) {
262 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
263 results = JSON.parse(res.rows[1].get);
264 assert.equal(results.data.length, 20);
269 it.skip('should support an ambiguous primary key', function (done) {
270 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"IssueToShipping","query":{"orderBy":[{"attribute":"lineNumber"},{"attribute":"subNumber"}],"parameters":[{"attribute":"order.uuid","operator":"=","value":"d3538bbd-826a-4351-b35c-795d7db99ba0"}],"rowOffset":0,"rowLimit":50},"username":"admin","encryptionKey":"this is any content"}$$);';
278 datasource.query(sql, creds, function (err, res) {
281 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
282 results = JSON.parse(res.rows[1].get);
283 assert.equal(results.length, 0);
288 it('should allow the shortcut of querying a toOne directly by its natural key', function (done) {
289 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"IncidentListItem","query":{"orderBy":[{"attribute":"priorityOrder"},{"attribute":"updated","descending":true},{"attribute":"number","descending":true,"numeric":true}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"category","operator":"","isCharacteristic":false,"value":"Customer"},{"attribute":["owner.username","assignedTo.username"],"operator":"","isCharacteristic":false,"value":"admin"}]},"username":"admin","encryptionKey":"this is any content"}$$);';
291 datasource.query(sql, creds, function (err, res) {
294 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
295 results = JSON.parse(res.rows[1].get);
296 assert.isNumber(results.data.length);
301 it('should allow the shortcut of querying a toOne directly by its natural key with an attribute array', function (done) {
302 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"SalesOrderListItem","query":{"orderBy":[{"attribute":"number"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":["number","customerPurchaseOrderNumber","status","orderNotes","currency","billtoName","billtoCity","billtoState","billtoCountry","shiptoName","shiptoCity","shiptoState","shiptoCountry"],"operator":"MATCHES","value":"trem"},{"attribute":"status","value":"O"}]},"username":"admin","encryptionKey":"this is any content"}$$);';
304 datasource.query(sql, creds, function (err, res) {
307 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
308 results = JSON.parse(res.rows[1].get);
309 assert.isNumber(results.data.length);
314 it('should allow querying by characteristics', function (done) {
315 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ContactListItem","query":{"orderBy":[{"attribute":"lastName"},{"attribute":"firstName"},{"attribute":"primaryEmail"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"isActive","operator":"=","value":true},{"attribute":"CONTACT-BIRTHDAY","operator":"MATCHES","isCharacteristic":true,"value":"foo"}]},"username":"admin","encryptionKey":"this is any content"}$$);';
317 datasource.query(sql, creds, function (err, res) {
320 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
321 results = JSON.parse(res.rows[1].get);
322 assert.equal(results.length, 0);
327 it('should work with an empty parameters list', function (done) {
328 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"IncidentListItem","query":{"parameters":[],"orderBy":[],"rowLimit":100},"username":"admin","encryptionKey":"xq5j2"}$$);';
330 datasource.query(sql, creds, function (err, res) {
333 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
334 results = JSON.parse(res.rows[1].get);
335 assert.equal(results.data.length, 4);
340 it('should facilitate the count query', function (done) {
341 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ContactListItem","query":{"count":true,"orderBy":[{"attribute":"lastName"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":"isActive","operator":"=","value":true},{"attribute":"owner.username","operator":"","isCharacteristic":false,"value":"admin"}]},"username":"admin","encryptionKey":"this is any content"}$$);';
342 datasource.query(sql, creds, function (err, res) {
345 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
346 results = JSON.parse(res.rows[1].get);
347 assert.equal(results.data[0].count, 5);
352 it('should allow an order-by on a toOne', function (done) {
353 var sql = 'select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"TaxAssignment","query":{"orderBy":[{"attribute":"tax"}],"rowOffset":0,"rowLimit":50},"username":"admin","encryptionKey":"this is any content"}$$)';
355 datasource.query(sql, creds, function (err, res) {
358 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
359 results = JSON.parse(res.rows[1].get);
360 assert.equal(results.data.length, 4);
365 it('should correctly fix a long list of natural key attributes', function (done) {
366 var sql = 'select xt.js_init();select xt.get($${"nameSpace":"XM","type":"IncidentListItem","query":{"orderBy":[{"attribute":"priorityOrder"},{"attribute":"updated","descending":true},{"attribute":"number","descending":true,"numeric":true}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":["number","description","status","category","severity","priority","resolution","project"],"operator":"MATCHES","value":"Certify"},{"attribute":["owner.username","assignedTo.username"],"operator":"","isCharacteristic":false,"value":"admin"}]},"username":"admin","encryptionKey":"this is any content"}$$);';
368 datasource.query(sql, creds, function (err, res) {
371 assert.equal(1, res.rowCount, JSON.stringify(res.rows));
372 results = JSON.parse(res.rows[1].get);
373 assert.isNumber(results.data.length);
380 //select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"IncidentListItem","query":{"orderBy":[{"attribute":"priorityOrder"},{"attribute":"updated","descending":true},{"attribute":"number","descending":true,"numeric":true}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":["owner.username","assignedTo.username"],"operator":"","isCharacteristic":false,"value":"admin"},{"attribute":"project","operator":"","isCharacteristic":false,"value":"GREENLEAF"},{"attribute":"foundIn","operator":"","isCharacteristic":false,"value":"d0e6c507-eac5-461c-f63e-91e352a3ffb1"}]},"username":"admin","encryptionKey":"this is any content"}$$)
385 //select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ProjectListItem","query":{"orderBy":[{"attribute":"number"}],"rowOffset":0,"rowLimit":50,"parameters":[{"attribute":["number","name","projectType","status","department"],"operator":"MATCHES","value":"foo"},{"attribute":"status","operator":"!=","value":"C"},{"attribute":"number","operator":"MATCHES","isCharacteristic":false,"value":"tre"},{"attribute":["owner.username","assignedTo.username"],"operator":"","isCharacteristic":false,"value":"admin"}]},"username":"admin","encryptionKey":"this is any content"}$$)
386 //select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ItemRelation","query":{"parameters":[{"attribute":"projectExpenseMethod","operator":"=","value":"E"},{"attribute":"isActive","value":true},{"attribute":"number","operator":"BEGINS_WITH","value":"pro","keySearch":false}],"orderBy":[{"attribute":"number"}],"rowLimit":1},"username":"admin","encryptionKey":"this is any content"}$$)
387 //select xt.js_init(true);select xt.get($${"nameSpace":"XM","type":"ItemRelation","query":{"parameters":[{"attribute":"projectExpenseMethod","operator":"ANY","value":["E","A"]},{"attribute":"isActive","value":true},{"attribute":"number","operator":"BEGINS_WITH","value":"pro","keySearch":false}],"orderBy":[{"attribute":"number"}],"rowLimit":1},"username":"admin","encryptionKey":"this is any content"}$$)