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, XM:true, XV:true, process:true, module:true, require:true,
5 describe:true, before:true, enyo:true, it:true, _:true, console:true,
6 beforeEach:true, afterEach:true, setTimeout:true, setInterval:true,
12 var zombieAuth = require("../../lib/zombie_auth"),
13 _ = require("underscore"),
14 smoke = require("../../lib/smoke"),
15 common = require("../../lib/common"),
16 assert = require("chai").assert;
18 describe('Workspaces', function () {
19 this.timeout(20 * 1000);
20 it('should log in first', function (done) {
21 zombieAuth.loadApp(done);
24 it('should be plumbed correctly', function () {
25 // look at all the workspaces in XV
26 _.each(XV, function (value, key) {
27 if (XV.inheritsFrom(value.prototype, "XV.Workspace")) {
28 // XXX TODO WorkOrderWorkspace should not be here
29 if (_.contains(['SalesOrderBase', 'AccountDocumentWorkspace', 'OrderedReferenceWorkspace', 'EmailProfileWorkspace', 'WorkOrderWorkspace'], key) ||
30 value.prototype.modelAmnesty) {
31 // exclude abstract classes and child workspaces
35 describe('XV.' + key, function () {
36 it('should reflect well in the history panel', function () {
37 var master = new enyo.Control(),
39 workspace = master.createComponent({kind: "XV." + key});
41 if (workspace.model) {
42 Klass = XT.getObjectByName(workspace.model);
43 assert.isNotNull(Klass);
44 if (Klass.prototype.getAttributeNames().indexOf(Klass.prototype.nameAttribute) < 0 &&
45 typeof Klass.prototype[Klass.prototype.nameAttribute] !== 'function' &&
46 Klass.prototype.nameAttribute.indexOf(".") < 0 && // don't bother with dotted nameAttributes
47 Klass.prototype.keepInHistory &&
48 Klass.prototype.idAttribute === 'uuid') {
49 assert.fail(0, 1, workspace.model + " does not contain its nameAttribute, which will reflect " +
50 "poorly in the history panel");
55 it('should have its attrs set up right', function () {
56 var master = new enyo.Control(),
57 workspace = master.createComponent({kind: "XV." + key}),
58 Klass = XT.getObjectByName(workspace.getModel()),
62 // workspaces with models with meta might mislead us
65 var attrs = _.compact(_.map(workspace.$, function (component) {
66 return component.attr;
68 _.each(attrs, function (attr) {
69 common.verifyAttr(attr, workspace.model);
79 * Test the INCDT-21110 fix.
80 * http://www.xtuple.org/xtincident/view/default/21110
82 describe.skip('INCDT-21110: Record remains locked when Back->Discard selected', function () {
83 var workspaceContainer, workspace, model, id, moduleContainer;
85 beforeEach(function (done) {
86 this.timeout(10 * 1000);
88 smoke.navigateToExistingWorkspace(XT.app, "XV.ClassCodeList", function (_workspaceContainer) {
89 workspaceContainer = _workspaceContainer;
90 moduleContainer = XT.app.$.postbooks;
91 assert.equal(workspaceContainer, XT.app.$.postbooks.getActive());
93 workspace = workspaceContainer.$.workspace;
94 id = workspace.getValue().id;
95 model = workspace.getValue();
97 assert.isTrue(model.hasLockKey(), "model should have lock");
98 assert.isFalse(model.isNew());
103 afterEach(function (done) {
104 this.timeout(10 * 1000);
106 // maybe one of the tests already released the lock
107 if (!model.hasLockKey()) {
111 model.on("lockChange", function () {
112 model.off("lockChange");
113 assert.isFalse(model.hasLockKey());
114 // XXX solves inexplicable race condition
115 setTimeout(function () {
119 workspaceContainer.close();
121 it('test base case', function () {
124 it('test lock condition on "close and discard"', function (done) {
126 * This test presupposes that we have obtained the lock. When the
127 * lock has been released, the test completes.
129 var handleLockChange = function () {
130 model.off("lockChange", handleLockChange);
131 assert.isFalse(model.hasLockKey());
135 * Guard on notifyPopup; when the notifyPopup is showing, 'tap' the
136 * popup's "Discard" button.
138 notifyPopupInterval = setInterval(function () {
139 if (!moduleContainer.$.notifyPopup.showing) { return; }
141 clearInterval(notifyPopupInterval);
142 model.on("lockChange", handleLockChange);
143 moduleContainer.notifyTap(null, { originator: { name: "notifyNo" }});
146 * When the model is READY_CLEAN, edit the value of inputWidget
148 handleBeforeEdit = function () {
149 if (model.isDirty()) { return; }
151 model.off("statusChange", handleBeforeEdit);
152 workspace.$.inputWidget.setValue("a valid name");
155 * When the model becomes dirty as a result of the edit, 'tap' the
156 * container's "Back" button.
158 handleAfterEdit = function () {
159 if (!model.isDirty()) { return; }
161 model.off("statusChange", handleAfterEdit);
162 workspaceContainer.$.backButton.bubble("onclick");
165 model.on("statusChange", handleBeforeEdit);
166 model.on("statusChange", handleAfterEdit);