Moving Blog

As you have probably noticed, this blog has not been updated for a while. It doesn’t really fit my needs anymore so I created a new general blog to take over. The new address is:

http://andypike.wordpress.com

Feel free to update your links.

Cheers

Cathedral Builders

I just watched a very interesting video on YouTube about software development leadership which is on the Google Tech Talks Channel (here), it’s pretty long but worth a watch if that kind of thing is interesting to you. At the very end of the talk (at about 1:26:45) is an interesting story.

The story is about an Italian philosopher that was walking through a quarry a long time ago and came across a stone cutter. He asked the stone cutter “What are you doing?” to which the stone cutter replied “I’m cutting stone. I don’t like it but it’s the only job I could get”. So the philosopher moves on and asks the next guy he comes across the same question: “What are you doing?”. The second stone cutter replies “I’m earning a living. I’m putting a roof over my head and food on the table”. So the philosopher continues and asks a third stone cutter the same question “What are you doing?”. The last stone cutter said “I’m building a cathedral”.

In a software development team you want your developers to be Cathedral Builders not Stone Cutters. How do you know if a developer is a Cathedral Builder? The way to tell is what your developers do when there is something about the job that annoys them. If they complain about it they are stone cutters, if they ignore it they are earning a living but if they fix it then they are Cathedral Builders.

According to the presentation, you get Cathedral Builders by moving responsibility and decision-making to the lowest possible level which allows people to reach their full potential and become Cathedral Builders. It’s the individual that counts and allows them to use there own initiative. The leader’s job is to have the overall vision of the project and to guide the developers through it. If there is something that is annoying the developers, a good leader will help them fix it, not get in the way. You need to make your developers feel valued, help them to feel proud of the product they are making and you need to listen to their ideas. You need to create a culture of constant improvement.

I’m paraphrasing the presentation of course and propbably not doing it justice. So take a look.

SOA, Messages, DTOs and Mappers

OK, I’m currently in the middle of refactoring the current architecture. I’ve been reading about Messages, DTOs (Data Transport Objects) and SOA (Service Oriented Architecture). What I’ve been reading makes sense but I’m finding it hard to locate some really good examples of how it should be done. So I’m going to outline my current understanding and initial idea of what I’m going to do. Hopefully somebody with some experience in this field can give me a few pointers.

SOA

Service methods should be course grained which minimize round trips from the client. To my way of thinking a client could be remote and communicates with our services via web-services or a local web/windows application that calls services directly. So in our application, the client is our MonoRail web application where the controllers call the injected services directly. In a Service Oriented Architecture our services should model real world business processes rather than domain entities. I must admit that I sometimes find it hard to name services correctly so they aren’t named after domain entities, but I guess this will come with more experience with SOA.

DTOs

When I first encountered the idea of DTOs I didn’t really understand the point of them. I thought, why can’t I just pass up the domain objects through the layers up to the front-end? After all, I was always taught that I should reuse code and use the DRY principle (Don’t Repeat Yourself). DTO’s by their very nature introduce code duplication, which seemed all wrong.

I have now seen the light and understand their benefits which out way the code duplication issue. Their benefits include:

  • Minimizing data transferred to the client which improves performance all around especially for remote clients which access services over the network (via web-services or even Ajax calls).
  • Keeps things clean by only exposing the required data for the given service call which also improves serialization especially when a collection is marked as lazy with ORM.
  • Stops unexpected data persistence when using ORM such as NHibernate/ActiveRecord when the session flushes at the end of the request.
  • Improves security when data binding requests (as we do in MonoRail) where a HTTP request could be created to modify data even though it is not available in the front-end.
  • Isolates the front-end from changes in the domain.

Ben has a more detailed post about the advantages of using DTOs which is well worth a read.

Mappers

Mappers are pretty simple classes that the service uses to map from a domain entity to a DTO and back again. The mappers that I’m using will map from a particular domain entity to a particular DTO or collection of DTOs. Currently I’m doing this “manually”, but I’m thinking about ways to do this automatically using reflection and matching on properties that match by name and type. More on this in a later post if I still think it is a possible solution.

Messages

Depending on what you read, the terms Messages and DTOs seem to be interchangeable. However I think there is a difference. I’m currently thinking (which may be wrong) that a service call should accept a request message and should return a response message. Both should be unique to the service call as they are course grained. These messages can contain domain DTOs which are tailored to the particular usage. The DTO’s can be reused in multiple service calls.

I feel an example coming on to help demonstrate my thoughts.

An Example

Imagine we have a User domain entity which comprises an id, first name, last name, email, user name, password, status and permissions list. We also have a UserStatus domain entity which includes an id, name and code. These domain objects would be mapped using an ORM such as NHibernate or ActiveRecord which we want to isolate from the front-end.

public class User
{
    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public UserStatus Status { get; set; }
    public List<string> Permissions { get; set; }
}
public class UserStatus
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public int Code { get; set; }
}

Now imagine in our front-end we want to be able to show a list of users and be able to filter by their status. We might create a UserDTO which is stripped down to only the fields we want to show in the list:

public class UserDTO
{
    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public UserStatusDTO Status { get; set; }
}

We might also create a UserStatusDTO that contains the data required to show a filter with all possible status options:

public class UserStatusDTO
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

Next we need a single service call that will return a list of users and all possible statuses.

public interface IAccountsService
{
    public RetrieveUsersForListingResponse RetrieveUsersForListing(RetrieveUsersForListingRequest);
}

Finally we need two messages which will be unique for the service call, one request and one response:

public class RetrieveUsersForListingRequest
{
    public Guid FilterByStatusId { get; set; }
}
public class RetrieveUsersForListingResponse
{
    public List<UserDTO> Users { get; set; }
    public List<UserStatusDTO> Statuses { get; set; }
}

Obviously we need an implementation for our service interface which I won’t go into now but the service should basically validate the request, call the required repositories, map the domain entities to DTOs and construct the response which is returned. The service now has clear responsibilities.

The benefits here are pretty clear. We have a single service call to return two object lists rather than a separate call for each list. We also stripped down the returned data to only what is required. These benefits are especially useful when calling the service over the network. When called from our MonoRail application (our client) this helps to keep the controllers as thin as possible and allow them to do their job cleanly.

We could extend this example by providing service calls for retrieving and saving a user (for editing). We’d need a new user DTO (for example UserDetailsDTO) which includes the data that a user is allowed to edit and new request and response messages. But I think you get the idea now (and this post is pretty big now).

I’ll be refactoring the current PixelBugs architecture to match this pattern which you can take a look at on Google Code for more examples.

So what do you think? I’d be interested in any thoughts or comments even as a confirmation that I’m on the right lines. Of course I may have completely misunderstood the concepts, if so, please let me know.

Cards are the new Issues

I’m going to start taking this blog in a slightly different direction from now on. Up to now I’ve been giving a step-by-step account of development of the PixelBugs project. Since my last post, I’ve made quite a few changes and to describe them all in detail here would take up too much of my very limited time. So from now on I’ll be highlighting important changes, decisions and interesting snippets of code rather that the full commentary. Of course the source is still all available on Google Code as before so you can always check it out. I’ll still be developing in the same TDD way:

  1. Write tests which may not compile
  2. Write the minimal amount of code so the solution builds but tests fail
  3. Add the implementation by any means necessary so the tests pass
  4. Refactor the code to remove duplication and improve design with tests still passing

This is know as red-green-refactor. So on that note, what’s changed since last time?

Cards
The first major change is the move to cards rather than issues. The reason for this is that we have just started to introduce agile development at work at I’m really happy with the way that is going. So I have decided to turn this project into an agile project management tool rather than a traditional issue tracker. I’m not sure what that means for the name, but we’ll see what happens.

So to introduce cards I had to refactor the existing tests that used issues then refactored the issue domain/service with their new names. That was a pretty straight forward and all tests passed after this was done.

Next I extended the domain to include things like card status, priority, type and comments. I also added some other properties for things like story points:

Once these extra properties were added I had to refactor the new card view to have status, priority and type selects and a new story points input box. In addition to this, I refactored the card index view to display cards in lanes by status just like a card wall in real life might be (not styled yet):

I’ve added a show (details) page for a card when it is clicked on the wall and also a new card editing view. I found one interesting bug when editing an existing card. There is a select for the card owner that has an option added to the start of the list so that you can select “No Owner”. To do this I used the firstoption parameter of the $FormHelper.Select method. This worked fine if you are setting it to a user, but if you set a card owner to “No Owner” from a user, it never updated. I tracked this down to the fact that I’m using Guid’s as my primary keys and the default value for the firstoption is 0 (zero). Now because the databinder doesn’t know what to do in this case it doesn’t change the owner value even though I had AutoLoadBehavior.NullIfInvalidKey set. The fix was pretty easy, just add a firstoptionvalue parameter and set it to empty string. This equates to null when databinding and so fixes the bug. Here is the NVelocity:

<div class="control">
    $Form.LabelFor("card.owner.id", $strings.Labels_OwnedBy)
    $Form.Select("card.owner.id", $users, "%{value='Id', text='FullName', firstoption='$strings.Options_NoOwner', firstoptionvalue=''}")
</div>

jQuery in, prototypejs out
In the past and for the start of this project I used prototypejs which is a great JavaScript library. I’ve been hearing a lot of positive things about jQuery and so I thought this was the perfect project to give it a go. So I’ve removed prototypejs in favour of jQuery and refactored the small amount of JavaScript which was very simple. The first piece of jQuery worth sharing here is the drag and drop functionality I’ve added to the card wall. This enables the user to drag a card from one lane to another and when the card is dropped an Ajax call is made which updates the card status. Here is the code:

$("div.card").draggable({
    helper: 'clone',
    ghosting: true,
    opacity: 0.5,
    fx: 300,
    handle: 'div.handle'
});
$(".lane").droppable({
    accept: "div.card",
    hoverClass: "droppableHover",
    drop: function(ev, ui) {
        //Show the wait animation
        $("#wait").show();
        //Get the id of the card and the new status id
        var card = ui.draggable[0];
        var statusId = this.id;
        //Use ajax to update the card status
        jQuery.ajax({
            url: 'UpdateStatus.ashx',
            type: 'POST',
            data: { cardId: card.id, statusId: statusId },
            success: function(data) {
                card.setAttribute("status", statusId);
                $("div.card").each(function() {
                    $("#" + this.getAttribute("status")).append(this);
                });
                $("#wait").hide();
            },
            error: function() {
                $("#wait").hide();
                alert("Unable to change the card status");
            }
        });
    }
});

So how does this work? Well, it’s actually very straight forward. The first block simply initialises the cards to be draggable. This is done with the CSS selector “div.card”, we then define what should happen when dragging: we’d like to drag a clone rather that the actual card div, we’d like it to be 50% transparent and we’d like to only drag from a handle (not the whole div). The reason for the handle is to fix the conflict between clicking a card to see its details and clicking a card to start the drag.

The second block deals with where the cards can be dropped. So we use another CSS selector to define the lanes a droppable. We specify that they will only accept cards and the CSS class to add when hovering over a lane. Then, when we drop a card we show the wait animation and fire an Ajax call to an action in the controller to update the card status. If this succeeds we move the card in the UI, if it fails we leave the card where it is and show an error message.

WYSIWYG editor
The next change was to refactor the new and edit views to remove some duplication. The main part of the form is the same for both views, so I’ve brought that out into it’s own partial view and then use this in both the new and edit views.

Now that we have removed this duplication I wanted to add a WYSIWYG editor instead of the standard textarea control. I looked into TinyMCE but this seemed to be really heavyweight compared to my current needs. After some more searching I found NicEdit which has all the features I currently need and is very lightweight. To add NicEdit to our existing textarea we just use the following:

bkLib.onDomLoaded(function() {
    new nicEditor({
        iconsPath: '$siteroot/Content/js/nicEdit/nicEditorIcons.gif',
        buttonList: ['bold','italic','underline','forecolor','left','center','right','ol','ul','fontSize','fontFamily','fontFormat','indent','outdent']
    }).panelInstance('card_body');
});

This code allows us to specify where the icons are located and we can pick which buttons display, very easy to setup and configure.

Live Writer
You may have noticed that I’m not using screenshots for code in this post. That’s because I’ve switched to using Microsoft Live Writer which has a plug-in for formatting code snippets. This has really helped and has reduced the amount of time I spend writing posts which means I can spend more time coding, wahoo!

That’s for for today, except to say that we now have 53 passing tests and 100% code coverage in our web and core assemblies. PixelDragons.Commons has no test coverage at the moment and that’s because this was created before I started TTD. As I touch Commons, I’ll add tests to rectify this. As usual the full source code is available on Google Code:

Url: http://code.google.com/p/pixelbugs/
Svn Revision: r19

Services, Refactoring & Castle Trunk

Hello again and welcome to the latest edition of Developing PixelBugs. This time around we’re not adding any new features, but instead we’ll be adding a service layer and some refactoring. During this process I found a reason to upgrade to the Castle trunk from RC3, but more on that later.

Adding a service layer
So far we haven’t anywhere for our business logic to sit. It shouldn’t sit in the controllers and it shouldn’t sit in the repositories. So we need the service layer. To cover the functionality so far we need to add two services, one for security and one for managing issues.

I first created a new interface called ISecurityService which has two methods. One for authenticating a user from their username and password and returns a security token. The second method validates a security token and returns the authenticated user:

Next I added some unit tests for this service and refactored the existing security controller tests so that the controller now only takes an ISecurityService as a constructor argument. I modified the tests as required to work with this new interface (going through the normal process) and registered the service with Windsor (via a new services.config file) to allow the acceptance tests to pass. I also refactored the authentication filter tests to use ISecurityService and the authentication filter implementation.

All the tests are now passing. I really see the value in tests now and have full confidence that it’s all working after the significant change I’ve just made.

Next I followed the same process to add another service called IIssueService for use by the issue controller:

After completing the process, all tests are passing

Refactoring
Once the service layer was in I decided to carry out some refactoring. Here’s what I did:

I want to stop using the session to store stuff, so I now store the security token in a cookie rather than the session. This avoids the timeout problem and keeps the user signed in until they sign out. This was great except that one of my tests (Authenticate_Success) failed with a NotSupportedException. This was due to Castle RC3 test support not implementing CreateCookie. So I now have the perfect reason to upgrade to the trunk. This is something I always planned to do, but now I have a reason to do it now (see details below).

Here are some other refactorings:

  • Refactored views to use url helper rather than hard-coded ($Form.FormTag and $Url.Link)
  • Moved base test classes to PixelDragons.Commons.TestSupport
  • Removed duplication where possible

Upgrading to Castle trunk
Here are the tasks I performed to upgrade from Castle RC3 to the trunk. I found some of the information I needed here:

  • Using TortoiseSVN, connect to the Castle SubVersion server and get the latest committed code (details here)
  • Run the build without tests using NAnt (see “How to build.txt”)
  • Replace the Castle assemblies in our lib folder with the newly built ones
  • Tried to build the solution which resulted in LOTS of errors
  • Updated the filter Perform method from public bool Perform(ExecuteEnum exec, IRailsEngineContext context, Controller controller) to
    public bool Perform(ExecuteWhen exec, IEngineContext context, IController controller, IControllerContext controllerContext)
  • Replaced all using NHibernate.Expression with using NHibernate.Criterion
  • In UserRepository changed new EqExpression to Expression.Eq
  • In facilities.config I removed the “hibernate.” prefix from the arfacility config settings
  • In facilities.config I removed the startable facility
  • In facilities.config I replaced Castle.MonoRail.WindsorExtension.RailsFacility with Castle.MonoRail.WindsorExtension.MonoRailFacility
  • Removed the HttpModule Castle.MonoRail.Framework.EngineContextModule from the web.config

Test Coverage
Once all of this was done and the tests were all passing again. I thought I better check my test coverage, so I downloaded the last free version of NCover and NCoverExplorer and gave it a run. I found a few areas that weren’t covered by my tests, so I added more tests. We now have 40 passing tests:

and pretty good coverage (apart from PixelDragons.Commons):

So that’s it for this time. Not much of a post I know but hey. As usual the code is committed to Google Code, so feel free to take a look.

Url: http://code.google.com/p/pixelbugs/
Svn Revision: r10

Adding Security

Here we are again ready for another installment. This time around I’m going to be looking at the security of the application. What do I mean by that? Really I mean authentication and authorization. This is another one of those things that is far easier to add at the beginning (like the resources from last time) rather than once there is a large code base. For this edition I’m not going to go into the full detail as I have before as I think you know the process I go through now, but I will be highlighting the main areas of interest. Don’t forget that all the source is available from Google Code. To recap, this is my normal process:

  • Create a test that doesn’t compile
  • Add the minimal code so the build succeeds
  • Add the implementation so that the tests pass

Without further ado, here is the new class diagram which contains the changes for this iteration which we’ll talk about below:

Authentication
I’m going to start off with some pretty simple authentication to get the ball rolling. Of course I’m always thinking about improvements and future refactorings, I’m sure we will revisit this area again. I’m currently thinking about storing a user name and password for each user. A user should be able to enter their credentials on a sign in page which submits to an action that authenticates them and stores their user id in the session. Then I’ll create a filter to check the session and load up the user before each action. If the session expires or the loading of the user fails we will redirect to a nice error page and cancel execution of the requested action.

So here is a controller unit test that tests the authentication of correct credentials:

As you can see here I’m calling the repository directly, but I think I’ll be introducing a service layer pretty soon which would be a nicer interface. I will probably increase the security too by only storing the password hash and matching on that instead, but that’s for another day. The next unit test is for our authentication filter:

And here is the implementation of this filter, notice that we add the current user to the controller property bag for convenience:

Finally for authentication, I’ve created a number of acceptance tests that test the filter and security controller. The problem with these tests is that they rely on some test data that needs to be in your database before they pass. So inside the Core assembly is a folder for sql scripts where I’ve added a script for populating the database with test data. Make sure you run this script before running the tests. To make acceptance tests easier to write I’ve created a SignIn method that encapsulates the sign in process that can be called from other tests as all other pages are now protected:

And here is an example of using this method in a simple test:

As I mentioned above, I’ve created a number of acceptance tests so take a look at the source for more examples.

Authorization
For authorization I’d like to define a number of fine grained permissions that control each feature of the application such as CreateIssues, ViewIssues, EditIssues, DeleteIssues etc. Then these permissions could be grouped together into roles. There might be some built-in roles in the system (such as Administrator that have all permissions), but a user should be able to modify the permissions in a role and even create their own roles. These roles could then be granted to a user. The user’s roles (and therefore their set of permissions) should then control which parts of the application they can access. I’d like this implemented in the easiest way possible for the developer to use and should control which controller actions can be accessed and whether or not to show a particular UI element in the views.

How are we going to do this? After some research and experimenting here is my current solution:

The User domain class should implement the .NET IPrinciple interface. This enables us to store the user object anywhere that supports IPrinciple (like the monorail context). I’ve looked into the built in security support in .NET but I had some issues. The main problem was that it made unit testing much harder. I’d prefer to add attributes that do not impact on testing. It required passing literal strings around which isn’t great. The attributes were also a bit hard to read. So I’ll create a custom attribute to mark the actions with the permission that is required. Then I’ll create an authorization filter to check the permissions on an action and for the current user and only allow execution to continue if the user has the authority to.

Looking at the class diagram above, notice that our User class now has a collection of Roles and a Role has a collection of Permissions. A permission is a system entity that we want to code against. So it makes sense for it to be an enum. We will therefore create our own custom mapping to render the permissions list for a role into a comma separated list which can be stored in one field in the Role table (mainly to reduce the sql joins when loading a user). There is also a new method in the User class called HasPermission which will take a Permission (enum) and check whether that user has the given permission.

Here are the User.HasPermission tests that now pass (after going through the normal process outlined above):

I’ve created a number of unit tests for the new AuhorizationFilter. Here is one that tests the normal success case:

I guess the more interesting parts of this is the actual implementation of the custom attribute, how it’s used and the AuhorizationFilter:

You mark a controller action like this:

Here is the AuthenticationFilter that checks the permissions:

As you can see from the filter, if the current action requires a permission we get the current user and check to make sure they have the authority to execute it. If they do execution continues as normal but if they don’t we redirect them to a nice error page. If the action doesn’t require any permissions the filter allows execution to continue. Sweet!

One final part of authorization is hiding UI elements based on permissions. For example, on the issue list page is a “New Issue” link that takes you to the new issue form. Obviously we want to hide this link to users who do not have the permission to create issues. If you remember, as part of our authentication filter we store the current user in the property bag. This allows us to do this:

I’m not a fan of passing literal strings around but I didn’t know of another way in NVelocity. So I’ve overriden the HasPermission user method to accept a string which is converted to a Permission enum. If this conversion fails an exception is thrown which is ok.

So after all that we now have 24 passing tests:

What’s next?
Well I think a service layer will be required plus some improvements to the repository calls we are making. We’ll also need to improve the issues list with paging etc and add some more properties to an issue. Once we’ve done that I’d like to spend some time on the UI and also on how issues are organized. Possibly via Client – Project – Version – Cycle. But more on this later.

As always the full source is available via Google Code. Thanks to BenL for pointing out the missing files etc that I forgot to commit, oops!

Url: http://code.google.com/p/pixelbugs/
Svn Revision: r9

Extending Issues

In this installment I’ll be extending our rather basic Issue domain class to include some extra properties. These properties won’t be the complete set I have in mind, but in the interest of incremental changes (and an amount to work to I can write about in one post), I’ll limit it. We’ll be adding three new properties, CreatedDate, AssignedTo and ReportedBy. The later two will require a new domain class: User. Here is the class diagram of what we intend to add:

First of all we’ll change our New_Success unit test to mock out a new repository called IUserRepository and check that the property bag has a list of users that we get from the new repository that can be used to set the issue’s ReportedBy and AssignedTo properties. You might also notice that I have changed the way we set repositories for controllers. We no longer use public property setters, but now we use the constructor. The cool thing about using Windsor is that we didn’t need to change any configuration. Anyway, here is our new test:

Again, this doesn’t build as User and IUserRepository do not exist. So lets add them in the same way we added the Issue and IIssueRepository. We also need to add the new constructor parameter to the controller and the other unit tests.

The solution builds again now but running the tests, 3 fail. The New_Success unit test fails because we haven’t added the code to the controller that populates the property bag. The two acceptance tests fail because we haven’t injected the new IUserRepository and so the controller cannot be created. Adding these few things now fixes all the tests.

Next on the list is a change to the New_RenderNewIssuePage acceptance test to ensure that a select control exists on the page for the “Assigned To” and “Reported By” user for the issue being created. Running this test fails as expected, so we add controls to the Issue/New.vm view as follows:

All the tests now pass again but we haven’t added the new properties to the Issue class yet. So we change the New_CompleteFormAndSubmit acceptance test to check for these properties. We haven’t stored any users yet (need to solve the test data problem) but for now we can test against the issue being set as unassigned and reported anonymously.

As expected the test fails, so we add the properties to the Issue class and modify the list view to display them:

Running the tests again fail, why? We are getting the following error message:

SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM

This is because we are not setting the new CreatedDate property in the Create action. So lets add that and run the tests again. We get passed that error, but now the test is failing because the “Unassigned” and “Anonymous” text is not present, instead we have: $issue.AssignedTo and $issue.ReportedBy, this is because these properties are Users and they are set to null.

What we need now is a Helper. Helpers are a nice place to encapsulate your view UI formatting code and other such helper methods. Can you guess what’s coming? Yes a new unit test for our non-existent UI Helper:

Of course as we’ve seen before, this doesn’t compile. So we just add the new UIHelper class with an empty method called FormatUser. The solution builds now and the tests fail as expected. Once we add the implementation, these new tests now pass. Of course the New_CompleteFormAndSubmit acceptance test still fails, to fix it we need to register the helper with the IssueController and then use it in the view like so:

As you may have noticed above, I’ve also added a helper method for formatting dates. I won’t bore you with the details here but I followed the same process as the other helper methods above. We now have 8 tests that pass!

Test data for acceptance tests
From the above tests I can see that I haven’t tested the case of selected a user for either the “Assigned To” or “Reported By” fields in my acceptance tests. To do that I need some test data (i.e. a user to select) which I don’t currently have. I’ll have a think about this and see if I can find a good solution. I decided to add a new test for this case and for now, I populated the database with a test user and then created a new acceptance test which selects the first user in the select list (index 1) and then confirms that the name of the user selected is on the following page:

Of course this is only a reliable test if there isn’t already an issue in the list with the same user selected. So we need a better solution for test data.

To get this test to pass I had to make a few minor changes. The first was to change the select list names to include .id so they now should be issue.assignedTo.id in the tests and the views. I also needed to change the base class of the controller to ARSmartDispatcherController so I could use the ARDataBind attribute in the Create action:

Using ARDataBind allows MonoRail to automatically load up the nested objects (the users) from the database via ActiveRecord based on the id’s posted from the form. This loading only works if the select list control name ends in the primary key field, in this case Id.

We now have 9 tests passing (as long as there is a user in the database for the last test). So far so good.

Resources
One other job I’ve done in this round is replacing all the hard coded text in the views with resource strings. This is very easy to do and from experience best to put in from day one. To do this I just added a new resource file (.resx) to the web application for this controller and then added a reference to it in the controller class:

[Resource("strings", "PixelDragons.PixelBugs.Web.Resources.Controllers.IssueController")]

Then in the views for this controller, just use the syntax $strings.RESOURCE_NAME. Simple really.

Housekeeping
Just a few minor housekeeping changes this time. I noticed that the unit test asserts had the expected and actual parameters the wrong way round, so I’ve swapped these. I’ve also added a FullName property to the User class. This property isn’t under the control of ActiveRecord, it just concatenates the users first name and last name for convenience.

That’s it for now, you can get the full source code from Google Code:

Url: http://code.google.com/p/pixelbugs
Svn Revision: r7

Listing issues

Here we are again. We left the last installment with 3 passing tests which is a good start. In this installment we’ll create an acceptance test for creating a new issue and start the work of displaying a list of created issues.

But first things first, I think I need to expand on one subject from the previous post that I didn’t really cover and that is Moq, the mocking framework I’m using (for the first time). So, in Create_Success unit test, here is the code to mock out our IIssueRepository:

So what’s happening here? Well, Moq uses Lambda expressions to define how to mock out calls. In the first line above we create our mock object for the IIssueRepository interface (notice we don’t have an implementation of this interface yet). The next line defines what method of IIssueRepository (r) Moq should expect to be called and when it does, what it should return. In this case, IIssueRepository has a Save method that returns the saved object. Notice that we set the controller property IssueRepository to mock.Object rather than just mock. That’s it! I’m sure we’ll see some more complex examples as we go on.

Anyway back to development. We’ll start with a new acceptance test which will request the Issue/New view, complete the form with test data and click the save button. It’ll check that the summary of the issue created is then present on screen as we’ll be showing the list of created issues. Here it is (click for a larger version):

As before this test fails. This is because the controller IssueRepository is null, so we need to create an implementation and configure Windsor to inject it. So I’ve created a new class inside the Core assembly called IssueRepository, it implements IIssueRepository and is derived off of the PixelDragons.Commons ARRepository<T> where T is our Issue class:

To inject this class using Windsor I’ve added it to a new configuration file in the web application called Repositories.config and referenced it in the web.config. I’ve also created a blank database called pixeldragons_pixelbugs and setup the connection string in the Facilities.config. In addition I’ve added ActiveRecordStarter.CreateSchema() to the GlobalApplication. This will recreate the database schema each time the application starts up. So watch out for that. It’s good enough for now, but this will be another area to address as we develop further.

Running the acceptance test again fails. This is because we don’t have a List action in our controller or a corresponding view file. So let’s start by adding a unit test for the List action:

This doesn’t compile at first, so I added an empty List method to the issue controller. This fixes the build and this test fails as expected. We now have two failing tests. To fix the List_Success test, we just need to add the following:

To fix the failing acceptance test we need to add the list view file. Here it is:

Running the tests again, all 5 pass!! Very cool.

Now we have these tests passing I had a look at the database that ActiveRecord created for us and noticed that the issue description field has been created as nvarchar(255) which is the default string type. As we are using SQL Server 2005, we really want this field to be nvarchar(max), a simple change to the Property attribute for the Description property in the Issue class fixes this:

[Property(SqlType="NVARCHAR(MAX)")]

I also then made a small change to the New Issue view to change the description text box to a text area with some basic css styles to at least make the pages viewable (nothing fancy).

Housekeeping
OK, you may have noticed a couple of minor housekeeping changes to the tests. I’ve added an App.config which contains the server, port and url extension to use for acceptance tests and the override for BuildUrlInfo in the unit tests. I’ve moved the BuildUrlInfo method into a new unit test base class called ControllerUnitTestBase which derives itself from BaseControllerTest. There is also a new base class for the acceptance tests called AcceptanceTestBase. This class has a single method at the moment called BuildUrl which basically takes the controller and action names as parameters and builds a url from these and the items stored in the App.config file. This base class also now contains the TestFixture attribute with the ApartmentState setting that is required for WatiN to run correctly. The final minor change is the default redirect in Default.aspx which now points to the issues list, so you can now run the application and start adding issues. Obviously we have a long way to go before this is a usable application, but we are on the road.

Roadmap
Here is a very rough list in no particular order of things that we’ll be looking at in the next few installments:

  • Add some extra properties to Issue such as date created, priority, status, etc
  • Improve the css styles and start work on the UI
  • Add users, permissions and a login page
  • Allow users to be assigned to issues
  • Improve the issues list by adding paging, searching and filtering

The latest code is committed to subversion, you can get it from here:

Url: http://code.google.com/p/pixelbugs/
Svn Revision: r6

Creating a new issue

We left the last installment with a basic structure for our application, ready for development. I guess this is a good time to state our goals for this project and how we will develop moving forward. The approach we will be taking is test driven development. That means writing tests first that fail, and then adding the implementation which allows the tests to pass. We will be developing in incremental steps, so for each feature we’ll start with the very basics and then add to these as we go. The goal for this project is for me to give something back to the Castle community and to improve my skills. I’m no TDD expert and so this will be a learning experience for me too. So, if you spot a problem with what I am doing, feel free to add your comments. Who knows, we might end up with a pretty good product in it’s own right that we can all use. Cool!

Now, down to business. We’ll start by creating our first unit test. We’re going to be using the built-in support for unit testing that MonoRail supplies via the BaseControllerTest class and the MbUnit unit testing framework.

We’ll start by adding a test for the “New Issue” page. This will be the page where users will be able to create new bugs/feature requests/tasks etc. These will be called “Issues” as a grouping name. So we’ll need an “Issue” controller and that should have a New() action. Calling the New() action should render the correct view. So, here is our first test (click for full size):

Obviously, this doesn’t even build as we don’t have an IssueController, so let’s add that and the code required to pass this test:

The build now succeeds and the test passes. Wahoo! So what have we done? The test fixture contains a single test that creates the controller and calls the PrepareController base class method which mocks the services that a controller relies on during normal operation. We then call the New() action and verify that the correct view was selected for rendering. Pretty simple.

We then created the required IssueController and added an empty New() method (the action). That’s it! MonoRail will automatically select the view file to render based on the controller and action names which is enough to pass this test. You can of course override this if required using the RenderView() method. MonoRail knows which controller action to call based on the url of the requested page, so http://localhost/Issue/New.ashx will route through to the Issue controller and New action. There is a standard set of action names that I use for various crud tasks:

New – Shows a form to the user for entering information about the entity to create.

Create – The New view should post it’s form to the Create action. This action will persist the entity and redirect to the next view (normally an entity list or confirmation page).

Edit – Like New, but is used to show a form for editing an existing entity. May use a view component to hold the comment UI between this and the New view.

Update – Like Create, but this is where the Edit view should post it’s form. This action will persist the entity changes and redirect to the next view (normally an entity list or confirmation page).

List – Shows a list of entities

Index – A general home page for the controller, like an overview or summary etc

Delete – Deletes a given entity and redirect to the next view (normally an entity list or confirmation page).

Obviously we can add others where required, but this is the standard I stick to for these tasks.

Back to our code, there is something missing. The eagle eyed amongst you will notice that we haven’t created a view for the New action. So, lets fix that now, with an acceptance test to start with, we’ll be using WatiN for acceptance testing (click for full size):

The url is hardcoded for now in the test, we’ll address this later. Running this test fails, the error message shows us that we haven’t registered the IssueController with Windsor, so lets do that and add the view file next and see what happens to the test:

It passes! To be honest there where a couple of other minor things that I had to do to make the test pass. I first added an entry in the Controllers.config file for the IssueController and added the view file. But I also needed to modify the default layout to render the page title and add the layout and rescue attributes to the IssueController. Here is the layout, notice the $!title variables (click for full size):

In the view file, we use the capturefor component to set the $title variable that is picked up in the layout. Here is the view file (Views\Issue\New.vm):

Now this isn’t much of a “New Issue” view as there isn’t a form to collect the information about the issue. We’re going to be developing in small increments so let’s just add summary and description fields and a submit button. Our acceptance test now looks like this (click for full size):

Of course, this test fails so we now need to make some changes to the view to make it pass (click for full size):

The acceptance test now passes and if you take a look at this page in your browser you will see the form (without any css styling yet) and you can interact with it. The form has client-side validation thanks to the validation library that we have included. The validation works based on the class you set for the given fields. There is a whole set built-in or you can create your own.

That’s cool, next on the list is the Create action. So as before, let’s start with a new unit test:

Again, this test didn’t build, so I had to add a number of new things. Firstly the Issue domain class has been added to the Core assembly. It has three properties: Id, Summary and Description. I’ve also added the relevant ActiveRecord attributes. One controversial decision is to use Guid’s as the primary key type. I know most (if not all) of the samples I’ve seen use int’s, but I have been involved in a number of projects and Guid’s have helped a lot to avoid conflicts is various scenarios. I guess this topic will raise some comments so I’ll leave it there for now. Here is the Issue class:

I’ve also added a new interface, IIssueRepository which implements IRepository. Where does IRepository come from? Enter PixelDragons.Commons. IRepository is based on the excellent Rhino.Commons IRepository but I’ve modified it to suit my needs. PixelDragons.Commons is a new assembly that I’ve added to the solution that I’ve used in other projects, more on this later.

The last thing to add is the Create action and IssueRepository property in the IssueController. I’ve added that and the code inside it to pass the test. The IssueRepository will be injected by Windsor during normal running of the application rather than set as it is in our test. Here is the IssueController after these changes:

Running this test fails unexpectedly, so what is the problem. Take a look at the error:

Message: The action did not redirect correctly Equal assertion failed: [[/Issue/List.rails]]!=[[/Issue/List.ashx]]

I see, the url extensions don’t match. We are using ashx, but rails is the default. I spent some time trying to workout how to override this. I couldn’t see a nice clean property or constructor parameter so I ended up adding the following to the test fixture (click for a larger version):

I’m not in love with this and I can see some refactoring coming in the way of a new test base class, but it’s ok for now. After running the tests again, they all pass:

That feels like a good place to leave it for now. Next time we’ll add an acceptance test for creating an issue and maybe start looking at the issue list.

Again, just to reiterate, I’m no TDD expert so if I’m doing anything wrong feel free to comment. This is as much a learning exercise for me as anything. I’ve committed the latest code and you can get it here:

Url: http://code.google.com/p/pixelbugs
Svn Revision: r5

Getting Started

OK, so the first thing to do is to setup the Visual Studio 2008 solution and some base projects. Here I have created three projects:

PixelDragons.PixelBugs.Core – This project will contain our domain objects, services and other business logic for the application. There’s nothing to add here yet so it’s just an empty project.

PixelDragons.PixelBugs.Tests – This project will contain the unit and acceptance tests, so I’ve just added an empty folder for each and added various references in preparation.

PixelDragons.PixelBugs.Web – This is a web application project that will provide the front end for the bug tracker. Here I’ve just added a basic folder structure, configuration and some supporting files.

Technology Choices
I’ve decided to start with Castle RC3 rather than the trunk build. This is because I know there are many users using this version and there is some refactoring required to move to the trunk. I’d like to cover this in a future post when the time is right as I think this will be valuable for those users that only use official releases.

In addition to this, I have made some other technology choices. Firstly, regarding testing, I’m using MbUnit and WatiN for unit and acceptance testing. I’ve used NUnit and MSTest in the passed but I’ve been hearing some good things about MbUnit, so this is a perfect opportunity to try it out. I’ve also chosen to use (try out) Moq for mocking. Again, I haven’t used this before, but there is a buzz around this open source project so it’s worth a look.

I’ve also setup the configuration for various facilities that we will be using including logging facility (using log4net), automatic transaction management facility, monorail facility and the active record facility. Another configuration choice is the URL file extension of .ashx. This is because this file extension is already part of ASP.NET and so you won’t need any extra IIS configuration which is important if you are running on shared hosting.

Finally, two javascript libraries that I’ve used before: prototypejs and Really Easy Field Validation. I know there is built-in support in monorail for validation and even prototype, but I’d prefer to have some more control over these.

First Run
OK, so building and running the web application at the moment isn’t all that interesting. I’ve setup a redirect inside the Default.aspx file to go to /Home/Index.ashx which of course will fail as we don’t have any controllers yet, but at least we know the configuration is correct and we have referenced the right assemblies:

That’s it for now, we’ll add our first test in the next installment, in the meantime you can get the source code for this post from:

Url: http://code.google.com/p/pixelbugs/
Svn Revision: r4