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?