I developed a slightly complex Viewlet to implement a fully dynamic user navigation. This user navigation pattern works without apparent problem and MVC design is attached as UserNavigationMVC.pdf for a high level preview of the design. However, I encountered an integration testing problem that I did not manage to resolve for the last few days. I need some pointers to understand what is going wrong. Here is the test:
function run(){
describe( “viewlets Suite”, function(){
beforeEach(function( currentSpec ){
// Setup as a new ColdBox request for this suite, VERY IMPORTANT. ELSE EVERYTHING LOOKS LIKE THE SAME REQUEST.
setup();
});
it( “index (called on navigation by default)”, function(){
var event = execute( event=“viewlets.index”, renderResults=true );
expect( prc.loginstatus ).toBeTrue();
expect( event.getValue( name=“sessionUserFirstName”, private=true ) ).toBe( “BAMBOO” );
expect( event.getValue( name=“sessionUserLastName”, private=true ) ).toBe( “TESTS” );
expect( event.getValue( name=“sessionUserUItheme”, private=true ) ).toBe( “black” );
expect( event.getValue( name=“sessionUserLocale”, private=true ) ).toBe( “en_SG” );
});
it( “sessionwrapper (called for navigation menu)”, function(){
//var content = event.getCollection().cbox_rendered_content;
var event = execute( event=“viewlets.sessionwrapper”, renderResults=true );
// expectations go here.
expect( false ).toBeTrue();
});
});
}
}
The results of the ViewletsTest.cfc are attached as TestRun.png. Here is the corresponding Viewlets.cfc handler for the sessionwrapper event in error.
I have also attached the complete Viewlets.cfc, the Sessionwrapper.cfm view, and the Foundation.cfm layout files in order to explain the Viewlet nesting.
function sessionwrapper( event, rc, prc ){
// This event calls the menu wrapper template customised in the user’s locale and language.
// Get the ID of the user authenticated for the current session
prc.sessionUserID = #listgetAt(getAuthUser(),1)#;
// Get the current session userID
// Always keep track of the current session userID to authorise access
// The default cursor structure passed by the authorizeUser method is (seqID=1,tabID=1,optID=1)
prc.sessionUserNavCursor = accessAuth.authorizeUser(prc.sessionUserID);
// Update the current user session navigation cursor with the parameters
// passed via URL to the request context.
// The default navigation cursor passed by the authorizeUser method is (seqID=1,tabID=1,optID=1)
// meaning the first app, the first module within the app, the first menu option
// within the module.
try {
// Based on the parameter values passed in the request context
prc.sessionUserNavCursor.seqID = rc.seqID;
prc.sessionUserNavCursor.tabID = rc.tabID;
prc.sessionUserNavCursor.optID = rc.optID;
} catch(NavigationParamError e) {
// Check the integrity of the navigation cursor
prc.errorMsg = “#e.message#”;
flash.put(“message”, “#prc.errorMsg#”);
// Channel the error message to the View for user display
//return sessionwrapper(event,rc,prc);
}
// Get the session user’s details that are needed to customise the user interface.
prc.sessionUserinfo_qData = userSVC.read(prc.sessionUserID);
prc.sessionUserFirstName = prc.sessionUserinfo_qData.getUserFirstName();
prc.sessionUserLastName = prc.sessionUserinfo_qData.getUserLastName();
prc.sessionUserUItheme = prc.sessionUserinfo_qData.getUserUItheme();
prc.sessionUserLocale = prc.sessionUserinfo_qData.getUserLocaleCD();
// retrieve user locale parameters
var structULocale = localeSVC.LocaleParameters(prc.sessionUserLocale);
prc.sessionUserLocaleData = structULocale;
// retrieve user session date and time parameters
var structUDatetime = localeSVC.displayDatetimeFormat(prc.sessionUserLocale);
prc.sessionUserDatetime = structUDatetime;
// Retrieve user interface colour theme
prc.structUItheme = buildViews.getUItheme(prc.sessionUserUItheme);
// Retrieve resource bundles for the user locale
prc.structRB = buildViews.getResourceBundles(prc.sessionUserlocale);
// Retrieve the translations for the user locale
prc.structTSL = buildViews.buildTranslations(prc.sessionUserLocale);
// Retrieve all applications accessible by the user
prc.AppsList = buildContext.getUserApplications(prc.sessionUserID);
// Retrieve the user authorised navigation array
prc.userNavArray = buildContext.getUserNavigationArray(prc.sessionUserID);
// Build navigation menu - Depends on the application navigation cursor (seqID)
// Navigation parameters will be passed to rc context
prc.structNav = buildNav.buildMenuOptions(prc.sessionUserID, prc.sessionUserNavCursor.seqID);
// render out content
//event.setView(view = “viewlets/index”, layout=“Foundation”);
//displays a black screen (UI theme = black) but passes the test
//event.setView(“viewlets/sessionwrapper”);
//displays a black screen (UI theme = black) but test results screen is blank…
//event.setView( view=“viewlets/sessionwrapper”, layout=“Foundation” );
//displays a black screen (UI theme = black) but passes the test
return renderView( “viewlets/sessionwrapper” );
// works fine but causes an error in the integration test
}
TestBox absolutely requires an event.setView(viewlets/something) to pass the test, while renderView() does the job for me instead but does not pass the test. Any idea?
UserNavigationMVC.pdf (190 KB)
Viewlets.cfc (6.05 KB)
sessionwrapper.cfm (18.1 KB)
Foundation.cfm (7.41 KB)