Cucumber Spring Integration

I have a normal Spring-enabled project arranged as a Maven project. There were already JUnit tests in the project, along with the requisite Spring configuration.

I needed to add Cucumber tests to the project. I started by adding a cucumber directory to my src/test/java and src/test/resources directories.

I added my feature file in ../src/test/resources/com/cdi/igs/adapter/cucumber/features/Login.feature.

Feature: Login

  @2014w34 @US2422
  Scenario Outline: A lite registered player with email verified should be able submit username and password in the poker client.
  After submission player will see a system message to complete registration and will get re-direct to complete registration step 2 in IGP

    Given my username is "<UserName>"
    And my password is "<Password>"
    And my registration status is "lit"
    And my email verification status is verified as "<email verification status>"
    When I provide my credentials
    Then I should receive the following Poker status "<login result>"
  Examples:
    | UserName | Password   | login result            |email verification status|
    | player1  | Password#1 | AUTH_FAILED_LIT         | 1                       |
  @2014w34 @US2326
  Scenario Outline: A fully registered user should be able to login into the existing poker client. User in examples must be a fully registered user. 0 = SUCCESS, 1 = AUTH_FAILED

    Given my username is "<UserName>"
    And my password is "<Password>"
    And my registration status is "ful"
    When I provide my credentials
    Then I should receive the following Poker status "<Login Result>"
    And I should receive the following demographic data "<First Name>" "<Last Name>" "<Address1>" "<Address2>" "<City>" "<State>" "<Zip>"
    And I should have a third party authentication token

  Examples:
    | UserName | Password   | Login Result | First Name | Last Name | Address1          | Address2 | City     | State | Zip   |
    | player2  | Password#1 | SUCCESS      | Player     | Test      | 1505 Test Address | Apt 100  | New York | NY    | 80000 |


  @2014w34 @US2538
  Scenario Outline: A lite registered user  whose email is not verified will be shown the relevant messaging, and they will be requested to become fully registered
    Given my username is "<UserName>"
    And my password is "<Password>"
    And my registration status is "lit"
    And my email verification status is verified as "<email verification status>"
    When I provide my credentials
    Then I should receive the following Poker status "<login result>"

  Examples:
    | UserName    | Password        |email verification status  | login result             |
    | 8player     | Password!#01    |0                          | AUTH_FAILED_LIT_NO_EMAIL |


  @2014w36 @US2639
  Scenario Outline: Player with existing Password locked status with IGP authentication, cannot login to poker client.

    Given my username is "<UserName>"
    And my password is "<Password>"
    And my person status is "psl"
    When I provide my credentials
    Then I should receive the following Poker status "<login result>"

  Examples:
    | UserName | Password     | login result              |
    | gawky1  | Password#1    | LOCKED_PASSWORD_RESET     |

  @2014w36 @US2629
  Scenario Outline: Player with existing Reset locked status with IGP authentication, cannot login to poker client.

    Given my username is "<UserName>"
    And my password is "<Password>"
    And my person status is "rsl"
    When I provide my credentials
    Then I should receive the following Poker status "<login result>"

  Examples:
    | UserName  | Password      | login result                  |
    | gawky     | Password#1    | LOCKED_CUSTOMER_SERVICE_RESET |

I added my steps file that defines the implementations in …/src/test/java/com/cdi/igs/adapter/cucumber/steps/LoginSteps.java.

package com.cdi.igs.adapter.cucumber.steps;

import com.cdi.igs.adapter.login.LoginRequest;
import com.cdi.igs.adapter.login.LoginResponse;
import com.cdi.igs.adapter.poker.login.PokerLoginService;
import com.cdi.igs.dao.person.Person;
import com.cdi.igs.dao.person.PersonRepository;
import com.cdi.igs.dao.personhasverifiableitem.PersonHasVerifiableItem;
import com.cdi.igs.dao.personhasverifiableitem.PersonHasVerifiableItemRepository;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;

import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
 * Login cucumber steps.
 * @author norris.shelton
 */
@ContextConfiguration("classpath:TestCucumber-context.xml")
public class LoginSteps {
    @Autowired
    private PersonRepository        personRepository;
    @Autowired
    private PersonHasVerifiableItemRepository personHasVerifiableItemRepository;
    @Autowired
    private PokerLoginService       pokerLoginService;


    private String     username;
    private String     password;
    private Person     person;
    LoginResponse loginResponse;

    @Given("^my username is \"([^\"]*)\"$")
    public void my_username_is(String username) throws Throwable {
        this.username = username;
    }


    @And("^my password is \"([^\"]*)\"$")
    public void my_password_is(String password) throws Throwable {
        this.password = password;
    }

    @Given("^my registration status is \"(.*?)\"$")
    public void my_registration_status_is(String registrationStatus) throws Throwable {
        person = personRepository.findByUserName(username);
        assertEquals(registrationStatus, person.getIdRegistrationStatus());
    }



    @Then("^I should receive the following Poker status \"(.*?)\"$")
    public void i_should_receive_the_following_Poker_status(String responseStatus) throws Throwable {
        assertEquals(responseStatus, loginResponse.getStatus().value());
    }

    @Given("^my email verification status is verified as \"(.*?)\"$")
    public void my_email_verification_status_is_verified_as(String emailVerificationStatus) throws Throwable {
     List<PersonHasVerifiableItem> personHasVerifiableItemList =
             personHasVerifiableItemRepository.findByIdPersonAndIdVerifiableItemOrderByTimeStampDesc(person.getIdPerson(), "ema");
        if (!personHasVerifiableItemList.isEmpty()) {
            for (PersonHasVerifiableItem emailVerifiableItem : personHasVerifiableItemList) {
                if (emailVerifiableItem.isSuccess()) {
                    assertEquals(person.getIdPerson(),emailVerifiableItem.getIdPerson());
                    break;
                }
            }
        }
    }

    @Given("^my person status is \"(.*?)\"$")
    public void my_person_status_is(String personStatus) throws Throwable {
        person = personRepository.findByUserName(username);
        assertEquals(personStatus, person.getIdPersonStatus());
    }

    @When("^I provide my credentials$")
    public void I_provide_my_credentials() throws Throwable {
        LoginRequest loginRequest = new LoginRequest();
        loginRequest.setUserId(username);
        loginRequest.setPassword(password);
        loginResponse = pokerLoginService.login(loginRequest);
    }

    @And(
        "^I should receive the following demographic data \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"" +
        "([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$")
    public void I_should_receive_the_following_demographic_data(String firstName,
                                                                String lastName,
                                                                String address1,
                                                                String address2,
                                                                String city,
                                                                String state,
                                                                String zip)
    throws Throwable {
        assertEquals(firstName, StringUtils.trimToEmpty(loginResponse.getFirstName()));
        assertEquals(lastName, StringUtils.trimToEmpty(loginResponse.getLastName()));
        assertEquals(address1, StringUtils.trimToEmpty(loginResponse.getStreetAddress1()));
        assertEquals(address2, StringUtils.trimToEmpty(loginResponse.getStreetAddress2()));
        assertEquals(city, StringUtils.trimToEmpty(loginResponse.getCity()));
        assertEquals(state, StringUtils.trimToEmpty(loginResponse.getIdState()));
        assertEquals(zip, StringUtils.trimToEmpty(loginResponse.getZipCode()));
    }

    @And("^I should have a third party authentication token$")
    public void I_should_have_a_third_party_authentication_token() throws Throwable {
        assertNotNull(StringUtils.trimToNull(loginResponse.getThirdPartyAuthenticationToken()));
    }
}

Now that I have the feature and the steps created, I added in the Cucumber runner in
…/src/test/java/com/cdi/igs/adapter/cucumber/TestCucumber.java. Notice the glue property of @CucumberOptions. That defines directories to scan.

package com.cdi.igs.adapter.cucumber;</code>

import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;

/**
* JUnit test class for cucumber.
* @author norris.shelton
*/
@RunWith(Cucumber.class)
@CucumberOptions(
tags = {},
glue = {"com.cdi.igs.adapter.cucumber", "cucumber.api.spring"})
public class TestCucumber {
}

In the top of the LoginSteps class, there was a ContextConfiguration annotation.

@ContextConfiguration("classpath:TestCucumber-context.xml")

That Spring context config file is located in …/src/test/resources/TestCucumber-context.xml and thee contents of that are as follows:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="classpath*:TestAdapter-context.xml"/>
</beans>

It merely says use whatever Spring configuration has already been defined for the rest of the project.

Posted in Cucumber, Integration Tests, Java, JUnit, Spring, TDD, Test Driven Development, Unit Tests | Leave a comment

Creating an enum from it’s values

Enum’s provide valueOf(String) to get an enum via it’s String value.  This is good, but doesn’t help if we need to get an enum from one of it’s other values.  I added the following method to an enum.

public static OperationEnum get(String anyProperty) {

    OperationEnum returnValue = null;
    for (OperationEnum operationEnum : values()) {
        if (operationEnum.key.equals(anyProperty) ||
            operationEnum.description.equals(anyProperty)) {
            returnValue = operationEnum;
            break;
        }
    }
    if (returnValue == null) {
        returnValue = valueOf(anyProperty);
    }
    return returnValue;
}

The Enum that I have has a key and a description property. If it doesn’t find a value, I have it use the standard valueOf() implementation as a fallback.

I tested it with the following:

package com.cdi.igs.models.enums;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.junit.Assert.assertEquals;

/**
 * Tests the operation enum class.
 * @author norris.shelton
 */
public class TestOperationEnum {
    @Rule
    public ExpectedException expectedEx = ExpectedException.none();

    /**
     * Verify that an illegal argument exception is thrown if an unknown value is provided.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testIllegalArgumentException() {
        OperationEnum.get("junk");
    }

    /**
     * Verify that the enum can be found via it's value.
     */
    @Test
    public void testValue() {
        OperationEnum operationEnum = OperationEnum.get("LEAVE_TABLE");
        assertEquals(OperationEnum.LEAVE_TABLE, operationEnum);
    }

    /**
     * Verify that the enum can be found via it's key property.
     */
    @Test
    public void testKey() {
        OperationEnum operationEnum = OperationEnum.get("102");
        assertEquals(OperationEnum.CHIPS_TO_TABLE, operationEnum);
    }

    /**
     * Verify that the enum can be found via it's description property.
     */
    @Test
    public void testDescription() {
        OperationEnum operationEnum = OperationEnum.get("leave table");
        assertEquals(OperationEnum.LEAVE_TABLE, operationEnum);
    }
}
Posted in Uncategorized | Tagged , | Leave a comment

Homebrew commands for mac

I had to switch to Homebrew when we got Mavericks OSX 10.9

Update Homebrew

brew update

Upgrade outdated formulas

brew upgrade

To see what old versions of a formula would be removed

brew cleanup -n

To remove old versions of a formula

brew cleanup

Posted in Mac | Leave a comment

Hamcrest matcher – not

Have you ever had the case where you had to test for the negative of something? I was helping a teammate who wanted to test that a collection was not empty. It was pretty hard to track down how to test for that.

We settled on not()

import static org.hamcrest.Matchers.not;
...
...not(hasSize(0))

This was pretty hard to find. There wasn’t much documentation on negation.

Posted in hamcrest, Java, JUnit | Leave a comment

Regex validation with Jquery Validation Plugin

We needed several regex validations. I coded various custom validators with the regex included, so the regex could be re-used instead of typing the regex again and again.

        /**
         * Custom validator for letters (uppercase/lowercase)
         */
        $.validator.addMethod("lettersOnly", function (value, element) {
            return this.optional(element) || /^[a-zA-Z]+$/i.test(value);
        }, "Please enter letters only.");

        /**
         * Custom validator for numbers only (0-9)
         */
        $.validator.addMethod("numbersOnly", function (value, element) {
            return this.optional(element) || /^[0-9]+$/i.test(value);
        }, "Please enter numbers only.");

        /**
         * Custom validator for dates (0-9 and slashes).  Does not check month, day or year.
         */
        $.validator.addMethod("date", function (value, element) {
            return this.optional(element) || /^[0-9/]+$/i.test(value);
        }, "Please enter dates only.");

        /**
         * Custom validator for phone numbers (0-9, (, ) and -).  Does not check number of digits, etc.
         */
        $.validator.addMethod("phone", function (value, element) {
            return this.optional(element) || /^[0-9()-]+$/i.test(value);
        }, "Please enter dates only.");

        /**
         * Custom validators for letters and numbers only.  Uppercase/lowercase letters and numbers (0-9).
         */
        $.validator.addMethod("lettersAndNumbersOnly", function (value, element) {
            return this.optional(element) || /^[a-zA-Z0-9]+$/i.test(value);
        }, "Please enter letters and numbers only.");

Here is an example of how the validation was wired in via the rules section of the Jquery validation plugin

            rules: {
                firstName: {
                    required: true,
                    minlength: 1,
                    maxlength: 32,
                    lettersOnly: true
                },
Posted in javascript, JQuery | Tagged , , , | Leave a comment

Injecting value from Spring Properties in Java

This is so easy, but I rarely use it and always forget how to use it. This is how you define a properties:

<util:properties id="commonProperties" location="classpath:common-dev.properties"/>

The contents of the properties file is:

hostUrl=my.host.com

To inject it into a class:

    @Value("#{commonProperties.hostUrl}")
    private String hostUrl;
Posted in Java, Spring | Tagged , , | Leave a comment

JDK setting on Mac OS X Maverick causing you pain?

I found a very useful link

http://www.jayway.com/2014/01/15/how-to-switch-jdk-version-on-mac-os-x-maverick/

I added the following to my .profile and typed setjdk 1.7 at the command prompt. Problem solved.

function setjdk() {  
  if [ $# -ne 0 ]; then  
   removeFromPath '/System/Library/Frameworks/JavaVM.framework/Home/bin'  
   if [ -n "${JAVA_HOME+x}" ]; then  
    removeFromPath $JAVA_HOME  
   fi  
   export JAVA_HOME=`/usr/libexec/java_home -v $@`  
   export PATH=$JAVA_HOME/bin:$PATH  
  fi  
 }  
 function removeFromPath() {  
  export PATH=$(echo $PATH | sed -E -e "s;:$1;;" -e "s;$1:?;;")  
 }
setjdk 1.7
Posted in Bash, OS/X | Tagged , , , | Leave a comment