This is a follow up to the 1st in this series: http://iwayneo.blogspot.co.uk/2012/10/building-www.html
And the second http://iwayneo.blogspot.co.uk/2012/10/building-www_16.html
Third day; Third blast at the site and it's been 11 days since I last looked at the code. I've done a lot of client work and a lot of work on www.sonatribe.com in between then and now so i don't really have a clue where I left it! Looking at the selenium tests I can see that the site spins up and it tries to reach the admin/categories/add URL - there's no link so I guess that's as good a place as any to start.Without getting anal about testing the UI by precompiling it and blah I'm going to dive right in and add the link to the /admin page and get that step passing. It's as simple as:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<a href="/admin/categories">Add category</a> |
One step further! Now the selenium test moves the browser to the admin/categories/add url but again there's no code to handle this. Again - all URLs start with a route so I look at the routing test and find there's no route test defined for this URL so I go ahead and add that:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Test] | |
public void When_navigating_to_manage_categories_add_url_result_is_correct() | |
{ | |
const string expectedAction = "add"; | |
const string expectedController = "Admin"; | |
const string url = "~/admin/categories/add"; | |
var result = GetRouteData(url); | |
result.Values["Action"].Should().Be(expectedAction); | |
result.Values["Controller"].Should().Be(expectedController); | |
} |
This test obviously fails as there's no route actually defined - tests don't make code durrrrrr... I'll add that to the BrightonSausageCoEcomms.RouteConfig class:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
routes.MapRoute( | |
name: "AdminCategoriesAdd", | |
url: "Admin/Categories/Add", | |
defaults: new { controller = "Admin", action = "CategoriesAdd" } | |
); |
Chuck in a cheeky little view in /Views/Admin/CategoriesAdd.cshtml with it's corresponding empty view method returning View() in the controler (test first obviously) and we're done! Spinning up the selenium test again lets us go another step further. Next line in the feature is: "And I enter "category1" into the "CategoryName" textbox". This is again going to fail because we have no CategoryName text box so I'll add that
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<input type="text" name="CategoryName" id="CategoryName"/> |
Spinning up the selenium tests again I can see the browser is taken to the add category page and the CategoryName is populated! It's almost too much to handle... There's also a checkbox to add so I'll do the same rinse and repeat until I get past that line. Once that's all good I fumble on the next big line: "When I click the "Save" button". I'll add the save button then shall I?! Now the problem isn't really here - now that I added it - that line goes through ok... The problem is the next line: "Then I should see "category1" show up in the list of existing categories"
That's a pretty big statement! First up I added the submit button but since there's no form nothing happens. Even if there were it's not going anywhere as the controller has no clue what to do with such a request. Even if it did - what the hell does it do to make that sort of magic actually happen? Curiouser and curiouser... I'll add the form tag and see wha gwarn... The code now looks like:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<form method="POST" action="/admin/categories/add"> | |
<input type="text" name="CategoryName" id="CategoryName" /> | |
<input type="checkbox" name="Enabled" id="Enabled" /> | |
<input type="submit" name="Save" id="Save" value="Save" /> | |
</form> |
Perfecto.. except an HTTP POST to that url goes nowhere - although we have the routing set up we only know how to accept the HTTP GET verb - lets make the controller able to deal with the POST verb by adding another action.
This action is going to be slightly different because we're going to be recieving data from the forms post. The name of the category and the enabled value will be sent to the action in the form of a view model. A view model is just that - it's the model specific to the view. A model is just a data structure. So our test will need to pass this viewmodel into the action. And the action will need to be decorated with the HttpPost attribute and it will return a redirect to the admin/categories view but that's pretty much all we know for now. Here's the test (I'm leaving out the attribute part for now as I'm on the train and the reception is awful!):
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Test] | |
public void When_requesting_the_admin_categories__add_post_page_result_is_correct() | |
{ | |
var controller = new AdminController(); | |
var viewModel = new CategoriesAddViewModel(); | |
var result = controller.Categories(viewModel); | |
result.Should().BeAssignableTo<ActionResult>(); | |
} |
Notice we now have a CategoriesAddViewModel - I used resharper to drive the definition of that so by the time I had the test written I had the overload for Categories(CategoriesAddViewModel) created and the CategoriesAddViewModel inside the mvc project - all be it a blank class - it's enough to get this test passing for now.
That's it for now - I'm done for today. Not a lot achieved but I'm fried!!
Comments
Post a Comment