Live Demos

Wednesday, April 28, 2010

Coding Dojo XP Part 2: TDD & BDD with Nunit, Moq, WatiN, SpecFlow, and MVC 2.0


This post is a continuation of a 3 part series about my first coding dojo experience and what we created. I’m going to assume you’ve read part 1 of this series. Otherwise, you might be lost.

With that said, let me make a correction here to part 1 :)

The feature scenario should’ve been this:

Scenario: Sign Guestbook
Given I am on the sign guestbook page
When I have filled out all required information
When I press sign
Then I should be redirected to the full list of guestbook entries and see a success message

and not this:

Scenario: Sign Guestbook
Given I have filled out all required information
When I press sign
Then I should be redirected to the full list of guestbook entries and see a success message

This means our SignGuestbookDefinitions changed to this:

    [Binding]
public class SignGuestBookDefinitions
{
[
Given(@"I am on the sign guestbook page")]
public void GivenIAmOnTheSignGuestbookPage()
{
var browser = new IE();
browser.GoTo(
"http://localhost:2345/guestbook/sign");
Assert.That(browser.Title, Is.EqualTo("Sign Guestbook"));
}

[
When(@"I have filled out all required information")]
public void GivenIHaveFilledOutAllRequiredInformation()
{
ScenarioContext.Current.Pending();
}

[
When(@"I press sign")]
public void WhenIPressSign()
{
ScenarioContext.Current.Pending();
}

[
Then(@"I should be redirected to the full list of guestbook entries and see a success message")]
public void ThenIShouldBeRedirectedToTheFullListOfGuestbookEntriesAndSeeASuccessMessage()
{
ScenarioContext.Current.Pending();
}
}

Basically, I missed an important step that makes more sense now. Sorry about that!

Let’s go ahead and dig in. So last time I said I’d pick up with the unit tests necessary to get the next step definition working in our SpecFlow feature. So that’s where we are…

First, add a new class library project called Dojo.UnitTests and add a reference to moq, nunit.framework, and the Dojo.UI.

Now we’ll create a new file called GuestbookControllerTests. Basically we’re going to test our controller because that’s where we’re going to throw our view model to our view.

Second, write our test. Here’s what our first controller test looks like:

[TestFixture]
public class GuestbookControllerTests
{
[
Test]
public void Sign_viewdata_model_should_return_SignGuestbookView()
{
var guestbookController = new GuestbookController();
var result = guestbookController.Sign();

Assert.That(result.ViewData.Model, Is.TypeOf(typeof(SignGuestbookView)));
}
}

Now, to make it pass. We need to create a new class called SignGuestbookView, which we’ll place in our Dojo.UI project under the Models folder. For the time being, it doesn’t have any properties. We want to do the bare minimum to get the test to pass.

Run the test and it will fail stating that the value was actually null. So, we have to pass in this new class to our view. To do that, we edit the GuestbookController in our Dojo.UI project. It should now look like this:

        public ViewResult Sign()
{
return View(new SignGuestbookView());
}

Okay, now we’re getting somewhere. We have all green now. However, we don’t really have anything yet. We’re trying to meet the “I have filled out all required information” step definition, so what is all required information? Well, in this case, it’s Name, Email, Comments and all are required. So…let’s keep going.

Let’s go ahead and add our properties to our SignGuestbookView so it’ll look like this:

    public class SignGuestbookView
{
public string Name { get; set; }
public string Email { get; set; }
public string Comments { get; set; }
}

I’m not going to write a test to verify that the get set works for each one. Okay, so let’s create the view. I’ll use the MVC 2.0 syntax instead of my usual fluentHTML. So, here it is:

<%=Html.ValidationSummary(false, "Important Message") %>
<%
using (Html.BeginForm())
{
%>
<fieldset>
<
legend>Sign Guestbook</legend>
<
p><%=Html.LabelFor(f=>f.Name) %><br /><%=Html.TextBoxFor(f=>f.Name) %></p>
<
p><%=Html.LabelFor(f=>f.Email) %><br /><%=Html.TextBoxFor(f => f.Email)%></p>
<
p><%=Html.LabelFor(f=>f.Comments) %><br /><%=Html.TextAreaFor(f=>f.Comments) %></p>
<
input type="submit" value="Sign" />
</
fieldset>
<%} %>

I don’t think this needs any explanation, but basically it uses the model, SignGuestbookView, passed in from the controller. The f in the lambda expression represents the model. I’ve also seen it model=>model.Name, etc, but I like the f because it’s short and to me represents field. When we hit play and browse to guestbook/sign now, we get this view:

image

So now we can go back to our feature step definitions (SignGuestbookDefinitions.cs in the Dojo.Features project) and play with some more WatiN.

So back in our SignGuestbookDefinitions class, in the GivenIHaveFilledOutAllRequiredInformation step, we’re going to fill in our textboxes. It’s pretty easy, here it is:

[When(@"I have filled out all required information")]
public void GivenIHaveFilledOutAllRequiredInformation()
{
_browser.TextField(
Find.ByName("Name")).TypeText("John Doe");
_browser.TextField(
Find.ByName("Email")).TypeText("john@email.com");
_browser.TextField(
Find.ByName("Comments")).TypeText("John wuz here.");
}

That’s it! I love WatiN, it’s really cool for browser automation. OH! I should mention, I made the browser from the first step a private field. You’ll also notice that you don’t have to GoTo a URL again because the step definitions cascade down as I mentioned in the first post.

Okay, we have our next step complete. Now let’s implement the WhenIPressSign.

        [When(@"I press sign")]
public void WhenIPressSign()
{
_browser.Button(
Find.ByValue("Sign")).Click();
}

Done! Next please! Okay, now we’re going to get into some fun stuff. So we need to redirect to a full list of guestbook entries and show a success message. So let’s handle the redirect first. Let’s write the test. I’m going to be using the MvcContrib.TestHelper for these tests. Here it is:

        [Test]
public void Sign_should_redirect_when_no_model_errors_present()
{
var result = _controller.Sign(new SignGuestbookView());

result.AssertActionRedirect().ToAction(
"Index");
}

The AssertActionRedirect is part of the MvcContrib.TestHelper…VERY HANDY! Make sure to download the new version that is compatiable with MVC 2.0. So when we run this, it fails because we’re not redirecting currently, so let’s fix that problem.

        [HttpPost]
public RedirectToRouteResult Sign(SignGuestbookView model)
{
return RedirectToAction("Index");
}

Okay, run the test again and we get green! Now what? Well, let’s go check our step and see what we need to do next. We should show a success message and a full list of entries. Let’s take care of the success message now. Here’s the new test:

[Test]
public void Sign_should_redirect_when_no_model_errors_present_and_pass_a_success_flag()
{
var result = _controller.Sign(new SignGuestbookView());

result.AssertActionRedirect()
.WithParameter(
"showSuccess", true)
.ToAction(
"Index");
}

So, let’s implement this to work in the Sign(SignGuestbookView model) action:

        [HttpPost]
public RedirectToRouteResult Sign(SignGuestbookView model)
{
return RedirectToAction("Index", new {showSuccess = true});
}

Now we need to make a change to our Index action like this:

        public ActionResult Index(bool showSuccess)
{
if (showSuccess)
ViewData[
"Success"] = "true";

return View();
}

Okay, let’s setup the display message in the Index view. This view just has this:

<html xmlns="http://www.w3.org/1999/xhtml" >
<
head runat="server">
<
title>View Guestbook</title>
</
head>
<
body>
<
div>
<%=Html.DivSuccessMessage("Guestbook entry successfully added.") %>
</div>
</
body>
</
html>

The DivSuccessMessage is a helper I wrote to check the ViewData[“Success”]. You can read more about my favorite extensions in an old post. Okay, I think we’re done with the success message. So, now we need to show a full list of guestbook entries. Well, I’m not sure how to test this one without assuming we have guestbook entries, so I’ll handle that with unit tests and in our step definition, we’re just going to make sure we’re on the right page. So, let’s go ahead and setup our final step definition and run those tests. They should all pass now. Here’s the final implementation:

[Then(@"I should be redirected to the full list of guestbook entries and see a success message")]
public void ThenIShouldBeRedirectedToTheFullListOfGuestbookEntriesAndSeeASuccessMessage()
{
Assert.That(_browser.Title, Is.EqualTo("View Guestbook"));
Assert.That(_browser.Div(Find.ByClass("success-message")).Text, Is.EqualTo("Guestbook entry successfully added."));
}

So this verifies that we’re on the right page and that our success message is displayed. You should see this:

image

I love seeing green! So, obviously we’re not done with everything required for our feature, but we’re close and have the basics all setup and configured. What’s nice is that we have built and tested the functionality and the application is ignorant of our actual implementation…because right now we don’t have any implementation. That’s a good thing. We should be able to build a whole guestbook app without ever actually knowing where we’re going to store the data. I think this is probably the safest way to develop because you know you’re not tying your application to a particular implmentation. Anyhow…let’s keep going.

First things first, we need to save our SignGuestbookView in the Sign action. Here’s our first test:

[Test]
public void Sign_should_save_and_redirect_when_no_model_errors_present()
{
var result = _controller.Sign(new SignGuestbookView());
_repository.Verify(rep=>rep.Save(
new GuestbookEntry()));

result.AssertActionRedirect().ToAction(
"Index");
}

I’m using moq to verify that a save method was called on our repository. Let’s make this pass. First we need a repository…should look like this:

    public interface IGuestbookRepository
{
void Save(GuestbookEntry model);
}

Now we need the GuestbookEntry, which is our domain model representation of a guestbook entry.

    public class GuestbookEntry
{
public string Name { get; set; }
public string Email { get; set; }
public string Comments { get; set; }
}

Now we need to define the repository in our test class like this:

private readonly Mock<IGuestbookRepository> _repository = new Mock<IGuestbookRepository>();

Okay, now we need to implement our controller action like so:

        public ActionResult Sign(SignGuestbookView model)
{
if (ViewData.ModelState.IsValid)
{
_repository.Save(model.CreateGuestbookEntry());
return RedirectToAction("Index", new {showSuccess = true});
}

return View(model);
}

Now we have to pass in our _repository in the controller’s constructor like this:

        private readonly IGuestbookRepository _repository;
public GuestbookController(IGuestbookRepository repository)
{
_repository = repository;
}

In order to finally get it to pass, I had to override the equals on the GuestbookEntry so moq could pick up the Save actually being called. So here are the tests for that implementation:

[TestFixture]
public class GuestBookEntryTests
{
[
Test]
public void GuestbookEntry_should_equal_another_GuestbookEntry_if_email_addresses_match()
{
var entry = new GuestbookEntry();

Assert.That(entry, Is.EqualTo(new GuestbookEntry()));
}

[
Test]
public void GuestbookEntry_should_not_equal_another_GuestbookEntry_if_email_addresses_do_not_match()
{
var entry = new GuestbookEntry();

Assert.That(entry, Is.Not.EqualTo(new GuestbookEntry{Email = "donotmatch@email.com"}));
}
}

Here’s the implementation:

        public override bool Equals(object obj)
{
var other = obj as GuestbookEntry;
return other != null && other.Email == Email;
}

Okay, so now all we need to do is display the guestbook entries. Well, here’s the test:

[Test]
public void Index_should_return_all_entries()
{
_repository.Setup(rep => rep.GetAll()).Returns(
new List<GuestbookEntry> {new GuestbookEntry()});
var result = _controller.Index(false);

Assert.That(result.AssertViewRendered().ViewData.Model, Is.TypeOf(typeof (List<GuestbookEntry>)));
Assert.That(((IList<GuestbookEntry>)result.AssertViewRendered().ViewData.Model).Count, Is.EqualTo(1));
}

I’m using moq again here to GetAll from my repository and I return a list with just one GuestbookEntry in it. I call the Index action and pass in false because I don’t care about showing the success message. Then I assert that the model is of type list<guestbookentry> then I assert that there is one record in the list.

So, let’s get this test to pass. We need to add a new method to the repository called GetAll like this:

    public interface IGuestbookRepository
{
void Save(GuestbookEntry model);
IList<GuestbookEntry> GetAll();
}

Also, just FYI, I added a new project called Dojo.Core and added a domain folder & interfaces folder and put the GuestbookEntry and IGuestbookRepository in that project. Anyhow, let’s keep going…so now all we need to do is implement the index action like this:

       public ActionResult Index(bool showSuccess)
{
if (showSuccess)
ViewData[
"Success"] = "true";

return View(_repository.GetAll());
}

Now we have all green. Alright, that’s it for this one. Feels good to see this:

image

Next post will have some of the implementation items in it. I probably won’t post every little detail like I have in this one and part 1, but I will provide the downloadable source. I did not get to the EmitMapper because I ended up just creating the CreateGuestbookEntry() on the view. I actually think I may have left that out of this post, but it is in the downloadable project.

Please note that when downloading the projects, you need to have SpecFlow installed, VS 2008 SP1 & MVC 2.0. Also, I’m going to add in a dummy repository and an empty constructor to the GuestbookController so the project will run without errors when you download it. I’ll tie in StructureMap in the next post.

I hope you enjoyed the post. Thanks for reading!

Download the Part 2 Solution

Shout it

88 comments:

  1. Hi! I just wanted to ask if you ever have any issues with hackers?
    My last blog (wordpress) was hacked and I ended up losing several weeks of hard work due to no
    backup. Do you have any solutions to stop hackers?
    Feel free to visit my site ... www.youtube.com

    ReplyDelete
  2. Hi there! I'm at work surfing around your blog from my new apple iphone! Just wanted to say I love reading through your blog and look forward to all your posts! Keep up the outstanding work!
    my web page - dora the explorer birthday invitations

    ReplyDelete
  3. Developing muscle mass mass is about emotion the
    muscle through the entire total rep.
    Here is my weblog hoist adjustable dumbbells

    ReplyDelete
  4. Hello, this weekend is fastidious in favor of me, because this time i am reading this wonderful informative article here at my
    home.
    Also visit my blog post ... adult acne

    ReplyDelete
  5. Ahaa, its nice dialogue about this post at
    this place at this weblog, I have read all that, so now me also commenting at this place.


    Look into my web site: how to buy a car with bad credit

    ReplyDelete
  6. Promotional stickers design your own frames are beautiful,
    and elephant wall stickers can do the same job. Products
    only with water, can be calibrated with a laser or an inkjet printer.


    my website create stickers

    ReplyDelete
  7. Also manufactures are getting thin wafers room )
    of an undisclosed width - regarding 2017. This particular washing machine among the the major models
    you require.

    Feel free to surf to my blog :: tanie noclegi zakopane

    ReplyDelete
  8. So, an area require vegetation aside produced by grasses
    may offer a cesspool you might want to. Then a septic installer
    installs the computer according to that plan.


    Feel free to visit my website ... tanie noclegi zakopane

    ReplyDelete
  9. Now you may already be aware of affiliate programs, accomplishing work or making salary online.
    This makes these user experience deserving.

    my webpage tanie noclegi zakopane

    ReplyDelete
  10. Besides the environment, the grant made it economical too,' Bahor said. With involving everyone, individuals will learn the main reason why and how you need solar juice.

    My web page :: tanie noclegi zakopane

    ReplyDelete
  11. You can also work off angst at the wellness center or here in one of unique
    swimming pools.

    Visit my web blog :: tanie noclegi zakopane

    ReplyDelete
  12. Individuals with allergy cannot become chemists or hairstylists.
    Injured cesspools may drain and release unattractive odours.


    Here is my website; rolety tychy

    ReplyDelete
  13. Spend your money when enjoying the links rather than on a first class resort.


    My blog: rolety katowice

    ReplyDelete
  14. More than the task is getting easier in today's computer and scientific disciplines age. Try to sign up for your very own spouse's
    health insurance, if you are perhaps married.

    Also visit my blog post rolety katowice

    ReplyDelete
  15. The Canoe House tastefully incorporates a restaurant, guest lounge, lounge bar as well wine cellar.


    my blog: okna katowice

    ReplyDelete
  16. They can be the appropriate ice breakers at nay gathering or party.
    Uncover a bargain of hiring T-shirt printing services might be also important.


    my page; rolety katowice

    ReplyDelete
  17. Artists try a variety having to do with materials and suggestions for creating figurines.
    Follow the instructions that come with the solution.

    my site rolety katowice

    ReplyDelete
  18. Wherever possible, erase spills when they may are warm.
    It is single safe toy for kids that can endure the rigors to
    become a child's girl doll!

    Here is my web blog: rolety tychy

    ReplyDelete
  19. If you are not prepared to do this, produces tell and again, no sale.
    On the the problem would have to arise from the bank holder's position.

    Feel free to visit my website; rolety tychy

    ReplyDelete
  20. Nevertheless it has to be done caringly to retain the natural
    sound completely. Two-chord songs like Iko-Iko, are great to ignite
    a kids interest.

    Feel free to visit my web page :: rolety tychy

    ReplyDelete
  21. These exercises are not included in view pattern of dance moves.
    If there is no plan or preparation, your excellent ratio
    will largely drop.

    Visit my web site - rolety tychy

    ReplyDelete
  22. This will make available you the gain advantage of having your current unique qualities an individual want in any shirt.
    It's also possible to buy t shirts online and are obtainable at reasonable statistics.

    Take a look at my blog: okna katowice

    ReplyDelete
  23. So, some kind of area without plants aside from grasses
    may hold a meaningful cesspool.underneath.
    Using Blogs for building self-assurance is nothing besides deception.


    Here is my page :: rolety tychy

    ReplyDelete
  24. You will ascertain a speedy tax return on your stock by comparison.
    Decided by present technology this particular DOE roadmap should be conservative.


    Visit my site: rolety tychy

    ReplyDelete
  25. Being in the independent music department has positive aspects.

    Records play a great part in binding people with unlike ethnicity.


    Check out my homepage; rolety katowice

    ReplyDelete
  26. Stairs can be a big weight for the much older. Homestays and
    bungalows always be the best modes together with accommodation on village tours in
    Kerala.

    Also visit my website rolety katowice

    ReplyDelete
  27. A complete good example is the holidays tropical island
    of Minorca. As a product a lot of those get caught right in to useless of Tax.


    My blog; rolety tychy

    ReplyDelete
  28. Whether or not this comes to maintaining cesspools, a company can handle all of
    the clean-up. That old owner may never planted trees as well as shrubs
    on your cesspool.

    Also visit my web site; okna katowice

    ReplyDelete
  29. It indisputably is, but exclusive of being excessively polished.
    These mini cookware are a sound choice for marginal roasts and fowl like Cornish hens.


    My web site ... rolety katowice

    ReplyDelete
  30. Them will set the mood for this particular event. How of them performed actually lend each
    other to sexual description of Juggalettes?

    My web site :: rolety tychy

    ReplyDelete
  31. As soon as you are not prepared to do this, they can tell and again,
    no sale. What's more, thought usually takes their serious amounts of find the lessons concluded.

    Here is my web page: rolety katowice

    ReplyDelete
  32. Each day billions of youngsters . log onto the online market place.
    At last, when you are quenched with what you keep built, put the idea apart for a little time.


    Take a look at my webpage okna katowice

    ReplyDelete
  33. Aspirin water will strengthen technique of mulching imparts against diseases.

    They specialize for treating their patients as a this therapeutic course
    of action.

    Also visit my blog post - grzejniki dekoracyjne

    ReplyDelete
  34. Applied this, it's not strange that many online businesses invest in consumer's
    service training. Now security plays greatest role in
    every one of the fields.

    Also visit my web site grzejniki chromowane

    ReplyDelete
  35. Make sure so as to monitor yourself really you don't fall out of unquestionably the habit. Plus many frequently used training treats can make unforeseen health tribulations.

    My web-site; grzejniki chromowane

    ReplyDelete
  36. You will run your power generator on bio-fuel guarantee that a complete
    fresh life. All the parts of this solar
    panel itself are perhaps very simple.

    Take a look at my web site - grzejniki chromowane

    ReplyDelete
  37. Another option may be to a gas-powered power generator and maintain keep in mind this on standby.


    my weblog ... grzejniki chromowane

    ReplyDelete
  38. Vivaldi's melodies are simple, and uncomplicated to listen to. This guidance event was fairly acclaimed by each and every the participants, performers and audience as well.

    My weblog - grzejniki chromowane

    ReplyDelete
  39. When it is regarded as sensitive, there is a need for .
    I use markers myself, that's the yes and basically no.

    Have a look at my homepage: grzejniki łazienkowe

    ReplyDelete
  40. You have to create a product that maximizes period and in
    the work out. Texas holdem poker Edge is the same as your private Colorado Hold 'Em Poker on-line coach.

    Feel free to surf to my web blog ... grzejniki łazienkowe

    ReplyDelete
  41. The level of incitement varies depending on the dog. Martingale collar has minimum
    constriction on any dog's neck applies even stress.

    Have a look at my weblog; grzejniki łazienkowe

    ReplyDelete
  42. Perhaps one thing to ponder is to certain that the boards blend in
    organically.

    Check out my page :: grzejniki chromowane

    ReplyDelete
  43. Tahiti is the largest of the most important 118 islands that define
    French Polynesia.

    Take a look at my web blog ... grzejniki dekoracyjne

    ReplyDelete
  44. Another must nurture typically the photographer's a sense love. Adjustments are something that pulls people with or even uniqueness and types on the tops.

    My homepage szkolenia ppoż

    ReplyDelete
  45. Finally it target Usa market for mammoth market and Europe for small globally market.


    Here is my website ... pomiary natężenia oświetlenia

    ReplyDelete
  46. Various credit direction firms possibly will try to efforts along with the actual bank for you.
    You effectively even see bit of first post of our call still on associated with eCover!


    my web page; minimalne wymagania maszyn

    ReplyDelete
  47. (Smile.) A new crowd was music and singing that much!
    It could very well be anything the idea we wouldn't of course believe to be more a nuisance.

    Here is my site; szkolenia z pierwszej pomocy

    ReplyDelete
  48. Also, they provide a secure and healthy connected with illumination.
    However, metal workforce need powerful siding brakes to make work faster.


    Here is my blog post :: szkolenia z pierwszej pomocy

    ReplyDelete
  49. Usually Kauai holiday escape home rental can be obtained in the area of these shorelines.


    Here is my page :: badania termowizyjne

    ReplyDelete
  50. In this particular case consider detox protocols several years
    before an the application is submitted. Make certain you are
    very much an independent contractor, not an worker.

    Also visit my site; ochrona przeciwpożarowa

    ReplyDelete
  51. So you should take some significant points from installing Registry Winner app.


    Visit my webpage - badania termowizyjne

    ReplyDelete
  52. Many companies are therefore proposing services in software program program
    development.

    Also visit my web page ... minimalne wymagania maszyn

    ReplyDelete
  53. The birth of ones e-commerce has specified the world many choices .
    . The advent of the translation features has even created a wider market
    for web surfers.

    My website ... badania termowizyjne

    ReplyDelete
  54. Training starts in just seconds away . few short several weeks.
    By not growing to be past this intentional blocker, you would not get a large number of sales.


    my blog ... szkolenia z pierwszej pomocy

    ReplyDelete
  55. You will not necessarily expected to check out the company at
    whichever point of a moment. In the end, you might find it
    an easy strategy help your vendor.

    My web blog: ochrona przeciwpożarowa

    ReplyDelete
  56. But in every case make sure this the roofer has been insured and certified.

    A certain manufacturers are simply meant to stay industry leaders.


    My web site: szkolenia bhp

    ReplyDelete
  57. Real diamonds are highly transparent, graphite completely opaque and the shortlist
    goes on.

    Feel free to visit my web page - minimalne wymagania maszyn

    ReplyDelete
  58. British traditions are along with songs as leading representations.
    Provided 1961, the Regional music.Association has been honoring the top in country music.


    Here is my website :: pomiary natężenia oświetlenia

    ReplyDelete
  59. It is about the pursuit of hopes and the eventual satisfaction when may well achieved.

    For details see the schooling resources provided below.


    Check out my blog post :: szkolenia bhp

    ReplyDelete
  60. Any mobile numbers may well be directly uploaded in the software and also your way
    through MS-Excel Format.

    My website :: badania termowizyjne

    ReplyDelete
  61. In the islands, various sized holiday rental homes are at hand.
    You can keep an eye on some of each finest rubber farms on backwater trips around Kerala.


    My web page; minimalne wymagania maszyn

    ReplyDelete
  62. The second best part about MSM observation drops is the player are really lower priced.
    With an increase in temperature a body produces considerably
    antibodies.

    Also visit my web blog; szkolenia bhp

    ReplyDelete
  63. Indie musicians can as well as exist alone without the help of indie record names.
    Utah jazz can be improvised upon and very can be classical," said Banks.

    Here is my web site http://www.przegladfinansowy.com.pl/

    ReplyDelete
  64. These books unquestionably are written by a person's well known fighters of MMA. Realize that the buyer sees bad sales folks all day, each and every day.

    My blog; http://www.style-domow.pl/

    ReplyDelete
  65. There may be more in the sense of privateness and noise seclusion in
    a Ottawa two-story home.

    My webpage gsa search engine ranker

    ReplyDelete
  66. Then you can have a great time hearing to your
    popular genre of music with these stations. Distinct artists face large numbers of challenges.


    Here is my blog: cztery-kola.com.pl - www.cztery-kola.com.pl -

    ReplyDelete
  67. The second best benefit about MSM observation drops is that they are really affordable.
    Located in this way the type of immune system has always been
    improved and its functions are heightened.

    My blog ... gsa search engine ranker

    ReplyDelete
  68. Solar energy also adds value to your home. (2) It may possibly shift a lot
    more in solar power's favor as price tag continue to moderate.

    Here is my site: gsa search engine ranker

    ReplyDelete
  69. The performance closed with a a bottle of champagne shower courtesy these Palms Pool girls.



    Also visit my web page - gsa search engine ranker

    ReplyDelete
  70. If the messaging is too detailed, then you
    are in all likelihood to pay additional. Later, other websites also expanded straight into the T-shirt
    printing documents and photos business.

    Check out my web blog :: gsa search engine ranker

    ReplyDelete
  71. Other ways to expose your site actually take place to do with your site.

    However, there are several downsides that always be noted.


    Also visit my blog: gsa search engine ranker

    ReplyDelete
  72. They also have focused on protection aspect apart ranging from providing a great number
    of free space. Koh Samui bungalows give a little more homely comfort.


    Also visit my web blog: gsa search engine ranker

    ReplyDelete
  73. That taxes an liver, kidneys and also lymph system.
    Today, the Gold District has some belonging to the most valuable legitimate estate in the
    country.

    my webpage :: gsa search engine ranker

    ReplyDelete
  74. The use of solar cells in the house usually quite very expensive.


    My weblog - gsa search engine ranker

    ReplyDelete
  75. This was basically how the particular solar panel happens to be constructed.

    You can do this through that offer them a thinning
    wash with the new water hose.

    Also visit my site http://swiadomespoleczenstwo.com.pl/

    ReplyDelete
  76. Workmanship should gain at least a one year warranty.
    You might need to help to forestall climate change solar technology
    is a means to use.

    my website: gsa search engine ranker

    ReplyDelete
  77. They've got forgotten the music tradition of ones own nation. Not necessarily ruse out loud humor kind of fun, but at least interesting.

    My page gsa search engine ranker

    ReplyDelete
  78. Come to Kauai vacation home rental and rediscover yourself in the lap of the harmony of
    nature.

    Stop by my blog - gsa search engine ranker

    ReplyDelete
  79. Also, find along with what kinds at warranties the
    building firm offers on workers and workmanship.


    Here is my homepage gsa search engine ranker

    ReplyDelete
  80. They probably know even the pit is at. The partially cleaned chemical
    was drained best suited river or the sea.

    Feel free to visit my web page :: smaczne-dania.
    pl - -

    ReplyDelete
  81. Australia has country legends like Slim Dirty and James Blundell.
    There are usually also country creators in Russia,
    Ones Middle East, The united kingdom and Germany.


    My web site gsa search engine ranker

    ReplyDelete
  82. The web screen SMS software is now gaining mammoth popularity in Of india.


    Here is my webpage ... gsa search engine ranker

    ReplyDelete
  83. 'Reinforce your veto considering something positive. Try to commit enough space just for each of these types of in their sites.

    Here is my page gsa search engine ranker

    ReplyDelete
  84. Offering solution is using rust-proofing coat on to all metal tools.

    The design and layout from the teahouses vary based on the owner's tastes.

    Feel free to visit my web blog - http://multitech-info.com.pl/

    ReplyDelete
  85. In some corporate blogs, all posts depart through a guide before they're written. You want to attach with your website reader in a absolute way.

    my web-site ... gsa search engine ranker

    ReplyDelete
  86. Now be the best suited time to look at more
    vacations too, since there would be less investment
    decision. How long will definately the kids wind up as able to play the game?


    my blog post pozycjonowanie

    ReplyDelete
  87. Understand though that these co-pays do not add
    up towards your annual deductible. Each insurer offers different amazing advantages and monthly luxury
    amounts.

    Here is my webpage: pozycjonowanie

    ReplyDelete
  88. Also the clients are offered best quality in trade of their worth.



    Feel free to visit my webpage ... pozycjonowanie

    ReplyDelete