RSS

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,

 
Leave a 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).

 
Leave a comment

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: , ,

Is It Ethical to Monitor Your Employees?

In the early days of the Internet, it was easy to achieve anonymity when browsing around the web. The anonymity of the Internet played along with what users had enjoyed for many years, a privacy. Today, with the availability of social media sites all over the Internet, such as Facebook, Twitter and Pinterest, the anonymity has shifted away from the path of privacy. This shifting allow many companies to use social media to its selfish purpose of monitoring its employees. Companies begin to use social media as a mean to perform ‘additional’ background check. The step taken is too far and has crossed the boundary of individual’s privacy. But, when it comes to individual privacy and company’s policy to monitor its employees, the boundary is as thin as a strand of hair.

There are many reason a company needs to monitor its employees. Among them are security, intellectual property and trade secret protection, audit trail and usage / performance study. All these purposes will only benefit the company to increase its efficiency in running a business. In some cases, monitoring employees is indispensable, such as in security. Preventing outside intruders from attacking from inside is one of the main reason companies need to monitor its employees. Some of the steps in security monitoring are running a background software to check downloaded files, capturing employees’ browsing history and keeping history of connected devices. Security compromise can be caused by a slight and insignificant but careless action such as plugging in a USB drive into the company’s laptop or browsing to an unsecured or compromised web site. In this matter, companies have the rights to take necessary step to protect itself from any security threats.

Security threats come from all different directions but more dangerous threats often come from individual employees. To prevent this, companies require extensive background check, including secret clearance before they hire each employees. Some companies have been gone too far when performing ‘extensive’ background check by asking for access to employees’ social media sites such as Facebook or Twitter.

In the days where the Internet is an integral part of our daily life, it has become more difficult for us to achieve complete privacy. Although the nature of the Internet is anonymity, every time we use social media sites, we are voluntarily giving up our right to remain anonymous. Privacy is harder to come by without anonymity. We expose ourselves through comments, pictures and tweets we post every day and we allow ourselves to be discover-able, thus, giving up our privacy in return of virtual socialize world. It has never been easier to track and scout you in much details before and all are within the clicks of the mouse.

The wake of social media sites in a stronger follow-up of 1990’s Dot-com Bubble has pushed many companies to change its way of doing business. One of the biggest impact of this for companies is marketing and advertising. Companies leverage the power of social media with its more targeted advertising to grow and market their business. Many companies who are late in taking advantage of social media would be seeing decline in their business. Individuals have also reaped the benefit of social medias. It’s easier to keep in touch with your friends, share pictures and memory together and receive news from the other side of the world. Social medias have made it easier than ever before. However, this is still not a justification for a company to perform additional check on its potential employees by accessing their social media sites. Social media users still have their own privacy despite the openness of the Internet today. Giving up our anonymity doesn’t mean we also giving up our privacy and nobody should cross the line of our privacy for any reason. We as individual should draw a line and define the boundary between our privacy and everything else. For companies, it’s between our privacy and company’s monitoring policy. And that boundary is the workplace.

 
Leave a comment

Posted by on July 31, 2014 in General

 

Tags: , , , ,

 
Follow

Get every new post delivered to your Inbox.

Join 47 other followers

%d bloggers like this: