0

I have a Sites page(1) that takes either 1 or 2 parameters that directs the user to one of two pages based on a query using the first parameter. If the query returns a record with one value, a form(2) loads to accept their input; otherwise, I redirect to a Warning/Error page(3).

There is an action on page 1 that runs the query, so the first parameter needs to exist; the second is optional.

I create the necessary records in my test before I instantiate the controller, but I can't get past the following error: System.NullPointerException: Argument cannot be null.

Here's the controller:

global class InventorySubmissionController {

private ApexPages.StandardController sc;

public final Portal_Inventory__c submission {get;set;}
public Inventory_Shipment__c inventory {get;set;} // the Patient Inventory
public Boolean bIdFound {get;set;}
public Boolean bDisplaySubmissionError {get;set;}
public Boolean bDisplayInputArea {get;set;}
public Boolean bSubmissionComplete {get;set;}

private String piId = '';
private String sms = '';

public InventorySubmissionController() {

    bIdFound = false;
    // Are we displaying an existing submission, or creating a new one?
    try {
        bIdFound = (ApexPages.currentPage().getParameters().containsKey('pi') &&
                            ApexPages.currentPage().getParameters().get('pi').length()>0);
        if(bIdFound) {
            // Expected result
            piId = ApexPages.currentPage().getParameters().get('pi');
            // Determine whether this inventory has already been submitted
            validateSubmission();

            // Create an Inventory Submission record with the Inventory Id, recordtype Id and the associated dates
            // ** Note: We cannot create or link to a Patient Inventory at this time, as the Portal User does not have
            //      access to them (specifically due to the relationship to Account and Contact) **
            submission = new Portal_Inventory__c(
                PatientInventory__c = piId,
                Date_Received__c = Date.today());

            // Retrieve the Delivery Date by way of the Delivery Schedule
            Delivery_Schedule__c ds = getActiveDeliverySchedule(piId);
            submission.Delivery_Date__c = getNextDeliveryDate(ds, Date.today());
            // Set dataSource (initially)
            submission.Data_Source__c = 'Email Portal';             
            // Retrieve the Inventory recordtype also by way of the Delivery Schedule
            Boolean isPureFlow = Utils.isPureFlow(ds.Contact__r.PureFlow_SL_Start_Date__c, ds.Contact__r.PureFlow_SL_End_Date__c);
            submission.Inventory_RecordType__c = (isPureFlow) ? 'PureFlow' : 'Bags Only';
            submission.Inventory_RTId__c = Utils.GetRecordTypeId('Inventory_Shipment__c', submission.Inventory_RecordType__c);                          
        }
    } catch (QueryException e) {
        System.debug('An error occurred querying Inventory Submission: ' + e.getMessage());
        submission = new Portal_Inventory__c();
    }               

    // We should have the id of a shell inventory with the 'pi' page parameter
    if(bIdFound) {

        submission.PatientInventory__c = ApexPages.currentPage().getParameters().get('pi');

    } else {
        System.debug('[55] No parameter found (pi) ');          
    }
    // If this was submitted from an SMS reminder, we should be able to retrieve the 'sms' parameter
    if(ApexPages.currentPage().getParameters().containsKey('sms') &&
        ApexPages.currentPage().getParameters().get('sms').length()>0) {

            submission.sms__c = (ApexPages.currentPage().getParameters().get('sms') == 'true') ? true : false;
            submission.Data_Source__c = 'SMS Portal';               
    }

    sc = new ApexPages.StandardController(submission);
    // Display the form/input area
    bDisplayInputArea = (validateSubmission() <> null) ? true : false;

    NxDiagnostics.popAll();
}

In the test, I create the supporting records (Contact, Delivery Schedule, Patient Inventory), Create the page reference for the Welcome page (1), put the 'pi' parameter in place with the Patient Inventory.Id, set it as the Test.setCurrentPage, and then instantiate the controller... which results in the NullPointerException. Do I need to create PageReferences for the other pages as well? I'm not testing anything from them, yet.

  • 1
    The line number that is reported with the NullPointerException will tell you which source code line to look at. If that doesn't allow you you to work out what is wrong you can add debugging as described in How do I start to debug my own Apex code?. – Keith C Jun 18 '14 at 19:24
  • The line that is referenced (that I neglected to include, sorry) is "sc = new ApexPages.StandardController(submission);" and the debug returns '[55] No parameter found (pi)'. In my test I have a line to add the pi parameter before I create the controller. PageReference pageRef = Page.InventoryPortalWelcome; ApexPages.currentPage().getParameters().put('pi',pi.Id); Test.setCurrentPage(pageRef); InventorySubmissionController controller = new InventorySubmissionController(); – Duncan Stewart Jun 18 '14 at 20:03
  • I've only seen the ApexPages.StandardController used in the pattern that the documentation identifies e.g. Building a Controller Extension where it is constructor argument. Is there some reason your are not doing that? – Keith C Jun 18 '14 at 20:13
  • I wouldn't expect your change to make a difference but if you have it working now that is good. – Keith C Jun 18 '14 at 20:34
  • If that fixed the issue, please add it as the answer so that other with the same problem can benefit. – Richard N Jun 18 '14 at 20:37
1

[Note - I took Keith's suggestion and moved my comment here; apologies to him for making his comments appear out of context - DS]

Okay, what I have discovered is that by changing the order of things in my test, the error goes away.

PageReference pageRef = Page.InventoryPortalWelcome;
Test.setCurrentPage(pageRef);
ApexPages.currentPage().getParameters().put('pi',pi.Id);

// Instantiate the controller, which implements the page
InventorySubmissionController controller = new InventorySubmissionController();

When I assigned the parameter before Test.setCurrentPage(), it apparently didn't take; this sequence ^ does work [PageReference > setCurrentPage() > getParameters()], and instantiating the controller then works correctly, and I can verify/assert that the correct new page reference was provided on save(). Thanks for your help on this, Keith!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.