RSS

Monthly Archives: August 2014

ASP.Net MVC Unit Test Controller with HttpContext (ControllerContext)

Often time, I have MVC Controller that access ControllerContext, so my unit test for the controller will have to mock this.

I create 2 files: MockHttpSession.cs and Helpers.cs

MockHttpSession.cs is just mocking HttpSession by create a Dictionary to store object. Moq framework that I use won’t be able to mock HttpSession, so I have to create my own.

Helpers.cs has methods to mock ControllerContext, HttpContext, HttpResponseBase, HttpRequestBase, ClaimsPrincipal, and ClaimsIdentity. You can pass in custom object in the parameter, otherwise, it will use the default.

MockHttpSession.cs

class MockHttpSession : HttpSessionStateBase
{
    readonly Dictionary<string, object> _SessionDictionary = new Dictionary<string, object>();
    public override object this[string name]
    {
        get
        {
            object obj = null;
            _SessionDictionary.TryGetValue(name, out obj);
            return obj;
        }
        set { _SessionDictionary[name] = value; }
    }
}

Helpers.cs

class Helpers
{
    internal static Mock<ControllerContext> GetMvcControllerContextMock(HttpContextBase httpContextBase = null)
    {
        // Set default HttpContextBase
        if (httpContextBase == null)
            httpContextBase = GetHttpContextMock().Object;

        var _controllerContextMock = new Mock<ControllerContext>();

        // Add default HttpContextBase
        _controllerContextMock.Setup(x => x.HttpContext).Returns(httpContextBase);

        return _controllerContextMock;
    }

    internal static Mock<HttpContextBase> GetHttpContextMock(ClaimsPrincipal claimsPrincipal = null, ClaimsIdentity claimsIdentity = null, HttpResponseBase httpResponseBase = null, HttpRequestBase httpRequestBase = null)
    {
        var _httpContextMock = new Mock<HttpContextBase>();

        // Set default ClaimsIdentity
        if (claimsIdentity == null)
            claimsIdentity = GetClaimsIdentityMock().Object;

        // Set default ClaimsPrincipal
        if (claimsPrincipal == null)
            claimsPrincipal = GetClaimsPrincipalMock(claimsIdentity).Object;

        // Set default HttpContextBase
        if (httpResponseBase == null)
            httpResponseBase = GetHttpResponseBaseMock().Object;
        if (httpRequestBase == null)
            httpRequestBase = GetHttpRequestBaseMock().Object;

        // Add Session object to HttpContext
        var _session = new MockHttpSession();

        // Add ClaimsPrincipal to HttpContext.User
        _httpContextMock.Setup(x => x.User).Returns(claimsPrincipal);

        // Add UserClaims to HttpContext.Session
        _httpContextMock.Setup(x => x.Session).Returns(_session);

        // Add HttpContextBase object to HttpContext
        _httpContextMock.Setup(x => x.Response).Returns(httpResponseBase);

        _httpContextMock.Setup(x => x.Request).Returns(httpRequestBase);
        return _httpContextMock;
    }

    internal static Mock<HttpResponseBase> GetHttpResponseBaseMock(int? statusCode = 0)
    {
        var _httpResponseMock = new Mock<HttpResponseBase>();

        // Set default StatusCode
        if (statusCode == null)
            statusCode = (int) HttpStatusCode.OK;

        // Add StatusCode to HttpResponse.StatusCode
        _httpResponseMock.Setup(x => x.StatusCode).Returns(statusCode.Value);

        return _httpResponseMock;
    }

    internal static Mock<HttpRequestBase> GetHttpRequestBaseMock()
    {
        var _httpRequestMock = new Mock<HttpRequestBase>();

        // Add StatusCode to HttpResponse.StatusCode
        _httpRequestMock.Setup(x => x.QueryString).Returns(new NameValueCollection());
        _httpRequestMock.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(string.Empty);
        _httpRequestMock.Setup(x => x.PathInfo).Returns(string.Empty);
        _httpRequestMock.Setup(x => x.Url).Returns(new Uri("http://site/"));
        return _httpRequestMock;
    }

    internal static Mock<ClaimsPrincipal> GetClaimsPrincipalMock(ClaimsIdentity identity = null)
    {
        // Set default ClaimsIdentity
        if (identity == null)
            identity = GetClaimsIdentityMock().Object;

        var _principalMock = new Mock<ClaimsPrincipal>();
        _principalMock.Setup(x => x.Identity).Returns(identity);

        return _principalMock;
    }

    internal static Mock<ClaimsIdentity> GetClaimsIdentityMock(List<Claim> claimCollection = null, bool isAuthenticated = true)
    {
        // Set default ClaimCollection
        if (claimCollection == null)
        {
            claimCollection = new List<Claim>();
            //claimCollection.AddRange(Models.ValidClaims);
        }

        var _identityMock = new Mock<ClaimsIdentity>();
        _identityMock.Setup(x => x.IsAuthenticated).Returns(isAuthenticated);
        _identityMock.Setup(x => x.Claims).Returns(claimCollection);

        return _identityMock;
    }
}

Usage

[TestMethod]
public void Index_Get_ViewNotNull()
{
    // Arrange
    var _controller = new OrderController();
    _controller.ControllerContext = Helpers.GetMvcControllerContextMock(Helpers.GetHttpContextMock().Object).Object;

    // Act
    var _result = _controller.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(_result);
}

Version attow: ASP.Net MVC 5, Moq 4.1,

Advertisements
 
1 Comment

Posted by on August 15, 2014 in General

 

Tags: , ,

Events are Fired Multiple Times in jQuery Mobile

I have situation where some of my events (that attach to pageshow event, or click of a button event) run multiple times in jQuery Mobile.

Following is my code in most pages. I would attach event after a page is showed.

Well, because the nature of jQuery Mobile handles page (it will keep <div data-role="page"></div> of the first page your load), every time the page is loaded, this code will be run again and again which means the events get attached multiple times.. which means they will be fired multiple times once triggered.

$(document).on("pageshow", function() {
    // attach event here
    $("#btnSubmit").click(function() {
        // code to handle event here
    });
});

Solution is simple. Instead of using .on, I changed to .one. .one ensure that the code will only be run one time.

$(document).one("pageshow", function() {
    // attach event here
    $("#btnSubmit").click(function() {
        // code to handle event here
    });
});

Version attow: jQuery Mobile 1.3.2

 
Leave a comment

Posted by on August 14, 2014 in General

 

Tags: ,

How to Create Valid and Trusted SSL Certificate (Wildcard) for Development

For development purpose, sometime you need trusted SSL certificate that won’t give you certificate validation error. To avoid this problem, you can buy valid certificate from trusted CA. Another way is to create your own. This will guide you how to create trusted root certificate authority and self-signed certificate.

Tools

Following are required tools:

  • makecert.exe
  • pvk2pfx.exe

Both of these files can be found in your Microsoft SDKs folder, or try search in one of the following folder. If your machine is 32-bit, search under “Program Files (x86)” folder instead.

  • C:\Program Files\Microsoft SDKs\Windows\
  • C:\Program Files\Microsoft Visual Studio 8\
  • C:\Program Files\Microsoft Visual Studio 11.0\
  • C:\Program Files\Windows Kits\
  • C:\Program Files\Microsoft.NET\SDK\
  • C:\Program Files (x86)\Microsoft Visual Studio 9.0\
  • C:\Program Files (x86)\Microsoft Visual Studio 8\

Preparation

It’s a good idea to create a new folder and place all files in the new folder. When running the commands to create the certificates, run it under the new folder as well.

Root Certificate Authority

C:\DevCert> makecert.exe -r -n "CN=dev.root" -pe -sv dev.root.pvk -a sha1 -len 2048 -b 01/01/2014 -e 12/31/2200 -cy authority dev.root.cer
C:\DevCert> pvk2pfx.exe -pvk dev.root.pvk -spc dev.root.cer -pfx dev.root.pfx

You can change certificate name, valid to and valid from dates (-n “CN=dev.root”, -b 01/01/2014, -e 12/31/2200, respectively), to whatever you like.
You may be prompted to create a password. This is the password to your private key.

This command will generate 3 certificates:

  • dev.root.cer (certificate)
  • dev.root.pvk (private key)
  • dev.root.pfx (certificate containing private key)

Install “dev.root.cer” root certificate to the store (Computer Account), under “Trusted Root Certification Authorities” folder.

SSL Certificate

C:\DevCert> makecert.exe -iv dev.root.pvk -ic dev.root.cer -n "CN=dev.site" -pe -sv dev.site.pvk -a sha1 -len 2048 -b 01/01/2014 -e 12/31/2200 -sky exchange dev.site.cer -eku 1.3.6.1.5.5.7.3.1
C:\DevCert> pvk2pfx.exe -pvk dev.site.pvk -spc dev.site.cer -pfx dev.site.pfx

You can change certificate name, valid to and valid from dates (-n “CN=dev.site”, -b 01/01/2014, -e 12/31/2200, respectively), to whatever you like.
You may be prompted to create a password. This is the password to your private key.

This command will generate 3 certificates:

  • dev.site.cer (certificate)
  • dev.site.pvk (private key)
  • dev.site.pfx (certificate containing private key)

Wildcard Certificate

You can create a wilcard certificate by prepend “*” (asterisk) on certificate name, for example:

C:\DevCert> makecert.exe -iv dev.root.pvk -ic dev.root.cer -n "CN=*.dev.site" -pe -sv w.dev.site.pvk -a sha1 -len 2048 -b 01/01/2014 -e 12/31/2200 -sky exchange w.dev.site.cer -eku 1.3.6.1.5.5.7.3.1

Installation

In Certificate snap-in of Management Console (mmc):

  • For root CA certificate, “dev.root.cer” must be imported into “Trusted Root Certification Authorities” folder.
  • For regular (or wildcard) certificate, “dev.site.pfx” must be imported into “Personal” folder.

SSL / TLS Usage

To use certificate as SSL certificate, the CN name must match host name of the site. For example, if the site has host name “dev.site”, the certificate CN’s name must also be “dev.site”.

To use wildcard certificate in multiple sites as SSL certificate for the same IP address, it must have valid host name (ie, *.dev.site). With this approach, each site using the wildcard certificate must have different host name (ie, blog.dev.site and news.dev.site).

 
2 Comments

Posted by on August 13, 2014 in General

 

Tags: , , , ,

$(document).ready in jQuery Mobile?

Due to jQuery Mobile’s way of handling page transition (using Hijax to get pseudo page), $(document).ready is no longer a valid option. What’s the substitute?

$(document).on("pageshow", function() {
    // your code here
});

Version attow: jQuery Mobile 1.3.2

 
Leave a comment

Posted by on August 12, 2014 in General

 

Tags: ,

MongoDB Terminology Translation from RDBMS

RDBMS MongoDB
Database Database
Table Collection
Row Document
Index Index
Join Embedding & Linking

Source: 10gen’s Schema Design

Version attow: MongoDB 2.6

 
Leave a comment

Posted by on August 11, 2014 in General

 

Tags: , ,

Naming Convention Sample

Following is a sample of naming convention sample for HTML and CSS. Although this can be used for HTML and CSS, it’s best optimized for ASP.Net MVC project.

CSS Rules

  • All custom CSS rules go into <Project>\Content\<filename>.css
  • To avoid conflict, target by Class name is preferable than ID.
  • Don’t-fix-what’s-working philosophy: don’t style unless it’s necessary which means no gold-plating.

 

CSS Class Name

  • Application hierarchy structure should follow ASP.NET MVC namespace.
  • Class name is lower case dash-separated for each word.
  • Class name should be hierarchical according to application structure. This means when we look at the class name, we immediately know at what level the rule is applied to.
    • If the class targets a specific element in a View, class name should follow this convention:
      .stack247-<area>-<controller>-<view>-<description>

      • For example: .stack247-agent-prospect-details-input-box, .stack247-agent-prospect-details-hide-text
    • If the class targets elements in a Controller, class name should follow this convention:
      .stack247-<area>-<controller>-<description>

      • For example: .stack247-agent-prospect-input-box, .stack247-agent-prospect-hide-text
    • If the class targets application-wide View, class name should follow this convention:
      .stack247-<view>-<description>

      • For example: .stack247-details-input-box, .stack247-details-hide-text
    • If the class targets application-wide Controller, class name should follow this convention:
      .stack247-<controller>-<description>

      • For example: .stack247-prospect-input-box, .stack247-prospect-hide-text
    • If the class targets application-wide element, class name should follow this convention:
      .stack247-<description>

      • For example: .stack247-input-box, .stack247-hide-text
    • <description> can be the target element or a purpose but it should be very short.
  • When overriding framework CSS rules (jQuery Mobile, Kendo UI, etc), the specificity must be hierarchical according to application structure.
    • When overriding, the more specific, the better. More about CSS Specificity: http://css-tricks.com/specifics-on-css-specificity/
    • If the overriding rule targets a specific element in a View, specify class to only that element in the View:
      • For example: .stack247-agent-prospect-details .k-grid-header
    • If the overriding rule targets elements in a Controller, specify class to only elements in the Controller:
      • For example: .stack247-agent-prospect .k-grid-header
    • If the overriding rule targets elements in an Area, specify class to only elements in the Controller:
      • For example: .stack247-agent .k-grid-header
    • If the overriding rule targets application-wide element, specify class to those elements:
      • For example: .k-grid-header
  • Use your best judgment: if the CSS rule is re-usable across a View / Controller / Area or if it’s re-usable across the application, use class name and specificity that apply to targeted section.

 

HTML ID

Since CSS styles sometime target a specific HTML element by its ID, the following naming conventions apply to naming the HTML element ID.

  • HTML ID should be lower case of 3 letters (or less) of the element type + camelCase short description
    • For example: #divDashboardResult
  • The following are element type and its abbreviation:
    Element Abbreviation
    <div> div
    <input type=”textbox” /> txt
    <input type=”checkbox” /> cb
    <input type=”radio” /> rb
    <input type=”button” /> btn
    <span> spn
    <ul> ul
    <li> li
    <a> a
    <form> frm
    <table> tbl
    <thead> thd
    <tbody> tbd
    <th> th
    <td> td
    <tr> tr
 
Leave a comment

Posted by on August 4, 2014 in General

 

Tags: , ,

 
%d bloggers like this: