AzureWebFarm 0.9.2 Released

I’m happy to announce that I’ve just released AzureWebFarm 0.9.2 to Nuget.

This release involves months of work by myself and Matt Davies to really tighten up the farm, perform a lot of stress testing on it (including some reasonably heavy production loads) and take the (larger than we expected – I’ll do a separate blog post on this in the next few days) step to upgrade to Windows Server 2012 / .NET 4.5 support. We will be deploying this version to production farms over the next few weeks and if there are no issues then we will be releasing v1.0 in the near future.

I’m pleased to announce that with Windows Server 2012 and the Azure SDK 1.8 (which we’ve discovered comes with some quite massive and seemingly undocumented deployment speed improvements that we are reliably getting deployment times (including package upload) of around 9 minutes for a new web farm! We think this is incredible that you can get an enterprise-grade, clustered, load-balanced, IIS8 / Windows Server 2012 powered web farm with background execution capabilities that you can scale up and down in less than 10 minutes!!!

What’s new?

The changes we’ve introduced in this version are (in no particular order):

  • If a web.config file is included with a background worker application then it will no longer cause an exception in the web farm and in fact will not be overwritten
  • Upgraded to Azure SDK 1.8 along with the deployment speed improvements this entails
  • Decreased the number of files that are needed in the web farm web project significantly (now it’s just web.config, app.config, Probe.aspx, Probe.aspx.cs and WebRole.cs)
  • Added missing HTTP certificate config in the example cloud project config files
  • Set a bunch of internally used classes to `internal` from `public` to reduce the possibility of any confusion
  • Refactored core code to make it easier to unit test and maintain
  • Improved the test coverage of the codebase
  • Changes to config settings while the farm is deployed will now update the farm without requiring the roles to be manually restarted (the roles won’t automatically restart either – they will always use the latest version of the config settings)
  • Added handling to OnStop to ensure all ASP.NET requests are served before a role is restarted as per http://blogs.msdn.com/b/windowsazure/archive/2013/01/14/the-right-way-to-handle-azure-onstop-events.aspx
  • Added configurable logging via Castle.Core so you can adjust the verbosity of the trace logs and intercept the logs if you would like to redirect it to different instrumentation
  • Removed dependencies on Azure Storage within uncaught code called from OnRun() – this means that the web farm should not go down if there is an Azure Storage outage
  • Added configuration setting to allow for syncing to be disabled without needing to redeploy the farm
  • Added functionality to ensure all web deploy connections get funnelled to a single role instance at a time (with robust failover if that role instance fails). This resolves an issue when using MsDeploy v3+ on the server that we discovered and will be documented in a later blog post.
  • Changed the example config files to use Windows Server 2012
  • Opened up a readme.txt file when you install the NuGet package to outline any breaking changes
  • Improved documentation on github

Breaking Changes

If you are upgrading from a previous version of Azure Web Farm then make sure you look at the breaking changes file to see upgrade instructions as there are a number of breaking changes in this release.

Future Direction

What’s in store for Azure Web Farm in the future? This is a rough idea of the sorts of things we are looking into (we don’t have a timeline on this – if you want to help out to make it happen faster though please contact us):

  • Out of the box auto-scaling support using Wasabi
  • Better installation experience – using nuget install scripts to take away some of the tedious manual configuration when creating a new farm
  • Improving the syncing speed – it currently takes 30-90s to sync a new deployment across the farm and we are confident we can get that down significantly

TestStack.Seleno 0.4 released

Lately I’ve been spending a fair bit of spare time working hard on getting the TestStack.Seleno project ready for a (rather massive!) 0.4 release. It’s been a lot of fun and I’m quite proud of the impact the core TestStack team and other contributors have made on the library. We feel that it is “production ready” now and will be moving towards a 1.0 release in the somewhat near future.

I won’t bother going into a huge amount of detail on the release because Michael Whelan has done that already, but I’ll list down the major changes here as a tl;dr:

  • Added a bunch of global configuration options:
    • Ability to specify a Castle.Core logger factory to intercept our internal logging
    • Ability to more easily specify a non-Firefox web browser
    • Ability to specify a deployed web application out-of-the-box
    • Ability to more explicitly specify your MVC routes
    • Ability to override the minimum (implicit) wait timeout inside of Selenium
  • Ability to explicitly specify the initial page for a test and initialise the first page object in one line of code
  • Continuous Integration support (now runs in TeamCity)
  • A new HTML Control model that provides a nice API on top of Selenium Web Driver to interact with HTML controls (including easy extensibility for your own controls)
  • A clearer public API
  • Improved test coverage and extensive refactoring of the core library code

You can get the latest version of Seleno on NuGet, or check out our GitHub repository for the latest source code and the getting started documentation. Let us know what you think, or if there are any features that you would like to see. Feel free to add an issue or pull request – the more community interaction we get the better we can make Seleno!

Resolving request-scoped objects into a singleton with Autofac

This week I had an issue raised on my Github site for examples of unobtrusive validation with ASP.NET MVC. The person that raised the issue was having a problem where they wanted their fluent validation modules to be singleton, but they wanted to inject a factory that can be invoked to return a request-scoped object (in this case some sort of database store). Inevitably they came across the “No scope with a Tag matching ‘AutofacWebRequest’ is visible from the scope in which the instance was requested” error.

I’ve blogged previously about a technique for using DependencyResolver.Current and being able to unit test it for similar situations. It’s not a great solution, but it does work and at least it can be unit tested.

Low and behold though, thanks to the power of the Internet, the person that raised the issue asked a question on StackOverflow and got a really elegant solution for how to inject factories in a singleton that will correctly resolve request-scoped objects. I’m pretty excited about it so I thought I’d give it more exposure by doing this blog post.

This is the technique in all it’s glory (I’ve renamed the method name slightly to make it more readable):

public Func<T> HttpRequestScopedFactoryFor<T>()
{
    return () => DependencyResolver.Current.GetService<T>();
}

...

builder.RegisterType<SomeRequestScopedComponent>().As<ISomeRequestScopedComponent>().InstancePerHttpRequest();
builder.RegisterInstance(HttpRequestScopedFactoryFor<ISomeRequestScopedComponent>()); // this is the magic bit

This will then allow you to do something like this:

builder.RegisterType<SomeSingletonType>().As<ISomeSingletonType>().SingleInstance();

...

public class SomeSingletonType
{
    private readonly Func<ISomeRequestScopedComponent> _someRequestScopedComponentFactory;

    public SomeSingletonType(Func<ISomeRequestScopedComponent> someRequestScopedComponentFactory())
    {
        _someRequestScopedComponentFactory = someRequestScopedComponentFactory;
    }

    public void SomeMethod() {
        var requestScopedComponent = _requestScopedComponentFactory();
        ...
    }
}

Nice and even easier to unit test than using DependencyResolver.Current directly!

Big thanks to @thardy and @felix.

Announcing NHibernate.SqlAzure version 1.0!

I’m proud to be able to announce the release of version 1.0 of NHibernate.SqlAzure!

This library takes care of retrying when the transient errors that SQL Azure throws at you occur while using the NHibernate ORM. It’s been in Beta for the last few months and has been successfully used on a number of production websites.

Changes from 0.9 to 1.0

  • Bug fix when using Schema validation (thanks to @hmvs)
  • There is now a transient error detection strategy and associated NHibernate driver (SqlAzureClientDriverWithTimeoutRetries; say that 10 times fast!!) that retries for timeout exceptions (see the Github page for details and also thanks to @hmvs for a contribution towards this)
  • Some instances where exceptions where wrapped in NHibernate exceptions (batching, transactions) are now picked up as transient exceptions when before they were ignored
  • You can now easily log connection and command exceptions separately (see the CommandRetry and ConnectionRetry virtual methods on the driver class you use)
  • The documentation is a bit more comprehensive now
  • I finished writing all the automated tests I wanted to
  • Been road-tested on a number of sites over the last few months in production

This project is a collaborative effort along with my partner in code crime - Matt Davies – all code was either pair programmed together or reviewed by the other party.

Go and grab it from NuGet today and let me know how you go! Installation / usage instructions are on the Github page.

Running AspNetCompiler after creating web deploy package using VisualStudio 2012 with round-tripping to 2010

I’ve previously blogged (as a side-note of an unrelated problem I was having) the approach that I use to overcome the problem that the AspNetCompiler has when you have the extraneous web.config files in the obj folder after creating a web deploy package.

The usual way you will come across this problem is running MvcBuildViews in a subsequent build after creating the package. The solution that I previously posted included a few MSBuild targets that can be called prior to running MvcBuildViews to clean up the web deploy files.

If you have tried using these targets after upgrading your project to Visual Studio 2012 then you will have noticed that some of the targets no longer work because they have been renamed. The following code is what I now use and it is compatible with the Visual Studio 2010 round-tripping support.

  <Target Name="CleanWebDeploy" BeforeTargets="MvcBuildViews" Condition="'$(MvcBuildViews)'=='true'">
    <Message Text="Running Clean Web Deploy Target" />
    <CallTarget Targets="CleanWebsitesPackage" />
    <CallTarget Targets="CleanWebsitesPackageTempDir" Condition="'$(VisualStudioVersion)'=='10.0'" />
    <CallTarget Targets="CleanWebsitesTransformParametersFiles" Condition="'$(VisualStudioVersion)'=='10.0'" />
    <CallTarget Targets="CleanWebsitesWPPAllFilesInSingleFolder" Condition="'$(VisualStudioVersion)'!='10.0'" />
    <CallTarget Targets="CleanWebPublishPipelineIntermediateOutput" Condition="'$(VisualStudioVersion)'!='10.0'" />
  </Target>

Automated Testing of ASP.NET Web API and MVC applications

Yesterday I started working on my first professional usage of ASP.NET Web API and as part of that created a handy base class to perform full-stack unit and/or integration testing of controller actions in-process. It was based on some stuff I found online, but put my own flair on so I thought I would share it here in case anyone else found it useful. While I’m at it I thought I’d briefly outline my testing strategy for most MVC applications I write.

ASP.NET MVC Testing

When I’m testing an ASP.NET MVC application I have had good mileage with covering the following (this is a combination of what you might consider to be integration and unit tests):

  • Routes: Typically you aren’t going to change the URLs in your application (because then you would be dealing with potential search engine optimisation and bookmarking issues) so if they do change it’s a good indication that (in an MVC application) you’ve added a new route definition that has broken some existing definitions. I will typically test the URLs for all controller actions (including mapping route values to action input parameters) and test that calling Url.Route with the same parameters results in the same route being generated. This kind of testing has saved my bacon many times in the past and it is quick and effective to write the tests whenever adding a new controller action using the code I use (a version of MVCContrib.TestHelper that I modified to use NSubstitute). It’s particularly handy when you have areas in your application because they have a nasty tendency of breaking your routes.
  • Controllers: If any particular controller action is more than a few lines of code (and thus it isn’t bleedingly obviously that it’s either correct or not correct just by looking at it), then like all complex business logic I try and unit test the controllers. I do this using the Fluent MVC Testing library that I created because it’s terse and easy to write these tests.
  • Controller Instantiation: As previously blogged.
  • Filters, Filter Providers and Model Binders: I will typically unit test these, for an example see my previous post about unit testing filter providers.
  • UI Testing: If the circumstances of the project allow for it then well-placed full-stack tests provide a lot of extra confidence. My fellow TestStacker Mehdi Khalili has a brilliant slide deck on this.
  • Database Layer: I perform tests against individual queries / commands / repository methods by doing a full integration test against a real database and wrapping the whole thing in a Transaction Scope so I can roll-back any changes in the test teardown. This ensures the test database always remains clean (read: empty) and each test can work in isolation.
  • Database migrations: I like to include one test that brings the test database to version 0 and then back up to the latest version so that if you ever need to use your down migrations then you have confidence they work (as well as continuing confidence that all of your up migrations work).
  • Business logic / services / domain logic: I will always unit test this
  • Infrastructure code: Where practical I try and unit test this. Sometimes this code is tested as a result of other tests e.g. the database tests and controller instantiation tests

If there are any particular types of testing that you would like me to do a more detailed blog post feel free to add a comment below.

ASP.NET Web API

The tests above have a nice mixture of unit and integrations tests and I find that they combine to provide a good level of confidence and coverage as the codebase evolves. I have only really played around with Web API in my spare time so far so the following recommendations are likely to evolve over time, but this is my current gut feel about this kind of testing.

Firstly, there are a few good posts I came across that give a broad idea of the different ways in which you can test Web API:

And then my initial approach / thoughts:

  • Routes:The other day I stumbled across a library someone had created to do route testing for ASP.NET Web API and while I’m not a fan of the syntax they created (vs MVCContrib.TestHelper style syntax) it’s a good start in this direction. For the moment I’m thinking (as you will see) that I can take care of route testing implicitly. Furthermore, at least for my current project, the number of routes I’m dealing with doesn’t necessitate route testing. If the routes that you deal with are complex enough and or large enough in number then unit testing routes will likely provide a lot of value.
    Controllers: There is less need for a library like Fluent MVC Testing with Web API since most of your controllers will simply return the data that they queried directly and rely on formatters to give the correct response. This makes unit testing the controllers really simple. As for route testing the initial approach I’ve settled on will cover this testing anyway.
  • Controller Instantiation: For the same reason this is valuable for ASP.NET MVC projects I think this is valuable (and just as easy to test). In my current project I haven’t bothered creating this yet since I’m only dealing with one controller with a couple of dependencies so I don’t have any code for this.
  • Filters, etc.: I think there is value in unit testing these things in the same way as there is for MVC applications. In this instance the approach I’ve settled on tests these as well because it’s a full stack test. This is fine for simple filters / formatters etc., but if you have complex ones then I highly recommend unit testing them as well.
  • UI Testing: This one is interesting, because at first thought there is no UI to test so this isn’t applicable. However, the way I see it, the equivalent in API tests are testing from the viewpoint of the client/consumer e.g. if I make a get request to this URL then I expect that object in JSON format. If you are producing an API according to a specification then this is the viewpoint the specification is written in and depending on how you do things, the acceptance criteria for the work you are doing will also be in terms of this. For these reasons, I think in some ways, while it is integration testing, testing the full stack from the viewpoint of a client provides a lot of bang for buck. As I will explain further below, this is the approach I have decided to initially take. I should note that the traditional pain points of UI testing for MVC applications (cross-browser differences, really slow, out of process so you can’t easily mock things, etc.) can easily be mitigated when doing this testing, which is why I find it a suitable approach in lieu of some of the other testing I might normally do.
  • Database / business logic / infrastructure: None of this changes.

The approach I’ve taken for Web API testing

This is heavily based on the ASP.Net Web Api Integration Tests With Self Hosting post I linked to above. The problems I had with the code shown in that post was:

  • The route was defined in the test rather than re-using the routes you define in your application
  • The test itself is defined within a lamdba
  • There was no abstraction of the code to set up the server
  • The base URL was specified multiple times
  • The test was really verbose (apart from not abstracting out the server it had a stream reader and WebRequest.Create etc.)

In the end I created a base class (using NUnit, but the same applies to any unit testing framework) that abstracted away the creation of the server as well as the HTTP call. This resulted in tests that were dead simple and very terse (for the moment there is only a get request, but you can easily add other methods and headers etc.). I also exposed the dependency injection so that I could insert mocks to control whether I want to unit test the controller action or integration test it with real dependencies. In this case it uses Autofac, but again the same applies for any DI framework.

Another thing to note is that I’ve baked in support for detecting if Fiddler is currently running and proxying requests through Fiddler in that instance. That way you can seemlessly move your test between your local computer (with or without Fiddler running) and your CI server without changing any code. The fact it proxies through Fiddler makes it really easy to debug exactly what is going on too.

Two other things to note are that you need to change PingController to a controller (or any class really) in the assembly that contains your API controllers and that this assumes you have created a static method inside the RouteConfig class called RegisterApiRoutes that defines the routes for your API.

using System;
using System.Net.Http;
using System.Web.Http.SelfHost;
using Autofac;
using Autofac.Integration.WebApi;
using NUnit.Framework;
using WebApiTesting.App_Start;
using WebApiTesting.Controllers;

namespace WebApiTesting.Tests.TestHelpers
{
    class WebApiTestBase
    {
        private HttpSelfHostServer _webServer;
        protected IContainer Container { get; private set; }
        protected ContainerBuilder ContainerBuilder { get; set; }
        protected Uri BaseUri { get; private set; }

        private bool _fiddlerActive = true;

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            var client = new HttpClient();
            try
            {
                client.GetAsync("http://ipv4.fiddler/").Wait();
            }
            catch (Exception)
            {
                _fiddlerActive = false;
            }
        }

        [SetUp]
        public virtual void Setup()
        {
            BaseUri = new Uri("http://localhost:3000");
            var config = new HttpSelfHostConfiguration(BaseUri);

            ContainerBuilder = ContainerBuilder ?? new ContainerBuilder();
            ContainerBuilder.RegisterApiControllers(typeof(PingController).Assembly);
            Container = ContainerBuilder.Build();

            RouteConfig.RegisterApiRoutes(config);
            config.DependencyResolver = new AutofacWebApiDependencyResolver(Container);

            _webServer = new HttpSelfHostServer(config);
            _webServer.OpenAsync().Wait();
        }

        protected HttpResponse PerformGetTo(string url)
        {
            var client = new HttpClient();
            var response = client.GetAsync((_fiddlerActive ? "http://ipv4.fiddler:3000/" : BaseUri.ToString()) + url).Result;
            var content = response.Content.ReadAsStringAsync().Result;

            return new HttpResponse { Content = content, Response = response };
        }

        [TearDown]
        public void Teardown()
        {
            _webServer.CloseAsync().Wait();
            _webServer.Dispose();
            Container.Dispose();
            ContainerBuilder = null;
            Container = null;
        }
    }

    class HttpResponse
    {
        public string Content { get; set; }
        public HttpResponseMessage Response { get; set; }
    }
}

So, how exactly do you use this class? Great question, but first a bit of context. My example will be for a endpoint at /api/ping that takes a GET request and returns the UTC system time in ISO format within an object with a property “Timestamp” along with a 200 OK if the database is up and running or a blank response with a 500 error if the database is not up and running.

Here is my test class:

using System;
using System.Net;
using Autofac;
using NSubstitute;
using NUnit.Framework;
using WebApiTesting.Infrastructure;
using WebApiTesting.Tests.TestHelpers;

namespace WebApiTesting.Tests.Controllers
{
    internal class PingControllerTests : WebApiTestBase
    {
        private IDateTimeProvider _dateTimeProvider;
        private IPingRepository _pingRepository;

        [SetUp]
        public override void Setup()
        {
            ContainerBuilder = new ContainerBuilder();
            _dateTimeProvider = Substitute.For<IDateTimeProvider>();
            _pingRepository = Substitute.For<IPingRepository>();
            ContainerBuilder.Register(c => _dateTimeProvider);
            ContainerBuilder.Register(c => _pingRepository);
            base.Setup();
        }

        [Test]
        public void GivenTheDatabaseIsUpAndRunning_WhenGetToPing_ReturnCurrentTimestampAnd200Ok()
        {
            _dateTimeProvider.Now().Returns(new DateTimeOffset(new DateTime(2012, 11, 4, 12, 20, 6), TimeSpan.Zero));

            var response = PerformGetTo("api/ping");

            Assert.That(response.Response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
            Assert.That(response.Content, Is.EqualTo(@"{""Timestamp"":""2012-11-04 12:20:06""}"));
        }

        [Test]
        public void GivenTheDatabaseIsNotRunning_WhenGetToPing_Return500ErrorWithNoContent()
        {
            _pingRepository.When(r => r.CheckDatabase()).Do(a => { throw new Exception(); });

            var response = PerformGetTo("api/ping");

            Assert.That(response.Response.StatusCode, Is.EqualTo(HttpStatusCode.InternalServerError));
            Assert.That(response.Content, Is.EqualTo(string.Empty));
        }
    }
}

There are a few things to note:

  • To register the listener to the port you need to run Visual Studio (and your CI test runner) as admin otherwise you will get a could not register port error.
  • I used port 3000, but if you are running as admin and get an error saying that port can’t be registered it then you might have something else on that port so feel free to change.
  • Unfortunately I couldn’t make use of AutoSubstitute, but unfortunately that broke the HTTP server (I imagine because it was giving mocks for things that the server needed real stuff for). The downside of this is that I have to keep track of the dependencies of the controller within the test making the test more verbose.
  • Because I need the container builder before starting up the web server I have to create the container builder in the setup method and register everything that I need to mock for any of the tests there, rather than setting up what needs to be mocked in each individual test.
  • I am setting up and shutting down the web server for each test to isolate them, but if there are a lot of tests this might be too slow and attaching start up to fixture setup or even test assembly set up might be a better option.
  • As mentioned above for now there is only a PerformGetTo method, but it would be easy to support the other things needed.

I’ve uploaded the example source code to Github. Feel free to fork it and play around. If you have any suggestions or improvements feel free to add a comment :)

Enjoy!

Explaining seemingly weird NSubstitute behaviour

I think that NSubstitute is an absolutely amazing library! I’ve used a few different mocking libraries and NSubstitute is hands down the best one. Not only is the syntax beautiful and terse, but it’s the simplest mocking library you could ever use. Don’t know the difference between a mock and a stub? WHO CARES! It’s not something you should need to know. I couldn’t explain it better than the NSubstitute homepage:

Mock, stub, fake, spy, test double? Strict or loose? Nah, just substitute for the type you need!

NSubstitute is designed for Arrange-Act-Assert (AAA) testing, so you just need to arrange how it should work, then assert it received the calls you expected once you’re done. Because you’ve got more important code to write than whether you need a mock or a stub.

99 times out of 100 you will have nothing but pleasure with NSubstitute, but like all things it’s not perfect. When I first started using NSubstitute I didn’t realise how it was implemented and just assumed it used some sort of crazy voodoo magic. More recently, I’ve actually contributed to NSubstitute to fix a bug I was experiencing. After doing so, I understand a lot more now how it actually works. It turns out it’s not magic, but it is very clever.

One of the things that can trip you up about the way it’s implemented is due to the fact that .Returns and Arg.Any/Is are based on a static stack and thus sometimes if you do things like set up a received check or return value for a  non-virtual method or set up a return value using the result of a substituted call then what the code looks like it should do doesn’t actually happen. When this does happen, if you don’t understand the implementation of what’s going on then this can be incredibly difficult to diagnose and you will generally spend a few confused hours.

This recently happened for some of the devs on my team and I wanted to try and explain to them what was happening so I came up with a gist that shows some examples for .Returns of the effect the static stack implementation has. I haven’t done any for Arg.Is/Any at this stage.

If you come across problems with NSubstitute or you need to explain to other people this behaviour feel free to use my gist. It uses NUnit and all of the tests in the gist passed when I ran it (against NSubstitute 1.4.3).

On myself and FluentMVCTesting joining TestStack

I’d like to announce that I’m joining TestStack and my FluentMCVTesting library will become a TestStack library.

What is TestStack?

I think it can be summed up nicely by a post from one of the core TestStack team, Michael Whelan, in the blog post he wrote. tl;dr: TestStack is a collection of open source projects which mainly focus on making the left side of Marrick’s Agile Testing Quadrant easier!

Why am I joining TestStack?

I think that the libraries in TestStack are awesome and the core team are a group of people I trust and respect. It’s a pleasure to be invited into the core team and I think it’s really great for the FluentMVCTesting library to be present alongside the other awesome testing libraries.

What will happen to FluentMVCTesting?

The nuget package and namespace is changing to have a TestStack prefix for consistency with other TestStack libraries, but other than that nothing much – the library is the same library, but it’s more likely to have additions made to it and hopefully more people using it.

If you update the existing FluentMVCTesting package then it will include the new package as a dependency and wrap around the new classes, but mark the old classes as deprecated. This should provide a smooth transition to existing users of the package as well as letting them know there is a new package out there.

I’m also dropping the strong signing support for now to keep consistency with the other TestStack libraries. We will add that in due course to all the libraries if we feel there is enough demand for it.

Announcing ChameleonForms 0.1

One of the things I find frustrating with ASP.NET MVC out of the box is creating forms. That’s not to say I find it more frustrating than other frameworks or libraries though; on the contrary I think it’s painful almost always. I think ASP.NET MVC has an amazingly powerful and useful capacity to handle forms. However, out of the box I find it fiddly and annoying to output the HTML associated with the form in a consistent and maintainable way across a whole website.

The other problem occurs when you want to change the layout of the form. For instance, imagine I create a proof-of-concept application using Twitter Bootstrap to get up and running with something that looks nice quickly. I may well want to scrap the application because it turns out to not be popular or useful. On the other hand, if it became really popular then I might want to spend some more time and effort customising the look-and-feel. At that point I will more than likely want to move away from the HTML template that Twitter Bootstrap imposes on you to use a more semantic markup (e.g. definition lists).

Enter Chameleon Forms

For the last 2 years, while I was working at Curtin University I was lucky enough to be able to use a library that we developed for tersely and maintainably developing forms that conformed to the forms standard that we had at Curtin. We had the advantage that the library was able to be specific to the Curtin standard for forms and didn’t have to be very generic. We still ensured that the library was very flexible though, because we want to make sure we could use it for most of the use cases we came across and still be able to break out into straight HTML for the weird edge cases.

ChameleonForms is my attempt to use the learnings and concepts from the previous forms library I was using and apply them to a new, open source library that I can use on my personal and professional projects to ease the pain of creating forms and improve the maintainability of them.

I am implementing this library alongside Matt Davies, who I often work closely with.

This blog post is announcing the initial release of this library, which contains basic functionality only. There is more information about the library, an example of how to use it and the roadmap we have for it at the Github page.

If you want to install this initial version from NuGet then simply use:

Install-Package ChameleonForms

Enjoy!

Acceptance Criteria for Social sign-in integration

Earlier in the year I was developing some business logic to integrate social (in this case Facebook) sign-in with a website’s existing “local account”. At the time I created a set of acceptance criteria in conjunction with the product owner in order to work through the rather complex logic that results (as you will see there are quite a few permutations and it gets quite complex to express this understandably).

I recently started working on specifying some work that involves social sign-in integration and it occurred to me that the previous work I had done is probably quite relevant and reusable in other situations. To that end I’ve included the acceptance criteria below in case it’s helpful for anyone.

Note: Don’t hesitate to adjust it according to your needs; some of it is specific to the implementation that I did earlier in the year. I would say it’s worth using it as a base to consider some of the possibilities when linking your website’s login with social sign-in.

GIVEN a user is not logged in
AND doesn't have a "local account"
WHEN the user authenticates their facebook account
THEN a new "local account" will be created for them linked to their facebook account
AND the user will be logged into the new "local account"
 
 
GIVEN a user is logged in
AND has not linked a facebook account
WHEN the user authenticates their facebook account
THEN the user will be prompted for their password to link their facebook account
 
 
GIVEN a user is logged in
AND has linked their facebook account
WHEN the user authenticates their facebook account
THEN they will be redirected to the Home page
 
 
GIVEN a user is not logged in
AND has linked a facebook account
WHEN the user authenticates their facebook account
THEN the user is logged into their "local account"
 
 
GIVEN a user has linked a facebook account
AND a second user is logged in
WHEN the second user tries to authenticate that facebook account
THEN the second user will be displayed a message indicating that facebook account is linked to another account
 
 
GIVEN a user is logged in
AND has a facebook email that matches the email of a non-Facebook-linked "local account"
WHEN the user authenticates their facebook account
THEN the user will be displayed a message indicating that email address is used by another user
 
 
GIVEN a user is not logged in
AND has a facebook email that matches the email of a non-Facebook-linked "local account"
WHEN the user authenticates their facebook account
THEN the user will be prompted for their password to link their facebook account and log in
 
 
GIVEN a user is logged in
AND has not linked a facebook account
AND they have authenticated their facebook account
WHEN the user submits their password
THEN the user's facebook account will be linked to their "local account"
 
 
GIVEN a user is not logged in
AND has a facebook email that matches the email of a non-Facebook-linked "local account"
AND they have authenticated their facebook account
WHEN the user submits their password
THEN the user's facebook account will be linked to their "local account"
AND they will be logged in