Archive for the ‘tipsandtechniques’ Category

Using jQuery and Facebook together

Monday, July 23rd, 2012

I wanted to give a big shout out to Jenny and Lih for their post on Loading Facebook Javascript SDK.

This fixed all the problems I was having trying to build a jQuery UI multiple friend selector widget.

For instance, I was in a weird situation where FB.api was undefined after the FB SDK was fully initialised and had updated things like fb:name tags and setAutoGrow.

It is also a vastly cleaner way to add the FB SDK in the jQuery era. It should be the default answer to the question “How do I load the javascript SDK?”.

Export securables from SQL Server 2005 or higher.

Monday, July 18th, 2011

Brian Kelley wanted something to store role security for disaster recovery. It came in very handy to get the permissions used on a development system into a live system.

Since I was only worried about a single role, I added the condition “AND dprins.name = @RoleName” at the end.

First Steps into RhinoMocks

Monday, April 25th, 2011

RhinoMocks has been on my radar for a long time, but today is the first day I have managed to use it to good effect.

Up until now, when I wanted to test something, I felt that I had to make a whole database to test my code against. Now, though, I can’t. My domain model is a tiny part of a legacy database. Now, I can build up just the pieces of data I need.

I am going to assume you are using an ORM layer (and if not, why aren’t you?). At work, I’m on nHibernate but your tastes may run to Entity Framework or something else. Whatever it is, so long as you can easily create new domain objects.

My example is based on a small piece of workflow logic. If an Entity meets certain conditions, it is authorized to progress through the workflow. Specifically, we have a student who is trying to apply for a programme limited to Undergraduates. We will go through our requirements and what we need to test, look at a method of testing using a database and then look at how RhinoMocks can help us.

We start with the very basic data entities.

public enum StudentCategory
{
  Undergraduate,
  Postgraduate
}

public class Student
{
  public virtual string Id { get;set; }
  public virtual StudentCategory Category { get; set; }

}

public interface IStudentRepository 
{
  Student GetStudentById(string Id);
}

Now, we worry about the student programme we are trying to assign these poor layabouts, I’m sorry, students to. This is another Entity with AssignedStudents mapped into the database as a One-To-Many relationship.

The Strategy pattern is used here to give the programme its rules on who can be assigned. The class we are implementing only uses one rule. Other options could include using a collection of IAuthorizationRule implementations or implementing IAuthorizationRule with a class that is composed of other rules.

// The behavior we really care about.
public interface IStudentProgramme
{
  public bool AddStudent(Student newStudent);
  public IEnumerable<Student> AssignedStudents { get; }
}

// Concrete implementation of IStudentProgramme
public class ExampleStudentProgramme : IStudentProgramme
{
  private IAuthorizationRule<Student> rule;

  private IList<Student> assignedStudents { get; set; }

  public ExampleStudentProgramme(IAuthorizationRule<Student> rule)
  {
    this.rules = rule;
    this.assignedStudents = new List<Student>();
  }

  public int Id { get;set; }

  public IEnumerable<Student> AssignedStudents 
  {
    get 
    {
      return assignedStudents;
    }
  }

  public bool AddStudent(Student newStudent)
  {
    if (rule.Authorize(newStudent))
    {
      AssignedStudents.Add(newStudent);
      return true;
    }
    return false;
  }
}

// Rule used in the Strategy pattern
public class MustBeUnderGrad : IAuthorizationRule<Student>
{
  public bool Authorize(Student student)
  {
    return student.Category == StudentCategory.Undergraduate;
  }
}

// Repository Interface
public interface IProgrammeRepository 
{
  IStudentProgramme GetProgrammeById(string Id);
}

Testing will be performed from the client perspective. They call us from outside our little black box and they don’t care how we fulfill their request. We can test the little bits like the MustBeUnderGrad rules by themselves but that will only tell us about the implementation that we have covered. If we test the unit as a whole it gives us much more confidence in the interface we are providing to others.

There are many ways to call into this kind of component. It could be a windows application, an MVC web app, a web service or something else. Whatever it is, we can provide the following interface to consumers of our component:

public StudentProgrammes
{
  private readonly IProgrammeRepository programmeRepository;

  private readonly IStudentRepository studentRepository;

  public StudentProgrammes(IProgrammeRepository programmeRepository, IStudentRepository studentRepository)
  {
    this.programmeRepository = programmeRepository;
    this.studentRepository = studentRepository;
  }

  public bool AssignStudentToProgramme(int studentId, int programmeId)
  {
    Student student = studentRepository.GetStudentById(studentId);
    IStudentProgramme programme = programmeRepository.GetProgrammeById(programmeId);

    return programme.AddStudent(student);
  }
}

Now that we have the example all coded up the next thing to look at is how we can build a test using the database.

[TestMethod]
public void TestAssignUndergraduateReturnsTrue()
{
  // Arrange
  // Build the nHibernate session and wire up the repositories
  ISession session = TestSupport.BuildSessionFactory();
  IProgrammeRepository programmeRepository = new ProgrammeRepository(session);  
  IStudentRepository studentRepository = new StudentRepository(session);
  IStudentProgrammes programmes = new StudentProgrammes(programmeRepository, studentRepository);

  // Act
  bool result = programmes.AssignStudentId(2);

  // Assert
  Assert.IsTrue(result);
}

That is an elegant way of dealing with code in the main system but building a session and using data from a real database can cause us problems. What if someone else goes to the database and deletes some of your test data? Where are you maintaining it? How are you sure that a particular ID will exercise the test correctly? When things change, you lose your hair trying to find out why.

That’s the database method. Now we look at how Rhinomocks can help us instead.

public void TestAssignUndergraduateReturnsTrue()
{
  // Arrange
  IStudentProgramme exampleProgramme = new ExampleStudentProgramme(new MustBeUnderGrad())
  {
    Id = 1
  };

  Student student = new Student
  {
    Id = 2,
    Category = StudentCategory.Undergraduate
  };

  IStudentRepository studentRepository = MockRepository.GenerateStub<IStudentRepository>();
  IProgrammeRepository programmeRepository = MockRepository.GenerateStub<IProgrammeRepository>();

  programmeRepository.Stub(stuboptions => programmeRepository.GetProgrammeById(Args.Is(1))).Return(programme);
  studentRepository.Stub(stuboptions => studentRepository.GetStudentById(Args.Is(2))).Return(student);
  
  programmeRepository.Replay();
  studentRepository.Replay();

  IStudentProgrammes programmes = new StudentProgrammes(programmeRepository, studentRepository);
 
  // Act
  bool result = programmes.AssignStudentId(2);

  // Assert
  Assert.IsTrue(result);
}

What we are doing here is setting up our input objects in our code so that all the properties that we know are needed are set as we expect them. Using MockRepository.GenerateStub we create a magic proxy object that will return a certain object for a certain input. To tell it what those inputs are, we use the .Stub() call. The magic of RhinoMocks uses the lambda function to figure out what we want to do and then the call to .Return() sets the output to be returned for those inputs.

.Replay() then tells the magic proxy objects that they won’t be configured anymore and to act in the way we have told them to.

When the code under test calls the magic proxy objects we give it, it gets the objects we want it to have. Then it runs through all its own logic and if we haven’t screwed up somewhere then it will return the correct value.

This may seem more complicated right now but all the complication is up front. The key benefit is that all of your assumptions are built up here in the test. The only change that can affect your inputs are in your code. We’ve prevented the major cause of non-determinism affecting our test results.

The other key benefit is that you aren’t using other systems that you have to reach across a network or through a process barrier that could slow down tests of logic. If it’s just objects in memory, your tests will blaze through and as we all know, speed is vital in the test-write-retest cycle.

There are ways to clean up what could turn into messy tests too. In most situations, you can factor out the initial object creation because the same or similar objects will be reused a lot. Also, if you’ve got lots of calls being made into other objects, it may be worth refactoring the code under test and see why it is making so many different calls.

One last note. This isn’t test driven development since we’ve written the test last. When this returns green, how do we know that it’s because our code works and not that our test will always succeed? That’s too much for now though, go experiment.

What were your results?

Move Visual Studio’s folder out of My Documents

Tuesday, March 29th, 2011

I’ve just started in a new office and finding my way around some of their more interesting choices. One of which is to make My Documents a network share and limit the size of it. Everything in that folder gets backed up, so I only want important and useful files in it. The entries in the default Visual Studio folder don’t count.

Thankfully, there is a way to shift everything that Visual Studio creates into another location.

Use Regedit and look in HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0. Change all occurrences of the directory you don’t want (“z:\” in my case) to the one you do (“c:\local\”). You’ll also want to look in the \Profile\ key and the subkeys of \vsmacros\.

Creating a Connect Website using FacebookSDK and ASP.NET MVC 3

Monday, March 7th, 2011

The goal is to have a login link with Facebook link that lets the site personalize the content if the user wants to log in with their Facebook details. This is based on a days worth of experiments so I’m not 100% convinced I’m doing this right. Let me know in the comments if you see something wrong.

First, you need to have an application set up on Facebook. To set up your Canvas Page and Canvas URL you must first register your Facebook app and enter in your basic app information. With that complete, click the “Facebook Integration” tab on the left side of the configuration screen and make a note of the App ID and App Secret Key. Never reveal your secret key to anyone! You do not have to look at the other settings, but it is advisable to go through Facebook’s documentation and understand what they all mean.

To get started with FacebookSDK in a File|New ASP.NET MVC 3 Project, get the FacebookWebMVC package from NuGet or download package 5.0.3. You want the Newtonsoft.Json, Facebook, Facebook.Web and Facebook.Web.MVC assemblies.

Once you have referenced the right assemblies, open “/Views/Shared/_Layout.cshtml” and add the following to the bottom before the closing body tag.

    <div id="fb-root">
    </div>
    <script src="http://connect.facebook.net/en_US/all.js"></script>
    <script>
        FB.init({ appId: '@Facebook.FacebookContext.Current.AppId', status: true, cookie: true, xfbml: true });
        $('#fbLogin').click(function () {
            FB.login(function (response) {
                if (response.session) {
                    window.location = '@Url.Action("AboutMe")'
                } else {
                    // user cancelled login
                }
            });
        });
        $('#fbLogout').click(function () {
            FB.logout(function (response) {window.location = '@Url.Action("Index")';});
        });
    </script>

This script block and div initializes Facebook’s JavaScript SDK and attaches the events that authenticate and authorize this site against Facebook for the current user of the browser.

Replace the contents of “/Views/Shared/_LogOnPartial.cshtml” with the following and save the image into the “/Content/” directory.

@if (Model != null && Model.Session != null)
{
    <p>Welcome <b>@Model.DisplayName</b>! <a href="#" id="fbLogout">Logout</a></p>
}
else
{
    <p>
        <img id="fbLogin" src="../../Content/login-button.png" />
    </p>
}

Login with Facebook

There’s better ways of loading data into the partial. Using a ViewModel with DisplayName and Authenticated properties would be a good start. For now, let’s carry on with the dynamic model.

Add the following to HomeController.cs

    using Facebook;
    using Facebook.Web;

    // snip    

        public FacebookSession CurrentSession
        {
            get { return new Authorizer().Session; }
        }

        public ActionResult AboutMe()
        {
            dynamic model = new ExpandoObject();

            if (this.CurrentSession != null)
            {
                var app = new FacebookClient(this.CurrentSession.AccessToken);

                dynamic me = app.Get("me");
                dynamic friends = app.Get("/me/friends");

                model.Name = me.name;
                model.FriendCount = friends.data.Count;
            }
            else
            {
                model.Name = "Guest User";
                model.FriendCount = 0;
            }

            model.Session = this.CurrentSession;
            return View(model);
        }

The AboutMe is doing the heavy lifting. The Authorizer comes from the Facebook namespace and handles the session information. If it is not null we have a logged in user and can personalize data on the page. In this very simple case, a name and a friend count.

If you want to prevent a request with a null CurrentSession (i.e. a request from an unauthenticated Facebook user) add the [FacebookAuthorize] attribute to the Action method.

This works in a simple fashion but CurrentSession could do with being easily mockable and I’m a little wary of how complex the controller actions could get if I’m not careful. What would you recommend?