view release on metacpan or search on metacpan
- ldapLookup: always display AJAX error
- Improve AJAX error reporting
- Dispatch.pm: revamp/simplify session management
- Rip out entry definitions for deprecated newEmployee target
- Plumb in an empObject prototype distinct from empProfile
- js: make ldapLookupSubmit GET instead of PUT
- dispatch: tweak debug log messages
- js: lower ACL profile of ldapLookupSubmit and privHistory targets
- Revamp LDAP lookup feature (GET first)
- js: handle empty nick in ldapLookupSubmit
- Add "Sync" option to LDAP lookup result miniMenu
- js: simplify LDAP lookup failure handling
- Reinstate "Priv (status) menu" with privHistory target
- Display workforce ID instead of EID in simpleEmployeeBrowser
- Change "Status"/"Since" to "Privlevel"/"Effective"
- dmenu: add Schedule menu
- js: Tweak text of menu entries
- js: rename "searchEmp" to "actionEmplSearch" in emp-lib.js
- js: move dform and dbrowser entries to lib.js
0.139 2016-09-28 19:12 CEST
- Drop LDAPdochazka entry from simpleEmployeeBrowser
- Clarify difference between LDAP and Dochazka employees
- Put masquerade at end of Employee menu
- Dispatch.pm: reduce log verbosity
- Implement LDAP sync miniMenu entry in simpleEmployeeBrowser
0.140 2016-09-29 00:16 CEST
- build/ops: change OBS_PROJECT to Application:Dochazka
- build/ops: require App::MFILE::WWW 0.147 for dtable feature
- Implement basic (read-only) Privhistory table
0.141 2016-11-01 15:40 CET
- Display effective date more readably
- Dispatch.pm: AJAX call session/terminate on logout
- js: Enable active users to "LDAP sync" themselves
0.142 2016-11-05 22:40 CET
- js: implement "REST server details" dform
- js: make REST server details form return to mainMenu
- build/ops: require App::MFILE::WWW 0.152
- Plumb in drowselect target, privhistory edit menu option
- lib.js: add aclProfileWrite prop to pHeffective and pHpriv
- Implement "Add record" option in privhistory drowselect
- emp-lib.js: call lib.displayError() whenever AJAX fails
- Implement "Delete record" option in Privhistory drowselect
0.143 2017-02-25 09:28 CET
- Dispatch.pm: implement user agent lookup table
- Dispatch.pm: refactor session management
- Drop SHID column from schedule history table
- build/ops: designed to work with App::Dochazka::REST >=0.549
- Add scode field to schedhistory dtable and drowselect
- Make schedule menu visible to all
- Implement schedule update dform
- Improve usability of "employee profile edit" feature
- Implement "schedule edit (from schedule display)" feature
- Implement "delete schedule from lookup" feature
- sched-lib.js: refactor schedEditSave and schedDelete
- Implement "schedule edit and delete from browser" feature
- Move "{priv,schedule} history EDIT" to miniMenu
0.148 2017-08-29 15:16 CEST
- schedhistory: make dtable columns visible to inactive+
- Employee Profile: rename priv/status entries
- Employee Profile: show current schedule
- Implement "target stack" feature/redesign
- js: emp-lib: migrate ldapSync from Employee Profile
- js: emp-lib: migrate empProfileEditSave to target stack
- tests: js: first dochazka-www unit test
- tests: js: migrate unit test to QUnit 2.4.0
- build/ops: require App::MFILE::WWW 0.158
0.149 2017-09-24 00:03 CEST
- build/ops: add ext/codepaths file to MANIFEST
- js: tests: add simple test cases for mainMenu targets
- Dispatch.pm: upon login success, expurgate currentUser object
- js: tests: force root user for mainMenu test
- js: tests: refactor and add test for mainEmpl menu
- js: tests: use setTimeout properly
- js: tests/main-menu.js: refactor to do login/logout
- Dispatch.pm: use _prep_ajax_response for logout
- daction-start.js: call loggout instead of logout
- tests/main-menu.js: use current user object correctly
- js: tests: refactor all three existing tests
0.150 2017-09-25 17:36 CEST
- js: emp-lib: migrate ldapLookupSubmit() to target stack
- js: Throw up multi-day interval viewer even for empty query
- js: drop schedHistoryDtable which is no longer used
- js: emp-lib: display "Direct reports" as "(none)" instead of "(undefined)"
- js: let supervisors masquerade as their reports
- js: fix functional tests
- build/ops: require App::MFILE::WWW 0.175 for menu prototype and new fillUserBox() behavior
0.166 2017-11-15 12:11 CET
- js: canned-tests: implement log() - logs messages to both console log and test
protocol
- js: canned-tests: implement getMenuEntry() - avoids hard-coding of menu entry
numbers
- js: tests: implement new test "Masquerading as active, set inactive as supervisor"
- js: empProfile: call reports "Supervisees"
- js: Always load employee profile from server
0.167 2017-11-27 13:21 CET
- js: caches: check more carefully if activityCache populated; refactor masqEmployee
- js: allow inactives to view intervals
- js: hide inaccessible functionality from passerbies
- js: implement vetting of privlevels when adding/modifying status records
ext/codepaths view on Meta::CPAN
dmenu.mainMenu (sets flag)
dmenu.mainEmpl (sets flag)
daction.myProfileAction -> empLib.myProfileAction
dform.empProfile { "xtarget": "mainEmpl" }
dform.empProfileEdit
daction.empProfileEditSave
unwindToFlag()
daction.ldapSync -> empLib.ldapSync
unwindToFlag()
dform.ldapLookup
daction.ldapLookupSubmit -> empLib.ldapLookupSubmit
share/js/dochazka-www/canned-tests.js view on Meta::CPAN
containsFunc = function (assert, lookIn, lookInDesc, lookFor) {
// console.log("containsFunc() looking for ->" + lookFor + "<- in ->" + lookIn + "<-");
// asserts that the string lookIn contains substring lookFor
// lookInDesc describes what lookIn represents
assert.notStrictEqual(
lookIn.indexOf(lookFor),
-1,
lookInDesc + " contains substring \"" + lookFor + "\""
);
},
getMenuEntryFunc = function (assert, htmlbuf, searchKey) {
var rx = new RegExp('(\\d+)\\. ' + searchKey),
match = htmlbuf.match(rx),
msg,
sel;
logFunc(assert, htmlbuf);
logFunc(assert, "*** REACHED looking for " + searchKey);
assert.ok(match !== null, "There is a match 1");
if (match !== null) {
assert.ok(match.length >= 1, "There is a match 2");
sel = match[1];
share/js/dochazka-www/canned-tests.js view on Meta::CPAN
}
},
// failure callback
fc = function (st) {
console.log("AJAX: " + rest["path"] + " failure", st);
coreLib.displayError(st.payload.message);
};
ajax(rest, sc, fc);
},
"getMenuEntry": getMenuEntryFunc,
"log": logFunc,
"loggout": function (assert) {
var cu,
htmlbuf,
mainarea;
console.log("TEST: post-logout tests");
assert.ok(true, '*** REACHED logging out ***');
cu = currentUser();
share/js/dochazka-www/canned-tests.js view on Meta::CPAN
assert.ok(cu, "current user object after login: " + QUnit.dump.parse(cu));
assert.strictEqual(cu.obj.nick, nick, 'we are now ' + nick);
assert.strictEqual(cu.priv, priv, nick + ' has ' + priv + ' privileges');
assert.ok(true, "Starting app in fixture");
root(); // start app in QUnit fixture
msg = '*** REACHED commence app start with nick ' + nick;
console.log(msg);
assert.ok(true, msg);
},
"mainMenu": function (assert) {
var msg;
stackFunc(assert, 1, 'starting app', 'dmenu', 'mainMenu');
mainareaFormFunc(assert, 'mainMenu');
msg = '*** REACHED main menu';
console.log(msg);
assert.ok(true, msg);
assert.ok(true, $('#mainarea').html());
},
"mainareaForm": mainareaFormFunc,
"mainEmplToLdapLookup": function (assert) {
var htmlbuf;
share/js/dochazka-www/canned-tests.js view on Meta::CPAN
"The searchEmployee form contains a data entry field"
);
assert.strictEqual(
coreLib.focusedItem().name,
'entry0',
'Focus is on data entry field'
);
assert.ok(true, "*** REACHED searchEmployee dform");
},
"mainMenuSelectEmpProfile": function (assert) {
var htmlbuf,
mainmarea,
sel;
mainareaFormFunc(assert, 'mainMenu');
sel = $('input[name="sel"]').val();
assert.strictEqual(sel, '', "Selection form field is empty");
sel = getMenuEntryFunc(assert, $('#mainarea').html(), 'Profile');
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
logFunc(assert, "*** REACHED selected Profile in main menu");
},
"mainMenuToMainAdmin": function (assert) {
var htmlbuf,
mainmarea,
sel;
mainareaFormFunc(assert, 'mainMenu');
sel = $('input[name="sel"]').val();
assert.strictEqual(sel, '', "Selection form field is empty");
// press '0' key in sel, but value does not change?
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 48})); // press '0' key
sel = $('input[name="sel"]').val();
assert.strictEqual(sel, '', "Selection form field is empty even after simulating 0 keypress");
// simulating keypress doesn't work, so just set the input val
sel = getMenuEntryFunc(assert, $('#mainarea').html(), 'Admin');
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
assert.ok(true, $('#mainarea').html());
stackFunc(assert, 2, 'navigating from mainMenu to mainAdmin', 'dmenu', 'mainAdmin');
mainareaFormFunc(assert, 'mainAdmin');
containsFunc(assert, $('#mainarea').html(), "#mainarea", "Admin menu");
assert.ok(true, "*** REACHED mainAdmin dmenu");
},
"mainMenuToMainSched": function (assert) {
var htmlbuf,
mainmarea,
sel;
mainareaFormFunc(assert, 'mainMenu');
sel = $('input[name="sel"]').val();
assert.strictEqual(sel, '', "Selection form field is empty");
sel = getMenuEntryFunc(assert, $('#mainarea').html(), 'Schedules');
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
stackFunc(assert, 2, 'navigating from mainMenu to mainSched', 'dmenu', 'mainSched');
mainareaFormFunc(assert, 'mainSched');
containsFunc(assert, $('#mainarea').html(), "#mainarea", "Schedule menu");
assert.ok(true, "*** REACHED mainSched dmenu");
},
"mainSchedToSchedLookup": function (assert) {
var entry0,
entry1,
sel;
assert.ok(true, 'select 1 ("Look up schedule by code or ID") in mainSched as root');
sel = getMenuEntryFunc(assert, $('#mainarea').html(), 'Look up');
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
stackFunc(assert, 3, 'navigating from mainSched to schedLookup', 'dform', 'schedLookup');
mainareaFormFunc(assert, 'schedLookup');
containsFunc(assert, $('#mainarea').html(), "#mainarea",
"Look up schedule by code or ID");
entry0 = $('form#schedLookup input[name="entry0"]');
entry1 = $('form#schedLookup input[name="entry1"]');
assert.ok(entry0, "There is an entry0 in the schedLookup form");
share/js/dochazka-www/daction-init.js view on Meta::CPAN
// Interval actions
target.push('createMultipleIntSave', {
'name': 'createMultipleIntSave',
'type': 'daction',
'menuText': 'Save',
'aclProfile': 'active',
'start': dactionStart('createMultipleIntSave'),
'pushable': false
});
target.push('createSingleIntMenuItem', {
'name': 'createSingleIntMenuItem',
'type': 'daction',
'menuText': 'Create single',
'aclProfile': 'active',
'start': dactionStart('createSingleIntMenuItem'),
'pushable': false
});
target.push('createSingleIntSave', {
'name': 'createSingleIntSave',
'type': 'daction',
'menuText': 'Save',
'aclProfile': 'active',
'start': dactionStart('createSingleIntSave'),
'pushable': false
});
share/js/dochazka-www/daction-start.js view on Meta::CPAN
"browseAllSchedules": schedLib.browseAllSchedules,
"actionSchedLookup": schedLib.actionSchedLookup,
"createSchedule": schedLib.createSchedule,
"actionDisplaySchedule": schedLib.actionDisplaySchedule,
"schedEditSave": schedLib.schedEditSave,
"schedReallyDelete": schedLib.schedReallyDelete,
// create interval actions
"createMultipleIntSave": intLib.createMultipleIntSave,
"createNextScheduledIntervalSave": intLib.createNextScheduledIntervalSave,
"createSingleIntMenuItem": intLib.createSingleIntMenuItem,
"createSingleIntSave": intLib.createSingleIntSave,
"createLockSave": lockLib.createLockSave,
"deleteSingleInt": intLib.deleteSingleInt,
"deleteLock": lockLib.deleteLock,
"updateSingleIntSave": intLib.updateSingleIntSave,
"viewIntervalsAction": intLib.viewIntervalsAction,
"viewLocksAction": lockLib.viewLocksAction,
// activity select actions
"selectActivityAction": appCaches.selectActivityAction,
share/js/dochazka-www/dbrowser-init.js view on Meta::CPAN
target.push('simpleEmployeeBrowser', {
'name': 'simpleEmployeeBrowser',
'type': 'dbrowser',
'menuText': 'simpleEmployeeBrowser',
'title': 'Employee search results',
'preamble': null,
'aclProfile': 'admin',
'entriesRead': [entries.ePnick, entries.ePsec_id, entries.ePfullname,
entries.ePemail, entries.ePremark],
'miniMenu': {
entries: ['ldapSync', 'empProfileEdit']
}
});
target.push('setSupervisorBrowser', {
'name': 'setSupervisorBrowser',
'type': 'dbrowser',
'menuText': 'setSupervisorBrowser',
'title': 'Supervisor candidates',
'preamble': null,
'aclProfile': 'admin',
'entriesRead': [entries.ePnick, entries.ePsec_id, entries.ePfullname,
entries.ePemail, entries.ePremark],
'miniMenu': {
entries: ['empProfileSetSuperChoose']
}
});
target.push('masqueradeCandidatesBrowser', {
'name': 'masqueradeCandidatesBrowser',
'type': 'dbrowser',
'menuText': 'masqueradeCandidatesBrowser',
'title': 'Masquerade candidates',
'preamble': null,
'aclProfile': 'admin',
'entriesRead': [entries.ePnick, entries.ePsec_id, entries.ePfullname,
entries.ePemail, entries.ePremark],
'miniMenu': {
entries: ['masqEmployee']
}
});
target.push('simpleScheduleBrowser', {
'name': 'simpleScheduleBrowser',
'type': 'dbrowser',
'menuText': 'Browse schedules',
'title': 'All schedules',
'preamble': null,
'aclProfile': 'admin',
'entriesRead': [entries.sDid, entries.sDcode,
coreLib.emptyLineEntry, entries.sDmon,
entries.sDtue, entries.sDwed, entries.sDthu,
entries.sDfri, entries.sDsat, entries.sDsun,
coreLib.emptyLineEntry, entries.ePremark],
'miniMenu': {
entries: ['schedEditFromBrowser', 'schedDeleteFromBrowser']
}
});
};
});
share/js/dochazka-www/dcallback-init.js view on Meta::CPAN
return function () {
target.push('multiDayViewer', {
'name': 'multiDayViewer',
'type': 'dcallback',
'menuText': 'multiDayViewer',
'aclProfile': 'inactive',
'callback': viewer.multiDayViewer,
'rememberState': true,
'miniMenu': {
entries: ['viewIntervalsMultiDayRaw'],
}
});
target.push('viewIntervalsMultiDayRaw', {
'name': 'viewIntervalsMultiDayRaw',
'type': 'dcallback',
'menuText': 'Raw JSON',
'title': 'Multi-day interval viewer (RAW)',
'preamble': 'Attendance intervals from [BEGIN] to [END]',
'aclProfile': 'inactive',
'callback': intLib.viewIntervalsMultiDayCallbackRaw,
'miniMenu': {
entries: [],
}
});
};
});
share/js/dochazka-www/dform-init.js view on Meta::CPAN
coreLib.emptyLineEntry,
entries.iNtoBeCreated,
],
'entriesWrite': [
entries.iNdate,
entries.iNtimerange,
entries.iNact,
entries.iNdesc,
],
'rememberState': true,
'miniMenu': {
entries: ['createSingleIntSave'],
}
}); // createLastPlusOffset
target.push('createMultipleInt', {
'name': 'createMultipleInt',
'type': 'dform',
'menuText': 'Create multiple',
'title': 'Create multiple intervals according to schedule',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
share/js/dochazka-www/dform-init.js view on Meta::CPAN
entries.iNyearHidden,
],
'entriesWrite': [
entries.iNyear,
entries.iNmonth,
entries.iNdaylist,
entries.iNact,
entries.iNdesc,
],
'rememberState': true,
'miniMenu': {
entries: ['selectActivityAction', 'createMultipleIntSave', 'viewIntervalsAction']
}
}); // createMultipleInt
target.push('createNextScheduled', {
// before doing any calculations, look up/calculate:
// - employee's schedule
// - existing intervals on date
// - schedule intervals on date
// timerange will be:
share/js/dochazka-www/dform-init.js view on Meta::CPAN
coreLib.emptyLineEntry,
entries.iNtoBeCreated,
],
'entriesWrite': [
entries.iNdate,
entries.iNtimerange,
entries.iNact,
entries.iNdesc,
],
'rememberState': true,
'miniMenu': {
entries: ['selectActivityAction', 'createSingleIntSave'],
}
}); // createNextScheduled
target.push('createSingleInt', {
'name': 'createSingleInt',
'type': 'dform',
'menuText': 'Create',
'title': 'Create an arbitrary interval',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
"(2) date YYYY-MM-DD; year is optional " +
"(3) time range HH:MM-HH:MM or HH:MM+HH:MM (start time plus offset) " +
"or +HH:MM (last existing interval plus offset) or + (next scheduled " +
"interval) (4) Use 'Select activity' if you don't know activity code " +
'(5) Description is optional',
'aclProfile': 'active',
'entriesWrite': [entries.iNdate, entries.iNtimerange, entries.iNact, entries.iNdesc,],
'rememberState': true,
'miniMenu': {
entries: ['selectActivityAction', 'createSingleIntSave']
}
}); // createSingleInt
target.push('createLock', {
'name': 'createLock',
'type': 'dform',
'menuText': 'Create',
'title': 'Create a Lock',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field ",
'aclProfile': 'active',
'entriesWrite': [entries.iNyear, entries.iNmonth,],
'rememberState': true,
'miniMenu': {
entries: ['createLockSave']
}
}); // createLock
target.push('createSingleIntFixedDay', {
'name': 'createSingleIntFixedDay',
'type': 'dform',
'menuText': 'Create',
'title': 'Create an arbitrary interval',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
"(2) time range HH:MM-HH:MM " +
"(3) Use 'Select activity' if you don't know activity code " +
'(4) Description is optional',
'aclProfile': 'active',
'entriesRead': [entries.iNdate,],
'entriesWrite': [entries.iNtimerangeNoOffset, entries.iNact, entries.iNdesc,],
'rememberState': true,
'miniMenu': {
entries: ['selectActivityAction', 'createSingleIntSave']
}
}); // createSingleIntFixedDay
target.push('displaySingleInt', {
'name': 'displaySingleInt',
'type': 'dform',
'menuText': 'Single interval',
'title': 'Display a single interval',
'aclProfile': 'active',
'entriesRead': [entries.iNdaterange, entries.iNtimerange, entries.iNact, entries.iNdesc,],
'miniMenu': {
entries: []
}
}); // displaySingleInt
target.push('empProfile', {
'name': 'empProfile',
'type': 'dform',
'menuText': 'Profile',
'title': 'Employee profile',
'preamble': null,
share/js/dochazka-www/dform-init.js view on Meta::CPAN
entries.ePfullname, entries.ePnick,
entries.ePsec_id, entries.ePemail,
entries.ePremark,
coreLib.emptyLineEntry,
entries.ePsuperNick, entries.ePhasReports,
coreLib.emptyLineEntry,
entries.ePpriv, entries.ePprivEffective,
coreLib.emptyLineEntry,
entries.ePscode, entries.ePsid, entries.ePschedEffective
],
'miniMenu': {
entries: [
'actionPrivHistory',
'actionSchedHistory',
'empProfileEdit',
'ldapSync',
'empProfileSetSuperSearch',
'empProfileSetSuperDelete',
]
}
}); // empProfile
share/js/dochazka-www/dform-init.js view on Meta::CPAN
'name': 'empProfileEdit',
'type': 'dform',
'menuText': 'Edit remark',
'title': 'Employee profile edit',
'preamble': 'Only the remark field can be modified;<br>' +
'All other fields are synced from LDAP',
'aclProfile': 'admin',
'entriesRead': [entries.ePfullname, entries.ePnick,
entries.ePsec_id, entries.ePemail],
'entriesWrite': [entries.ePremark],
'miniMenu': {
entries: ['empProfileEditSave']
}
}); // empProfileEdit
target.push('empProfileSetSuperConfirm', {
'name': 'empProfileSetSuperConfirm',
'type': 'dform',
'menuText': 'empProfileSetSuperConfirm',
'title': 'Set employee supervisor - confirmation',
'preamble': 'Do you really want to do this?',
'aclProfile': 'admin',
'entriesRead': [
entries.ePsetsuperofEID,
entries.ePsetsupertoEID,
entries.ePsetsuperof,
entries.ePsetsuperto,
],
'miniMenu': {
entries: ['empProfileSetSuperCommit']
}
}); // empProfileEdit
target.push('ldapDisplayEmployee', {
'name': 'ldapDisplayEmployee',
'type': 'dform',
'title': 'LDAP employee record',
'preamble': null,
'aclProfile': 'active',
'entriesRead': [entries.ePfullname, entries.ePnick,
entries.ePsec_id, entries.ePemail, entries.LDAPdochazka],
'miniMenu': {
entries: ['ldapSync']
}
}); // ldapDisplayEmployee
target.push('ldapLookup', {
'name': 'ldapLookup',
'type': 'dform',
'menuText': 'Look up an LDAP employee',
'title': 'Look up an LDAP employee',
'preamble': 'Enter employee nick for exact (case insensitive) match',
'aclProfile': 'active',
'entriesWrite': [entries.ePnick],
'rememberState': true,
'miniMenu': {
entries: ['ldapLookupSubmit']
}
}); // ldapLookup
target.push('privHistoryAddRecord', {
'name': 'privHistoryAddRecord',
'type': 'dform',
'menuText': 'Add record',
'title': 'Add privhistory (status) record',
'preamble': '<b>Effective</b> date format YYYY-MM-DD;<br>' +
'<b>Priv</b> one of (passerby, inactive, active, admin)',
'aclProfile': 'admin',
'entriesRead': [entries.ePnick],
'entriesWrite': [entries.pHeffective, entries.pHpriv],
'miniMenu': {
entries: ['privHistorySaveAction']
}
}); // privHistoryAddRecord
target.push('schedHistoryAddRecord', {
'name': 'schedHistoryAddRecord',
'type': 'dform',
'menuText': 'Add record',
'title': 'Add schedule history record',
'preamble': '<b>Effective date</b> format YYYY-MM-DD;<br>' +
'Enter schedule ID or schedule code - not both',
'aclProfile': 'admin',
'entriesRead': [entries.ePnick],
'entriesWrite': [entries.pHeffective, entries.sDid, entries.sDcode],
'miniMenu': {
entries: ['schedHistorySaveAction']
}
}); // schedHistoryAddRecord
target.push('restServerDetails', {
'name': 'restServerDetails',
'type': 'dform',
'menuText': 'REST server',
'title': 'REST server details',
'aclProfile': 'admin',
'entriesRead': [entries.rSDurl, entries.rSDversion],
'miniMenu': {
entries: []
}
}); // restServerDetails
target.push('schedDisplay', {
'name': 'schedDisplay',
'type': 'dform',
'menuText': 'schedDisplay',
'title': 'Schedule',
'aclProfile': 'passerby',
'entriesRead': [entries.sDid, entries.sDcode,
coreLib.emptyLineEntry, entries.sDmon,
entries.sDtue, entries.sDwed, entries.sDthu,
entries.sDfri, entries.sDsat, entries.sDsun,
coreLib.emptyLineEntry, entries.ePremark],
'miniMenu': {
entries: ['schedEdit', 'schedDelete']
}
}); // schedDisplay
var schedEditObj = {
'type': 'dform',
'menuText': 'Edit',
'title': 'Schedule edit',
'preamble': 'Only schedule code and remark can be modified<br>' +
'Note: code change will affect <b>all employees</b> with this schedule',
'aclProfile': 'admin',
'entriesRead': [entries.sDid,
coreLib.emptyLineEntry, entries.sDmon,
entries.sDtue, entries.sDwed, entries.sDthu,
entries.sDfri, entries.sDsat, entries.sDsun],
'entriesWrite': [entries.sDcode, entries.ePremark],
'miniMenu': {
entries: ['schedEditSave']
}
},
schedEditFromBrowserObj = coreLib.shallowCopy(schedEditObj);
schedEditObj['name'] = 'schedEdit';
target.push('schedEdit', schedEditObj);
schedEditFromBrowserObj['name'] = 'schedEditFromBrowser';
target.push('schedEditFromBrowser', schedEditFromBrowserObj);
share/js/dochazka-www/dform-init.js view on Meta::CPAN
'menuText': 'Delete',
'title': 'Schedule delete',
'preamble': 'If you are really sure you want to delete this schedule,<br>' +
'select "Yes, I really mean it" below',
'aclProfile': 'admin',
'entriesRead': [entries.sDid, entries.sDcode,
coreLib.emptyLineEntry, entries.sDmon,
entries.sDtue, entries.sDwed, entries.sDthu,
entries.sDfri, entries.sDsat, entries.sDsun,
coreLib.emptyLineEntry, entries.ePremark],
'miniMenu': {
entries: ['schedReallyDelete']
}
},
schedDeleteFromBrowserObj = coreLib.shallowCopy(schedDeleteObj);
schedDeleteObj.name = 'schedDelete';
target.push('schedDelete', schedDeleteObj);
schedDeleteFromBrowserObj['name'] = 'schedDeleteFromBrowser';
target.push('schedDeleteFromBrowser', schedDeleteFromBrowserObj);
target.push('schedLookup', {
'name': 'schedLookup',
'type': 'dform',
'menuText': 'Look up schedule by code or ID',
'title': 'Look up schedule by code or ID',
'preamble': 'Enter a schedule code or ID (must be an exact match)',
'aclProfile': 'passerby',
'entriesWrite': [entries.sScode, entries.sSid],
'rememberState': true,
'miniMenu': {
entries: ['actionSchedLookup']
}
}); // schedLookup
target.push('schedNewBoilerplate', {
'name': 'schedNewBoilerplate',
'type': 'dform',
'menuText': 'Boilerplate (quick form for Mon-Fri schedules)',
'title': 'Create a new schedule - boilerplate',
'preamble': 'Hint: separate schedule intervals by semi-colon<br>' +
'Example: 8:00-12:00; 12:30-16:30<br>' +
'<b>Schedule intervals will be replicated for Monday-Friday</b><br>' +
'Note: schedule code is optional',
'aclProfile': 'admin',
'entriesRead': [entries.sDid],
'entriesWrite': [entries.sCboiler, entries.sDcode],
'miniMenu': {
entries: ['createSchedule']
}
}); // schedNewBoilerPlate
target.push('schedNewCustom', {
'name': 'schedNewCustom',
'type': 'dform',
'menuText': 'Custom (long form)',
'title': 'Create a new schedule - custom',
'preamble': 'Hint: separate schedule intervals by semi-colon<br>' +
'Example: 8:00-12:00; 12:30-16:30<br>' +
'Note: schedule code is optional',
'aclProfile': 'admin',
'entriesRead': [entries.sDid],
'entriesWrite': [entries.sDmon, entries.sDtue,
entries.sDwed, entries.sDthu, entries.sDfri,
entries.sDsat, entries.sDsun, entries.sDcode],
'miniMenu': {
entries: ['createSchedule']
}
}); // schedNewCustom
target.push('searchEmployee', {
'name': 'searchEmployee',
'type': 'dform',
'menuText': 'Search Dochazka employees',
'title': 'Search Dochazka employees',
'preamble': 'Enter search key, % is wildcard',
'aclProfile': 'admin',
'entriesWrite': [entries.sEnick],
'miniMenu': {
entries: ['actionEmplSearch']
}
}); // searchEmployee
target.push('updateSingleInt', {
'name': 'updateSingleInt',
'type': 'dform',
'menuText': 'Update',
'title': 'Update an interval',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
"(2) time range HH:MM-HH:MM " +
"(3) Use 'Select activity' if you don't know activity code " +
'(4) Description is optional',
'aclProfile': 'active',
'entriesRead': [entries.iNdate, entries.acTaid],
'entriesWrite': [entries.iNtimerangeNoOffset, entries.iNact, entries.iNdesc,],
'rememberState': true,
'miniMenu': {
entries: ['selectActivityAction', 'updateSingleIntSave']
}
}); // updateSingleInt
target.push('viewIntervalsPrep', {
'name': 'viewIntervalsPrep',
'type': 'dform',
'menuText': 'View',
'title': 'View intervals for date or range of dates',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
share/js/dochazka-www/dform-init.js view on Meta::CPAN
entries.iNdaterangeBegin,
entries.iNdaterangeEnd,
entries.iNyearHidden,
],
'entriesWrite': [
entries.iNyear,
entries.iNmonth,
entries.iNdayrange,
],
'rememberState': true,
'miniMenu': {
entries: ['viewIntervalsAction']
}
}); // viewIntervalsPrep
target.push('viewLocksPrep', {
'name': 'viewLocksPrep',
'type': 'dform',
'menuText': 'View',
'title': 'View locks',
'preamble': "Hints: (1) TAB or ENTER to validate and advance to next field " +
"(2) enter month by name (e.g. \"June\") or number (e.g. \"6\"); " +
"DEFAULT: current month ",
'aclProfile': 'inactive',
'entriesWrite': [
entries.iNyear,
],
'rememberState': true,
'miniMenu': {
entries: ['viewLocksAction']
}
}); // viewLocksPrep
}; // return function ()
});
share/js/dochazka-www/dmenu-init.js view on Meta::CPAN
'aclProfile': 'admin',
'entries': ['ldapLookup', 'searchEmployee', 'restServerDetailsAction']
});
target.push('mainInt', {
'name': 'mainInt',
'type': 'dmenu',
'menuText': 'Intervals',
'title': 'Interval menu',
'aclProfile': 'inactive',
'entries': ['viewIntervalsPrep', 'createSingleIntMenuItem', 'createMultipleInt',],
});
target.push('mainLock', {
'name': 'mainLock',
'type': 'dmenu',
'menuText': 'Locks',
'title': 'Lock menu',
'aclProfile': 'inactive',
'entries': ['viewLocksPrep', 'createLock',],
});
target.push('mainMenu', {
'name': 'mainMenu',
'type': 'dmenu',
'menuText': 'Main',
'title': 'Main menu',
'aclProfile': 'passerby',
'entries': ['myProfileAction', 'mainInt', 'mainLock', 'mainSched', 'masqEmployee',
'mainAdmin']
});
target.push('mainSched', {
'name': 'mainSched',
share/js/dochazka-www/dnotice-init.js view on Meta::CPAN
return function () {
// demo notice from App::MFILE::WWW
target.push('demoNotice', {
'name': 'demoNotice',
'type': 'dnotice',
'menuText': 'Demo notice',
'title': 'Demo notice',
'preamble': 'This is just an illustration',
'aclProfile': 'passerby',
'back': 'demoMenu'
});
};
});
share/js/dochazka-www/drowselect-init.js view on Meta::CPAN
return function () {
target.push('privHistoryDrowselect', {
'name': 'privHistoryDrowselect',
'type': 'drowselect',
'menuText': 'privHistoryDrowselect',
'title': 'Status history - edit',
'preamble': null,
'aclProfile': 'admin',
'entriesRead': [entries.ePnick, entries.pHeffective, entries.pHpriv],
'miniMenu': {
entries: ['privHistoryAddRecordAction', 'privHistoryDeleteAction']
}
});
target.push('schedHistoryDrowselect', {
'name': 'schedHistoryDrowselect',
'type': 'drowselect',
'menuText': 'schedHistoryDrowselect',
'title': 'Schedule history',
'preamble': null,
'aclProfile': 'inactive',
'entriesRead': [entries.pHeffective, entries.sDid, entries.sDcode],
'miniMenu': {
entries: ['actionSchedLookup', 'schedHistoryAddRecordAction', 'schedHistoryDeleteAction'],
}
});
target.push('selectActivity', {
'name': 'selectActivity',
'type': 'drowselect',
'menuText': 'Select activity',
'title': 'Select activity',
'preamble': null,
'aclProfile': 'active',
'entriesRead': [entries.acTcode, entries.acTaid, entries.acTdesc],
'submitAction': 'selectActivityGo',
'miniMenu': {
entries: [],
}
});
target.push('viewIntervalsDrowselect', {
'name': 'viewIntervalsDrowselect',
'type': 'drowselect',
'menuText': 'View',
'title': 'Intervals in date',
'preamble': null,
'aclProfile': 'passerby',
'entriesRead': [
entries.iNdate, entries.iNtimerange, entries.iNiid, entries.acTcode,
entries.iNshortDesc,
],
'miniMenu': {
entries: ['createSingleIntFixedDay', 'updateSingleInt', 'deleteSingleInt'],
}
}); // viewIntervalsDrowselect
target.push('viewLocksDrowselect', {
'name': 'viewLocksDrowselect',
'type': 'drowselect',
'menuText': 'View',
'title': 'Lock list',
'preamble': null,
'aclProfile': 'passerby',
'entriesRead': [
entries.lOintvl, entries.lOlid,
],
'miniMenu': {
entries: ['deleteLock'],
}
}); // viewLocksDrowselect
};
});
share/js/dochazka-www/dtable-init.js view on Meta::CPAN
return function () {
target.push('privHistoryDtable', {
'name': 'privHistoryDtable',
'type': 'dtable',
'menuText': 'Status history',
'title': 'Status history',
'preamble': null,
'aclProfile': 'passerby',
'entriesRead': [entries.ePnick, entries.pHeffective, entries.pHpriv],
'miniMenu': {
entries: ['actionPrivHistoryEdit']
}
});
};
});
share/js/dochazka-www/int-lib.js view on Meta::CPAN
);
} else if (st.code === "DISPATCH_FILLUP_NO_INTERVALS_CREATED") {
coreLib.displayResult("The dates in question already have 100% schedule fulfillment");
} else {
coreLib.displayError(st.text);
}
};
ajax(rest, sc);
},
createSingleIntMenuItem = function (obj) {
stack.push('createSingleInt');
},
createSingleIntSave = function (obj) {
var caller = stack.getTarget().name,
cu = currentUser('obj'),
rest,
sc = function (st) {
if (caller === 'createSingleIntFixedDay') {
stack.unwindToTarget('viewIntervalsAction');
share/js/dochazka-www/int-lib.js view on Meta::CPAN
}
r += "</pre><br>";
return r;
}
;
// here is where we define methods implementing the various
// interval-related actions (see daction-start.js)
return {
createMultipleIntSave: createMultipleIntSave,
createSingleIntMenuItem: createSingleIntMenuItem,
createSingleIntSave: createSingleIntSave,
deleteSingleInt: deleteSingleInt,
vetDayList: vetDayList,
vetDayRange: vetDayRange,
updateSingleIntSave: updateSingleIntSave,
viewIntervalsAction: viewIntervalsAction,
viewIntervalsMultiDayCallback: viewIntervalsMultiDayCallback,
viewIntervalsMultiDayCallbackRaw: viewIntervalsMultiDayCallbackRaw,
};
share/js/dochazka-www/sched-history-lib.js view on Meta::CPAN
// success callback
sc = function (st) {
if (st.code === 'DOCHAZKA_CUD_OK') {
console.log("Payload is", st.payload);
stack.unwindToTarget("actionSchedHistory");
}
},
fc = function (st) {
lib.displayError(st.payload.message);
if (st.payload.code === '404') {
// go back to miniMenu listener
$('input[name="sel"]').val('').focus();
}
};
ajax(rest, sc, fc);
// start.drowselectListen();
},
schedHistoryDeleteAction = function () {
var shid,
set = lib.drowselectState.set,
share/js/dochazka-www/target-init.js view on Meta::CPAN
// populate target objects
initRoundTwo('dform');
initRoundTwo('dmenu');
initRoundTwo('dcallback');
initRoundTwo('dbrowser');
initRoundTwo('dnotice');
initRoundTwo('dtable');
initRoundTwo('drowselect');
stack.push('mainMenu');
populateContinue(populateArray);
};
return function () {
// round one - set up the targets
console.log("dochazka-www/target-init.js: round one");
dactionInitRoundOne();
dcallbackInitRoundOne();
dformInitRoundOne();
share/js/dochazka-www/test.js view on Meta::CPAN
'QUnit',
'app/tests/dummy',
'app/tests/01-users',
'app/tests/main-menu',
'app/tests/main-empl',
'app/tests/main-sched',
], function (
QUnit,
dummyTests,
createTestingUsers,
mainMenuTests,
mainEmplTests,
mainSchedTests,
) {
QUnit.module("dochazka-www");
dummyTests();
createTestingUsers();
mainMenuTests();
mainEmplTests();
mainSchedTests();
});
share/js/dochazka-www/tests/01-users.js view on Meta::CPAN
QUnit.test(test_desc, function (assert) {
console.log('***TEST*** ' + prefix + test_desc);
var done = assert.async(6);
assert.expect(25);
login({"nam": "root", "pwd": "immutable"});
setTimeout(function () {
ct.login(assert, "root", "admin");
done();
}, 1000);
setTimeout(function () {
ct.mainMenu(assert);
done();
}, 2000);
setTimeout(function () {
// create the employees
ct.employeeCreate(assert, "active");
ct.employeeCreate(assert, "inactive");
done();
}, 2400);
setTimeout(function () {
// add privhistory records
share/js/dochazka-www/tests/ldap.js view on Meta::CPAN
return function () {
test_desc = 'LDAP lookup - success';
QUnit.test(test_desc, function (assert) {
console.log('***TEST*** ' + prefix + test_desc);
var done = assert.async(4);
login({"nam": "root", "pwd": "immutable"});
setTimeout(function () {
ct.login(assert, "root", "admin");
ct.mainMenuToMainEmpl(assert);
ct.mainEmplToLdapLookup(assert);
ct.submitLdapLookup(assert, 'ncutler');
done();
}, 1000);
setTimeout(function () {
var ldapDochazka;
ct.stack(
assert,
4,
'Displaying LDAP employee after successful LDAP lookup',
share/js/dochazka-www/tests/ldap.js view on Meta::CPAN
ldapDochazka === "YES" || ldapDochazka === "NO",
"Answer to whether ncutler is in Dochazka (" + ldapDochazka + ") makes sense",
);
assert.ok(true, "*** REACHED Employee LDAP lookup success");
ct.contains(
assert,
$('#mainarea').html(),
"#mainarea html",
"0. LDAP sync",
);
assert.ok(true, "*** REACHED miniMenu contains 0. LDAP sync");
// choose '0' for ldapSync
$('input[name="sel"]').val('0');
$('input[name="sel"]').focus();
start.mmKeyListener($.Event("keydown", {keyCode: 13}));
assert.ok(true, "*** REACHED pressed 0 for LDAP sync");
done();
}, 3000);
setTimeout(function () {
var ldapDochazka = $('#LDAPdochazka').text();
ct.stack(
share/js/dochazka-www/tests/ldap.js view on Meta::CPAN
}, 5500);
});
test_desc = 'LDAP lookup - failure';
QUnit.test(test_desc, function (assert) {
console.log('***TEST*** ' + prefix + test_desc);
var done = assert.async(4);
login({"nam": "root", "pwd": "immutable"});
setTimeout(function () {
ct.login(assert, "root", "admin");
ct.mainMenuToMainEmpl(assert);
ct.mainEmplToLdapLookup(assert);
ct.submitLdapLookup(assert, 'NONEXISTENTfoobarbazblatFISHBEAR');
done();
}, 1000);
setTimeout(function () {
ct.stack(
assert,
3,
'failed LDAP lookup',
'dform',
share/js/dochazka-www/tests/main-empl.js view on Meta::CPAN
QUnit.test(test_desc, function (assert) {
var done = assert.async(4),
fullProfile;
console.log("***TEST*** " + prefix + test_desc);
login({"nam": "demo", "pwd": "demo"});
setTimeout(function() {
ct.login(assert, "demo", "passerby");
done();
}, 1500);
setTimeout(function () {
ct.mainMenu(assert);
// assert.ok(true, "Employee profile cache: " + QUnit.dump.parse(appCaches.profileCache));
assert.ok(appCaches.profileCacheLength() > 0, "Employee profile cache populated");
fullProfile = appCaches.getProfileByNick('demo');
assert.ok("emp" in fullProfile, "Employee profile cache populated with an employee");
assert.strictEqual(
fullProfile.emp.nick,
"demo",
"Employee profile cache populated with employee \"demo\""
);
assert.ok(true, 'select 1 ("Profile") in mainMenu as demo');
$('input[name="sel"]').val('1');
$('input[name="sel"]').focus();
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
// no AJAX call is initiated, because the profile is already in the cache
// ct.ajaxCallInitiated(assert);
done();
}, 2000);
setTimeout(function() {
// assert.ok(true, $("#mainarea").html());
ct.mainareaForm(assert, 'empProfile');
share/js/dochazka-www/tests/main-empl.js view on Meta::CPAN
QUnit.test(test_desc, function (assert) {
console.log('***TEST*** ' + prefix + test_desc);
var done = assert.async(5);
login({"nam": "root", "pwd": "immutable"});
setTimeout(function () {
ct.login(assert, "root", "admin");
done();
}, 1500);
setTimeout(function () {
var sel;
ct.mainMenu(assert);
ct.mainMenuToMainAdmin(assert);
ct.mainAdminToSearchEmployee(assert);
// enter search term into form
$('#searchEmployee input[name="entry0"]').val('inactive');
sel = ct.getMenuEntry(assert, $('#minimenu').html(), 'Search');
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
start.mmKeyListener($.Event("keydown", {keyCode: 13}));
ct.log(assert, "*** REACHED initiated search for Dochazka employee inactive");
done();
}, 2000);
setTimeout(function () {
var htmlbuf = $("#mainarea").html();
ct.log(assert, htmlbuf);
ct.stack(
share/js/dochazka-www/tests/main-empl.js view on Meta::CPAN
$('#ePnick').text(),
"inactive",
"Dochazka employee search succeeded - nick inactive displayed",
);
ct.contains(
assert,
$('#minimenu').html(),
"#minimenu html",
". LDAP sync",
);
assert.ok(true, "*** REACHED miniMenu contains substring '. LDAP sync'");
// // choose '0' for ldapSync
// $('input[name="sel"]').val('0');
// $('input[name="sel"]').focus();
// start.mmKeyListener($.Event("keydown", {keyCode: 13}));
// assert.ok(true, "*** REACHED pressed 0 for LDAP sync");
done();
}, 3000);
setTimeout(function () {
// ct.contains(
// assert,
share/js/dochazka-www/tests/main-empl.js view on Meta::CPAN
console.log('***TEST*** ' + prefix + test_desc);
var done = assert.async(10);
login({"nam": "root", "pwd": "immutable"});
setTimeout(function () {
ct.login(assert, "root", "admin");
done();
}, 1500);
setTimeout(function () {
var mainarea,
sel;
ct.mainMenu(assert);
assert.strictEqual($('#userbox').text(), 'Employee: root ADMIN');
ct.mainareaForm(assert, 'mainMenu');
sel = ct.getMenuEntry(assert, $('#mainarea').html(), 'Masquerade');
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
ct.stack(assert, 2, 'navigating from mainMenu to searchEmployee', 'dform', 'searchEmployee');
mainarea = $('#mainarea').html();
ct.contains(assert, mainarea, "#mainarea", "Search Dochazka employees");
assert.ok(true, "*** REACHED searchEmployee dform");
done();
}, 2000);
setTimeout(function () {
var minimenu,
sel;
// enter a search string
$('input[id="sEnick"]').val('act%');
assert.strictEqual($('input[id="sEnick"]').val(), 'act%', "Search string entered into form");
minimenu = $('#minimenu').html();
ct.contains(assert, minimenu, "searchEmployee miniMenu", ". Search");
sel = ct.getMenuEntry(assert, minimenu, 'Search')
ct.log(assert, "searchEmployee miniMenu contains Search as selection " + sel);
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
done();
}, 2500);
setTimeout(function () {
var mainarea,
minimenu,
sel;
ct.stack(assert, 3, 'browsing results of successful Dochazka employee search',
'dbrowser', 'masqueradeCandidatesBrowser');
assert.ok(true, "*** REACHED masqueradeCandidatesBrowser dform");
mainarea = $('#mainarea').html();
minimenu = $('#minimenu').html();
ct.contains(assert, mainarea, "Masquerade candidates browser", 'Masquerade candidates');
ct.contains(assert, minimenu, "Masquerade selection in miniMenu", ". Masquerade");
assert.ok(true, "*** REACHED Masquerade selection in masqueradeCandidatesBrowser miniMenu");
sel = ct.getMenuEntry(assert, minimenu, 'Masquerade');
assert.ok(true, "masqueradeCandidatesBrowser miniMenu contains Masquerade as selection " + sel);
// select Masquerade (first time - begin)
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
ct.stack(assert, 1, 'selected Masquerade in masqueradeCandidatesBrowser', 'dmenu', 'mainMenu');
assert.strictEqual($('#userbox').text(), '!!! Employee: active (MASQUERADE) !!!');
assert.ok(true, "*** REACHED masquerading as employee \"active\"");
done();
}, 3000);
setTimeout(function () {
ct.mainMenuSelectEmpProfile(assert);
done();
}, 3500);
setTimeout(function () {
var htmlbuf,
sel;
// mainMenu, myProfileAction, empProfile
ct.stack(assert, 3, 'navigating from mainMenu to empProfile', 'dform', 'empProfile');
ct.mainareaForm(assert, 'empProfile');
ct.contains(assert, $('#mainarea').html(), "#mainarea", "Employee profile");
ct.log(assert, "*** REACHED empProfile dform");
// Whatever the supervisor is, delete it
sel = ct.getMenuEntry(assert, $('#minimenu').html(), "Remove supervisor");
assert.ok(true, "Selection is " + sel);
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
// mainMenu, myProfileAction, empProfile, searchEmployee
ct.stack(
assert,
4,
'selected Delete supervisor in empProfile',
'dform',
'empProfileSetSuperConfirm'
);
htmlbuf = $("#mainarea").html(),
ct.contains(
assert,
htmlbuf,
"#mainarea html",
"Set employee supervisor - confirmation",
);
ct.mainareaForm(assert, "empProfileSetSuperConfirm");
sel = ct.getMenuEntry(assert, $('#minimenu').html(), 'Yes, I really do');
assert.ok(true, "Selection is " + sel);
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
done();
}, 4000);
setTimeout(function () {
var sel;
ct.stack(
share/js/dochazka-www/tests/main-empl.js view on Meta::CPAN
'empProfile'
);
ct.log(assert, $('#mainarea').html());
ct.contains(
assert,
$('#ePsuperNick').text(),
"#ePsuperNick text",
"(none)",
);
ct.log(assert, "*** REACHED supervisor deleted; no supervisor is set");
sel = ct.getMenuEntry(assert, $('#minimenu').html(), "Set supervisor");
assert.ok(true, "Selection is " + sel);
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
// mainMenu, myProfileAction, empProfile, searchEmployee
ct.stack(assert, 4, 'selected Set supervisor in empProfile', 'dform', 'searchEmployee');
// enter search term into form
$('#searchEmployee input[name="entry0"]').val('inactive');
sel = ct.getMenuEntry(assert, $('#minimenu').html(), 'Search');
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
start.mmKeyListener($.Event("keydown", {keyCode: 13}));
assert.ok(true, "*** REACHED initiated search for Dochazka employee inactive");
done();
}, 4500);
setTimeout(function () {
var htmlbuf,
sel;
ct.stack(
share/js/dochazka-www/tests/main-empl.js view on Meta::CPAN
$('#ePnick').text(),
"inactive",
"Dochazka employee search succeeded - nick inactive displayed",
);
ct.contains(
assert,
$('#minimenu').html(),
"#minimenu html",
". Set supervisor",
);
assert.ok(true, "*** REACHED miniMenu contains substring '. Set supervisor'");
sel = ct.getMenuEntry(assert, $('#minimenu').html(), 'Set supervisor');
assert.ok(true, "Selection is " + sel);
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
ct.stack(
assert,
6,
'selected Set supervisor in setSupervisorBrowser',
'dform',
'empProfileSetSuperConfirm'
);
htmlbuf = $("#mainarea").html(),
ct.contains(
assert,
htmlbuf,
"#mainarea html",
"Set employee supervisor - confirmation",
);
ct.mainareaForm(assert, "empProfileSetSuperConfirm");
sel = ct.getMenuEntry(assert, $('#minimenu').html(), 'Yes, I really do');
assert.ok(true, "Selection is " + sel);
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
done();
}, 5000);
setTimeout(function () {
var sel;
ct.stack(
share/js/dochazka-www/tests/main-empl.js view on Meta::CPAN
"inactive",
);
ct.log(assert, "*** REACHED supervisor set to inactive");
$('input[name="sel"]').val('x');
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
ct.stack(
assert,
1,
'back to mainMenu after setting supervisor',
'dmenu',
'mainMenu'
);
// turn off masquerade
sel = ct.getMenuEntry(assert, $('#mainarea').html(), 'Masquerade');
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
assert.strictEqual($('#userbox').text(), 'Employee: root ADMIN');
loggout();
done();
}, 5500);
setTimeout(function () {
ct.loggout(assert);
share/js/dochazka-www/tests/main-menu.js view on Meta::CPAN
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// *************************************************************************
//
// app/tests/main-menu.js
//
// Tests exercising the "mainMenu" dmenu
//
"use strict";
define ([
'QUnit',
'jquery',
'app/canned-tests',
'lib',
'login',
'loggout',
share/js/dochazka-www/tests/main-menu.js view on Meta::CPAN
var done = assert.async(3),
mainarea,
htmlbuf,
cu;
login({"nam": "root", "pwd": "immutable"});
setTimeout(function () {
ct.login(assert, "root", "admin");
done();
}, 1000);
setTimeout(function () {
ct.mainMenu(assert);
loggout();
done();
}, 1500);
setTimeout(function () {
ct.loggout(assert);
done();
}, 2000);
});
test_desc = 'masquerade as employee "active"';
share/js/dochazka-www/tests/main-menu.js view on Meta::CPAN
htmlbuf,
sel,
cu;
assert.expect(66);
login({"nam": "root", "pwd": "immutable"});
setTimeout(function () {
ct.login(assert, "root", "admin");
done();
}, 1000);
setTimeout(function () {
ct.mainMenu(assert);
assert.strictEqual($('#userbox').text(), 'Employee: root ADMIN');
ct.mainareaForm(assert, 'mainMenu');
sel = ct.getMenuEntry(assert, $('#mainarea').html(), 'Masquerade');
if (! coreLib.isInteger(sel)) {
console.log("BAILING OUT");
assert.ok(false, "BAILING OUT");
done();
}
console.log("Main menu contains Masquerade as selection " + sel);
assert.ok(true, "Main menu contains Masquerade as selection " + sel);
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
ct.stack(assert, 2, 'navigating from mainMenu to searchEmployee', 'dform', 'searchEmployee');
mainarea = $('#mainarea').html();
ct.contains(assert, mainarea, "#mainarea", "Search Dochazka employees");
assert.ok(true, "*** REACHED searchEmployee dform");
done();
}, 2000);
setTimeout(function () {
// enter a search string
$('input[id="sEnick"]').val('act%');
assert.strictEqual($('input[id="sEnick"]').val(), 'act%', "Search string entered into form");
minimenu = $('#minimenu').html();
ct.contains(assert, minimenu, "searchEmployee miniMenu", ". Search");
sel = ct.getMenuEntry(assert, minimenu, 'Search')
ct.log(assert, "searchEmployee miniMenu contains Search as selection " + sel);
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
}, 2500);
setTimeout(function () {
ct.stack(assert, 3, 'browsing results of successful Dochazka employee search',
'dbrowser', 'masqueradeCandidatesBrowser');
assert.ok(true, "*** REACHED masqueradeCandidatesBrowser dform");
mainarea = $('#mainarea').html();
minimenu = $('#minimenu').html();
ct.contains(assert, mainarea, "Masquerade candidates browser", 'Masquerade candidates');
ct.contains(assert, minimenu, "Masquerade selection in miniMenu", ". Masquerade");
assert.ok(true, "*** REACHED Masquerade selection in masqueradeCandidatesBrowser miniMenu");
sel = ct.getMenuEntry(assert, minimenu, 'Masquerade');
assert.ok(true, "masqueradeCandidatesBrowser miniMenu contains Masquerade as selection " + sel);
// select Masquerade (first time - begin)
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
ct.stack(assert, 1, 'selected Masquerade in masqueradeCandidatesBrowser', 'dmenu', 'mainMenu');
assert.strictEqual($('#userbox').text(), '!!! Employee: active (MASQUERADE) !!!');
assert.ok(true, "*** REACHED masquerading as employee \"active\"");
done();
}, 3000);
setTimeout(function () {
ct.mainareaForm(assert, 'mainMenu');
htmlbuf = $('#mainarea').html();
sel = ct.getMenuEntry(assert, htmlbuf, 'Masquerade');
assert.ok(true, "Main menu contains Masquerade as selection " + sel);
// select Masqerade (second time - end)
$('input[name="sel"]').val(sel);
$('input[name="sel"]').focus();
// press ENTER -> submit the form
$('input[name="sel"]').trigger($.Event("keydown", {keyCode: 13}));
assert.strictEqual($('#userbox').text(), 'Employee: root ADMIN');
loggout();
done();
}, 3500);
share/js/dochazka-www/tests/main-sched.js view on Meta::CPAN
test_desc = 'schedule menu appears';
QUnit.test(test_desc, function (assert) {
console.log('***TEST*** ' + prefix + test_desc);
var done = assert.async(3);
login({"nam": "root", "pwd": "immutable"});
setTimeout(function () {
ct.login(assert, "root", "admin");
done();
}, 1000);
setTimeout(function () {
ct.mainMenu(assert);
ct.mainMenuToMainSched(assert);
loggout();
done();
}, 1500);
setTimeout(function () {
ct.loggout(assert);
done();
}, 2200);
});
test_desc = 'schedule lookup - bogus ID';
QUnit.test(test_desc, function (assert) {
console.log('***TEST*** ' + prefix + test_desc);
var done = assert.async(4);
login({"nam": "root", "pwd": "immutable"});
setTimeout(function () {
ct.login(assert, "root", "admin");
done();
}, 1000);
setTimeout(function () {
var entry1;
ct.mainMenu(assert);
ct.mainMenuToMainSched(assert);
ct.mainSchedToSchedLookup(assert);
entry1 = $('form#schedLookup input[name="entry1"]');
entry1.val('BOGOSITYWHELP');
assert.strictEqual(entry1.val(), 'BOGOSITYWHELP', "Form filled out with bogus data");
$('input[name="sel"]').val('1');
$('input[name="sel"]').focus();
start.mmKeyListener($.Event("keydown", {keyCode: 13}));
assert.ok(true, "*** REACHED schedLookup form submitted");
ct.ajaxCallInitiated(assert);
done();