SuccessConsole Output

Started calculate disk usage of build
Finished Calculation of disk usage of build in 0 seconds
Started calculate disk usage of workspace
Finished Calculation of disk usage of workspace in 0 seconds
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building GeoGig Web API Automated Functional Tests 1.1.0
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ geogig-web-api-functional-tests ---
[INFO] Deleting /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/target
[INFO] 
[INFO] --- git-commit-id-plugin:2.1.8:revision (default) @ geogig-web-api-functional-tests ---
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ geogig-web-api-functional-tests ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ geogig-web-api-functional-tests ---
[INFO] No sources to compile
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ geogig-web-api-functional-tests ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 48 resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ geogig-web-api-functional-tests ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 10 source files to /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/target/test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.17:test (default-test) @ geogig-web-api-functional-tests ---
[INFO] Surefire report directory: /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.geogig.web.functional.WebAPICucumberHooksTest
Running org.geogig.web.functional.RunFunctionalTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.065 sec - in org.geogig.web.functional.WebAPICucumberHooksTest
@Commands
Feature: Add
  The add command allows a user to stage features in the repository and is supported through the "/repos/{repository}/add" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.mortbay.log - Logging to org.slf4j.impl.SimpleLogger(org.mortbay.log) via org.mortbay.log.Slf4jLog
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Add.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/add"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Adding outside of a transaction issues 500 "Transaction required"      # Add.feature:12
    Given There is an empty repository named repo1                                 # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/add"                                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "No transaction was specified" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Adding outside of a repository issues 404 "Not found" # Add.feature:18
    Given There is an empty multirepo server                      # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/add"                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"           # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"   # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Adding with no path filter stages all features                                               # Add.feature:25
    Given There is an empty repository named repo1                                                       # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                              # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have unstaged "Point.1" on the "repo1" repo in the "@txId" transaction                         # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    And I have unstaged "Point.2" on the "repo1" repo in the "@txId" transaction                         # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    And I have unstaged "Line.1" on the "repo1" repo in the "@txId" transaction                          # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    And the repo1 repository's "STAGE_HEAD" in the @txId transaction should have the following features: # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
    When I call "GET /repos/repo1/add?transactionId={@txId}"                                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Add/text()" equals "Success"                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "STAGE_HEAD" in the @txId transaction should have the following features: # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Adding with a path filter stages specified features                                          # Add.feature:42
    Given There is an empty repository named repo1                                                       # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                              # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have unstaged "Point.1" on the "repo1" repo in the "@txId" transaction                         # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    And I have unstaged "Point.2" on the "repo1" repo in the "@txId" transaction                         # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    And I have unstaged "Line.1" on the "repo1" repo in the "@txId" transaction                          # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    And the repo1 repository's "STAGE_HEAD" in the @txId transaction should have the following features: # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
    When I call "GET /repos/repo1/add?path=Points/Point.1&transactionId={@txId}"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Add/text()" equals "Success"                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "STAGE_HEAD" in the @txId transaction should have the following features: # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Adding on a conflicted path resolves the conflict                     # Add.feature:58
    Given There is an empty repository named repo1                                # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                       # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And There are conflicts on the "repo1" repo in the @txId transaction          # WebAPICucumberHooks.There_are_conflict(String,String)
    When I call "GET /repos/repo1/add?path=Points/Point.1&transactionId={@txId}"  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Add/text()" equals "Success"                         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And There should be no conflicts on the "repo1" repo in the @txId transaction # WebAPICucumberHooks.There_should_be_no_conflicts(String,String)
@Repo
Feature: AffectedFeatures
  The AffectedFeatures resource provides a list of features changed in a commit and is supported through the "/repos/{repository}/repo/affectedfeatures" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # AffectedFeatures.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/repo/affectedfeatures"             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: AffectedFeatures outside of a repository issues 404 "Not found" # AffectedFeatures.feature:12
    Given There is an empty multirepo server                                # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/repo/affectedfeatures"                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                     # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"             # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: AffectedFeatures with no commit issues a 400 status code     # AffectedFeatures.feature:19
    Given There is an empty repository named repo1                       # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/repo/affectedfeatures"                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                             # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "You must specify a commit id." # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: AffectedFeatures with an invalid commit issues a 400 status code   # AffectedFeatures.feature:25
    Given There is an empty repository named repo1                             # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/repo/affectedfeatures?commitId=invalid"      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "You must specify a valid commit id." # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: AffectedFeatures lists all features changed in a commit                        # AffectedFeatures.feature:31
    Given There is a default multirepo server                                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have committed "Point.1_modified" on the "repo1" repo in the "" transaction      # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo1/repo/affectedfeatures?commitId={@ObjectId|repo1|master}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                    # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "{@ObjectId|repo1|master~1:Points/Point.1}"       # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: Blame
  The blame command allows a user to see who last modified each attribute of a feature and is supported through the "/repos/{repository}/blame" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Blame.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/blame"                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling blame without a feature path issues a 500 status code                         # Blame.feature:12
    Given There is an empty repository named repo1                                                # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/blame"                                                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Required parameter 'path' was not provided." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling blame with an invalid commit issues a 500 status code                # Blame.feature:18
    Given There is an empty repository named repo1                                       # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/blame?commit=nonexistent&path=somePath"                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Could not resolve branch or commit" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling blame with an invalid feature path issues a 500 status code        # Blame.feature:24
    Given There is an empty repository named repo1                                     # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/blame?path=nonexistent"                              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "The supplied path does not exist" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling blame with a tree path issues a 500 status code                                   # Blame.feature:30
    Given There is a default multirepo server                                                         # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/blame?path=Points"                                                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "The supplied path does not resolve to a feature" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling blame with a feature path shows who modified each attribute                            # Blame.feature:36
    Given There is an empty repository named repo1                                                         # WebAPICucumberHooks.setUpEmptyRepo(String)
    And There is a feature with multiple authors on the "repo1" repo                                       # WebAPICucumberHooks.There_is_a_feature_with_multiple_authors(String)
    When I call "GET /repos/repo1/blame?path=Points/Point.1"                                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Blame/Attribute" 3 times                                # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/Blame/Attribute/commit/author/name/text()" that equals "Author1"      # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Blame/Attribute/commit/message/text()" that equals "Added Point.1"    # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Blame/Attribute/commit/author/name/text()" that equals "Author2"      # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Blame/Attribute/commit/message/text()" that equals "Modified Point.1" # WebAPICucumberHooks.checkOneXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling blame with a feature path and commit shows who modified each attribute # Blame.feature:48
    Given There is an empty repository named repo1                                         # WebAPICucumberHooks.setUpEmptyRepo(String)
    And There is a feature with multiple authors on the "repo1" repo                       # WebAPICucumberHooks.There_is_a_feature_with_multiple_authors(String)
    When I call "GET /repos/repo1/blame?path=Points/Point.1&commit=HEAD~1"                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Blame/Attribute" 3 times                # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xpath "/response/Blame/Attribute/commit/author/name/text()" equals "Author1"   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Blame/Attribute/commit/message/text()" equals "Added Point.1" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response body should not contain "Author2"                                     # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "Modified Point.1"                            # WebAPICucumberHooks.checkResponseTextNotContains(String)
@Commands
Feature: Branch
  The branch command allows a user to create and list branches and is supported through the "/repos/{repository}/branch" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Branch.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/branch"                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling branch without specifying list or a branch name issues a 500 status code # Branch.feature:12
    Given There is an empty repository named repo1                                           # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/branch"                                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Nothing to do."                         # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling branch with the list parameter lists all local branches          # Branch.feature:18
    Given There is an empty repository named repo1                                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    And There are multiple branches on the "repo1" repo                              # WebAPICucumberHooks.There_are_multiple_branches(String)
    When I call "GET /repos/repo1/branch?list=true"                                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                         # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Local/Branch" 3 times             # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/Remote/Branch" 0 times            # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/Local/Branch/name/text()" that equals "master"  # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Local/Branch/name/text()" that equals "branch1" # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Local/Branch/name/text()" that equals "branch2" # WebAPICucumberHooks.checkOneXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling branch with the list and remotes parameters lists all local and remote branches # Branch.feature:30
    Given There is an empty repository named repo1                                                  # WebAPICucumberHooks.setUpEmptyRepo(String)
    And There are multiple branches on the "repo1" repo                                             # WebAPICucumberHooks.There_are_multiple_branches(String)
    When I call "GET /repos/repo1/branch?list=true&remotes=true"                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Local/Branch" 3 times                            # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/Remote/Branch" 3 times                           # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/Local/Branch/name/text()" that equals "master"                 # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Local/Branch/name/text()" that equals "branch1"                # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Local/Branch/name/text()" that equals "branch2"                # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Remote/Branch/remoteName/text()" that equals "origin"          # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Remote/Branch/name/text()" that equals "master_remote"         # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Remote/Branch/name/text()" that equals "branch1_remote"        # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Remote/Branch/name/text()" that equals "branch2_remote"        # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And the response body should contain "branch2_remote"                                           # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling branch with a branch name creates a new branch                          # Branch.feature:47
    Given There is a default multirepo server                                               # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/branch?branchName=new_branch"                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/BranchCreated/name/text()" equals "new_branch"                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/BranchCreated/source/text()" equals "{@ObjectId|repo1|master}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/repo/manifest"                                            # WebAPICucumberHooks.callURL(String)
    Then the response body should contain "new_branch"                                      # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling branch with a branch name and source creates a new branch from the source # Branch.feature:57
    Given There is a default multirepo server                                                 # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/branch?branchName=new_branch&source=branch1"                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/BranchCreated/name/text()" equals "new_branch"                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/BranchCreated/source/text()" equals "{@ObjectId|repo1|branch1}"  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/BranchCreated/source" 1 times              # WebAPICucumberHooks.checkXPathCadinality(String,int)
    When I call "GET /repos/repo1/repo/manifest"                                              # WebAPICucumberHooks.callURL(String)
    Then the response body should contain "new_branch"                                        # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling branch with a branch name that already exists issues a 400 status code   # Branch.feature:68
    Given There is a default multirepo server                                                # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/branch?branchName=branch1"                                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "A branch named 'branch1' already exists." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling branch with a source that does not exist issues a 400 status code                   # Branch.feature:74
    Given There is a default multirepo server                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/branch?branchName=new_branch&source=nonexistent"                      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "nonexistent does not resolve to a repository object" # WebAPICucumberHooks.checkXPathEquals(String,String)
@Commands
Feature: Cat
  The cat command allows a user to display the attributes of a repository object and is supported through the "/repos/{repository}/cat" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Cat.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/cat"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling cat without specifying an object id issues a 500 status code                      # Cat.feature:12
    Given There is an empty repository named repo1                                                    # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/cat"                                                                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Required parameter 'objectid' was not provided." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling cat with an invalid object id issues a 400 status code                        # Cat.feature:18
    Given There is an empty repository named repo1                                                # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/cat?objectid=notobjectid"                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "You must specify a valid non-null ObjectId." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling cat with a nonexistent object id issues a 400 status code                                  # Cat.feature:24
    Given There is an empty repository named repo1                                                             # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/cat?objectid=0123456789012345678901234567890123456789"                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "The specified ObjectId was not found in the respository." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling cat on a commit returns details of that commit                              # Cat.feature:30
    Given There is a default multirepo server                                                   # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|master}"                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/id/text()" equals "{@ObjectId|repo1|master}"                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/parents/id/text()" equals "{@ObjectId|repo1|master~1}"      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/name/text()" equals "geogigUser"                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/email/text()" equals "repo1_Owner@geogig.org"        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/committer/name/text()" equals "geogigUser"                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/committer/email/text()" equals "repo1_Owner@geogig.org"     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/message/text()" contains "merge branch branch2 onto master" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling cat on a feature returns details of that feature                             # Cat.feature:43
    Given There is a default multirepo server                                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|master:Points/Point.1}"          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/feature/id/text()" equals "{@ObjectId|repo1|master:Points/Point.1}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/feature/attribute" 3 times                    # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "StringProp1_1"                                         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "1000"                                                  # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "POINT (0 0)"                                           # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling cat on a feature tree returns details of that tree                # Cat.feature:54
    Given There is a default multirepo server                                         # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|master:Points}"       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/tree/id/text()" equals "{@ObjectId|repo1|master:Points}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/tree/size/text()" equals "3"                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/tree/numtrees/text()" equals "0"                         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/tree/feature" 3 times              # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Point.1"                                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Point.2"                                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Point.3"                                    # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling cat on a tag returns details of that tag                                                              # Cat.feature:67
    Given There is a default multirepo server                                                                             # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And There is a tag called "tag1" on the "repo1" repo pointing to "{@ObjectId|repo1|master}" with the "My tag" message # WebAPICucumberHooks.There_is_a_tag(String,String,String,String)
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|refs/tags/tag1}"                                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/tag/id/text()" equals "{@ObjectId|repo1|refs/tags/tag1}"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/tag/commitid/text()" equals "{@ObjectId|repo1|master}"                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/tag/name/text()" equals "tag1"                                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/tag/message/text()" equals "My tag"                                                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/tag/tagger/name/text()" equals "geogigUser"                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/tag/tagger/email/text()" equals "repo1_Owner@geogig.org"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling cat on a feature type returns details of that feature type          # Cat.feature:80
    Given There is a default multirepo server                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/cat?objectid={@PointsTypeID}"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/featuretype/id/text()" equals "{@PointsTypeID}"            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/featuretype/name/text()" equals "http://geogig.org:Points" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/featuretype/attribute" 3 times       # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "sp"                                           # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "ip"                                           # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "geom"                                         # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: Checkout
  The checkout command allows a user to switch branches or resolve conflicts and is supported through the "/repos/{repository}/checkout" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Checkout.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/checkout"                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Checkout outside of a transaction issues 500 "Transaction required"    # Checkout.feature:12
    Given There is an empty repository named repo1                                 # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/checkout"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "No transaction was specified" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Checkout outside of a repository issues 404 "Not found" # Checkout.feature:18
    Given There is an empty multirepo server                        # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/checkout"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"             # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"     # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling checkout without specifying a branch or path issues a 500 status code         # Checkout.feature:25
    Given There is an empty repository named repo1                                                # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                       # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/checkout?transactionId={@txId}"                                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "No branch or commit specified for checkout." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling checkout with a branch name changes the current branch       # Checkout.feature:32
    Given There is a default multirepo server                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have a transaction as "@txId" on the "repo1" repo                      # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/checkout?transactionId={@txId}&branch=branch1" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/OldTarget/text()" equals "refs/heads/master"        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/NewTarget/text()" equals "branch1"                  # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling checkout with a conflicted path with 'ours' will checkout 'our' version of the feature                     # Checkout.feature:41
    Given There is an empty repository named repo1                                                                             # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                    # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And There are conflicts on the "repo1" repo in the @txId transaction                                                       # WebAPICucumberHooks.There_are_conflict(String,String)
    When I call "GET /repos/repo1/checkout?transactionId={@txId}&path=Points/Point.1&ours=true"                                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Path/text()" equals "Points/Point.1"                                                              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Strategy/text()" equals "ours"                                                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo1|@txId|WORK_HEAD:Points/Point.1}" equals "{@ObjectId|repo1|@txId|master:Points/Point.1}" # WebAPICucumberHooks.checkVariableEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling checkout with a conflicted path with 'theirs' will checkout 'their' version of the feature                  # Checkout.feature:52
    Given There is an empty repository named repo1                                                                              # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                     # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And There are conflicts on the "repo1" repo in the @txId transaction                                                        # WebAPICucumberHooks.There_are_conflict(String,String)
    When I call "GET /repos/repo1/checkout?transactionId={@txId}&path=Points/Point.1&theirs=true"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Path/text()" equals "Points/Point.1"                                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Strategy/text()" equals "theirs"                                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo1|@txId|WORK_HEAD:Points/Point.1}" equals "{@ObjectId|repo1|@txId|branch1:Points/Point.1}" # WebAPICucumberHooks.checkVariableEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling checkout with a conflicted path with neither 'ours' or 'theirs' issues a 500 status code                   # Checkout.feature:63
    Given There is an empty repository named repo1                                                                             # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                    # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And There are conflicts on the "repo1" repo in the @txId transaction                                                       # WebAPICucumberHooks.There_are_conflict(String,String)
    When I call "GET /repos/repo1/checkout?transactionId={@txId}&path=Points/Point.1"                                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Please specify either ours or theirs to update the feature path specified." # WebAPICucumberHooks.checkXPathEquals(String,String)
@Commands
Feature: Commit
  The commit command allows a user to commit staged changes and is supported through the "/repos/{repository}/commit" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Commit.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/commit"                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Commit outside of a transaction issues 500 "Transaction required"      # Commit.feature:12
    Given There is an empty repository named repo1                                 # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/commit"                                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "No transaction was specified" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Commit outside of a repository issues 404 "Not found" # Commit.feature:18
    Given There is an empty multirepo server                      # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/commit"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"           # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"   # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling commit with no changes creates an empty commit                    # Commit.feature:25
    Given There is an empty repository named repo1                                    # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                           # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/commit?transactionId={@txId}&message=My%20Message"  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commitId/text()" equals "{@ObjectId|repo1|@txId|master}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/added/text()" equals "0"                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/changed/text()" equals "0"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/deleted/text()" equals "0"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling commit with unstaged features creates an empty commit             # Commit.feature:36
    Given There is an empty repository named repo1                                    # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                           # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have unstaged "Point.1" on the "repo1" repo in the "@txId" transaction      # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    And I have unstaged "Point.2" on the "repo1" repo in the "@txId" transaction      # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    And I have unstaged "Line.1" on the "repo1" repo in the "@txId" transaction       # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    When I call "GET /repos/repo1/commit?transactionId={@txId}&message=My%20Message"  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commitId/text()" equals "{@ObjectId|repo1|@txId|master}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/added/text()" equals "0"                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/changed/text()" equals "0"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/deleted/text()" equals "0"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling commit with staged features commits all staged features           # Commit.feature:51
    Given There is an empty repository named repo1                                    # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                           # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have staged "Point.1" on the "repo1" repo in the "@txId" transaction        # WebAPICucumberHooks.I_have_staged(String,String,String)
    And I have staged "Point.2" on the "repo1" repo in the "@txId" transaction        # WebAPICucumberHooks.I_have_staged(String,String,String)
    And I have staged "Line.1" on the "repo1" repo in the "@txId" transaction         # WebAPICucumberHooks.I_have_staged(String,String,String)
    When I call "GET /repos/repo1/commit?transactionId={@txId}&message=My%20Message"  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commitId/text()" equals "{@ObjectId|repo1|@txId|master}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/added/text()" equals "3"                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/changed/text()" equals "0"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/deleted/text()" equals "0"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: I should be able supply commit with a different author name and commit message                                               # Commit.feature:65
    Given There is an empty repository named repo1                                                                                       # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                              # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have staged "Point.1" on the "repo1" repo in the "@txId" transaction                                                           # WebAPICucumberHooks.I_have_staged(String,String,String)
    And I have staged "Point.2" on the "repo1" repo in the "@txId" transaction                                                           # WebAPICucumberHooks.I_have_staged(String,String,String)
    And I have staged "Line.1" on the "repo1" repo in the "@txId" transaction                                                            # WebAPICucumberHooks.I_have_staged(String,String,String)
    When I call "GET /repos/repo1/commit?transactionId={@txId}&message=My%20Message&authorName=myAuthor&authorEmail=myAuthor@geogig.org" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commitId/text()" equals "{@ObjectId|repo1|@txId|master}"                                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/added/text()" equals "3"                                                                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/changed/text()" equals "0"                                                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/deleted/text()" equals "0"                                                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|@txId|master}"                                                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/name/text()" equals "myAuthor"                                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/email/text()" equals "myAuthor@geogig.org"                                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/message/text()" contains "My Message"                                                                # WebAPICucumberHooks.checkXPathValueContains(String,String)
@Commands
Feature: Config
  The config command allows a user to get and set config values and is supported through the "/repos/{repository}/config" endpoint
  The command must be executed using the HTTP GET or POST methods
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Config.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "DELETE /repos/repo1/config"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET,POST"            # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Config outside of a repository issues 404 "Not found" # Config.feature:12
    Given There is an empty multirepo server                      # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/config"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"           # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"   # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Config POST without specifying a key issues a 400 status code                                 # Config.feature:19
    Given There is an empty repository named repo1                                                        # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "POST /repos/repo1/config"                                                                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "You must specify the key when setting a config key." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Config POST without specifying a value issues a 400 status code                                 # Config.feature:25
    Given There is an empty repository named repo1                                                          # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "POST /repos/repo1/config?name=user.name"                                                   # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "You must specify the value when setting a config key." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Config POST with a name and value in the url sets the config entry and GET retrieves the set value # Config.feature:31
    Given There is an empty repository named repo1                                                             # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "POST /repos/repo1/config?name=user.name&value=myUser"                                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/config?name=user.name"                                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/value/text()" equals "myUser"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Config POST with a name and value as json sets the config entry and GET retrieves the set value # Config.feature:40
    Given There is an empty repository named repo1                                                          # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I post content-type "application/json" to "/repos/repo1/config" with                               # WebAPICucumberHooks.post_content(String,String,String)
      """
      {
        "name":"user.name",
        "value":"myUser"
      }
      """
    Then the response status should be '200'                                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/config?name=user.name"                                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/value/text()" equals "myUser"                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Config POST with a name and value as xml sets the config entry and GET retrieves the set value # Config.feature:55
    Given There is an empty repository named repo1                                                         # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I post content-type "application/xml" to "/repos/repo1/config" with                               # WebAPICucumberHooks.post_content(String,String,String)
      """
      <params>
        <name>user.name</name>
        <value>myUser</value>
      </params>
      """
    Then the response status should be '200'                                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/config?name=user.name"                                                   # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/value/text()" equals "myUser"                                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Config GET without a name will list all config entries           # Config.feature:70
    Given There is an empty repository named repo1                           # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "POST /repos/repo1/config?name=config.value1&value=myValue1" # WebAPICucumberHooks.callURL(String)
    And I call "POST /repos/repo1/config?name=config.value2&value=myValue2"  # WebAPICucumberHooks.callURL(String)
    When I call "GET /repos/repo1/config"                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response body should contain "config.value1"                     # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "myValue1"                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "config.value2"                     # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "myValue2"                          # WebAPICucumberHooks.checkResponseTextContains(String)
@RepositoryManagement
Feature: Create Repository
  Creating a repository on the server is done through the "/repos/{repository}/init" command
  The command must be executed using the HTTP PUT method
  If a repository with the provided name already exists, then a 409 "Conflict" error code shall be returned
  If the command succeeds, the response status code is 201 "Created"

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # CreateRepository.feature:8
    Given There is an empty multirepo server                         # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/init"                              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "PUT"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify trying to create an existing repo issues 409 "Conflict"                                # CreateRepository.feature:14
    Given There is a default multirepo server                                                             # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "PUT /repos/repo1/init"                                                                   # WebAPICucumberHooks.callURL(String)
    Then the response status should be '409'                                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                                              # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "false"                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/error/text()" equals "Cannot run init on an already initialized repository." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Create repository on empty server                                  # CreateRepository.feature:22
    Given There is an empty multirepo server                                   # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '201'                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                   # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "true"                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/name/text()" equals "repo1"                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/atom:link/@href" contains "/repos/repo1.xml" # WebAPICucumberHooks.checkXPathValueContains(String,String)

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed", JSON requested response # CreateRepository.feature:31
    Given There is an empty multirepo server                                                  # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/init.json"                                                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "PUT"                                          # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify trying to create an existing repo issues 409 "Conflict", JSON requested response     # CreateRepository.feature:37
    Given There is a default multirepo server                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "PUT /repos/repo1/init.json"                                                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '409'                                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                           # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "false"                                               # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.error" equals "Cannot run init on an already initialized repository." # WebAPICucumberHooks.checkJSONResponse(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Create repository on empty server, JSON requested response     # CreateRepository.feature:45
    Given There is an empty multirepo server                               # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init.json"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '201'                               # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"              # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "true"                   # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.name" equals "repo1"                # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.href" ends with "/repos/repo1.json" # WebAPICucumberHooks.checkJSONResponseEndsWith(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify JSON fomratted response of Init with JSON formatted request parameters          # CreateRepository.feature:54
    Given There is an empty multirepo server                                                       # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init.json" with the System Temp Directory as the parentDirectory # WebAPICucumberHooks.callURLWithJSONPaylod(String)
    Then the response status should be '201'                                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                      # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "true"                                           # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.name" equals "repo1"                                        # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.href" ends with "/repos/repo1.json"                         # WebAPICucumberHooks.checkJSONResponseEndsWith(String,String)
    And the parent directory of repository "repo1" equals System Temp directory                    # WebAPICucumberHooks.checkRepositoryParent(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify XML fomratted response of Init with JSON formatted request parameters      # CreateRepository.feature:64
    Given There is an empty multirepo server                                                  # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init" with the System Temp Directory as the parentDirectory # WebAPICucumberHooks.callURLWithJSONPaylod(String)
    Then the response status should be '201'                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                                  # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "true"                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/name/text()" equals "repo1"                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/atom:link/@href" contains "/repos/repo1.xml"                # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the parent directory of repository "repo1" equals System Temp directory               # WebAPICucumberHooks.checkRepositoryParent(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify JSON fomratted response of Init with URL Form encoded request parameters                 # CreateRepository.feature:74
    Given There is an empty multirepo server                                                                # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init.json" with a URL encoded Form containing a parentDirectory parameter # WebAPICucumberHooks.callURLWithFormPaylod(String)
    Then the response status should be '201'                                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                               # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "true"                                                    # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.name" equals "repo1"                                                 # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.href" ends with "/repos/repo1.json"                                  # WebAPICucumberHooks.checkJSONResponseEndsWith(String,String)
    And the parent directory of repository "repo1" equals System Temp directory                             # WebAPICucumberHooks.checkRepositoryParent(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify XML fomratted response of Init with URL Form encoded request parameters             # CreateRepository.feature:84
    Given There is an empty multirepo server                                                           # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init" with a URL encoded Form containing a parentDirectory parameter # WebAPICucumberHooks.callURLWithFormPaylod(String)
    Then the response status should be '201'                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                                           # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "true"                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/name/text()" equals "repo1"                                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/atom:link/@href" contains "/repos/repo1.xml"                         # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the parent directory of repository "repo1" equals System Temp directory                        # WebAPICucumberHooks.checkRepositoryParent(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify JSON fomratted response of Init with already existing repository                     # CreateRepository.feature:94
    Given There is a default multirepo server                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "PUT /repos/repo1/init.json" with the System Temp Directory as the parentDirectory      # WebAPICucumberHooks.callURLWithJSONPaylod(String)
    Then the response status should be '409'                                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                           # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "false"                                               # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.error" equals "Cannot run init on an already initialized repository." # WebAPICucumberHooks.checkJSONResponse(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify JSON fomratted response of Init with JSON formatted request parameters and Author          # CreateRepository.feature:102
    Given There is an empty multirepo server                                                                  # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init.json" with Author and the System Temp Directory as the parentDirectory # WebAPICucumberHooks.callURLWithJSONPayloadAndAuthor(String)
    Then the response status should be '201'                                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                                 # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "true"                                                      # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.name" equals "repo1"                                                   # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.href" ends with "/repos/repo1.json"                                    # WebAPICucumberHooks.checkJSONResponseEndsWith(String,String)
    And the parent directory of repository "repo1" equals System Temp directory                               # WebAPICucumberHooks.checkRepositoryParent(String)
    And the Author config of repository "repo1" is set                                                        # WebAPICucumberHooks.checkAuthorConfig(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify XML fomratted response of Init with JSON formatted request parameters and Author      # CreateRepository.feature:113
    Given There is an empty multirepo server                                                             # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init" with Author and the System Temp Directory as the parentDirectory # WebAPICucumberHooks.callURLWithJSONPayloadAndAuthor(String)
    Then the response status should be '201'                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                                             # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "true"                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/name/text()" equals "repo1"                                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/atom:link/@href" contains "/repos/repo1.xml"                           # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the parent directory of repository "repo1" equals System Temp directory                          # WebAPICucumberHooks.checkRepositoryParent(String)
    And the Author config of repository "repo1" is set                                                   # WebAPICucumberHooks.checkAuthorConfig(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify JSON fomratted response of Init with URL Form encoded request parameters and Author                 # CreateRepository.feature:124
    Given There is an empty multirepo server                                                                           # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init.json" with a URL encoded Form containing a parentDirectory parameter and Author # WebAPICucumberHooks.callURLWithFormPaylodWithAuthor(String)
    Then the response status should be '201'                                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                                          # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "true"                                                               # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.name" equals "repo1"                                                            # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.href" ends with "/repos/repo1.json"                                             # WebAPICucumberHooks.checkJSONResponseEndsWith(String,String)
    And the parent directory of repository "repo1" equals System Temp directory                                        # WebAPICucumberHooks.checkRepositoryParent(String)
    And the Author config of repository "repo1" is set                                                                 # WebAPICucumberHooks.checkAuthorConfig(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify XML fomratted response of Init with URL Form encoded request parameters and Author             # CreateRepository.feature:135
    Given There is an empty multirepo server                                                                      # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init" with a URL encoded Form containing a parentDirectory parameter and Author # WebAPICucumberHooks.callURLWithFormPaylodWithAuthor(String)
    Then the response status should be '201'                                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                                                      # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "true"                                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/name/text()" equals "repo1"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/atom:link/@href" contains "/repos/repo1.xml"                                    # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the parent directory of repository "repo1" equals System Temp directory                                   # WebAPICucumberHooks.checkRepositoryParent(String)
    And the Author config of repository "repo1" is set                                                            # WebAPICucumberHooks.checkAuthorConfig(String)
[Fatal Error] :1:1: Content is not allowed in prolog.

  Scenario: Verify Init with unsupported MediaType does not create a repository with defualt settings # CreateRepository.feature:146
    Given There is an empty multirepo server                                                          # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/init.json" with an unsupported media type                           # WebAPICucumberHooks.callURLWithUnsupportedMediaType(String)
    Then the response status should be '400'                                                          # WebAPICucumberHooks.checkStatusCode(int)
    And there should be no "repo1" created                                                            # WebAPICucumberHooks.checkRepoNotInitialized(String)
@RepositoryManagement
Feature: Delete Repository
  Deleting a repository through the web API is a non reversible operation.
  * In order to avoid accidental deletion of repositories, it is a two-step process:
  * first a GET call to "/repos/{repository}/delete" returns an automatically generated token with the format:
  * <response><success>true</success><token>d713df9c703733e2</token></response>.
  * To actually delete the repository, a HTTP DELETE method call to "/repos/{repository}?token={token}" must be issued, with a valid and non expired token.
  * An attempt to delete a non existent repository, results in a 404 "Not found" error code.
  * A successfull DELETE operation returns a 200 status code,
  * the XML response body is <deleted>true</deleted>, the JSON response body is '{"deleted":true}'
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Requesting delete token with wrong HTTP Method issues 405 "Method not allowed" # DeleteRepository.feature:12
    Given There is a default multirepo server                                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "POST /repos/repo1/delete"                                                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                                       # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository nonExistentRepo
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Requesting a delete token for a non existent repository issues 404 "Not found" # DeleteRepository.feature:18
    Given There is a default multirepo server                                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/nonExistentRepo/delete"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                    # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                            # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository nonExistentRepo
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Try deleting a non existent repository issues 404 "Not found" # DeleteRepository.feature:25
    Given There is a default multirepo server                             # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "DELETE /repos/nonExistentRepo?token=someToken"           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                              # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                   # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "error:No repository to delete." # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Disposing repository {}. Cause: manually removed by remove() or invalidateAll()
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Succesfully delete a repository                       # DeleteRepository.feature:32
    Given There is a default multirepo server                     # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo2/delete"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"      # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "true"        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/token"         # WebAPICucumberHooks.checkResponseContainsXPath(String)
    Then I save the response "/response/token/text()" as "@token" # WebAPICucumberHooks.saveResponseXPathValueAsVariable(String,String)
    When I call "DELETE /repos/repo2?token={@token}"              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"      # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/deleted/text()" equals "repo2"                # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Requesting delete token with wrong HTTP Method issues 405 "Method not allowed", JSON requested response # DeleteRepository.feature:45
    Given There is a default multirepo server                                                                       # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "POST /repos/repo1/delete.json"                                                                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                                                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                                                                # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository nonExistentRepo
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Requesting a delete token for a non existent repository issues 404 "Not found", JSON requested response # DeleteRepository.feature:51
    Given There is a default multirepo server                                                                       # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/nonExistentRepo/delete.json"                                                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                                             # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                                                     # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository nonExistentRepo
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Try deleting a non existent repository issues 404 "Not found", JSON requested response # DeleteRepository.feature:58
    Given There is a default multirepo server                                                      # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "DELETE /repos/nonExistentRepo.json?token=someToken"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                            # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "error:No repository to delete."                          # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Disposing repository {}. Cause: manually removed by remove() or invalidateAll()
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Succesfully delete a repository, JSON requested response # DeleteRepository.feature:65
    Given There is a default multirepo server                        # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo2/delete.json"                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"        # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "true"             # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json response "response" should contain "token"          # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    Then I save the json response "response.token" as "@token"       # WebAPICucumberHooks.saveResponseJSONValueAsVariable(String,String)
    When I call "DELETE /repos/repo2.json?token={@token}"            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"        # WebAPICucumberHooks.checkContentType(String)
    And the json object "deleted" equals "repo2"                     # WebAPICucumberHooks.checkJSONResponse(String,String)
@Repo
Feature: Depth
  The Depth resource returns the depth of the repository from a specific commit and is supported through the "/repos/{repository}/repo/getdepth" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Depth.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/repo/getdepth"                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Depth outside of a repository issues 404 "Not found" # Depth.feature:12
    Given There is an empty multirepo server                     # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/repo/getdepth"                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                     # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"          # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"  # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Depth with an invalid commit issues a 400 status code              # Depth.feature:19
    Given There is a default multirepo server                                  # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/repo/getdepth?commitId=invalid"              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                        # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "You must specify a valid commit id." # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Depth with no commit returns no depth for a non-shallow repository # Depth.feature:26
    Given There is a default multirepo server                                  # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/repo/getdepth"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                        # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain ""                                    # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository shallow
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository full

  Scenario: Depth with no commit returns the depth of a shallow repository # Depth.feature:33
    Given There is a default multirepo server with a shallow clone         # WebAPICucumberHooks.setUpDefaultMultiRepoWithShallowClone()
    When I call "GET /repos/shallow/repo/getdepth"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                               # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                    # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "1"                               # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Depth with a commit returns the number of ancestors that commit has     # Depth.feature:40
    Given There is a default multirepo server                                       # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/repo/getdepth?commitId={@ObjectId|repo1|branch1}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                             # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "1"                                        # WebAPICucumberHooks.checkResponseTextContains(String)
    When I call "GET /repos/repo1/repo/getdepth?commitId={@ObjectId|repo1|master}"  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                             # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "2"                                        # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: Diff
  The diff command allows a user to see the difference between two commits and is supported through the "/repos/{repository}/config" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Diff.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/diff"                              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Diff outside of a repository issues 404 "Not found" # Diff.feature:12
    Given There is an empty multirepo server                    # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/diff?oldRefSpec=someRefSpec"  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                    # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"         # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found" # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling diff without specifying an old ref spec issues a 500 status code                    # Diff.feature:19
    Given There is an empty repository named repo1                                                      # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/diff"                                                                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Required parameter 'oldRefSpec' was not provided." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling diff with an empty old ref spec issues a 500 status code # Diff.feature:25
    Given There is an empty repository named repo1                           # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/diff?oldRefSpec=%20"                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Invalid old ref spec"   # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling diff with an old ref spec returns all of the changes since that commit # Diff.feature:31
    Given There is a default multirepo server                                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/diff?oldRefSpec=master~2"                                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/diff" 6 times                           # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Points/Point.2"                                  # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Points/Point.3"                                  # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Lines/Line.2"                                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Lines/Line.3"                                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygons/Polygon.2"                              # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygons/Polygon.3"                              # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling diff with two ref specs returns all of the changes since those commits # Diff.feature:44
    Given There is a default multirepo server                                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/diff?oldRefSpec=master~2&newRefSpec=master~1"            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/diff" 3 times                           # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Points/Point.2"                                  # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Lines/Line.2"                                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygons/Polygon.2"                              # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Diff should support paging results                            # Diff.feature:54
    Given There is a default multirepo server                             # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/diff?oldRefSpec=master~2&page=0&show=2" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/diff" 2 times          # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Points/Point.2"                 # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Points/Point.3"                 # WebAPICucumberHooks.checkResponseTextContains(String)
    When I call "GET /repos/repo1/diff?oldRefSpec=master~2&page=1&show=2" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/diff" 2 times          # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Polygons/Polygon.2"             # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygons/Polygon.3"             # WebAPICucumberHooks.checkResponseTextContains(String)
    When I call "GET /repos/repo1/diff?oldRefSpec=master~2&page=2&show=2" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/diff" 2 times          # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Lines/Line.2"                   # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Lines/Line.3"                   # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: FeatureDiff
  The feature diff command allows a user to see the difference between two versions of a specific feature and is supported through the "/repos/{repository}/featurediff" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # FeatureDiff.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/featurediff"                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Feature diff outside of a repository issues 404 "Not found" # FeatureDiff.feature:12
    Given There is an empty multirepo server                            # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/featurediff?path=somePath"            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                 # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"         # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling feature diff without specifying a path issues a 500 status code               # FeatureDiff.feature:19
    Given There is an empty repository named repo1                                                # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/featurediff"                                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Required parameter 'path' was not provided." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling feature diff with an empty path issues a 500 status code     # FeatureDiff.feature:25
    Given There is an empty repository named repo1                               # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/featurediff?path=%20"                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Invalid path was specified" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Feature diff should work for an added feature                                                # FeatureDiff.feature:31
    Given There is a default multirepo server                                                            # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/featurediff?path=Points/Point.3&oldTreeish=master~1&newTreeish=master" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/diff" 3 times                                         # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "ADDED"                                                         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "StringProp1_3"                                                 # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "3000"                                                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "POINT (10 10)"                                                 # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should not contain "MODIFIED"                                                  # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "REMOVED"                                                   # WebAPICucumberHooks.checkResponseTextNotContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Feature diff should work for a removed feature                                               # FeatureDiff.feature:44
    Given There is a default multirepo server                                                            # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/featurediff?path=Points/Point.3&oldTreeish=master&newTreeish=master~1" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/diff" 3 times                                         # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "REMOVED"                                                       # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "StringProp1_3"                                                 # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "3000"                                                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "POINT (10 10)"                                                 # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should not contain "MODIFIED"                                                  # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "ADDED"                                                     # WebAPICucumberHooks.checkResponseTextNotContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Feature diff should work for a modified feature                                              # FeatureDiff.feature:57
    Given There is an empty repository named repo1                                                       # WebAPICucumberHooks.setUpEmptyRepo(String)
    And There is a feature with multiple authors on the "repo1" repo                                     # WebAPICucumberHooks.There_is_a_feature_with_multiple_authors(String)
    When I call "GET /repos/repo1/featurediff?path=Points/Point.1&oldTreeish=master~1&newTreeish=master" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/diff" 1 times                                         # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xpath "/response/diff/attributename/text()" equals "ip"                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/diff/changetype/text()" equals "MODIFIED"                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/diff/oldvalue/text()" equals "1000"                                         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/diff/newvalue/text()" equals "1500"                                         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response body should not contain "ADDED"                                                     # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "REMOVED"                                                   # WebAPICucumberHooks.checkResponseTextNotContains(String)
@Commands
Feature: Fetch
  The fetch command allows a user to fetch the changes from a remote repo and is supported through the "/repos/{repository}/featurediff" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Fetch.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/fetch"                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Fetch outside of a repository issues 404 "Not found" # Fetch.feature:12
    Given There is an empty multirepo server                     # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/fetch"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                     # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"          # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"  # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Fetching without specifying a remote issues a 500 status code              # Fetch.feature:19
    Given There is an empty repository named repo1                                     # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/fetch"                                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Nothing specified to fetch from." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Fetching with a remote name specified should fetch from that remote # Fetch.feature:25
    Given There is a default multirepo server with remotes                      # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/fetch?remote=repo1"                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Fetch/Remote" 1 times        # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/Fetch/Remote/Branch" 2 times # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "branch1"                              # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "master"                               # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.mortbay.log - jetty-6.1.5
[main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8182
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["7473c17eb330e528955b8d0f84b2b2800ca5d35d","87386e5600eaaa9eb911c4f89bcfed3f75da0c70"],"have":[]}
[btpool3-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 21.44 μs for 0 ids: []. Calculating reachable content ids...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 5.360 ms for 0 ids
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 537.5 μs
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 20.00 ms. Compressed size: 991 bytes. Uncompressed size: 3,179 bytes.
[btpool3-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["eeeb658a5c418e95cbef911b1d16ec753b7ee924"],"have":["7473c17eb330e528955b8d0f84b2b2800ca5d35d"]}
[btpool3-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 3.173 μs for 1 ids: [7473c17eb330e528955b8d0f84b2b2800ca5d35d]. Calculating reachable content ids...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 1.017 ms for 11 ids
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 15.34 μs
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 8 objects. Inserted: 8. Existing: 0. Time: 2.307 ms. Compressed size: 656 bytes. Uncompressed size: 1,488 bytes.
[btpool3-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["824b7a05d37e74ccc948eaa8e9ad0b33b73b33a0","a0bfad437a71b1d394b78653472757548b2ef723"],"have":["7473c17eb330e528955b8d0f84b2b2800ca5d35d","87386e5600eaaa9eb911c4f89bcfed3f75da0c70","eeeb658a5c418e95cbef911b1d16ec753b7ee924"]}
[btpool3-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 3.096 μs for 3 ids: [7473c17eb330e528955b8d0f84b2b2800ca5d35d, 87386e5600eaaa9eb911c4f89bcfed3f75da0c70, eeeb658a5c418e95cbef911b1d16ec753b7ee924]. Calculating reachable content ids...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 1.510 ms for 27 ids
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 17.10 μs
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 6 objects. Inserted: 6. Existing: 0. Time: 1.799 ms. Compressed size: 777 bytes. Uncompressed size: 1,673 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["7473c17eb330e528955b8d0f84b2b2800ca5d35d","87386e5600eaaa9eb911c4f89bcfed3f75da0c70"],"have":[]}
[btpool3-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.998 μs for 0 ids: []. Calculating reachable content ids...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 19.02 μs for 0 ids
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.14 μs
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 6.139 ms. Compressed size: 991 bytes. Uncompressed size: 3,179 bytes.
[btpool3-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["eeeb658a5c418e95cbef911b1d16ec753b7ee924","824b7a05d37e74ccc948eaa8e9ad0b33b73b33a0","a0bfad437a71b1d394b78653472757548b2ef723"],"have":["7473c17eb330e528955b8d0f84b2b2800ca5d35d","87386e5600eaaa9eb911c4f89bcfed3f75da0c70"]}
[btpool3-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.562 μs for 2 ids: [7473c17eb330e528955b8d0f84b2b2800ca5d35d, 87386e5600eaaa9eb911c4f89bcfed3f75da0c70]. Calculating reachable content ids...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 969.2 μs for 19 ids
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 12.38 μs
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 14 objects. Inserted: 14. Existing: 0. Time: 3.368 ms. Compressed size: 1,065 bytes. Uncompressed size: 3,161 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["7473c17eb330e528955b8d0f84b2b2800ca5d35d","87386e5600eaaa9eb911c4f89bcfed3f75da0c70"],"have":[]}
[btpool3-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 3.529 μs for 0 ids: []. Calculating reachable content ids...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 45.87 μs for 0 ids
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 8.445 μs
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 5.978 ms. Compressed size: 991 bytes. Uncompressed size: 3,179 bytes.
[btpool3-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["eeeb658a5c418e95cbef911b1d16ec753b7ee924","824b7a05d37e74ccc948eaa8e9ad0b33b73b33a0","a0bfad437a71b1d394b78653472757548b2ef723"],"have":["7473c17eb330e528955b8d0f84b2b2800ca5d35d","87386e5600eaaa9eb911c4f89bcfed3f75da0c70"]}
[btpool3-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 3.405 μs for 2 ids: [7473c17eb330e528955b8d0f84b2b2800ca5d35d, 87386e5600eaaa9eb911c4f89bcfed3f75da0c70]. Calculating reachable content ids...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 826.5 μs for 19 ids
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 15.61 μs
[btpool3-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 14 objects. Inserted: 14. Existing: 0. Time: 4.481 ms. Compressed size: 1,065 bytes. Uncompressed size: 3,161 bytes.
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  @HttpTest
  Scenario: Fetching with an http remote name specified should fetch from that remote # Fetch.feature:36
    Given There is a default multirepo server with http remotes                       # WebAPICucumberHooks.setUpDefaultMultiRepoWithHttpRemotes()
    When I call "GET /repos/repo3/fetch?remote=repo1"                                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Fetch/Remote" 1 times              # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/Fetch/Remote/Branch" 2 times       # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "branch1"                                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "master"                                     # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Fetching with all should fetch from all remotes                     # Fetch.feature:46
    Given There is a default multirepo server with remotes                      # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/fetch?all=true"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Fetch/Remote" 2 times        # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/Fetch/Remote/Branch" 5 times # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "branch1"                              # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "branch2"                              # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "master"                               # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "ADDED_REF"                            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should not contain "REMOVED_REF"                      # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "UPDATED_REF"                      # WebAPICucumberHooks.checkResponseTextNotContains(String)
[main] INFO org.mortbay.log - jetty-6.1.5
[main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8182
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa","e079bc12b29a2e1717e4ca4c01ce9061c8fb1cd8"],"have":[]}
[btpool4-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.337 μs for 0 ids: []. Calculating reachable content ids...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 14.19 μs for 0 ids
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 7.846 μs
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 4.170 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool4-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["eadd1164986420f979c441820bc52e3897e53d01"],"have":["5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa"]}
[btpool4-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.045 μs for 1 ids: [5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa]. Calculating reachable content ids...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 571.1 μs for 11 ids
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 12.11 μs
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 8 objects. Inserted: 8. Existing: 0. Time: 1.724 ms. Compressed size: 656 bytes. Uncompressed size: 1,488 bytes.
[btpool4-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["b2fd3883a7e72cdc9dcbed56aeb6e95d1c528607","9e36952a66a9a24346baa7aee5389a995a8e774f"],"have":["5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa","eadd1164986420f979c441820bc52e3897e53d01","e079bc12b29a2e1717e4ca4c01ce9061c8fb1cd8"]}
[btpool4-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.554 μs for 3 ids: [5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa, eadd1164986420f979c441820bc52e3897e53d01, e079bc12b29a2e1717e4ca4c01ce9061c8fb1cd8]. Calculating reachable content ids...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 887.7 μs for 27 ids
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 15.14 μs
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 6 objects. Inserted: 6. Existing: 0. Time: 1.586 ms. Compressed size: 778 bytes. Uncompressed size: 1,673 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa","e079bc12b29a2e1717e4ca4c01ce9061c8fb1cd8"],"have":[]}
[btpool4-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.247 μs for 0 ids: []. Calculating reachable content ids...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 52.14 μs for 0 ids
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 8.181 μs
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 4.576 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool4-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["eadd1164986420f979c441820bc52e3897e53d01","b2fd3883a7e72cdc9dcbed56aeb6e95d1c528607","9e36952a66a9a24346baa7aee5389a995a8e774f"],"have":["5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa","e079bc12b29a2e1717e4ca4c01ce9061c8fb1cd8"]}
[btpool4-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.944 μs for 2 ids: [5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa, e079bc12b29a2e1717e4ca4c01ce9061c8fb1cd8]. Calculating reachable content ids...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 768.8 μs for 19 ids
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 15.07 μs
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 14 objects. Inserted: 14. Existing: 0. Time: 2.673 ms. Compressed size: 1,066 bytes. Uncompressed size: 3,161 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa","e079bc12b29a2e1717e4ca4c01ce9061c8fb1cd8"],"have":[]}
[btpool4-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.460 μs for 0 ids: []. Calculating reachable content ids...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 16.79 μs for 0 ids
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 11.78 μs
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 5.044 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool4-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["eadd1164986420f979c441820bc52e3897e53d01","b2fd3883a7e72cdc9dcbed56aeb6e95d1c528607","9e36952a66a9a24346baa7aee5389a995a8e774f"],"have":["5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa","e079bc12b29a2e1717e4ca4c01ce9061c8fb1cd8"]}
[btpool4-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.368 μs for 2 ids: [5a164dc8818a331f4bcf3dfff45840e7e7f7a5aa, e079bc12b29a2e1717e4ca4c01ce9061c8fb1cd8]. Calculating reachable content ids...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 652.7 μs for 19 ids
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 13.36 μs
[btpool4-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 14 objects. Inserted: 14. Existing: 0. Time: 2.603 ms. Compressed size: 1,066 bytes. Uncompressed size: 3,161 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool4-1] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4

  @HttpTest
  Scenario: Fetching with all should fetch from all http remotes                # Fetch.feature:61
    Given There is a default multirepo server with http remotes                 # WebAPICucumberHooks.setUpDefaultMultiRepoWithHttpRemotes()
    When I call "GET /repos/repo3/fetch?all=true"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Fetch/Remote" 2 times        # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/Fetch/Remote/Branch" 5 times # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "branch1"                              # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "branch2"                              # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "master"                               # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "ADDED_REF"                            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should not contain "REMOVED_REF"                      # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "UPDATED_REF"                      # WebAPICucumberHooks.checkResponseTextNotContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Fetching with prune should prune remote branches that were deleted                       # Fetch.feature:75
    Given There is a default multirepo server with remotes                                           # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo2/fetch?all=true&prune=true"                                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                         # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Fetch/Remote" 1 times                             # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/Fetch/Remote/Branch" 1 times                      # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xpath "/response/Fetch/Remote/Branch/changeType/text()" equals "REMOVED_REF"             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Fetch/Remote/Branch/name/text()" equals "branch2"                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Fetch/Remote/Branch/oldValue/text()" equals "{@ObjectId|repo2|branch2}" # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.mortbay.log - jetty-6.1.5
[main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8182
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool5-1] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool5-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["7ba2e78a18752bda8cdc64abbf3cde3699bcca13","608df29f6323694a1ac5e7085fc0a2d92af689f7"],"have":[]}
[btpool5-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.334 μs for 0 ids: []. Calculating reachable content ids...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 14.04 μs for 0 ids
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 7.901 μs
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 4.089 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool5-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["00a2da273e2713ea2a97a4e36ce053527ba008c5"],"have":["7ba2e78a18752bda8cdc64abbf3cde3699bcca13"]}
[btpool5-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.703 μs for 1 ids: [7ba2e78a18752bda8cdc64abbf3cde3699bcca13]. Calculating reachable content ids...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 735.0 μs for 11 ids
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 15.73 μs
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 8 objects. Inserted: 8. Existing: 0. Time: 2.198 ms. Compressed size: 656 bytes. Uncompressed size: 1,488 bytes.
[btpool5-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["a397f966bc747c6b9aa346a140a6ba29f427dab9","e01c9b3fa371765cbd2fc08898c1b93f9a5eb41a"],"have":["608df29f6323694a1ac5e7085fc0a2d92af689f7","00a2da273e2713ea2a97a4e36ce053527ba008c5","7ba2e78a18752bda8cdc64abbf3cde3699bcca13"]}
[btpool5-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.893 μs for 3 ids: [608df29f6323694a1ac5e7085fc0a2d92af689f7, 00a2da273e2713ea2a97a4e36ce053527ba008c5, 7ba2e78a18752bda8cdc64abbf3cde3699bcca13]. Calculating reachable content ids...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 965.0 μs for 27 ids
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 13.18 μs
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 6 objects. Inserted: 6. Existing: 0. Time: 1.691 ms. Compressed size: 778 bytes. Uncompressed size: 1,673 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool5-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["7ba2e78a18752bda8cdc64abbf3cde3699bcca13","608df29f6323694a1ac5e7085fc0a2d92af689f7"],"have":[]}
[btpool5-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.471 μs for 0 ids: []. Calculating reachable content ids...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 14.20 μs for 0 ids
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 7.811 μs
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 3.682 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool5-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["00a2da273e2713ea2a97a4e36ce053527ba008c5","a397f966bc747c6b9aa346a140a6ba29f427dab9","e01c9b3fa371765cbd2fc08898c1b93f9a5eb41a"],"have":["608df29f6323694a1ac5e7085fc0a2d92af689f7","7ba2e78a18752bda8cdc64abbf3cde3699bcca13"]}
[btpool5-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.237 μs for 2 ids: [608df29f6323694a1ac5e7085fc0a2d92af689f7, 7ba2e78a18752bda8cdc64abbf3cde3699bcca13]. Calculating reachable content ids...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 816.7 μs for 19 ids
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 15.14 μs
[btpool5-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 14 objects. Inserted: 14. Existing: 0. Time: 4.266 ms. Compressed size: 1,065 bytes. Uncompressed size: 3,161 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  @HttpTest
  Scenario: Fetching with prune should prune remote branches that were deleted from http remote      # Fetch.feature:87
    Given There is a default multirepo server with http remotes                                      # WebAPICucumberHooks.setUpDefaultMultiRepoWithHttpRemotes()
    When I call "GET /repos/repo2/fetch?all=true&prune=true"                                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                         # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Fetch/Remote" 1 times                             # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/Fetch/Remote/Branch" 1 times                      # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xpath "/response/Fetch/Remote/Branch/changeType/text()" equals "REMOVED_REF"             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Fetch/Remote/Branch/name/text()" equals "branch2"                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Fetch/Remote/Branch/oldValue/text()" equals "{@ObjectId|repo2|branch2}" # WebAPICucumberHooks.checkXPathEquals(String,String)
@GeopackageSupport
Feature: Export GeoPackage
  The GeoPackage export Web-API allows for downloading a repository snapshot or a subset of it as a GeoPackage file.
  It is possible to filter out the downloaded content indicating the names of the layers to include from a given
  root tree, and to specify a bounding box to filter out the included features.
  Also, a flag can be passed as argument to indicate the generated geopackage shall include the Geogig GeoPackage
  extension, allowing to transparently log every change to a tracked layer in an audit table that can later be
  replyed on top of the repository.  
  
  API Spec: GET /repos/<repo>/export[.xml|.json]?format=gpkg[&root=<refspec>][&path=<layerName>[,<layerName>]+][&bbox=<boundingBox>][&interchange=<true|false>]

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # GeoPackageExport.feature:12
    Given There is an empty multirepo server                         # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "POST /repos/repo1/export?format=gpkg"               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify missing "format=gpkg" argument issues 400 "Bad request"       # GeoPackageExport.feature:18
    Given There is a default multirepo server                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/export"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                     # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "false"                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/error/text()" contains "output format not provided" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify unsupported output format argument issues 400 "Bad request"  # GeoPackageExport.feature:26
    Given There is a default multirepo server                                   # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/export?format=badFormat"                      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                    # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "false"                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/error/text()" contains "Unsupported output format" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository badRepo

  Scenario: Verify export on a non existent repository issues 404 "Not found" # GeoPackageExport.feature:34
    Given There is an empty multirepo server                                  # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/badRepo/export?format=gpkg"                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                       # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"               # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.mortbay.log - Task %s finished: %s
Found gpkg tables: [Polygons, Lines, Points]
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Export defaults: all layers from current head                                         # GeoPackageExport.feature:41
    Given There is a default multirepo server                                                     # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/export?format=gpkg"                                             # WebAPICucumberHooks.callURL(String)
    Then the response is an XML async task @taskId                                                # WebAPICucumberHooks.checkResponseIsAnXMLAsyncTask(String)
    And the task @taskId description contains "Export to Geopackage database"                     # WebAPICucumberHooks.the_task_taskId_description_contains(String,String)
    And when the task @taskId finishes                                                            # WebAPICucumberHooks.waitForAsyncTaskToFinish(String)
    Then the task @taskId status is FINISHED                                                      # WebAPICucumberHooks.checkAsyncTaskStatus(String,AsyncContext$Status)
    And the task @taskId result contains "atom:link/@href" with value "/tasks/{@taskId}/download" # WebAPICucumberHooks.the_task_taskId_result_contains_with_value(String,String,String)
    When I call "GET /tasks/{@taskId}/download"                                                   # WebAPICucumberHooks.callURL(String)
    Then the result is a valid GeoPackage file                                                    # WebAPICucumberHooks.gpkg_CheckResponseIsGeoPackage()

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed", JSON requested response # GeoPackageExport.feature:52
    Given There is an empty multirepo server                                                  # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "POST /repos/repo1/export.json?format=gpkg"                                   # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                                          # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify missing "format=gpkg" argument issues 400 "Bad request", JSON requested response # GeoPackageExport.feature:58
    Given There is a default multirepo server                                                       # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/export.json"                                                      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                       # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "false"                                           # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.error" equals "output format not provided"                        # WebAPICucumberHooks.checkJSONResponse(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify unsupported output format argument issues 400 "Bad request", JSON requested response # GeoPackageExport.feature:66
    Given There is a default multirepo server                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/export.json?format=badFormat"                                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                           # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "false"                                               # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.error" equals "Unsupported output format: badFormat"                  # WebAPICucumberHooks.checkJSONResponse(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository badRepo

  Scenario: Verify export on a non existent repository issues 404 "Not found", JSON requested response # GeoPackageExport.feature:74
    Given There is an empty multirepo server                                                           # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/badRepo/export.json?format=gpkg"                                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                                # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                                        # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.mortbay.log - Task %s finished: %s
Found gpkg tables: [Polygons, Points, Lines]
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Export defaults: all layers from current head, JSON requested response                                # GeoPackageExport.feature:81
    Given There is a default multirepo server                                                                     # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/export.json?format=gpkg"                                                        # WebAPICucumberHooks.callURL(String)
    Then the response is a JSON async task @taskId                                                                # WebAPICucumberHooks.checkResponseIsAJsonAsyncTask(String)
    And the JSON task @taskId description contains "Export to Geopackage database"                                # WebAPICucumberHooks.theJsonTaskTaskIdDescriptionContains(String,String)
    And when the JSON task @taskId finishes                                                                       # WebAPICucumberHooks.waitForAsyncJsonTaskToFinish(String)
    Then the JSON task @taskId status is FINISHED                                                                 # WebAPICucumberHooks.checkAsyncJsonTaskStatus(String,AsyncContext$Status)
    And the JSON task @taskId result contains "task.result.atom:link.href" with value "/tasks/{@taskId}/download" # WebAPICucumberHooks.theJsonTaskTaskIdResultContainsWithValue(String,String,String)
    When I call "GET /tasks/{@taskId}/download"                                                                   # WebAPICucumberHooks.callURL(String)
    Then the result is a valid GeoPackage file                                                                    # WebAPICucumberHooks.gpkg_CheckResponseIsGeoPackage()
@GeopackageSupport
Feature: Import GeoPackage
  The GeoPackage import Web-API allows for uploading a set of layers from a GeoPackage file
  onto a repository snapshot and create a new commit reflecting the imported contents. 
  The GeoPackage file is sent as a POST form arument named "fileUpload". 
  Other URL arguments can be used to control some aspects of the import.
  
  API Spec: POST /repos/<repo>/import?format=gpkg[&add=<true|false>][&alter=<true|false>]

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # GeoPackageImport.feature:10
    Given There is an empty multirepo server                         # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/import?format=gpkg"                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "POST"                # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify missing "format=gpkg" argument issues 400 "Bad request" # GeoPackageImport.feature:16
    Given There is an empty repository named repo1                         # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "POST /repos/repo1/import?transactionId={@txId}"           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                               # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"               # WebAPICucumberHooks.checkContentType(String)
    And the response xml matches                                           # WebAPICucumberHooks.checkXmlResponseMatches(String)
      """
      <response><success>false</success><error>missing required 'format' parameter</error></response>
      """
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify unsupported output format argument issues 400 "Bad request"    # GeoPackageImport.feature:27
    Given There is an empty repository named repo1                                # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                       # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "POST /repos/repo1/import?format=badFormat&transactionId={@txId}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                      # WebAPICucumberHooks.checkContentType(String)
    And the response xml matches                                                  # WebAPICucumberHooks.checkXmlResponseMatches(String)
      """
      <response><success>false</success><error>Unsupported input format: 'badFormat'</error></response>
      """
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository badRepo

  Scenario: Verify import to a non existent repository issues 404 "Not found"    # GeoPackageImport.feature:38
    Given There is an empty multirepo server                                     # WebAPICucumberHooks.setUpEmptyMultiRepo()
    And I have a geopackage file @gpkgFile                                       # WebAPICucumberHooks.gpkg_CreateSampleGeopackage(String)
    When I post @gpkgFile as "fileUpload" to "/repos/badRepo/import?format=gpkg" # WebAPICucumberHooks.gpkg_UploadFile(String,String,String)
    Then the response status should be '404'                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                          # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                  # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository targetRepo
[main] INFO org.mortbay.log - Task %s finished: %s

  Scenario: Import to an empty repository                                                                 # GeoPackageImport.feature:46
    Given There is an empty repository named targetRepo                                                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a geopackage file @gpkgFile                                                                # WebAPICucumberHooks.gpkg_CreateSampleGeopackage(String)
    And I have a transaction as "@txId" on the "targetRepo" repo                                          # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I post @gpkgFile as "fileUpload" to "/repos/targetRepo/import?format=gpkg&transactionId={@txId}" # WebAPICucumberHooks.gpkg_UploadFile(String,String,String)
    Then the response status should be '200'                                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the response is an XML async task @taskId                                                         # WebAPICucumberHooks.checkResponseIsAnXMLAsyncTask(String)
    And the task @taskId description contains "Importing GeoPackage database file."                       # WebAPICucumberHooks.the_task_taskId_description_contains(String,String)
    And when the task @taskId finishes                                                                    # WebAPICucumberHooks.waitForAsyncTaskToFinish(String)
    Then the task @taskId status is FINISHED                                                              # WebAPICucumberHooks.checkAsyncTaskStatus(String,AsyncContext$Status)
    And the xpath "/task/result/commit/id/text()" equals "{@ObjectId|targetRepo|@txId|master}"            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/task/result/commit/tree"                                        # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And I end the transaction with id "@txId" on the "targetRepo" repo                                    # WebAPICucumberHooks.endTransaction(String,String)
    And the targetRepo repository's "HEAD" should have the following features:                            # WebAPICucumberHooks.verifyRepositoryContents(String,String,DataTable)
    And I prune the task @taskId                                                                          # WebAPICucumberHooks.prune_task(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.mortbay.log - Task %s finished: %s
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Import an interchange geopackage with fast-forward merge                                                                               # GeoPackageImport.feature:66
    Given There is a default multirepo server                                                                                                      # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I export Points from "repo1" to a geopackage file with audit logs as @gpkgFile                                                             # WebAPICucumberHooks.gpkg_ExportAuditLogs(String,String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                        # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I add Points/4 to the geopackage file @gpkgFile                                                                                           # WebAPICucumberHooks.gpkg_AddFeature(String)
    And I post @gpkgFile as "fileUpload" to "/repos/repo1/import?format=gpkg&message=Imported%20Geopackage&interchange=true&transactionId={@txId}" # WebAPICucumberHooks.gpkg_UploadFile(String,String,String)
    Then the response status should be '200'                                                                                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response is an XML async task @taskId                                                                                                  # WebAPICucumberHooks.checkResponseIsAnXMLAsyncTask(String)
    And the task @taskId description contains "Importing GeoPackage database file."                                                                # WebAPICucumberHooks.the_task_taskId_description_contains(String,String)
    And when the task @taskId finishes                                                                                                             # WebAPICucumberHooks.waitForAsyncTaskToFinish(String)
    Then the task @taskId status is FINISHED                                                                                                       # WebAPICucumberHooks.checkAsyncTaskStatus(String,AsyncContext$Status)
    And the xpath "/task/result/newCommit/id/text()" equals "{@ObjectId|repo1|@txId|master}"                                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/task/result/newCommit/tree"                                                                              # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And the xpath "/task/result/newCommit/message" equals "Imported Geopackage"                                                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/task/result/importCommit/id/text()" equals "{@ObjectId|repo1|@txId|master}"                                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/task/result/importCommit/tree"                                                                           # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And the xpath "/task/result/importCommit/message" equals "Imported Geopackage"                                                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/task/result/NewFeatures/type/@name" equals "Points"                                                                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/task/result/NewFeatures/type/id/@provided" 1 times                                                       # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/task/result/NewFeatures/type/id/@assigned" 1 times                                                       # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And I save the response "/task/result/NewFeatures/type/id/@assigned" as "@newFeatureId"                                                        # WebAPICucumberHooks.saveResponseXPathValueAsVariable(String,String)
    And I end the transaction with id "@txId" on the "repo1" repo                                                                                  # WebAPICucumberHooks.endTransaction(String,String)
    And the repo1 repository's "HEAD" should have the following features:                                                                          # WebAPICucumberHooks.verifyRepositoryContents(String,String,DataTable)
    And I prune the task @taskId                                                                                                                   # WebAPICucumberHooks.prune_task(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.mortbay.log - Task %s finished: %s
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Import an interchange geopackage with non-conflicting merge                                                                            # GeoPackageImport.feature:96
    Given There is a default multirepo server                                                                                                      # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I export Points from "repo1" to a geopackage file with audit logs as @gpkgFile                                                             # WebAPICucumberHooks.gpkg_ExportAuditLogs(String,String)
    When I add Points/4 to the geopackage file @gpkgFile                                                                                           # WebAPICucumberHooks.gpkg_AddFeature(String)
    And I have removed "Point.1" on the "repo1" repo in the "" transaction                                                                         # WebAPICucumberHooks.I_have_removed(String,String,String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                        # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I post @gpkgFile as "fileUpload" to "/repos/repo1/import?format=gpkg&message=Imported%20Geopackage&interchange=true&transactionId={@txId}" # WebAPICucumberHooks.gpkg_UploadFile(String,String,String)
    Then the response status should be '200'                                                                                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response is an XML async task @taskId                                                                                                  # WebAPICucumberHooks.checkResponseIsAnXMLAsyncTask(String)
    And the task @taskId description contains "Importing GeoPackage database file."                                                                # WebAPICucumberHooks.the_task_taskId_description_contains(String,String)
    And when the task @taskId finishes                                                                                                             # WebAPICucumberHooks.waitForAsyncTaskToFinish(String)
    Then the task @taskId status is FINISHED                                                                                                       # WebAPICucumberHooks.checkAsyncTaskStatus(String,AsyncContext$Status)
    And the xpath "/task/result/newCommit/id/text()" equals "{@ObjectId|repo1|@txId|master}"                                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/task/result/newCommit/tree"                                                                              # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And the xpath "/task/result/newCommit/message" equals "Merge: Imported Geopackage"                                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/task/result/importCommit/id/text()" equals "{@ObjectId|repo1|@txId|master^2}"                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/task/result/importCommit/tree"                                                                           # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And the xpath "/task/result/importCommit/message" equals "Imported Geopackage"                                                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/task/result/NewFeatures/type/@name" equals "Points"                                                                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/task/result/NewFeatures/type/id/@provided" 1 times                                                       # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/task/result/NewFeatures/type/id/@assigned" 1 times                                                       # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And I save the response "/task/result/NewFeatures/type/id/@assigned" as "@newFeatureId"                                                        # WebAPICucumberHooks.saveResponseXPathValueAsVariable(String,String)
    And I end the transaction with id "@txId" on the "repo1" repo                                                                                  # WebAPICucumberHooks.endTransaction(String,String)
    And the repo1 repository's "HEAD" should have the following features:                                                                          # WebAPICucumberHooks.verifyRepositoryContents(String,String,DataTable)
    And I prune the task @taskId                                                                                                                   # WebAPICucumberHooks.prune_task(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.mortbay.log - Task %s finished: %s
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Import an interchange geopackage with conflicting merge                                                                                # GeoPackageImport.feature:126
    Given There is a default multirepo server                                                                                                      # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I export Points from "repo1" to a geopackage file with audit logs as @gpkgFile                                                             # WebAPICucumberHooks.gpkg_ExportAuditLogs(String,String)
    When I modify the Point features in the geopackage file @gpkgFile                                                                              # WebAPICucumberHooks.gpkg_ModifyFeature(String)
    And I add Points/4 to the geopackage file @gpkgFile                                                                                            # WebAPICucumberHooks.gpkg_AddFeature(String)
    And I have removed "Point.1" on the "repo1" repo in the "" transaction                                                                         # WebAPICucumberHooks.I_have_removed(String,String,String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                        # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I post @gpkgFile as "fileUpload" to "/repos/repo1/import?format=gpkg&message=Imported%20Geopackage&interchange=true&transactionId={@txId}" # WebAPICucumberHooks.gpkg_UploadFile(String,String,String)
    Then the response status should be '200'                                                                                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response is an XML async task @taskId                                                                                                  # WebAPICucumberHooks.checkResponseIsAnXMLAsyncTask(String)
    And the task @taskId description contains "Importing GeoPackage database file."                                                                # WebAPICucumberHooks.the_task_taskId_description_contains(String,String)
    And when the task @taskId finishes                                                                                                             # WebAPICucumberHooks.waitForAsyncTaskToFinish(String)
    Then the task @taskId status is FAILED                                                                                                         # WebAPICucumberHooks.checkAsyncTaskStatus(String,AsyncContext$Status)
    And the xml response should contain "/task/result/import/importCommit/id"                                                                      # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And I save the response "/task/result/import/importCommit/id/text()" as "@importCommit"                                                        # WebAPICucumberHooks.saveResponseXPathValueAsVariable(String,String)
    And the xml response should contain "/task/result/import/importCommit/tree"                                                                    # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And the xpath "/task/result/import/importCommit/message" equals "Imported Geopackage"                                                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/task/result/Merge/ours/text()" equals "{@ObjectId|repo1|@txId|master}"                                                         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/task/result/Merge/theirs/text()" equals "{@importCommit}"                                                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/task/result/Merge/ancestor/text()" equals "{@ObjectId|repo1|@txId|master~1}"                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/task/result/import/NewFeatures/type/@name" equals "Points"                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/task/result/import/NewFeatures/type/id/@provided" 1 times                                                # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/task/result/import/NewFeatures/type/id/@assigned" 1 times                                                # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And I save the response "/task/result/import/NewFeatures/type/id/@assigned" as "@newFeatureId"                                                 # WebAPICucumberHooks.saveResponseXPathValueAsVariable(String,String)
    And the xpath "/task/result/Merge/conflicts" equals "1"                                                                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "WORK_HEAD" in the @txId transaction should have the following features:                                            # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
    And I prune the task @taskId                                                                                                                   # WebAPICucumberHooks.prune_task(String)

  #<task><id>1</id><status>FINISHED</status><transactionId>c4da5a9b-5b09-4cb6-9055-e340d02b57ac</transactionId><description>Importing GeoPackage database file.</description><atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="alternate" href="/tasks/1.xml" type="application/xml"/><result><RevCommit><id>a1cde458d0658e096998b740b2eaa7b10796e624</id><treeId>37987a1d4afbf60be906d55576392965654d5d9c</treeId></RevCommit></result></task>
  # JSON tests
  Scenario: Verify wrong HTTP method issues 405 "Method not allowed", JSON requested response # GeoPackageImport.feature:162
    Given There is an empty multirepo server                                                  # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/import.json?format=gpkg"                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "POST"                                         # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify missing "format=gpkg" argument issues 400 "Bad request", JSON requested response # GeoPackageImport.feature:168
    Given There is an empty repository named repo1                                                  # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                         # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "POST /repos/repo1/import.json?transactionId={@txId}"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                       # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "false"                                           # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.error" equals "missing required 'format' parameter"               # WebAPICucumberHooks.checkJSONResponse(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify unsupported output format argument issues 400 "Bad request", JSON requested response # GeoPackageImport.feature:177
    Given There is an empty repository named repo1                                                      # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                             # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "POST /repos/repo1/import.json?format=badFormat&transactionId={@txId}"                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                           # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "false"                                               # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.error" equals "Unsupported input format: 'badFormat'"                 # WebAPICucumberHooks.checkJSONResponse(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository badRepo

  Scenario: Verify import to a non existent repository issues 404 "Not found", JSON requested response # GeoPackageImport.feature:186
    Given There is an empty multirepo server                                                           # WebAPICucumberHooks.setUpEmptyMultiRepo()
    And I have a geopackage file @gpkgFile                                                             # WebAPICucumberHooks.gpkg_CreateSampleGeopackage(String)
    When I post @gpkgFile as "fileUpload" to "/repos/badRepo/import.json?format=gpkg"                  # WebAPICucumberHooks.gpkg_UploadFile(String,String,String)
    Then the response status should be '404'                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                                # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                                        # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository targetRepo
[main] INFO org.mortbay.log - Task %s finished: %s

  Scenario: Import to an empty repository, JSON requested response                                             # GeoPackageImport.feature:194
    Given There is an empty repository named targetRepo                                                        # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a geopackage file @gpkgFile                                                                     # WebAPICucumberHooks.gpkg_CreateSampleGeopackage(String)
    And I have a transaction as "@txId" on the "targetRepo" repo                                               # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I post @gpkgFile as "fileUpload" to "/repos/targetRepo/import.json?format=gpkg&transactionId={@txId}" # WebAPICucumberHooks.gpkg_UploadFile(String,String,String)
    Then the response status should be '200'                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the response is a JSON async task @taskId                                                              # WebAPICucumberHooks.checkResponseIsAJsonAsyncTask(String)
    And the JSON task @taskId description contains "Importing GeoPackage database file."                       # WebAPICucumberHooks.theJsonTaskTaskIdDescriptionContains(String,String)
    And when the JSON task @taskId finishes                                                                    # WebAPICucumberHooks.waitForAsyncJsonTaskToFinish(String)
    Then the JSON task @taskId status is FINISHED                                                              # WebAPICucumberHooks.checkAsyncJsonTaskStatus(String,AsyncContext$Status)
    And the json object "task.result.commit.id" equals "{@ObjectId|targetRepo|@txId|master}"                   # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json response "task.result.commit" should contain "tree"                                           # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And I end the transaction with id "@txId" on the "targetRepo" repo                                         # WebAPICucumberHooks.endTransaction(String,String)
    And the targetRepo repository's "HEAD" should have the following features:                                 # WebAPICucumberHooks.verifyRepositoryContents(String,String,DataTable)
    And I prune the task @taskId                                                                               # WebAPICucumberHooks.prune_task(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.mortbay.log - Task %s finished: %s
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Import an interchange geopackage with fast-forward merge, JSON requested response                                                           # GeoPackageImport.feature:214
    Given There is a default multirepo server                                                                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I export Points from "repo1" to a geopackage file with audit logs as @gpkgFile                                                                  # WebAPICucumberHooks.gpkg_ExportAuditLogs(String,String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                             # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I add Points/4 to the geopackage file @gpkgFile                                                                                                # WebAPICucumberHooks.gpkg_AddFeature(String)
    And I post @gpkgFile as "fileUpload" to "/repos/repo1/import.json?format=gpkg&message=Imported%20Geopackage&interchange=true&transactionId={@txId}" # WebAPICucumberHooks.gpkg_UploadFile(String,String,String)
    Then the response status should be '200'                                                                                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response is a JSON async task @taskId                                                                                                       # WebAPICucumberHooks.checkResponseIsAJsonAsyncTask(String)
    And the JSON task @taskId description contains "Importing GeoPackage database file."                                                                # WebAPICucumberHooks.theJsonTaskTaskIdDescriptionContains(String,String)
    And when the JSON task @taskId finishes                                                                                                             # WebAPICucumberHooks.waitForAsyncJsonTaskToFinish(String)
    Then the JSON task @taskId status is FINISHED                                                                                                       # WebAPICucumberHooks.checkAsyncJsonTaskStatus(String,AsyncContext$Status)
    And the json object "task.result.newCommit.id" equals "{@ObjectId|repo1|@txId|master}"                                                              # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json response "task.result.newCommit" should contain "tree"                                                                                 # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json object "task.result.newCommit.message" equals "Imported Geopackage"                                                                    # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "task.result.importCommit.id" equals "{@ObjectId|repo1|@txId|master}"                                                           # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json response "task.result.importCommit" should contain "tree"                                                                              # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json object "task.result.importCommit.message" equals "Imported Geopackage"                                                                 # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "task.result.NewFeatures.type[0].name" equals "Points"                                                                          # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json response "task.result.NewFeatures.type[0].id[0].provided" should contain ""                                                            # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json response "task.result.NewFeatures.type[0].id[0].assigned" should contain ""                                                            # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And I save the json response "task.result.NewFeatures.type[0].id[0].assigned" as "@newFeatureId"                                                    # WebAPICucumberHooks.saveResponseJSONValueAsVariable(String,String)
    And I end the transaction with id "@txId" on the "repo1" repo                                                                                       # WebAPICucumberHooks.endTransaction(String,String)
    And the repo1 repository's "HEAD" should have the following features:                                                                               # WebAPICucumberHooks.verifyRepositoryContents(String,String,DataTable)
    And I prune the task @taskId                                                                                                                        # WebAPICucumberHooks.prune_task(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.mortbay.log - Task %s finished: %s
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Import an interchange geopackage with non-conflicting merge, JSON requested response                                                        # GeoPackageImport.feature:244
    Given There is a default multirepo server                                                                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I export Points from "repo1" to a geopackage file with audit logs as @gpkgFile                                                                  # WebAPICucumberHooks.gpkg_ExportAuditLogs(String,String)
    When I add Points/4 to the geopackage file @gpkgFile                                                                                                # WebAPICucumberHooks.gpkg_AddFeature(String)
    And I have removed "Point.1" on the "repo1" repo in the "" transaction                                                                              # WebAPICucumberHooks.I_have_removed(String,String,String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                             # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I post @gpkgFile as "fileUpload" to "/repos/repo1/import.json?format=gpkg&message=Imported%20Geopackage&interchange=true&transactionId={@txId}" # WebAPICucumberHooks.gpkg_UploadFile(String,String,String)
    Then the response status should be '200'                                                                                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response is a JSON async task @taskId                                                                                                       # WebAPICucumberHooks.checkResponseIsAJsonAsyncTask(String)
    And the JSON task @taskId description contains "Importing GeoPackage database file."                                                                # WebAPICucumberHooks.theJsonTaskTaskIdDescriptionContains(String,String)
    And when the JSON task @taskId finishes                                                                                                             # WebAPICucumberHooks.waitForAsyncJsonTaskToFinish(String)
    Then the JSON task @taskId status is FINISHED                                                                                                       # WebAPICucumberHooks.checkAsyncJsonTaskStatus(String,AsyncContext$Status)
    And the json object "task.result.newCommit.id" equals "{@ObjectId|repo1|@txId|master}"                                                              # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json response "task.result.newCommit" should contain "tree"                                                                                 # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json object "task.result.newCommit.message" equals "Merge: Imported Geopackage"                                                             # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "task.result.importCommit.id" equals "{@ObjectId|repo1|@txId|master^2}"                                                         # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json response "task.result.importCommit" should contain "tree"                                                                              # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json object "task.result.importCommit.message" equals "Imported Geopackage"                                                                 # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "task.result.NewFeatures.type[0].name" equals "Points"                                                                          # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json response "task.result.NewFeatures.type[0].id[0].provided" should contain ""                                                            # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json response "task.result.NewFeatures.type[0].id[0].assigned" should contain ""                                                            # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And I save the json response "task.result.NewFeatures.type[0].id[0].assigned" as "@newFeatureId"                                                    # WebAPICucumberHooks.saveResponseJSONValueAsVariable(String,String)
    And I end the transaction with id "@txId" on the "repo1" repo                                                                                       # WebAPICucumberHooks.endTransaction(String,String)
    And the repo1 repository's "HEAD" should have the following features:                                                                               # WebAPICucumberHooks.verifyRepositoryContents(String,String,DataTable)
    And I prune the task @taskId                                                                                                                        # WebAPICucumberHooks.prune_task(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.mortbay.log - Task %s finished: %s
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Import an interchange geopackage with conflicting merge, JSON requested response                                                            # GeoPackageImport.feature:274
    Given There is a default multirepo server                                                                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I export Points from "repo1" to a geopackage file with audit logs as @gpkgFile                                                                  # WebAPICucumberHooks.gpkg_ExportAuditLogs(String,String)
    When I modify the Point features in the geopackage file @gpkgFile                                                                                   # WebAPICucumberHooks.gpkg_ModifyFeature(String)
    And I add Points/4 to the geopackage file @gpkgFile                                                                                                 # WebAPICucumberHooks.gpkg_AddFeature(String)
    And I have removed "Point.1" on the "repo1" repo in the "" transaction                                                                              # WebAPICucumberHooks.I_have_removed(String,String,String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                             # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I post @gpkgFile as "fileUpload" to "/repos/repo1/import.json?format=gpkg&message=Imported%20Geopackage&interchange=true&transactionId={@txId}" # WebAPICucumberHooks.gpkg_UploadFile(String,String,String)
    Then the response status should be '200'                                                                                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response is a JSON async task @taskId                                                                                                       # WebAPICucumberHooks.checkResponseIsAJsonAsyncTask(String)
    And the JSON task @taskId description contains "Importing GeoPackage database file."                                                                # WebAPICucumberHooks.theJsonTaskTaskIdDescriptionContains(String,String)
    And when the JSON task @taskId finishes                                                                                                             # WebAPICucumberHooks.waitForAsyncJsonTaskToFinish(String)
    Then the JSON task @taskId status is FAILED                                                                                                         # WebAPICucumberHooks.checkAsyncJsonTaskStatus(String,AsyncContext$Status)
    And the json response "task.result.Merge" should contain "ours"                                                                                     # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json response "task.result.Merge" should contain "theirs"                                                                                   # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json response "task.result.Merge" should contain "ancestor"                                                                                 # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json response "task.result.import.importCommit" should contain "id"                                                                         # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And I save the json response "task.result.import.importCommit.id" as "@importCommit"                                                                # WebAPICucumberHooks.saveResponseJSONValueAsVariable(String,String)
    And the json response "task.result.import.importCommit" should contain "tree"                                                                       # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json object "task.result.import.importCommit.message" equals "Imported Geopackage"                                                          # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "task.result.Merge.ours" equals "{@ObjectId|repo1|@txId|master}"                                                                # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "task.result.Merge.theirs" equals "{@importCommit}"                                                                             # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "task.result.Merge.ancestor" equals "{@ObjectId|repo1|@txId|master~1}"                                                          # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "task.result.import.NewFeatures.type[0].name" equals "Points"                                                                   # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json response "task.result.import.NewFeatures.type[0].id[0].provided" should contain ""                                                     # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json response "task.result.import.NewFeatures.type[0].id[0].assigned" should contain ""                                                     # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And I save the json response "task.result.import.NewFeatures.type[0].id[0].assigned" as "@newFeatureId"                                             # WebAPICucumberHooks.saveResponseJSONValueAsVariable(String,String)
    And the json object "task.result.Merge.conflicts" equals "1"                                                                                        # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the repo1 repository's "WORK_HEAD" in the @txId transaction should have the following features:                                                 # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
    And I prune the task @taskId                                                                                                                        # WebAPICucumberHooks.prune_task(String)
@Commands
Feature: GetCommitGraph
  The get commit graph command allows a user to retrieve the commit graph of a repo and is supported through the "/repos/{repository}/getCommitGraph" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # GetCommitGraph.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/getCommitGraph"                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Getting the commit graph outside of a repository issues 404 "Not found" # GetCommitGraph.feature:12
    Given There is an empty multirepo server                                        # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/getCommitGraph?commitId=someId"                   # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                             # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                     # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Getting the commit graph without specifying a commit issues a 500 status code             # GetCommitGraph.feature:19
    Given There is an empty repository named repo1                                                    # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/getCommitGraph"                                                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Required parameter 'commitId' was not provided." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Getting the commit graph without specifying a depth returns the full graph # GetCommitGraph.feature:25
    Given There is a default multirepo server                                          # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/getCommitGraph?commitId={@ObjectId|repo1|master}"    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 5 times                     # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "{@ObjectId|repo1|master}"                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master~1}"                  # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master~2}"                  # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|branch1}"                   # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|branch2}"                   # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Getting the commit graph with a depth of 0 returns the full graph               # GetCommitGraph.feature:37
    Given There is a default multirepo server                                               # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/getCommitGraph?commitId={@ObjectId|repo1|master}&depth=0" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 5 times                          # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "{@ObjectId|repo1|master}"                         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master~1}"                       # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master~2}"                       # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|branch1}"                        # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|branch2}"                        # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Getting the commit graph with a depth of 2 returns only the commit and its parents # GetCommitGraph.feature:49
    Given There is a default multirepo server                                                  # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/getCommitGraph?commitId={@ObjectId|repo1|master}&depth=2"    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 3 times                             # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "{@ObjectId|repo1|master}"                            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master~1}"                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|branch2}"                           # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Getting the commit graph should support paging                                        # GetCommitGraph.feature:59
    Given There is a default multirepo server                                                     # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/getCommitGraph?commitId={@ObjectId|repo1|master}&show=2"        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 2 times                                # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "{@ObjectId|repo1|master}"                               # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master~1}"                             # WebAPICucumberHooks.checkResponseTextContains(String)
    When I call "GET /repos/repo1/getCommitGraph?commitId={@ObjectId|repo1|master}&show=2&page=1" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 2 times                                # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "{@ObjectId|repo1|branch2}"                              # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master~2}"                             # WebAPICucumberHooks.checkResponseTextContains(String)
    When I call "GET /repos/repo1/getCommitGraph?commitId={@ObjectId|repo1|master}&show=2&page=2" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 1 times                                # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "{@ObjectId|repo1|branch1}"                              # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: IndexCreate
  The Index Create command allows a user to add spatial index to a specified layer
  The command must be executed using the HTTP PUT method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository noRepo
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Create index fails when repository does not exist      # IndexCreate.feature:6
    Given There is an empty repository named repo1                 # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/noRepo/index/create?treeRefSpec=Point" # WebAPICucumberHooks.callURL(String)
    Then the response body should contain "Repository not found."  # WebAPICucumberHooks.checkResponseTextContains(String)
    Then the response status should be '404'                       # WebAPICucumberHooks.checkStatusCode(int)

  Scenario: Verify method not allowed on incorrect request type    # IndexCreate.feature:12
    Given There is a repo with some data                           # WebAPICucumberHooks.setUpRepoWithData()
    When I call "GET /repos/repo1/index/create?treeRefSpec=Points" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "PUT"               # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Create index fails when feature tree does not exist                # IndexCreate.feature:18
    Given There is an empty repository named repo1                             # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                    # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have staged "Point.1" on the "repo1" repo in the "@txId" transaction # WebAPICucumberHooks.I_have_staged(String,String,String)
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Point"              # WebAPICucumberHooks.callURL(String)
    Then the response body should contain "Can't find feature tree"            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response status should be '400'                                    # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify success after adding spatial index                                  # IndexCreate.feature:26
    Given There is a repo with some data                                               # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points"                     # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '201'                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"  # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features: # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify creating index with attribute                                             # IndexCreate.feature:37
    Given There is a repo with some data                                                     # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp"        # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '201'                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"        # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"     # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:       # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify creating index with bounds                                                # IndexCreate.feature:50
    Given There is a repo with some data                                                     # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&bounds=-60,-45,60,45"      # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '201'                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the repo1 repository's "HEAD:Points" index bounds should be "-60,-45,60,45"          # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "sp" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:       # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify creating index with extra attribute                                                   # IndexCreate.feature:63
    Given There is a repo with some data                                                                 # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp&extraAttributes=ip" # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '201'                                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                    # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"                 # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "ip"                 # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                   # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify creating index with full history                                        # IndexCreate.feature:76
    Given There is a default multirepo server                                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&indexHistory=true"       # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '201'                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"      # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:     # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch1:Points" index should have the following features:  # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch2:Points" index should have the following features:  # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "master~2:Points" index should have the following features: # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify creating index with full history and extra attributes                                # IndexCreate.feature:100
    Given There is a default multirepo server                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp&indexHistory=true" # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '201'                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                   # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"                # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"            # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                  # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch1:Points" index should track the extra attribute "sp"             # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should not track the extra attribute "ip"         # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should have the following features:               # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch2:Points" index should track the extra attribute "sp"             # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should not track the extra attribute "ip"         # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should have the following features:               # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "master~2:Points" index should track the extra attribute "sp"            # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should not track the extra attribute "ip"        # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should have the following features:              # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)

  Scenario: Verify 500 status code when tree ref spec is not provided                                  # IndexCreate.feature:132
    Given There is a repo with some data                                                               # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?extraAttributes=sp"                                     # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "false"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/error/text()" equals "Required parameter 'treeRefSpec' was not provided." # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '500'                                                            # WebAPICucumberHooks.checkStatusCode(int)
@Commands
Feature: IndexDrop
  The Index Drop command allows a user to remove an existing index from the repository
  The command must be executed using the HTTP DELETE method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository noRepo

  Scenario: Index drop fails with non-existent repository            # IndexDrop.feature:6
    Given There is an empty multirepo server                         # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "DELETE /repos/noRepo/index/drop?treeRefSpec=Points" # WebAPICucumberHooks.callURL(String)
    Then the response body should contain "Repository not found."    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response status should be '404'                          # WebAPICucumberHooks.checkStatusCode(int)

  Scenario: Verify method not allowed on incorrect request type  # IndexDrop.feature:12
    Given There is a repo with some data                         # WebAPICucumberHooks.setUpRepoWithData()
    When I call "GET /repos/repo1/index/drop?treeRefSpec=Points" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                     # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "DELETE"          # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify dropping spatial index                                                    # IndexDrop.feature:18
    Given There is a repo with some data                                                     # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points"                           # WebAPICucumberHooks.callURL(String)
    Then the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"       # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "sp" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:       # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    When I call "DELETE /repos/repo1/index/drop?treeRefSpec=Points"                          # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/dropped/treeName/text()" equals "Points"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "HEAD:Points" should not have an index                        # WebAPICucumberHooks.noIndexAtCommit(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify 500 status code when tree ref spec is not provided                                  # IndexDrop.feature:32
    Given There is a repo with some data                                                               # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp"                  # WebAPICucumberHooks.callURL(String)
    Then the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                 # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"               # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"           # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                 # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    When I call "DELETE /repos/repo1/index/drop"                                                       # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "false"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/error/text()" equals "Required parameter 'treeRefSpec' was not provided." # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '500'                                                            # WebAPICucumberHooks.checkStatusCode(int)
@Commands
Feature: IndexList
  The Index List command allows a user to display spatial index info for a feature tree
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository noRepo

  Scenario: Index list fails non-existent repository                   # IndexList.feature:6
    Given There is a repo with some data                               # WebAPICucumberHooks.setUpRepoWithData()
    When I call "GET /repos/noRepo/index/list?treeName=does_not_exist" # WebAPICucumberHooks.callURL(String)
    Then the response body should contain "Repository not found."      # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response status should be '404'                            # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify method not allowed on incorrect request type   # IndexList.feature:12
    Given There is a repo with some data                          # WebAPICucumberHooks.setUpRepoWithData()
    And I call "PUT /repos/repo1/index/create?treeRefSpec=Points" # WebAPICucumberHooks.callURL(String)
    When I call "POST /repos/repo1/index/list"                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"              # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify index list return for all feature trees                       # IndexList.feature:19
    Given There is a default multirepo server                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I call "PUT /repos/repo1/index/create?treeRefSpec=Points"                # WebAPICucumberHooks.callURL(String)
    And I call "PUT /repos/repo1/index/create?treeRefSpec=Lines"                 # WebAPICucumberHooks.callURL(String)
    When I call "GET /repos/repo1/index/list"                                    # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And there is an xpath "/response/index/treeName/text()" that equals "Points" # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/index/treeName/text()" that equals "Lines"  # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And the response status should be '200'                                      # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify correct index list return for a feature tree     # IndexList.feature:29
    Given There is a repo with some data                            # WebAPICucumberHooks.setUpRepoWithData()
    And I call "PUT /repos/repo1/index/create?treeRefSpec=Points"   # WebAPICucumberHooks.callURL(String)
    And I call "PUT /repos/repo1/index/create?treeRefSpec=Lines"    # WebAPICucumberHooks.callURL(String)
    When I call "GET /repos/repo1/index/list?treeName=Points"       # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response body should not contain "Lines"                # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response status should be '200'                         # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify failed index list return for non-existent feature tree                                    # IndexList.feature:39
    Given There is a repo with some data                                                                     # WebAPICucumberHooks.setUpRepoWithData()
    When I call "GET /repos/repo1/index/list?treeName=does_not_exist"                                        # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "false"                                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/error/text()" equals "The provided tree name was not found in the HEAD commit." # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '404'                                                                  # WebAPICucumberHooks.checkStatusCode(int)
@Commands
Feature: IndexRebuild
  The Index Rebuild command allows a user to rebuild the spatial index for a specified layer
  The command must be executed using the HTTP POST method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Index Rebuild fails for non-existent repository        # IndexRebuild.feature:6
    Given There is an empty multirepo server                       # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points" # WebAPICucumberHooks.callURL(String)
    Then the response body should contain "Repository not found."  # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response status should be '404'                        # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify method not allowed on incorrect request type     # IndexRebuild.feature:12
    Given There is a repo with some data                            # WebAPICucumberHooks.setUpRepoWithData()
    And I call "PUT /repos/repo1/index/create?treeRefSpec=Points"   # WebAPICucumberHooks.callURL(String)
    When I call "GET /repos/repo1/index/rebuild?treeRefSpec=Points" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "POST"               # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify quad tree after rebuilding spatial index                                      # IndexRebuild.feature:19
    Given There is a default multirepo server                                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp"             # WebAPICucumberHooks.callURL(String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"         # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"     # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    Then the repo1 repository's "HEAD:Points" index should have the following features:          # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch1:Points" should not have an index                         # WebAPICucumberHooks.noIndexAtCommit(String,String)
    And the repo1 repository's "branch2:Points" should not have an index                         # WebAPICucumberHooks.noIndexAtCommit(String,String)
    And the repo1 repository's "master~2:Points" should not have an index                        # WebAPICucumberHooks.noIndexAtCommit(String,String)
    When I call "POST /repos/repo1/index/rebuild?treeRefSpec=Points"                             # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/treesRebuilt/text()" equals "4"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"         # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"     # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:           # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch1:Points" index should track the extra attribute "sp"      # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should not track the extra attribute "ip"  # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should have the following features:        # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch2:Points" index should track the extra attribute "sp"      # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should not track the extra attribute "ip"  # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should have the following features:        # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "master~2:Points" index should track the extra attribute "sp"     # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should not track the extra attribute "ip" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should have the following features:       # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the response status should be '201'                                                      # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify 500 status code when tree ref spec is not provided                                  # IndexRebuild.feature:61
    Given There is a repo with some data                                                               # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp"                  # WebAPICucumberHooks.callURL(String)
    Then the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                 # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"               # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"           # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                 # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    When I call "POST /repos/repo1/index/rebuild"                                                      # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "false"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/error/text()" equals "Required parameter 'treeRefSpec' was not provided." # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '500'                                                            # WebAPICucumberHooks.checkStatusCode(int)
@Commands
Feature: IndexUpdate
  The Index Update command allows a user to update the spatial index with extra attributes
  The command must be executed using the HTTP POST method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository noRepo

  Scenario: Index update fails with non-existent repository                                      # IndexUpdate.feature:6
    Given There is an empty multirepo server                                                     # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "POST /repos/noRepo/index/update?treeRefSpec=Points&extraAttributes=ip&add=true" # WebAPICucumberHooks.callURL(String)
    Then the response body should contain "Repository not found."                                # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response status should be '404'                                                      # WebAPICucumberHooks.checkStatusCode(int)

  Scenario: Verify method not allowed on incorrect request type                                # IndexUpdate.feature:12
    Given There is a repo with some data                                                       # WebAPICucumberHooks.setUpRepoWithData()
    When I call "GET /repos/repo1/index/update?treeRefSpec=Points&extraAttributes=ip&add=true" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "POST"                                          # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify updating spatial index by adding attributes                                  # IndexUpdate.feature:18
    Given There is a repo with some data                                                        # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points"                              # WebAPICucumberHooks.callURL(String)
    Then the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"          # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "sp"    # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"    # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:          # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    When I call "POST /repos/repo1/index/update?treeRefSpec=Points&extraAttributes=sp"          # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"        # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"    # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:          # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the response status should be '201'                                                     # WebAPICucumberHooks.checkStatusCode(int)
    When I call "POST /repos/repo1/index/update?treeRefSpec=Points&extraAttributes=ip&add=true" # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"        # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "ip"        # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:          # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the response status should be '201'                                                     # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify success when overwriting the attributes of an index                                # IndexUpdate.feature:46
    Given There is a repo with some data                                                              # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp"                 # WebAPICucumberHooks.callURL(String)
    Then the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"              # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"          # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    When I call "POST /repos/repo1/index/update?treeRefSpec=Points&extraAttributes=ip&overwrite=true" # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                 # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "sp"          # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "ip"              # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the response status should be '201'                                                           # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify success when removing the attributes of an index                          # IndexUpdate.feature:66
    Given There is a repo with some data                                                     # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp"        # WebAPICucumberHooks.callURL(String)
    Then the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"       # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"     # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:       # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    When I call "POST /repos/repo1/index/update?treeRefSpec=Points&overwrite=true"           # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"        # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "sp" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:       # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the response status should be '201'                                                  # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify success when updating the bounds                                          # IndexUpdate.feature:86
    Given There is a repo with some data                                                     # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp"        # WebAPICucumberHooks.callURL(String)
    Then the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"       # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"     # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:       # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    When I call "POST /repos/repo1/index/update?treeRefSpec=Points&bounds=-60,-45,60,45"     # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "HEAD:Points" index bounds should be "-60,-45,60,45"          # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"     # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip" # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:       # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the response status should be '201'                                                  # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify success when updating the whole history of an index                                                  # IndexUpdate.feature:106
    Given There is a default multirepo server                                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp&indexHistory=true"                 # WebAPICucumberHooks.callURL(String)
    Then the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                                  # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"                                # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"                            # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                                  # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch1:Points" index should track the extra attribute "sp"                             # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should not track the extra attribute "ip"                         # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should have the following features:                               # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch2:Points" index should track the extra attribute "sp"                             # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should not track the extra attribute "ip"                         # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should have the following features:                               # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "master~2:Points" index should track the extra attribute "sp"                            # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should not track the extra attribute "ip"                        # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should have the following features:                              # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    When I call "POST /repos/repo1/index/update?treeRefSpec=Points&extraAttributes=ip&overwrite=true&indexHistory=true" # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                                   # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "sp"                            # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "ip"                                # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                                  # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch1:Points" index should not track the extra attribute "sp"                         # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should track the extra attribute "ip"                             # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should have the following features:                               # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch2:Points" index should not track the extra attribute "sp"                         # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should track the extra attribute "ip"                             # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should have the following features:                               # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "master~2:Points" index should not track the extra attribute "sp"                        # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should track the extra attribute "ip"                            # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should have the following features:                              # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the response status should be '201'                                                                             # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Verify success when updating only the head commit of an index                               # IndexUpdate.feature:165
    Given There is a default multirepo server                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp&indexHistory=true" # WebAPICucumberHooks.callURL(String)
    Then the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                  # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"                # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"            # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                  # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch1:Points" index should track the extra attribute "sp"             # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should not track the extra attribute "ip"         # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should have the following features:               # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch2:Points" index should track the extra attribute "sp"             # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should not track the extra attribute "ip"         # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should have the following features:               # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "master~2:Points" index should track the extra attribute "sp"            # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should not track the extra attribute "ip"        # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should have the following features:              # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    When I call "POST /repos/repo1/index/update?treeRefSpec=Points&extraAttributes=ip&overwrite=true"   # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "true"                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/index/treeName/text()" equals "Points"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                   # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "sp"            # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "ip"                # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                  # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch1:Points" index should track the extra attribute "sp"             # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should not track the extra attribute "ip"         # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch1:Points" index should have the following features:               # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "branch2:Points" index should track the extra attribute "sp"             # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should not track the extra attribute "ip"         # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "branch2:Points" index should have the following features:               # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the repo1 repository's "master~2:Points" index should track the extra attribute "sp"            # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should not track the extra attribute "ip"        # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "master~2:Points" index should have the following features:              # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    And the response status should be '201'                                                             # WebAPICucumberHooks.checkStatusCode(int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify 500 status code when tree ref spec is not provided                                  # IndexUpdate.feature:224
    Given There is a repo with some data                                                               # WebAPICucumberHooks.setUpRepoWithData()
    When I call "PUT /repos/repo1/index/create?treeRefSpec=Points&extraAttributes=sp"                  # WebAPICucumberHooks.callURL(String)
    Then the repo1 repository's "HEAD:Points" index bounds should be "-90,-180,90,180"                 # WebAPICucumberHooks.verifyIndexBounds(String,String,String)
    And the repo1 repository's "HEAD:Points" index should track the extra attribute "sp"               # WebAPICucumberHooks.verifyIndexExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should not track the extra attribute "ip"           # WebAPICucumberHooks.verifyIndexNotExtraAttributes(String,String,String)
    And the repo1 repository's "HEAD:Points" index should have the following features:                 # WebAPICucumberHooks.verifyIndexContents(String,String,DataTable)
    When I call "POST /repos/repo1/index/update"                                                       # WebAPICucumberHooks.callURL(String)
    Then the xpath "/response/success/text()" equals "false"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/error/text()" equals "Required parameter 'treeRefSpec' was not provided." # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the response status should be '500'                                                            # WebAPICucumberHooks.checkStatusCode(int)
@RepositoryManagement
Feature: List repositories
    In order to find out which repsitories are being served,
    As a Geogig Web API User,
    I want to get a list of available repositories

  Scenario: List repositories on a server with no repositories # ListRepositories.feature:7
    Given There is an empty multirepo server                   # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/"                                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                   # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"   # WebAPICucumberHooks.checkContentType(String)
    And the xml response should not contain "/repos/repo"      # WebAPICucumberHooks.responseDoesNotContainXPath(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Get list of repositories in default format             # ListRepositories.feature:14
    Given There is a default multirepo server                      # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/"                                      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"       # WebAPICucumberHooks.checkContentType(String)
    And the xml response should contain "/repos/repo/name" 2 times # WebAPICucumberHooks.checkXPathCadinality(String,int)

  Scenario: List repositories on a server with no repositories, JSON requested response # ListRepositories.feature:21
    Given There is an empty multirepo server                                            # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos.json/"                                                      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                           # WebAPICucumberHooks.checkContentType(String)
    And the json response "repos" contains an empty "repo" array                        # WebAPICucumberHooks.checkJSONResponseContainsEmptyArray(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Get list of repositories in default format, JSON requested response       # ListRepositories.feature:28
    Given There is a default multirepo server                                         # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos.json/"                                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                         # WebAPICucumberHooks.checkContentType(String)
    And the json response "repos.repo" should contain "name" 2 times                  # WebAPICucumberHooks.checkJSONResponseContains(String,String,int)
    And the json response "repos.repo" should contain "href" 2 times                  # WebAPICucumberHooks.checkJSONResponseContains(String,String,int)
    And the json response "repos.repo" attribute "href" should each contain "/repos/" # WebAPICucumberHooks.checkJsonArrayContains(String,String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Get Repository info in JSON format                       # ListRepositories.feature:37
    Given There is a default multirepo server                        # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos.json"                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"        # WebAPICucumberHooks.checkContentType(String)
    And the json response "repos.repo" should contain "href" 2 times # WebAPICucumberHooks.checkJSONResponseContains(String,String,int)
    Then I save the first href link from "repos.repo" as "@href"     # WebAPICucumberHooks.saveHrefLinkFromJSONResponse(String,String)
    When I call "GET {@href}"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"        # WebAPICucumberHooks.checkContentType(String)
    And the json response "repository" should contain "name"         # WebAPICucumberHooks.checkJSONResponseContains(String,String)
    And the json response "repository" should contain "location"     # WebAPICucumberHooks.checkJSONResponseContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Get Repository info in XML format                           # ListRepositories.feature:50
    Given There is a default multirepo server                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos.xml"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"            # WebAPICucumberHooks.checkContentType(String)
    And the xml response should contain "/repos/repo/atom:link" 2 times # WebAPICucumberHooks.checkXPathCadinality(String,int)
@Commands
Feature: Log
  The log command allows a user to view the commit log of a repo and is supported through the "/repos/{repository}/log" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Log.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/log"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Log outside of a repository issues 404 "Not found"  # Log.feature:12
    Given There is an empty multirepo server                    # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/log"                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                    # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"         # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found" # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Log will return the history of the current branch                                                # Log.feature:19
    Given There is a default multirepo server                                                                # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log"                                                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 5 times                                           # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master}"                # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "merge branch branch2 onto master" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master~1}"              # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "merge branch branch1 onto master" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master~2}"              # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "point1, line1, poly1"             # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|branch1}"               # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "point2, line2, poly2"             # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|branch2}"               # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "point3, line3, poly3"             # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: The firstParentOnly parameter limits the log to the first parent of each commit                  # Log.feature:36
    Given There is a default multirepo server                                                                # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log?firstParentOnly=true"                                                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 3 times                                           # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master}"                # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "merge branch branch2 onto master" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master~1}"              # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "merge branch branch1 onto master" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master~2}"              # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "point1, line1, poly1"             # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: The offset parameter skips a number of log entries                                   # Log.feature:49
    Given There is a default multirepo server                                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log?offset=2"                                                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 3 times                               # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master~2}"  # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "point1, line1, poly1" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|branch1}"   # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "point2, line2, poly2" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|branch2}"   # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "point3, line3, poly3" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: The limit parameter limits the number of entries returned                                        # Log.feature:62
    Given There is a default multirepo server                                                                # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log?limit=2"                                                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 2 times                                           # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master}"                # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "merge branch branch2 onto master" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master~1}"              # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "merge branch branch1 onto master" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: The since parameter limits the log to commits that happened after it                             # Log.feature:73
    Given There is a default multirepo server                                                                # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log?since=master~1"                                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 1 times                                           # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master}"                # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "merge branch branch2 onto master" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: The until parameter limits the log to commits that happened before it                            # Log.feature:82
    Given There is a default multirepo server                                                                # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log?until=master~1"                                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 3 times                                           # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master~1}"              # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "merge branch branch1 onto master" # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master~2}"              # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "point1, line1, poly1"             # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|branch1}"               # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "point2, line2, poly2"             # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: The countChanges parameter counts the number of features affected by each commit    # Log.feature:95
    Given There is a default multirepo server                                                   # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log?since=master~1&countChanges=true"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 1 times                              # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xpath "/response/commit/id/text()" equals "{@ObjectId|repo1|master}"                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/message/text()" contains "merge branch branch2 onto master" # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the xpath "/response/commit/adds/text()" equals "3"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/modifies/text()" equals "0"                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/removes/text()" equals "0"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: The returnRange parameter returns the first and last commit as well as the number of commits in the range # Log.feature:107
    Given There is a default multirepo server                                                                         # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log?returnRange=true"                                                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/untilCommit/id/text()" equals "{@ObjectId|repo1|master}"                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/untilCommit/message/text()" contains "merge branch branch2 onto master"                  # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the xpath "/response/sinceCommit/id/text()" equals "{@ObjectId|repo1|master~2}"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/sinceCommit/message/text()" contains "point1, line1, poly1"                              # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the xpath "/response/numCommits/text()" equals "5"                                                            # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: The path parameter limits the log to commits that affected that path                # Log.feature:118
    Given There is an empty repository named repo1                                              # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have committed "Point.1" on the "repo1" repo in the "" transaction                    # WebAPICucumberHooks.I_have_committed(String,String,String)
    And I have committed "Line.2" on the "repo1" repo in the "" transaction                     # WebAPICucumberHooks.I_have_committed(String,String,String)
    And I have committed "Point.2" on the "repo1" repo in the "" transaction                    # WebAPICucumberHooks.I_have_committed(String,String,String)
    And I have committed "Polygon.1" on the "repo1" repo in the "" transaction                  # WebAPICucumberHooks.I_have_committed(String,String,String)
    And I have committed "Polygon.2" on the "repo1" repo in the "" transaction                  # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo1/log?path=Points"                                              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/commit" 2 times                              # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master~2}" # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "Added Point.2"       # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/commit/id/text()" that equals "{@ObjectId|repo1|master~4}" # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/commit/message/text()" that contains "Added Point.1"       # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Using the summary parameter without a path issues a 500 status code                                  # Log.feature:134
    Given There is a default multirepo server                                                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log?summary=true"                                                              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "You must specify a feature type path when getting a summary." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Using the summary parameter without using text/csv content type issues a 500 status code                        # Log.feature:140
    Given There is a default multirepo server                                                                               # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log?path=Points&summary=true"                                                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Unsupported Media Type: This response is only compatible with text/csv." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: The summary parameter summarizes all of the changes to a feature type as a CSV # Log.feature:146
    Given There is a default multirepo server                                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/log.csv?since=master~1&path=Points&summary=true"         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/csv"                                      # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "ADDED,Points/Point.3"                            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master}"                        # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should not contain "ADDED,Points/Point.2"                        # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "ADDED,Points/Point.1"                        # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "Lines"                                       # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "Polygons"                                    # WebAPICucumberHooks.checkResponseTextNotContains(String)
@Commands
Feature: LsTree
  The LsTree command allows a user to view the contents of a tree in the repository and is supported through the "/repos/{repository}/ls-tree" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # LsTree.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/ls-tree"                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: LsTree outside of a repository issues 404 "Not found" # LsTree.feature:12
    Given There is an empty multirepo server                      # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/ls-tree"                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"           # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"   # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: By default, LsTree lists the children of the root tree # LsTree.feature:19
    Given There is a default multirepo server                      # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/ls-tree"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                       # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/node" 3 times   # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Points"                  # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Lines"                   # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygons"                # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Supplying the onlyTree parameter to LsTree lists only trees # LsTree.feature:29
    Given There is a default multirepo server                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/ls-tree?onlyTree=true&recursive=true" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                            # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/node" 3 times        # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Points"                       # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Lines"                        # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygons"                     # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Supplying the recursive parameter to LsTree lists all features # LsTree.feature:39
    Given There is a default multirepo server                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/ls-tree?recursive=true"                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/node" 9 times           # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Point.1"                         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Point.2"                         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Point.3"                         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Line.1"                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Line.2"                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Line.3"                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygon.1"                       # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygon.2"                       # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygon.3"                       # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Supplying both the recursive and showTree parameters lists all trees and features # LsTree.feature:55
    Given There is a default multirepo server                                                 # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/ls-tree?recursive=true&showTree=true"                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/node" 12 times                             # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Points"                                             # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Lines"                                              # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygons"                                           # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Point.1"                                            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Point.2"                                            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Point.3"                                            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Line.1"                                             # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Line.2"                                             # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Line.3"                                             # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygon.1"                                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygon.2"                                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygon.3"                                          # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Providing a refspec lists the features of the tree it resolves to # LsTree.feature:74
    Given There is a default multirepo server                                 # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/ls-tree?recursive=true&path=branch1:Points" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/node" 2 times              # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Point.1"                            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Point.2"                            # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Supplying the verbose parameter lists more information about each node # LsTree.feature:83
    Given There is a default multirepo server                                      # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/ls-tree?verbose=true"                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/node" 3 times                   # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Points"                                  # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@PointsTypeID}"                         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master:Points}"         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Lines"                                   # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@LinesTypeID}"                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master:Lines}"          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygons"                                # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@PolysTypeID}"                          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master:Polygons}"       # WebAPICucumberHooks.checkResponseTextContains(String)
@Repo
Feature: Manifest
  The manifest resources provides a list of all the branches in the repository and is supported through the "/repos/{repository}/repo/manifest" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Manifest.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/repo/manifest"                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Manifest lists all of the branches in the repository                           # Manifest.feature:12
    Given There is a default multirepo server                                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/repo/manifest"                                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                    # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "HEAD refs/heads/master {@ObjectId|repo1|master}" # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "refs/heads/master {@ObjectId|repo1|master}"      # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "refs/heads/branch1 {@ObjectId|repo1|branch1}"    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "refs/heads/branch2 {@ObjectId|repo1|branch2}"    # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  Scenario: Manifest also lists remote branches when the remotes parameter is specified          # Manifest.feature:22
    Given There is a default multirepo server with remotes                                       # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo2/repo/manifest?remotes=true"                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                          # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "HEAD refs/heads/master {@ObjectId|repo2|master}"       # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "refs/heads/master {@ObjectId|repo2|master}"            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "refs/heads/branch1 {@ObjectId|repo2|branch1}"          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "refs/heads/branch2 {@ObjectId|repo2|branch2}"          # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "refs/remotes/origin/HEAD {@ObjectId|repo1|master}"     # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "refs/remotes/origin/master {@ObjectId|repo1|master}"   # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "refs/remotes/origin/branch1 {@ObjectId|repo1|branch1}" # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "refs/remotes/origin/branch2 {@ObjectId|repo1|branch2}" # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: Merge
  The merge command allows a user to merge two branches and is supported through the "/repos/{repository}/merge" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Merge.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/merge"                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Merge outside of a transaction issues 500 "Transaction required"       # Merge.feature:12
    Given There is an empty repository named repo1                                 # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/merge?commit=branch1"                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "No transaction was specified" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Merge outside of a repository issues 404 "Not found" # Merge.feature:18
    Given There is an empty multirepo server                     # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/merge?commit=branch1"          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                     # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"          # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"  # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling merge with no commit to merge issues a 500 status code                        # Merge.feature:25
    Given There is an empty repository named repo1                                                # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                       # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/merge?transactionId={@txId}"                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Required parameter 'commit' was not provided." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Merging two branches returns the details of the merge                                # Merge.feature:32
    Given There is a repository with multiple branches named repo1                               # WebAPICucumberHooks.setUpMultipleBranches(String)
    And I have a transaction as "@txId" on the "repo1" repo                                      # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/merge?transactionId={@txId}&commit=non_conflicting"            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ours/text()" equals "{@ObjectId|repo1|master_original}"       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/theirs/text()" equals "{@ObjectId|repo1|non_conflicting}"     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ancestor/text()" equals "{@ObjectId|repo1|non_conflicting~1}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/mergedCommit/text()" equals "{@ObjectId|repo1|@txId|master}"  # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying author information to merge is applied to the merge commit                                                          # Merge.feature:43
    Given There is a repository with multiple branches named repo1                                                                        # WebAPICucumberHooks.setUpMultipleBranches(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                               # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/merge?transactionId={@txId}&commit=non_conflicting&authorName=myAuthor&authorEmail=myAuthor@geogig.org" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ours/text()" equals "{@ObjectId|repo1|master_original}"                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/theirs/text()" equals "{@ObjectId|repo1|non_conflicting}"                                              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ancestor/text()" equals "{@ObjectId|repo1|non_conflicting~1}"                                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/mergedCommit/text()" equals "{@ObjectId|repo1|@txId|master}"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|@txId|master}"                                                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/name/text()" equals "myAuthor"                                                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/email/text()" equals "myAuthor@geogig.org"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying the noCommit parameter prevents the merge commit from being created              # Merge.feature:59
    Given There is a repository with multiple branches named repo1                                     # WebAPICucumberHooks.setUpMultipleBranches(String)
    And I have a transaction as "@txId" on the "repo1" repo                                            # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/merge?transactionId={@txId}&commit=non_conflicting&noCommit=true"    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ours/text()" equals "{@ObjectId|repo1|master_original}"             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/theirs/text()" equals "{@ObjectId|repo1|non_conflicting}"           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ancestor/text()" equals "{@ObjectId|repo1|non_conflicting~1}"       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/mergedCommit/text()" equals "{@ObjectId|repo1|master_original}"     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo1|@txId|master}" equals "{@ObjectId|repo1|@txId|master_original}" # WebAPICucumberHooks.checkVariableEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Merging a conflicting branch returns details of the conflicts                                             # Merge.feature:71
    Given There is a repository with multiple branches named repo1                                                    # WebAPICucumberHooks.setUpMultipleBranches(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                           # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/merge?transactionId={@txId}&commit=conflicting"                                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ours/text()" equals "{@ObjectId|repo1|master_original}"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/theirs/text()" equals "{@ObjectId|repo1|conflicting}"                              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ancestor/text()" equals "{@ObjectId|repo1|conflicting~1}"                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/conflicts/text()" equals "1"                                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/change/text()" equals "CONFLICT"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/id/text()" equals "Points/Point.1"                                         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/ourvalue/text()" equals "{@ObjectId|repo1|master_original:Points/Point.1}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/theirvalue/text()" equals "0000000000000000000000000000000000000000"       # WebAPICucumberHooks.checkXPathEquals(String,String)
@Repo
Feature: MergeFeature
  The MergeFeature resource provides a method of merging two conflicting features and is supported through the "/repos/{repository}/repo/mergefeature" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # MergeFeature.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/repo/mergefeature"                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "POST"                # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: MergeFeature outside of a repository issues 404 "Not found" # MergeFeature.feature:12
    Given There is an empty multirepo server                            # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "POST /repos/repo1/repo/mergefeature"                   # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                 # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"         # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: MergeFeature with no json payload issues a 400 status code # MergeFeature.feature:19
    Given There is an empty repository named repo1                     # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "POST /repos/repo1/repo/mergefeature"                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                           # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "Invalid POST data."          # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: MergeFeature with an invalid json payload issues a 400 status code     # MergeFeature.feature:25
    Given There is an empty repository named repo1                                 # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I post content-type "text/plain" to "/repos/repo1/repo/mergefeature" with # WebAPICucumberHooks.post_content(String,String,String)
      """
      "unexpected format"
      """
    Then the response status should be '400'                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "Invalid POST data."                      # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: MergeFeature without a feature issues a 400 status code                      # MergeFeature.feature:34
    Given There is an empty repository named repo1                                       # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I post content-type "application/json" to "/repos/repo1/repo/mergefeature" with # WebAPICucumberHooks.post_content(String,String,String)
      """
      {}
      """
    Then the response status should be '400'                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "Invalid POST data."                            # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: MergeFeature without an "ours" id issues a 400 status code                   # MergeFeature.feature:43
    Given There is an empty repository named repo1                                       # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I post content-type "application/json" to "/repos/repo1/repo/mergefeature" with # WebAPICucumberHooks.post_content(String,String,String)
      """
      {
        "path"="Points/Point.1"
      }
      """
    Then the response status should be '400'                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "Invalid POST data."                            # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: MergeFeature without a "theirs" id issues a 400 status code                  # MergeFeature.feature:54
    Given There is a default multirepo server                                            # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I post content-type "application/json" to "/repos/repo1/repo/mergefeature" with # WebAPICucumberHooks.post_content(String,String,String)
      """
      {
        "path"="Points/Point.1",
        "ours"="{@ObjectId|repo1|master}"
      }
      """
    Then the response status should be '400'                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "Invalid POST data."                            # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: MergeFeature without any merges issues a 400 status code                     # MergeFeature.feature:66
    Given There is a default multirepo server                                            # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I post content-type "application/json" to "/repos/repo1/repo/mergefeature" with # WebAPICucumberHooks.post_content(String,String,String)
      """
      {
        "path"="Points/Point.1",
        "ours"="{@ObjectId|repo1|master}",
        "theirs"="{@ObjectId|repo1|branch1}"
      }
      """
    Then the response status should be '400'                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "Invalid POST data."                            # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: MergeFeature builds a new feature from provided merges using ours and theirs (both features are the same) # MergeFeature.feature:79
    Given There is a default multirepo server                                                                         # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I post content-type "application/json" to "/repos/repo1/repo/mergefeature" with                              # WebAPICucumberHooks.post_content(String,String,String)
      """
      {
        "path"="Points/Point.1",
        "ours"="{@ObjectId|repo1|master}",
        "theirs"="{@ObjectId|repo1|branch1}",
        "merges"={
          "ip"={"ours"=true},
          "sp"={"theirs"=true},
          "geom"={"ours"=true}
        }
      }
      """
    Then the response status should be '200'                                                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "{@ObjectId|repo1|master:Points/Point.1}"                                    # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: MergeFeature builds a new feature from provided merges with custom values (both features are the same) # MergeFeature.feature:97
    Given There is a default multirepo server                                                                      # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I post content-type "application/json" to "/repos/repo1/repo/mergefeature" with                           # WebAPICucumberHooks.post_content(String,String,String)
      """
      {
        "path"="Points/Point.1",
        "ours"="{@ObjectId|repo1|master}",
        "theirs"="{@ObjectId|repo1|branch1}",
        "merges"={
          "ip"={"value"=500},
          "sp"={"value"="new"},
          "geom"={"value"="POINT (1 1)"}
        }
      }
      """
    Then the response status should be '200'                                                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should not contain "{@ObjectId|repo1|master:Points/Point.1}"                             # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "{@ObjectId|repo1|branch1:Points/Point.1}"                            # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And I save the response as "@featureId"                                                                        # WebAPICucumberHooks.saveResponseAsVariable(String)
    When I call "GET /repos/repo1/cat?objectid={@featureId}"                                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/feature/id/text()" equals "{@featureId}"                                              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/feature/attribute" 3 times                                      # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "new"                                                                     # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "500"                                                                     # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "POINT (1 1)"                                                             # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: MergeFeature builds a new feature from provided merges (different versions of the same feature) # MergeFeature.feature:125
    Given There is a default multirepo server                                                               # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have committed "Point.1_modified" on the "repo1" repo in the "" transaction                       # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I post content-type "application/json" to "/repos/repo1/repo/mergefeature" with                    # WebAPICucumberHooks.post_content(String,String,String)
      """
      {
        "path"="Points/Point.1",
        "ours"="{@ObjectId|repo1|master}",
        "theirs"="{@ObjectId|repo1|branch1}",
        "merges"={
          "ip"={"ours"=true},
          "sp"={"theirs"=true},
          "geom"={"value"="POINT (1 1)"}
        }
      }
      """
    Then the response status should be '200'                                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should not contain "{@ObjectId|repo1|master:Points/Point.1}"                      # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should not contain "{@ObjectId|repo1|branch1:Points/Point.1}"                     # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And I save the response as "@featureId"                                                                 # WebAPICucumberHooks.saveResponseAsVariable(String)
    When I call "GET /repos/repo1/cat?objectid={@featureId}"                                                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/feature/id/text()" equals "{@featureId}"                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/feature/attribute" 3 times                               # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "1500"                                                             # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "StringProp1_1"                                                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "POINT (1 1)"                                                      # WebAPICucumberHooks.checkResponseTextContains(String)
@Repo
Feature: ObjectExists
  The ObjectExists resource is used to determine if an objectId exists in the repository and is supported through the "/repos/{repository}/repo/exists" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # ObjectExists.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/repo/exists"                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ObjectExists outside of a repository issues 404 "Not found" # ObjectExists.feature:12
    Given There is an empty multirepo server                            # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/repo/exists"                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                 # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"         # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ObjectExists with no object id issues a 400 status code       # ObjectExists.feature:19
    Given There is an empty repository named repo1                        # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/repo/exists"                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                              # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "You must specify an object id." # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ObjectExists with an invalid object id issues a 400 status code    # ObjectExists.feature:25
    Given There is an empty repository named repo1                             # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/repo/exists?oid=invalid"                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the response body should contain "You must specify a valid object id." # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: ObjectExists with a nonexistent object id returns "0"                           # ObjectExists.feature:31
    Given There is a default multirepo server                                               # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/repo/exists?oid=0123456789012345678901234567890123456789" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                     # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "0"                                                # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: ObjectExists with an existing object id returns "1"                            # ObjectExists.feature:38
    Given There is a default multirepo server                                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/repo/exists?oid={@ObjectId|repo1|master:Points/Point.1}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                    # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "1"                                               # WebAPICucumberHooks.checkResponseTextContains(String)
@Repo
Feature: Parents
  The Parents resource returns the parents of a specific commit and is supported through the "/repos/{repository}/repo/getparents" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Parents.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/repo/getparents"                   # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Parents outside of a repository issues 404 "Not found" # Parents.feature:12
    Given There is an empty multirepo server                       # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/repo/getparents"                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"            # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"    # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Parents with an invalid commit issues a 400 status code            # Parents.feature:19
    Given There is a default multirepo server                                  # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/repo/getparents?commitId=invalid"            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                        # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "You must specify a valid commit id." # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Parents with no commit returns no parents   # Parents.feature:26
    Given There is a default multirepo server           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/repo/getparents"      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain" # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain ""             # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Parents with a commit returns the parents of that commit                 # Parents.feature:33
    Given There is a default multirepo server                                        # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/repo/getparents?commitId={@ObjectId|repo1|master}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                              # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "{@ObjectId|repo1|master~1}"                # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|branch2}"                 # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: Pull
  The pull command allows a user to merge a remote branch into a local one and is supported through the "/repos/{repository}/pull" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Pull.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/pull"                              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Pull outside of a repository issues 404 "Not found" # Pull.feature:12
    Given There is an empty multirepo server                    # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/pull"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                    # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"         # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found" # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  Scenario: Pulling from a remote with remote changes updates the local ref                    # Pull.feature:19
    Given There is a default multirepo server with remotes                                     # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    And the variable "{@ObjectId|repo4|master}" equals "{@ObjectId|repo1|master~2}"            # WebAPICucumberHooks.checkVariableEquals(String,String)
    When I call "GET /repos/repo4/pull?remoteName=origin&ref=master"                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/ours/text()" equals "{@ObjectId|repo1|master~2}"       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/theirs/text()" equals "{@ObjectId|repo1|master}"       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/ancestor/text()" equals "{@ObjectId|repo1|master~2}"   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/mergedCommit/text()" equals "{@ObjectId|repo1|master}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Added/text()" equals "6"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Modified/text()" equals "0"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Removed/text()" equals "0"                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo4|master}" equals "{@ObjectId|repo1|master}"              # WebAPICucumberHooks.checkVariableEquals(String,String)
[main] INFO org.mortbay.log - jetty-6.1.5
[main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8182
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool6-1] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool6-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["abfb203493c9ad8e8cd17529bc01576c8dd11c8c","7bd3f29b781998b8bf59e7ca21e6e3422231d6bb"],"have":[]}
[btpool6-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.417 μs for 0 ids: []. Calculating reachable content ids...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 14.03 μs for 0 ids
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 7.803 μs
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 4.959 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool6-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["248e1076551488a684c485c82784f758e4a93bb1"],"have":["abfb203493c9ad8e8cd17529bc01576c8dd11c8c"]}
[btpool6-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.364 μs for 1 ids: [abfb203493c9ad8e8cd17529bc01576c8dd11c8c]. Calculating reachable content ids...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 489.0 μs for 11 ids
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.50 μs
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 8 objects. Inserted: 8. Existing: 0. Time: 1.383 ms. Compressed size: 656 bytes. Uncompressed size: 1,488 bytes.
[btpool6-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["e81130e61b1161d6eae09c4f9625387b4c992137","92e7aecafdeeb37cae603e54b8e1366d7187afc7"],"have":["248e1076551488a684c485c82784f758e4a93bb1","7bd3f29b781998b8bf59e7ca21e6e3422231d6bb","abfb203493c9ad8e8cd17529bc01576c8dd11c8c"]}
[btpool6-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.328 μs for 3 ids: [248e1076551488a684c485c82784f758e4a93bb1, 7bd3f29b781998b8bf59e7ca21e6e3422231d6bb, abfb203493c9ad8e8cd17529bc01576c8dd11c8c]. Calculating reachable content ids...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 584.2 μs for 27 ids
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 13.83 μs
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 6 objects. Inserted: 6. Existing: 0. Time: 1.167 ms. Compressed size: 778 bytes. Uncompressed size: 1,673 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool6-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["abfb203493c9ad8e8cd17529bc01576c8dd11c8c","7bd3f29b781998b8bf59e7ca21e6e3422231d6bb"],"have":[]}
[btpool6-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.371 μs for 0 ids: []. Calculating reachable content ids...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 14.48 μs for 0 ids
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 7.335 μs
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 3.209 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool6-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["248e1076551488a684c485c82784f758e4a93bb1","e81130e61b1161d6eae09c4f9625387b4c992137","92e7aecafdeeb37cae603e54b8e1366d7187afc7"],"have":["7bd3f29b781998b8bf59e7ca21e6e3422231d6bb","abfb203493c9ad8e8cd17529bc01576c8dd11c8c"]}
[btpool6-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.167 μs for 2 ids: [7bd3f29b781998b8bf59e7ca21e6e3422231d6bb, abfb203493c9ad8e8cd17529bc01576c8dd11c8c]. Calculating reachable content ids...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 505.2 μs for 19 ids
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.17 μs
[btpool6-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 14 objects. Inserted: 14. Existing: 0. Time: 2.342 ms. Compressed size: 1,066 bytes. Uncompressed size: 3,161 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  @HttpTest
  Scenario: Pulling from an http remote with remote changes updates the local ref              # Pull.feature:35
    Given There is a default multirepo server with http remotes                                # WebAPICucumberHooks.setUpDefaultMultiRepoWithHttpRemotes()
    And the variable "{@ObjectId|repo4|master}" equals "{@ObjectId|repo1|master~2}"            # WebAPICucumberHooks.checkVariableEquals(String,String)
    When I call "GET /repos/repo4/pull?remoteName=origin&ref=master"                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/ours/text()" equals "{@ObjectId|repo1|master~2}"       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/theirs/text()" equals "{@ObjectId|repo1|master}"       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/ancestor/text()" equals "{@ObjectId|repo1|master~2}"   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/mergedCommit/text()" equals "{@ObjectId|repo1|master}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Added/text()" equals "6"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Modified/text()" equals "0"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Removed/text()" equals "0"                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo4|master}" equals "{@ObjectId|repo1|master}"              # WebAPICucumberHooks.checkVariableEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  Scenario: Pulling from a remote with both local and remote changes creates a merge commit                                                    # Pull.feature:50
    Given There is a default multirepo server with remotes                                                                                     # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    And I have a transaction as "@txId" on the "repo4" repo                                                                                    # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have committed "Point.1_modified" on the "repo4" repo in the "@txId" transaction                                                     # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo4/pull?transactionId={@txId}&remoteName=origin&ref=master&authorName=myAuthor&authorEmail=myAuthor@geogig.org" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/ours/text()" equals "{@ObjectId|repo4|@txId|master~1}"                                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/theirs/text()" equals "{@ObjectId|repo1|master}"                                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/ancestor/text()" equals "{@ObjectId|repo1|master~2}"                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/mergedCommit/text()" equals "{@ObjectId|repo4|@txId|master}"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Added/text()" equals "6"                                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Modified/text()" equals "0"                                                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Removed/text()" equals "0"                                                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo4/cat?objectid={@ObjectId|repo4|@txId|master}"                                                                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/name/text()" equals "myAuthor"                                                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/email/text()" equals "myAuthor@geogig.org"                                                          # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.mortbay.log - jetty-6.1.5
[main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8182
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool7-1] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool7-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["37810383e8933714c4c80b79c4b1ff2f8e61e9b1","1380fdb7794985a62eee73fe284c51f922ca44e6"],"have":[]}
[btpool7-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.847 μs for 0 ids: []. Calculating reachable content ids...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 16.10 μs for 0 ids
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.07 μs
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 2.953 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool7-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["3b5b7d08a9039bc69eba75e3e5e2b7ee462dd6d8"],"have":["37810383e8933714c4c80b79c4b1ff2f8e61e9b1"]}
[btpool7-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.149 μs for 1 ids: [37810383e8933714c4c80b79c4b1ff2f8e61e9b1]. Calculating reachable content ids...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 414.3 μs for 11 ids
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.79 μs
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 8 objects. Inserted: 8. Existing: 0. Time: 1.288 ms. Compressed size: 657 bytes. Uncompressed size: 1,488 bytes.
[btpool7-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["72e3c511cd30d1ba450832b5295ec6ee4bb16bf5","6130ea3929743718aac2eadee17197ee3ae3bed2"],"have":["37810383e8933714c4c80b79c4b1ff2f8e61e9b1","3b5b7d08a9039bc69eba75e3e5e2b7ee462dd6d8","1380fdb7794985a62eee73fe284c51f922ca44e6"]}
[btpool7-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.384 μs for 3 ids: [37810383e8933714c4c80b79c4b1ff2f8e61e9b1, 3b5b7d08a9039bc69eba75e3e5e2b7ee462dd6d8, 1380fdb7794985a62eee73fe284c51f922ca44e6]. Calculating reachable content ids...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 514.8 μs for 27 ids
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.39 μs
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 6 objects. Inserted: 6. Existing: 0. Time: 1.349 ms. Compressed size: 778 bytes. Uncompressed size: 1,673 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool7-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["37810383e8933714c4c80b79c4b1ff2f8e61e9b1","1380fdb7794985a62eee73fe284c51f922ca44e6"],"have":[]}
[btpool7-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 3.408 μs for 0 ids: []. Calculating reachable content ids...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 13.71 μs for 0 ids
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 7.665 μs
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 3.883 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool7-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["3b5b7d08a9039bc69eba75e3e5e2b7ee462dd6d8","72e3c511cd30d1ba450832b5295ec6ee4bb16bf5","6130ea3929743718aac2eadee17197ee3ae3bed2"],"have":["37810383e8933714c4c80b79c4b1ff2f8e61e9b1","1380fdb7794985a62eee73fe284c51f922ca44e6"]}
[btpool7-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.450 μs for 2 ids: [37810383e8933714c4c80b79c4b1ff2f8e61e9b1, 1380fdb7794985a62eee73fe284c51f922ca44e6]. Calculating reachable content ids...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 433.3 μs for 19 ids
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.07 μs
[btpool7-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 14 objects. Inserted: 14. Existing: 0. Time: 2.039 ms. Compressed size: 1,066 bytes. Uncompressed size: 3,161 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  @HttpTest
  Scenario: Pulling from an http remote with both local and remote changes creates a merge commit                                              # Pull.feature:71
    Given There is a default multirepo server with http remotes                                                                                # WebAPICucumberHooks.setUpDefaultMultiRepoWithHttpRemotes()
    And I have a transaction as "@txId" on the "repo4" repo                                                                                    # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have committed "Point.1_modified" on the "repo4" repo in the "@txId" transaction                                                     # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo4/pull?transactionId={@txId}&remoteName=origin&ref=master&authorName=myAuthor&authorEmail=myAuthor@geogig.org" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/ours/text()" equals "{@ObjectId|repo4|@txId|master~1}"                                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/theirs/text()" equals "{@ObjectId|repo1|master}"                                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/ancestor/text()" equals "{@ObjectId|repo1|master~2}"                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Merge/mergedCommit/text()" equals "{@ObjectId|repo4|@txId|master}"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Added/text()" equals "6"                                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Modified/text()" equals "0"                                                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Pull/Removed/text()" equals "0"                                                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo4/cat?objectid={@ObjectId|repo4|@txId|master}"                                                                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/name/text()" equals "myAuthor"                                                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/email/text()" equals "myAuthor@geogig.org"                                                          # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  Scenario: Pulling from a remote with conflicting changes returns the details of the conflict                                                 # Pull.feature:91
    Given There is a default multirepo server with remotes                                                                                     # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    And I have a transaction as "@txId" on the "repo4" repo                                                                                    # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have committed "Point.2_modified" on the "repo4" repo in the "@txId" transaction                                                     # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo4/pull?transactionId={@txId}&remoteName=origin&ref=master&authorName=myAuthor&authorEmail=myAuthor@geogig.org" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ours/text()" equals "{@ObjectId|repo4|@txId|master}"                                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/theirs/text()" equals "{@ObjectId|repo1|master}"                                                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ancestor/text()" equals "{@ObjectId|repo1|master~2}"                                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/conflicts/text()" equals "1"                                                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Merge/Feature" 6 times                                                                      # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "CONFLICT"                                                                                            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "<theirvalue>{@ObjectId|repo1|master:Points/Point.2}</theirvalue>"                                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "<ourvalue>{@ObjectId|repo4|@txId|master:Points/Point.2}</ourvalue>"                                  # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.mortbay.log - jetty-6.1.5
[main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8182
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool8-1] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool8-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["4cb94d40fec9f1b2371f77d25487011e9eb213e1","dc634a7dae039c1be912d1528647133c2afd0aae"],"have":[]}
[btpool8-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 3.211 μs for 0 ids: []. Calculating reachable content ids...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 16.47 μs for 0 ids
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.58 μs
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 3.181 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool8-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["60eb9bd107180a2332394a57524be23f32ec51de"],"have":["4cb94d40fec9f1b2371f77d25487011e9eb213e1"]}
[btpool8-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.822 μs for 1 ids: [4cb94d40fec9f1b2371f77d25487011e9eb213e1]. Calculating reachable content ids...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 308.9 μs for 11 ids
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 13.83 μs
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 8 objects. Inserted: 8. Existing: 0. Time: 1.220 ms. Compressed size: 656 bytes. Uncompressed size: 1,488 bytes.
[btpool8-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["c957ff92ab96319de9beb97a92eb9e75bd9b1886","ac6303915455a5e7c37b007442a00bd040a14176"],"have":["4cb94d40fec9f1b2371f77d25487011e9eb213e1","dc634a7dae039c1be912d1528647133c2afd0aae","60eb9bd107180a2332394a57524be23f32ec51de"]}
[btpool8-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.493 μs for 3 ids: [4cb94d40fec9f1b2371f77d25487011e9eb213e1, dc634a7dae039c1be912d1528647133c2afd0aae, 60eb9bd107180a2332394a57524be23f32ec51de]. Calculating reachable content ids...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 520.5 μs for 27 ids
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.40 μs
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 6 objects. Inserted: 6. Existing: 0. Time: 1.101 ms. Compressed size: 778 bytes. Uncompressed size: 1,673 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool8-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["4cb94d40fec9f1b2371f77d25487011e9eb213e1","dc634a7dae039c1be912d1528647133c2afd0aae"],"have":[]}
[btpool8-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.362 μs for 0 ids: []. Calculating reachable content ids...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 16.67 μs for 0 ids
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.63 μs
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 2.877 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool8-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["60eb9bd107180a2332394a57524be23f32ec51de","c957ff92ab96319de9beb97a92eb9e75bd9b1886","ac6303915455a5e7c37b007442a00bd040a14176"],"have":["4cb94d40fec9f1b2371f77d25487011e9eb213e1","dc634a7dae039c1be912d1528647133c2afd0aae"]}
[btpool8-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 3.647 μs for 2 ids: [4cb94d40fec9f1b2371f77d25487011e9eb213e1, dc634a7dae039c1be912d1528647133c2afd0aae]. Calculating reachable content ids...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 776.9 μs for 19 ids
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 14.78 μs
[btpool8-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 14 objects. Inserted: 14. Existing: 0. Time: 2.629 ms. Compressed size: 1,066 bytes. Uncompressed size: 3,161 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  @HttpTest
  Scenario: Pulling from an http remote with conflicting changes returns the details of the conflict                                           # Pull.feature:108
    Given There is a default multirepo server with http remotes                                                                                # WebAPICucumberHooks.setUpDefaultMultiRepoWithHttpRemotes()
    And I have a transaction as "@txId" on the "repo4" repo                                                                                    # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have committed "Point.2_modified" on the "repo4" repo in the "@txId" transaction                                                     # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo4/pull?transactionId={@txId}&remoteName=origin&ref=master&authorName=myAuthor&authorEmail=myAuthor@geogig.org" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ours/text()" equals "{@ObjectId|repo4|@txId|master}"                                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/theirs/text()" equals "{@ObjectId|repo1|master}"                                                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ancestor/text()" equals "{@ObjectId|repo1|master~2}"                                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/conflicts/text()" equals "1"                                                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Merge/Feature" 6 times                                                                      # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "CONFLICT"                                                                                            # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "<theirvalue>{@ObjectId|repo1|master:Points/Point.2}</theirvalue>"                                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "<ourvalue>{@ObjectId|repo4|@txId|master:Points/Point.2}</ourvalue>"                                  # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: Push
  The push command allows a user to push a local branch to a remote and is supported through the "/repos/{repository}/push" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Push.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/push"                              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Push outside of a repository issues 404 "Not found" # Push.feature:12
    Given There is an empty multirepo server                    # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/push"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                    # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"         # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found" # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.plumbing.SendPack - Pushing Ref[refs/heads/master -> 0d0c4bec17783deb27b96e0103f1d888b113e73e] to refs/remotes/repo4/master(master)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  Scenario: Pushing changes to a remote results in a success                      # Push.feature:19
    Given There is a default multirepo server with remotes                        # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo1/push?remoteName=repo4&ref=master"               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Push/text()" equals "Success"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/dataPushed/text()" equals "true"                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo1|master}" equals "{@ObjectId|repo4|master}" # WebAPICucumberHooks.checkVariableEquals(String,String)
    When I call "GET /repos/repo1/push?remoteName=repo4&ref=master"               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Push/text()" equals "Success"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/dataPushed/text()" equals "false"                    # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.mortbay.log - jetty-6.1.5
[main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8182
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool9-1] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool9-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["7f5955c580b37a9f94bf508c1f82d94291874182","d8b7ae74171713aed78cde15b00ec936a3a17345"],"have":[]}
[btpool9-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.543 μs for 0 ids: []. Calculating reachable content ids...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 13.84 μs for 0 ids
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 7.556 μs
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 2.993 ms. Compressed size: 988 bytes. Uncompressed size: 3,179 bytes.
[btpool9-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["740e3b752b2dd484fbfe1c5f73e1ecf3cbedd3d8"],"have":["7f5955c580b37a9f94bf508c1f82d94291874182"]}
[btpool9-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.585 μs for 1 ids: [7f5955c580b37a9f94bf508c1f82d94291874182]. Calculating reachable content ids...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 369.2 μs for 11 ids
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.25 μs
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 8 objects. Inserted: 8. Existing: 0. Time: 1.284 ms. Compressed size: 656 bytes. Uncompressed size: 1,488 bytes.
[btpool9-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["8c431f2866c9e3c267f0ae4c0442b8930c65d268","9bbd308930e010165cc39893a42bcbe72ae5e073"],"have":["d8b7ae74171713aed78cde15b00ec936a3a17345","7f5955c580b37a9f94bf508c1f82d94291874182","740e3b752b2dd484fbfe1c5f73e1ecf3cbedd3d8"]}
[btpool9-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 3.403 μs for 3 ids: [d8b7ae74171713aed78cde15b00ec936a3a17345, 7f5955c580b37a9f94bf508c1f82d94291874182, 740e3b752b2dd484fbfe1c5f73e1ecf3cbedd3d8]. Calculating reachable content ids...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 559.5 μs for 27 ids
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 13.53 μs
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 6 objects. Inserted: 6. Existing: 0. Time: 1.038 ms. Compressed size: 777 bytes. Uncompressed size: 1,673 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool9-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["7f5955c580b37a9f94bf508c1f82d94291874182","d8b7ae74171713aed78cde15b00ec936a3a17345"],"have":[]}
[btpool9-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.422 μs for 0 ids: []. Calculating reachable content ids...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 14.13 μs for 0 ids
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 7.402 μs
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 2.830 ms. Compressed size: 988 bytes. Uncompressed size: 3,179 bytes.
[btpool9-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["740e3b752b2dd484fbfe1c5f73e1ecf3cbedd3d8","8c431f2866c9e3c267f0ae4c0442b8930c65d268","9bbd308930e010165cc39893a42bcbe72ae5e073"],"have":["d8b7ae74171713aed78cde15b00ec936a3a17345","7f5955c580b37a9f94bf508c1f82d94291874182"]}
[btpool9-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.917 μs for 2 ids: [d8b7ae74171713aed78cde15b00ec936a3a17345, 7f5955c580b37a9f94bf508c1f82d94291874182]. Calculating reachable content ids...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 730.5 μs for 19 ids
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 14.50 μs
[btpool9-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 14 objects. Inserted: 14. Existing: 0. Time: 2.728 ms. Compressed size: 1,065 bytes. Uncompressed size: 3,161 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool9-1] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[btpool9-1] INFO org.locationtech.geogig.rest.repository.PushManager - Updating ref 'refs/heads/master'[7f5955c580b37a9f94bf508c1f82d94291874182] -> 9bbd308930e010165cc39893a42bcbe72ae5e073
[main] INFO org.locationtech.geogig.plumbing.SendPack - Pushing Ref[refs/heads/master -> 9bbd308930e010165cc39893a42bcbe72ae5e073] to refs/remotes/repo4/master(master)
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  @HttpTest
  Scenario: Pushing changes to an http remote results in a success                # Push.feature:34
    Given There is a default multirepo server with http remotes                   # WebAPICucumberHooks.setUpDefaultMultiRepoWithHttpRemotes()
    When I call "GET /repos/repo1/push?remoteName=repo4&ref=master"               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Push/text()" equals "Success"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/dataPushed/text()" equals "true"                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo1|master}" equals "{@ObjectId|repo4|master}" # WebAPICucumberHooks.checkVariableEquals(String,String)
    When I call "GET /repos/repo1/push?remoteName=repo4&ref=master"               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Push/text()" equals "Success"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/dataPushed/text()" equals "false"                    # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Pushing changes to a remote with other changes issues a 500 status code                                                           # Push.feature:48
    Given There is a default multirepo server with remotes                                                                                    # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    And I have a transaction as "@txId" on the "repo4" repo                                                                                   # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have committed "Point.1_modified" on the "repo4" repo in the "@txId" transaction                                                    # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo4/push?transactionId={@txId}&remoteName=origin&ref=master"                                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Push failed: The remote repository has changes that would be lost in the event of a push." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.mortbay.log - jetty-6.1.5
[main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8182
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool10-1] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool10-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["08f8e7db876bc888e71419b9edb1c4289c7f9b90","1fc923e900f4aee930b54581d66f3dcd61b1316d"],"have":[]}
[btpool10-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 3.208 μs for 0 ids: []. Calculating reachable content ids...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 16.63 μs for 0 ids
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 10.70 μs
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 3.306 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool10-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["8a450fb34524db46b301caca066f224dd5b7572c"],"have":["08f8e7db876bc888e71419b9edb1c4289c7f9b90"]}
[btpool10-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.819 μs for 1 ids: [08f8e7db876bc888e71419b9edb1c4289c7f9b90]. Calculating reachable content ids...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 342.3 μs for 11 ids
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 14.09 μs
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 8 objects. Inserted: 8. Existing: 0. Time: 1.160 ms. Compressed size: 657 bytes. Uncompressed size: 1,488 bytes.
[btpool10-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["23d320f843aaaa353c9bc7c415b18a45ba5f59cf","2b34dc0513ed33605e26fc41e6d96bd9da638003"],"have":["8a450fb34524db46b301caca066f224dd5b7572c","1fc923e900f4aee930b54581d66f3dcd61b1316d","08f8e7db876bc888e71419b9edb1c4289c7f9b90"]}
[btpool10-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 3.127 μs for 3 ids: [8a450fb34524db46b301caca066f224dd5b7572c, 1fc923e900f4aee930b54581d66f3dcd61b1316d, 08f8e7db876bc888e71419b9edb1c4289c7f9b90]. Calculating reachable content ids...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 520.9 μs for 27 ids
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 13.55 μs
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 6 objects. Inserted: 6. Existing: 0. Time: 950.8 μs. Compressed size: 779 bytes. Uncompressed size: 1,673 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool10-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["08f8e7db876bc888e71419b9edb1c4289c7f9b90","1fc923e900f4aee930b54581d66f3dcd61b1316d"],"have":[]}
[btpool10-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.834 μs for 0 ids: []. Calculating reachable content ids...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 14.12 μs for 0 ids
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 7.920 μs
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 19 objects. Inserted: 19. Existing: 0. Time: 2.849 ms. Compressed size: 989 bytes. Uncompressed size: 3,179 bytes.
[btpool10-1] INFO org.locationtech.geogig.rest.repository.BatchedObjectResource - Serving request to send objects based on message {"want":["8a450fb34524db46b301caca066f224dd5b7572c","23d320f843aaaa353c9bc7c415b18a45ba5f59cf","2b34dc0513ed33605e26fc41e6d96bd9da638003"],"have":["1fc923e900f4aee930b54581d66f3dcd61b1316d","08f8e7db876bc888e71419b9edb1c4289c7f9b90"]}
[btpool10-1] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - scanning for previsit list...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - Previsit list built in 2.136 μs for 2 ids: [1fc923e900f4aee930b54581d66f3dcd61b1316d, 08f8e7db876bc888e71419b9edb1c4289c7f9b90]. Calculating reachable content ids...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - reachableContentIds took 409.4 μs for 19 ids
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - obtaining post order iterator on range...
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - PostOrderIterator.range took 9.780 μs
[btpool10-1] INFO org.locationtech.geogig.remote.BinaryPackedObjects - writing objects to remote...
[main] INFO org.locationtech.geogig.remote.HttpRemoteRepo - Processed 14 objects. Inserted: 14. Existing: 0. Time: 1.848 ms. Compressed size: 1,068 bytes. Uncompressed size: 3,161 bytes.
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.plumbing.CreateDeduplicator - No DeduplicationService service found, using default heap based one
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3

  @HttpTest
  Scenario: Pushing changes to an http remote with other changes issues a 500 status code                                                     # Push.feature:57
    Given There is a default multirepo server with http remotes                                                                               # WebAPICucumberHooks.setUpDefaultMultiRepoWithHttpRemotes()
    And I have a transaction as "@txId" on the "repo4" repo                                                                                   # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have committed "Point.1_modified" on the "repo4" repo in the "@txId" transaction                                                    # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo4/push?transactionId={@txId}&remoteName=origin&ref=master"                                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Push failed: The remote repository has changes that would be lost in the event of a push." # WebAPICucumberHooks.checkXPathEquals(String,String)
@Commands
Feature: RebuildGraph
  The RebuildGraph command allows a user to rebuild the graph database of a repository and is supported through the "/repos/{repository}/rebuildgraph" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # RebuildGraph.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/rebuildgraph"                      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: RebuildGraph outside of a repository issues 404 "Not found" # RebuildGraph.feature:12
    Given There is an empty multirepo server                            # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/rebuildgraph"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                 # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"         # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: RebuildGraph restores missing entries in the graph database                # RebuildGraph.feature:19
    Given There is a default multirepo server                                          # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And The graph database on the "repo1" repo has been truncated                      # WebAPICucumberHooks.Truncate_graph_database(String)
    When I call "GET /repos/repo1/rebuildgraph"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/RebuildGraph/updatedGraphElements/text()" equals "4"      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/RebuildGraph/UpdatedObject" 4 times # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "{@ObjectId|repo1|master}"                    # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|branch1}"                   # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|branch2}"                   # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "{@ObjectId|repo1|master~1}"                  # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: The quiet flag prevents all of the restored commits from being reported    # RebuildGraph.feature:32
    Given There is a default multirepo server                                          # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And The graph database on the "repo1" repo has been truncated                      # WebAPICucumberHooks.Truncate_graph_database(String)
    When I call "GET /repos/repo1/rebuildgraph?quiet=true"                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/RebuildGraph/updatedGraphElements/text()" equals "4"      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/RebuildGraph/UpdatedObject" 0 times # WebAPICucumberHooks.checkXPathCadinality(String,int)
@Commands
Feature: RefParse
  The RefParse command allows a user to get the details of a ref by name and is supported through the "/repos/{repository}/refparse" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # RefParse.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/refparse"                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: RefParse outside of a repository issues 404 "Not found" # RefParse.feature:12
    Given There is an empty multirepo server                        # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/refparse?name=someRef"            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"             # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"     # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling RefParse without a ref name issues a 500 status code                        # RefParse.feature:19
    Given There is an empty repository named repo1                                              # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/refparse"                                                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Required parameter 'name' was not provided." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling RefParse with a nonexistent name issues a 500 status code          # RefParse.feature:25
    Given There is an empty repository named repo1                                     # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/refparse?name=nonexistent"                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Unable to parse the provided name." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling RefParse with a ref name returns the details of that ref        # RefParse.feature:31
    Given There is a default multirepo server                                       # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/refparse?name=master"                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Ref/name/text()" equals "refs/heads/master"            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Ref/objectId/text()" equals "{@ObjectId|repo1|master}" # WebAPICucumberHooks.checkXPathEquals(String,String)
@Commands
Feature: Remote
  The remote command allows a user to manage the remotes of a repository and is supported through the "/repos/{repository}/remote" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # RemoteManagement.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/remote"                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Remote outside of a repository issues 404 "Not found" # RemoteManagement.feature:12
    Given There is an empty multirepo server                      # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/remote"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"           # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"   # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying the list parameter will list all remotes     # RemoteManagement.feature:19
    Given There is a default multirepo server with remotes         # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?list=true"                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                       # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Remote" 2 times # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "repo1"                   # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "repo2"                   # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying the list parameter with verbose will list more detail of all remotes # RemoteManagement.feature:28
    Given There is a default multirepo server with remotes                                 # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo2/remote?list=true&verbose=true"                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Remote/name/text()" equals "origin"                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Remote/url" 1 times                     # WebAPICucumberHooks.checkXPathCadinality(String,int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying the ping parameter without a remote name issues a 400 status code # RemoteManagement.feature:36
    Given There is a default multirepo server with remotes                              # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?ping=true"                                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "MISSING_NAME"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Pinging a reachable remote returns as successful         # RemoteManagement.feature:42
    Given There is a default multirepo server with remotes           # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?remoteName=repo1&ping=true" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/ping/success/text()" equals "true"      # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Pinging a nonexistent remote returns as not successful         # RemoteManagement.feature:49
    Given There is a default multirepo server with remotes                 # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?remoteName=nonexistent&ping=true" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/ping/success/text()" equals "false"           # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying the remove parameter without a remote name issues a 500 status code # RemoteManagement.feature:56
    Given There is a default multirepo server with remotes                                # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?remove=true"                                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "No remote was specified."              # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Removing a nonexistent remote issues a 400 status code           # RemoteManagement.feature:62
    Given There is a default multirepo server with remotes                   # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?remove=true&remoteName=nonexistent" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "REMOTE_NOT_FOUND"         # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Removing a valid remote name removes the remote            # RemoteManagement.feature:68
    Given There is a default multirepo server with remotes             # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?remove=true&remoteName=repo1" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/name/text()" equals "repo1"               # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo3/remote?list=true"                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Remote" 1 times     # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should not contain "repo1"                   # WebAPICucumberHooks.checkResponseTextNotContains(String)
    And the response body should contain "repo2"                       # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying the update parameter without a remote name issues a 500 status code # RemoteManagement.feature:81
    Given There is a default multirepo server with remotes                                # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?update=true"                                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "No remote was specified."              # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying the update parameter without a remote url issues a 500 status code # RemoteManagement.feature:87
    Given There is a default multirepo server with remotes                               # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?update=true&remoteName=repo1"                   # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "No URL was specified."                # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
java.lang.IllegalArgumentException: Update indexes does not support symbolic references
	at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
	at org.locationtech.geogig.porcelain.index.UpdateIndexesOp.setRef(UpdateIndexesOp.java:49)
	at org.locationtech.geogig.hooks.builtin.UpdateIndexesHook.post(UpdateIndexesHook.java:56)
	at org.locationtech.geogig.hooks.CommandHookChain.runPostHooks(CommandHookChain.java:65)
	at org.locationtech.geogig.hooks.CommandHooksDecorator$HooksListener.postCall(CommandHooksDecorator.java:60)
	at org.locationtech.geogig.repository.AbstractGeoGigOp.notifyPost(AbstractGeoGigOp.java:179)
	at org.locationtech.geogig.repository.AbstractGeoGigOp.call(AbstractGeoGigOp.java:155)
	at org.locationtech.geogig.porcelain.RemoteRemoveOp._call(RemoteRemoveOp.java:76)
	at org.locationtech.geogig.porcelain.RemoteRemoveOp._call(RemoteRemoveOp.java:31)
	at org.locationtech.geogig.repository.AbstractGeoGigOp.call(AbstractGeoGigOp.java:154)
	at org.locationtech.geogig.web.api.commands.RemoteManagement.remoteUpdate(RemoteManagement.java:229)
	at org.locationtech.geogig.web.api.commands.RemoteManagement.runInternal(RemoteManagement.java:187)
	at org.locationtech.geogig.web.api.AbstractWebAPICommand.run(AbstractWebAPICommand.java:147)
	at org.locationtech.geogig.rest.repository.CommandResource.runCommand(CommandResource.java:252)
	at org.locationtech.geogig.rest.repository.CommandResource.processRequest(CommandResource.java:193)
	at org.locationtech.geogig.rest.repository.CommandResource.getRepresentation(CommandResource.java:239)
	at org.restlet.resource.Resource.handleGet(Resource.java:415)
	at org.restlet.Finder.handle(Finder.java:292)
	at org.restlet.Filter.doHandle(Filter.java:105)
	at org.restlet.Filter.handle(Filter.java:134)
	at org.restlet.Router.handle(Router.java:444)
	at org.restlet.Filter.doHandle(Filter.java:105)
	at org.restlet.Filter.handle(Filter.java:134)
	at org.restlet.Router.handle(Router.java:444)
	at org.restlet.Filter.doHandle(Filter.java:105)
	at org.restlet.Filter.handle(Filter.java:134)
	at org.restlet.Filter.doHandle(Filter.java:105)
	at org.restlet.Filter.handle(Filter.java:134)
	at org.restlet.Filter.doHandle(Filter.java:105)
	at org.restlet.Filter.handle(Filter.java:134)
	at org.restlet.Filter.doHandle(Filter.java:105)
	at com.noelios.restlet.StatusFilter.doHandle(StatusFilter.java:87)
	at org.restlet.Filter.handle(Filter.java:134)
	at org.restlet.Filter.doHandle(Filter.java:105)
	at org.restlet.Filter.handle(Filter.java:134)
	at com.noelios.restlet.application.ApplicationHelper.handle(ApplicationHelper.java:96)
	at org.restlet.Application.handle(Application.java:293)
	at org.restlet.Uniform.handle(Uniform.java:97)
	at org.geogig.web.functional.DefaultFunctionalTestContext.callInternal(DefaultFunctionalTestContext.java:217)
	at org.geogig.web.functional.FunctionalTestContext.call(FunctionalTestContext.java:280)
	at org.geogig.web.functional.WebAPICucumberHooks.callURL(WebAPICucumberHooks.java:641)
	at sun.reflect.GeneratedMethodAccessor52.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at cucumber.runtime.Utils$1.call(Utils.java:37)
	at cucumber.runtime.Timeout.timeout(Timeout.java:13)
	at cucumber.runtime.Utils.invoke(Utils.java:31)
	at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:38)
	at cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:37)
	at cucumber.runtime.Runtime.runStep(Runtime.java:299)
	at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
	at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
	at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:44)
	at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:91)
	at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)
	at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70)
	at cucumber.api.junit.Cucumber.runChild(Cucumber.java:93)
	at cucumber.api.junit.Cucumber.runChild(Cucumber.java:37)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at cucumber.api.junit.Cucumber.run(Cucumber.java:98)
	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
	at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying a new url with the update parameter updates a remote               # RemoteManagement.feature:93
    Given There is a default multirepo server with remotes                               # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo2/remote?update=true&remoteName=origin&remoteURL=newUrl" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/name/text()" equals "origin"                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo2/remote?list=true&verbose=true"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Remote/name/text()" equals "origin"                         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Remote/url/text()" equals "newUrl"                          # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying a new name with the update parameter renames a remote                               # RemoteManagement.feature:105
    Given There is a default multirepo server with remotes                                                # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?update=true&remoteName=repo1&remoteURL=repo1url&newName=renamed" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/name/text()" equals "renamed"                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo3/remote?list=true"                                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Remote" 2 times                                        # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "renamed"                                                        # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "repo2"                                                          # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying the add parameter without a remote name issues a 500 status code # RemoteManagement.feature:118
    Given There is a default multirepo server with remotes                             # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?add=true"                                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "No remote was specified."           # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying the add parameter without a remote url issues a 500 status code # RemoteManagement.feature:124
    Given There is a default multirepo server with remotes                            # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?add=true&remoteName=newRemote"               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "No URL was specified."             # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo3
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo4
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying add with valid parameters adds a new remote                        # RemoteManagement.feature:130
    Given There is a default multirepo server with remotes                               # WebAPICucumberHooks.setUpDefaultMultiRepoWithRemotes()
    When I call "GET /repos/repo3/remote?add=true&remoteName=newRemote&remoteURL=newUrl" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/name/text()" equals "newRemote"                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo3/remote?list=true"                                      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Remote" 3 times                       # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "repo1"                                         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "repo2"                                         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "newRemote"                                     # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: Remove
  The remove command allows a user to remove features from the repository and is supported through the "/repos/{repository}/remove" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Remove.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/remove"                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Removing outside of a transaction issues 500 "Transaction required"    # Remove.feature:12
    Given There is an empty repository named repo1                                 # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/remove?path=somePath"                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "No transaction was specified" # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Removing outside of a repository issues 404 "Not found" # Remove.feature:18
    Given There is an empty multirepo server                        # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/remove?path=somePath"             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"             # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"     # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Removing with no path issues a 500 status code                                      # Remove.feature:25
    Given There is an empty repository named repo1                                              # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                     # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/remove?transactionId={@txId}"                                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Required parameter 'path' was not provided." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Removing with a feature path removes the specified feature                                   # Remove.feature:32
    Given There is a default multirepo server                                                            # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have a transaction as "@txId" on the "repo1" repo                                              # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And the repo1 repository's "STAGE_HEAD" in the @txId transaction should have the following features: # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
    When I call "GET /repos/repo1/remove?path=Points/Point.1&transactionId={@txId}"                      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Deleted/text()" equals "Points/Point.1"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "STAGE_HEAD" in the @txId transaction should have the following features: # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Removing with a tree path and no recursive parameter issues a 400 status code                               # Remove.feature:50
    Given There is a default multirepo server                                                                           # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have a transaction as "@txId" on the "repo1" repo                                                             # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/remove?path=Points&transactionId={@txId}"                                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Cannot remove tree Points if recursive or truncate is not specified" # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Removing with a tree path and the recursive parameter removes the specified feature tree     # Remove.feature:57
    Given There is a default multirepo server                                                            # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have a transaction as "@txId" on the "repo1" repo                                              # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And the repo1 repository's "STAGE_HEAD" in the @txId transaction should have the following features: # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
    When I call "GET /repos/repo1/remove?path=Points&recursive=true&transactionId={@txId}"               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                             # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Deleted/text()" equals "Points"                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "STAGE_HEAD" in the @txId transaction should have the following features: # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
@RepositoryManagement
Feature: Rename repository
  Repositories being served throught the Web API are served through the "/repos/<repository name>" entry point.
  The name of a repository is unique across a Web API instance.
  Renaming a repository is done through a "POST /repos/<repository name>/rename?name={new name}" call.
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository nonExistingRepo

  Scenario: Calling rename to a non existing repo issues 404 "Not Found" # RenameRepository.feature:7
    Given There is an empty multirepo server                             # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "POST /repos/nonExistingRepo/rename?name=renamedRepo"    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                             # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                  # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"          # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling rename on a repo using the wrong HTTP method issues 405 "Method not allowed" # RenameRepository.feature:14
    Given There is a default multirepo server                                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/rename?name=renamedRepo"                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "POST"                                            # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Trying to assign a duplicated name to a repo issues 400 "Bad request"               # RenameRepository.feature:20
    Given There is a default multirepo server                                                   # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "POST /repos/repo1/rename?name=repo2"                                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                                    # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "false"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/error/text()" equals "A repository with that name already exists." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Disposing repository {}. Cause: manually removed by remove() or invalidateAll()
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Renaming a repository returns a link to the new location issues 301 "Moved permanently" # RenameRepository.feature:28
    Given There is a default multirepo server                                                       # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "POST /repos/repo1/rename?name=repo1Renamed"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '301'                                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/xml"                                        # WebAPICucumberHooks.checkContentType(String)
    And the xpath "/response/success/text()" equals "true"                                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/name/text()" equals "repo1Renamed"                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/repo/atom:link/@href" contains "/repos/repo1Renamed.xml"               # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository nonExistingRepo

  Scenario: Calling rename to a non existing repo issues 404 "Not Found", JSON requested response # RenameRepository.feature:37
    Given There is an empty multirepo server                                                      # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "POST /repos/nonExistingRepo/rename.json?name=renamedRepo"                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                           # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                                   # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling rename on a repo using the wrong HTTP method issues 405 "Method not allowed", JSON requested response # RenameRepository.feature:44
    Given There is a default multirepo server                                                                             # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/rename.json?name=renamedRepo"                                                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                                                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "POST"                                                                     # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Trying to assign a duplicated name to a repo issues 400 "Bad request", JSON requested response # RenameRepository.feature:51
    Given There is a default multirepo server                                                              # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "POST /repos/repo1/rename.json?name=repo2"                                                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                              # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "false"                                                  # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.error" equals "A repository with that name already exists."              # WebAPICucumberHooks.checkJSONResponse(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Disposing repository {}. Cause: manually removed by remove() or invalidateAll()
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Renaming a repository returns a link to the new location issues 301 "Moved permanently", JSON requested response # RenameRepository.feature:59
    Given There is a default multirepo server                                                                                # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "POST /repos/repo1/rename.json?name=repo1Renamed"                                                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '301'                                                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "application/json"                                                                # WebAPICucumberHooks.checkContentType(String)
    And the json object "response.success" equals "true"                                                                     # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.name" equals "repo1Renamed"                                                           # WebAPICucumberHooks.checkJSONResponse(String,String)
    And the json object "response.repo.href" ends with "/repos/repo1Renamed.json"                                            # WebAPICucumberHooks.checkJSONResponseEndsWith(String,String)
@Commands
Feature: ReportMergeScenario
  The ReportMergeScenario command allows a user to see the results of a merge between two branches and is supported through the "/repos/{repository}/reportMergeScenario" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # ReportMergeScenario.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/reportMergeScenario"               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ReportMergeScenario outside of a repository issues 404 "Not found"              # ReportMergeScenario.feature:12
    Given There is an empty multirepo server                                                # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/reportMergeScenario?ourCommit=master&theirCommit=branch1" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                     # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                             # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling ReportMergeScenario with no "our" commit issues a 500 status code                # ReportMergeScenario.feature:19
    Given There is an empty repository named repo1                                                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/reportMergeScenario?theirCommit=branch1"                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                         # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Required parameter 'ourCommit' was not provided." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling ReportMergeScenario with no "their" commit issues a 500 status code                # ReportMergeScenario.feature:25
    Given There is an empty repository named repo1                                                     # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/reportMergeScenario?ourCommit=master"                                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Required parameter 'theirCommit' was not provided." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling ReportMergeScenario with an invalid "our" commit issues a 500 status code              # ReportMergeScenario.feature:31
    Given There is a repository with multiple branches named repo1                                         # WebAPICucumberHooks.setUpMultipleBranches(String)
    When I call "GET /repos/repo1/reportMergeScenario?ourCommit=nonexistent&theirCommit=branch1"           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "'our' commit could not be resolved to a commit object." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling ReportMergeScenario with an invalid "their" commit issues a 500 status code              # ReportMergeScenario.feature:37
    Given There is a repository with multiple branches named repo1                                           # WebAPICucumberHooks.setUpMultipleBranches(String)
    When I call "GET /repos/repo1/reportMergeScenario?ourCommit=master&theirCommit=nonexistent"              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "'their' commit could not be resolved to a commit object." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ReportMergeScenario with two valid commits returns the details of the merge             # ReportMergeScenario.feature:43
    Given There is a repository with multiple branches named repo1                                  # WebAPICucumberHooks.setUpMultipleBranches(String)
    When I call "GET /repos/repo1/reportMergeScenario?ourCommit=master&theirCommit=non_conflicting" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/change/text()" equals "ADDED"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/id/text()" equals "Points/Point.2"                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/geometry/text()" equals "POINT (-10 -10)"                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/crs/text()" equals "EPSG:4326"                           # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ReportMergeScenario with conflicting commits returns the details of the merge                       # ReportMergeScenario.feature:53
    Given There is a repository with multiple branches named repo1                                              # WebAPICucumberHooks.setUpMultipleBranches(String)
    When I call "GET /repos/repo1/reportMergeScenario?ourCommit=master&theirCommit=conflicting"                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/change/text()" equals "CONFLICT"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/id/text()" equals "Points/Point.1"                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/ourvalue/text()" equals "{@ObjectId|repo1|master:Points/Point.1}"    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/theirvalue/text()" equals "0000000000000000000000000000000000000000" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/geometry/text()" equals "POINT (0 0)"                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/crs/text()" equals "EPSG:4326"                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: ReportMergeScenario supports paging                                                                        # ReportMergeScenario.feature:65
    Given There is a default multirepo server                                                                          # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/reportMergeScenario?ourCommit=master~2&theirCommit=branch1&elementsPerPage=2&page=0" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Merge/Feature" 2 times                                              # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Points/Point.2"                                                              # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Polygons/Polygon.2"                                                          # WebAPICucumberHooks.checkResponseTextContains(String)
    When I call "GET /repos/repo1/reportMergeScenario?ourCommit=master~2&theirCommit=branch1&elementsPerPage=2&page=1" # WebAPICucumberHooks.callURL(String)
    And the xpath "/response/success/text()" equals "true"                                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Merge/Feature" 1 times                                              # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Lines/Line.2"                                                                # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: ResolveConflict
  The ResolveConflict command allows a user to resolve a conflict with a specific objectId and is supported through the "/repos/{repository}/resolveconflict" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # ResolveConflict.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/resolveconflict"                   # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ResolveConflict outside of a transaction issues 500 "Transaction required" # ResolveConflict.feature:12
    Given There is an empty repository named repo1                                     # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/resolveconflict?path=somePath/1&objectid=someId"     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "No transaction was specified"     # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ResolveConflict outside of a repository issues 404 "Not found"         # ResolveConflict.feature:18
    Given There is an empty multirepo server                                       # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/resolveconflict?path=somePath/1&objectid=someId" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                            # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                    # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ResolveConflict without a path issues a 500 status code                               # ResolveConflict.feature:25
    Given There is an empty repository named repo1                                                # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                       # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/resolveconflict?transactionId={@txId}&objectid=someId"          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Required parameter 'path' was not provided." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ResolveConflict without an object ID issues a 500 status code                             # ResolveConflict.feature:32
    Given There is an empty repository named repo1                                                    # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                           # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/resolveconflict?transactionId={@txId}&path=Points/Point.1"          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Required parameter 'objectid' was not provided." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ResolveConflict with an invalid path issues a 400 status code                                                                   # ResolveConflict.feature:39
    Given There is an empty repository named repo1                                                                                          # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                 # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And There are conflicts on the "repo1" repo in the @txId transaction                                                                    # WebAPICucumberHooks.There_are_conflict(String,String)
    When I call "GET /repos/repo1/resolveconflict?transactionId={@txId}&path=Points&objectid={@ObjectId|repo1|@txId|master:Points/Point.1}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '400'                                                                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "empty child path: '/'"                                                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: ResolveConflict with valid parameters resolves the conflict                                                                               # ResolveConflict.feature:47
    Given There is an empty repository named repo1                                                                                                    # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                           # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And There are conflicts on the "repo1" repo in the @txId transaction                                                                              # WebAPICucumberHooks.There_are_conflict(String,String)
    When I call "GET /repos/repo1/resolveconflict?transactionId={@txId}&path=Points/Point.1&objectid={@ObjectId|repo1|@txId|master~1:Points/Point.1}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Add/text()" equals "Success"                                                                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And There should be no conflicts on the "repo1" repo in the @txId transaction                                                                     # WebAPICucumberHooks.There_should_be_no_conflicts(String,String)
    And the variable "{@ObjectId|repo1|@txId|STAGE_HEAD:Points/Point.1}" equals "{@ObjectId|repo1|@txId|master~1:Points/Point.1}"                     # WebAPICucumberHooks.checkVariableEquals(String,String)
@Commands
Feature: RevertFeature
  The RevertFeature command allows a user to undo the changes made to a feature and is supported through the "/repos/{repository}/revertfeature" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # RevertFeature.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/revertfeature"                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: RevertFeature outside of a transaction issues 500 "Transaction required"                   # RevertFeature.feature:12
    Given There is an empty repository named repo1                                                     # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/revertfeature?path=somePath/1&newCommitId=someId&oldCommitId=someId" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "No transaction was specified"                     # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: RevertFeature outside of a repository issues 404 "Not found"                               # RevertFeature.feature:18
    Given There is an empty multirepo server                                                           # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/revertfeature?path=somePath/1&newCommitId=someId&oldCommitId=someId" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                                                # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                                        # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: RevertFeature without a path issues a 500 status code                                                                                # RevertFeature.feature:25
    Given There is a default multirepo server                                                                                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have a transaction as "@txId" on the "repo1" repo                                                                                      # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&oldCommitId={@ObjectId|repo1|master}&newCommitId={@ObjectId|repo1|master}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Required parameter 'path' was not provided."                                                # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: RevertFeature without a new commit ID issues a 500 status code                                                      # RevertFeature.feature:32
    Given There is a default multirepo server                                                                                   # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have a transaction as "@txId" on the "repo1" repo                                                                     # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&path=Points/Point.1&oldCommitId={@ObjectId|repo1|master}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Required parameter 'newCommitId' was not provided."                        # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: RevertFeature without an old commit ID issues a 500 status code                                                     # RevertFeature.feature:39
    Given There is a default multirepo server                                                                                   # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have a transaction as "@txId" on the "repo1" repo                                                                     # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&path=Points/Point.1&newCommitId={@ObjectId|repo1|master}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "Required parameter 'oldCommitId' was not provided."                        # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: RevertFeature with an invalid path issues a 500 status code                                                                                             # RevertFeature.feature:46
    Given There is a default multirepo server                                                                                                                       # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have a transaction as "@txId" on the "repo1" repo                                                                                                         # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&path=nonexistent&oldCommitId={@ObjectId|repo1|master~1}&newCommitId={@ObjectId|repo1|master}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                                                                        # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "The feature was not found in either commit tree."                                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: RevertFeature on an added feature removes that feature                                                                                                     # RevertFeature.feature:53
    Given There is a default multirepo server                                                                                                                          # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I have a transaction as "@txId" on the "repo1" repo                                                                                                            # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&path=Points/Point.3&oldCommitId={@ObjectId|repo1|master~1}&newCommitId={@ObjectId|repo1|master}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "master" in the @txId transaction should have the following features:                                                                   # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: RevertFeature on a modified feature undoes the change                                                                                                      # RevertFeature.feature:65
    Given There is an empty repository named repo1                                                                                                                     # WebAPICucumberHooks.setUpEmptyRepo(String)
    And There is a feature with multiple authors on the "repo1" repo                                                                                                   # WebAPICucumberHooks.There_is_a_feature_with_multiple_authors(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                                            # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&path=Points/Point.1&oldCommitId={@ObjectId|repo1|master~1}&newCommitId={@ObjectId|repo1|master}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                           # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo1|@txId|master:Points/Point.1}" equals "{@ObjectId|repo1|@txId|master~2:Points/Point.1}"                                          # WebAPICucumberHooks.checkVariableEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: RevertFeature on a removed feature adds it back                                                                                                                      # RevertFeature.feature:74
    Given There is a repository with multiple branches named repo1                                                                                                               # WebAPICucumberHooks.setUpMultipleBranches(String)
    And I have checked out "conflicting" on the "repo1" repo                                                                                                                     # WebAPICucumberHooks.I_have_checked_out(String,String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                                                      # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And the repo1 repository's "conflicting" in the @txId transaction should have the following features:                                                                        # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&path=Points/Point.1&oldCommitId={@ObjectId|repo1|conflicting~1}&newCommitId={@ObjectId|repo1|conflicting}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the repo1 repository's "conflicting" in the @txId transaction should have the following features:                                                                        # WebAPICucumberHooks.verifyRepositoryContentsTx(String,String,String,DataTable)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: If a feature has changed since the 'new' commit id, conflicts may be thrown                                                                                                        # RevertFeature.feature:88
    Given There is a repository with multiple branches named repo1                                                                                                                             # WebAPICucumberHooks.setUpMultipleBranches(String)
    And I have checked out "conflicting" on the "repo1" repo                                                                                                                                   # WebAPICucumberHooks.I_have_checked_out(String,String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                                                                    # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have committed "Point.1_modified" on the "repo1" repo in the "@txId" transaction                                                                                                     # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&path=Points/Point.1&oldCommitId={@ObjectId|repo1|@txId|conflicting~2}&newCommitId={@ObjectId|repo1|@txId|conflicting~1}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/conflicts/text()" equals "1"                                                                                                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/change/text()" equals "CONFLICT"                                                                                                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/id/text()" equals "Points/Point.1"                                                                                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/ourvalue/text()" equals "{@ObjectId|repo1|@txId|conflicting:Points/Point.1}"                                                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/theirvalue/text()" equals "{@ObjectId|repo1|@txId|conflicting~2:Points/Point.1}"                                                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying author information applies to the reverted commit as well as the merge commit                                                                                                                        # RevertFeature.feature:102
    Given There is an empty repository named repo1                                                                                                                                                                         # WebAPICucumberHooks.setUpEmptyRepo(String)
    And There is a feature with multiple authors on the "repo1" repo                                                                                                                                                       # WebAPICucumberHooks.There_is_a_feature_with_multiple_authors(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                                                                                                # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have committed "Point.2" on the "repo1" repo in the "@txId" transaction                                                                                                                                          # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&path=Points/Point.1&oldCommitId={@ObjectId|repo1|master~1}&newCommitId={@ObjectId|repo1|master}&authorName=myAuthor&authorEmail=myAuthor@geogig.org" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                                                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                                                                                                 # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|@txId|master}"                                                                                                                                             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                                                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/commit/author/name/text()" equals "myAuthor"                                                                                                                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/email/text()" equals "myAuthor@geogig.org"                                                                                                                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|@txId|master^2}"                                                                                                                                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                                                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/commit/author/name/text()" equals "myAuthor"                                                                                                                                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/commit/author/email/text()" equals "myAuthor@geogig.org"                                                                                                                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying a commit message applies to the revert commit                                                                                                                               # RevertFeature.feature:119
    Given There is an empty repository named repo1                                                                                                                                                # WebAPICucumberHooks.setUpEmptyRepo(String)
    And There is a feature with multiple authors on the "repo1" repo                                                                                                                              # WebAPICucumberHooks.There_is_a_feature_with_multiple_authors(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                                                                       # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have committed "Point.2" on the "repo1" repo in the "@txId" transaction                                                                                                                 # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&path=Points/Point.1&oldCommitId={@ObjectId|repo1|master~1}&newCommitId={@ObjectId|repo1|master}&commitMessage=My%20Message" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                                                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|@txId|master^2}"                                                                                                                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/commit/message/text()" equals "My Message"                                                                                                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Supplying a merge message applies to the merge commit                                                                                                                                # RevertFeature.feature:131
    Given There is an empty repository named repo1                                                                                                                                               # WebAPICucumberHooks.setUpEmptyRepo(String)
    And There is a feature with multiple authors on the "repo1" repo                                                                                                                             # WebAPICucumberHooks.There_is_a_feature_with_multiple_authors(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                                                                                                      # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have committed "Point.2" on the "repo1" repo in the "@txId" transaction                                                                                                                # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo1/revertfeature?transactionId={@txId}&path=Points/Point.1&oldCommitId={@ObjectId|repo1|master~1}&newCommitId={@ObjectId|repo1|master}&mergeMessage=My%20Message" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                                                                                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|@txId|master}"                                                                                                                   # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                                                                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/commit/message/text()" equals "My Message"                                                                                                                          # WebAPICucumberHooks.checkXPathEquals(String,String)
@Commands
Feature: Statistics
  The Statistics command allows a user to summarize the changes made to a branch and is supported through the "/repos/{repository}/statistics" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Statistics.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/statistics"                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Statistics outside of a repository issues 404 "Not found" # Statistics.feature:12
    Given There is an empty multirepo server                          # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/statistics"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                          # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"               # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"       # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Statistics summarizes the changes made to the repository                                             # Statistics.feature:19
    Given There is a default multirepo server                                                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/statistics"                                                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Statistics/FeatureTypes/FeatureType" 3 times                  # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/Statistics/FeatureTypes/FeatureType/name/text()" that contains "Points"     # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/Statistics/FeatureTypes/FeatureType/name/text()" that contains "Lines"      # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And there is an xpath "/response/Statistics/FeatureTypes/FeatureType/name/text()" that contains "Polygons"   # WebAPICucumberHooks.checkOneXPathValueContains(String,String)
    And the xpath "/response/Statistics/FeatureTypes/totalFeatureTypes/text()" equals "3"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/FeatureTypes/totalFeatures/text()" equals "9"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/latestCommit/id/text()" equals "{@ObjectId|repo1|master}"                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/latestCommit/message/text()" contains "merge branch branch2 onto master" # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the xpath "/response/Statistics/firstCommit/id/text()" equals "{@ObjectId|repo1|master~2}"               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/firstCommit/message/text()" contains "point1, line1, poly1"              # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the xpath "/response/Statistics/Authors/Author/name/text()" equals "geogigUser"                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/Authors/Author/email/text()" equals "repo1_Owner@geogig.org"             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/Authors/totalAuthors/text()" equals "1"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Statistics summarizes the changes since a particular timestamp up to a specific commit               # Statistics.feature:38
    Given There is a default multirepo server                                                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/statistics?since=0&branch=master~1"                                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Statistics/FeatureTypes/FeatureType" 3 times                  # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/Statistics/FeatureTypes/FeatureType/name/text()" that equals "Points"       # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Statistics/FeatureTypes/FeatureType/numFeatures/text()" that equals "2"     # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Statistics/FeatureTypes/FeatureType/name/text()" that equals "Lines"        # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Statistics/FeatureTypes/FeatureType/name/text()" that equals "Polygons"     # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And the xpath "/response/Statistics/FeatureTypes/totalFeatureTypes/text()" equals "3"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/FeatureTypes/totalFeatures/text()" equals "6"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/latestCommit/id/text()" equals "{@ObjectId|repo1|master~1}"              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/latestCommit/message/text()" contains "merge branch branch1 onto master" # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the xpath "/response/Statistics/firstCommit/id/text()" equals "{@ObjectId|repo1|master~2}"               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/firstCommit/message/text()" contains "point1, line1, poly1"              # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the xpath "/response/Statistics/Authors/Author/name/text()" equals "geogigUser"                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/Authors/Author/email/text()" equals "repo1_Owner@geogig.org"             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/Authors/totalAuthors/text()" equals "1"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Statistics can summarize the changes made to a specific path                                         # Statistics.feature:58
    Given There is a default multirepo server                                                                    # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/statistics?path=Points"                                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Statistics/FeatureTypes/FeatureType" 1 times                  # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xpath "/response/Statistics/FeatureTypes/FeatureType/name/text()" equals "Points"                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/FeatureTypes/FeatureType/numFeatures/text()" equals "3"                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/latestCommit/id/text()" equals "{@ObjectId|repo1|master}"                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/latestCommit/message/text()" contains "merge branch branch2 onto master" # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the xpath "/response/Statistics/firstCommit/id/text()" equals "{@ObjectId|repo1|master~2}"               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/firstCommit/message/text()" contains "point1, line1, poly1"              # WebAPICucumberHooks.checkXPathValueContains(String,String)
    And the xpath "/response/Statistics/Authors/Author/name/text()" equals "geogigUser"                          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/Authors/Author/email/text()" equals "repo1_Owner@geogig.org"             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Statistics/Authors/totalAuthors/text()" equals "1"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
@Commands
Feature: Status
  The Status command allows a user to see the current state of the repository and is supported through the "/repos/{repository}/status" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Status.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/status"                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Status outside of a repository issues 404 "Not found" # Status.feature:12
    Given There is an empty multirepo server                      # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/status"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                      # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"           # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"   # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Status shows the current branch and all staged and unstaged features # Status.feature:19
    Given There is an empty repository named repo1                               # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                      # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And I have staged "Line.1" on the "repo1" repo in the "@txId" transaction    # WebAPICucumberHooks.I_have_staged(String,String,String)
    And I have unstaged "Point.1" on the "repo1" repo in the "@txId" transaction # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    And I have unstaged "Point.2" on the "repo1" repo in the "@txId" transaction # WebAPICucumberHooks.I_have_unstaged(String,String,String)
    When I call "GET /repos/repo1/status?transactionId={@txId}"                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/header/branch/text()" equals "master"               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/staged/changeType/text()" equals "ADDED"            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/staged/newPath/text()" equals "Lines/Line.1"        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/unstaged" 2 times             # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "Points/Point.1"                        # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "Points/Point.2"                        # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Status shows conflicted features                                                                    # Status.feature:35
    Given There is an empty repository named repo1                                                              # WebAPICucumberHooks.setUpEmptyRepo(String)
    And I have a transaction as "@txId" on the "repo1" repo                                                     # WebAPICucumberHooks.beginTransactionAsVariable(String,String)
    And There are conflicts on the "repo1" repo in the @txId transaction                                        # WebAPICucumberHooks.There_are_conflict(String,String)
    When I call "GET /repos/repo1/status?transactionId={@txId}"                                                 # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/header/branch/text()" equals "master"                                              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/unmerged/changeType/text()" equals "CONFLICT"                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/unmerged/path/text()" equals "Points/Point.1"                                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/unmerged/ours/text()" equals "{@ObjectId|repo1|@txId|master:Points/Point.1}"       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/unmerged/theirs/text()" equals "0000000000000000000000000000000000000000"          # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/unmerged/ancestor/text()" equals "{@ObjectId|repo1|@txId|master~1:Points/Point.1}" # WebAPICucumberHooks.checkXPathEquals(String,String)
@Commands
Feature: Tag
  The Tag command allows a user to create, list, and delete tags and is supported through the "/repos/{repository}/tag" endpoint
  The command must be executed using the HTTP GET, POST, or DELETE methods
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Tag.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/tag"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET,POST,DELETE"     # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Tag outside of a repository issues 404 "Not found"  # Tag.feature:12
    Given There is an empty multirepo server                    # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/tag"                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                    # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"         # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found" # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Issuing a POST request to tag without a name issues a 500 status code                                                              # Tag.feature:19
    Given There is an empty repository named repo1                                                                                             # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "POST /repos/repo1/tag"                                                                                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "You must specify list or delete, or provide a name, message, and commit for the new tag." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Issuing a POST request to tag without a commit issues a 500 status code                  # Tag.feature:25
    Given There is an empty repository named repo1                                                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "POST /repos/repo1/tag?name=newTag"                                                  # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                         # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "You must specify a commit to point the tag to." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Issuing a POST request to tag with an invalid commit issues a 500 status code  # Tag.feature:31
    Given There is an empty repository named repo1                                         # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "POST /repos/repo1/tag?name=newTag&commit=nonexistent"                     # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                               # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "'nonexistent' could not be resolved." # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Issuing a POST request to tag with valid parameters creates a tag         # Tag.feature:37
    Given There is a default multirepo server                                         # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "POST /repos/repo1/tag?name=newTag&commit=master&message=My%20Tag"    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                          # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Tag/id" 1 times                    # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xpath "/response/Tag/commitid/text()" equals "{@ObjectId|repo1|master}"   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Tag/name/text()" equals "newTag"                         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Tag/message/text()" equals "My Tag"                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Tag/tagger/name/text()" equals "geogigUser"              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Tag/tagger/email/text()" equals "repo1_Owner@geogig.org" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Tag/tagger/timestamp" 1 times      # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/Tag/tagger/timeZoneOffset" 1 times # WebAPICucumberHooks.checkXPathCadinality(String,int)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Issuing a GET request to tag lists all tags                                           # Tag.feature:51
    Given There is a default multirepo server                                                     # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I call "POST /repos/repo1/tag?name=tag1&commit=master&message=My%20Tag%201"               # WebAPICucumberHooks.callURL(String)
    And I call "POST /repos/repo1/tag?name=tag2&commit=branch1&message=My%20Tag%202"              # WebAPICucumberHooks.callURL(String)
    When I call "GET /repos/repo1/tag"                                                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Tag" 2 times                                   # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And there is an xpath "/response/Tag/commitid/text()" that equals "{@ObjectId|repo1|master}"  # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Tag/name/text()" that equals "tag1"                          # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Tag/message/text()" that equals "My Tag 1"                   # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Tag/commitid/text()" that equals "{@ObjectId|repo1|branch1}" # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Tag/name/text()" that equals "tag2"                          # WebAPICucumberHooks.checkOneXPathEquals(String,String)
    And there is an xpath "/response/Tag/message/text()" that equals "My Tag 2"                   # WebAPICucumberHooks.checkOneXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Issuing a DELETE request to tag without a name issues a 500 status code          # Tag.feature:66
    Given There is an empty repository named repo1                                           # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "DELETE /repos/repo1/tag"                                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "You must specify the tag name to delete." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Issuing a DELETE request to tag deletes the tag                                  # Tag.feature:72
    Given There is a default multirepo server                                                # WebAPICucumberHooks.setUpDefaultMultiRepo()
    And I call "POST /repos/repo1/tag?name=tag1&commit=master&message=My%20Tag%201"          # WebAPICucumberHooks.callURL(String)
    And I call "POST /repos/repo1/tag?name=tag2&commit=branch1&message=My%20Tag%202"         # WebAPICucumberHooks.callURL(String)
    When I call "DELETE /repos/repo1/tag?name=tag1"                                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/DeletedTag/id" 1 times                    # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xpath "/response/DeletedTag/commitid/text()" equals "{@ObjectId|repo1|master}"   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/DeletedTag/name/text()" equals "tag1"                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/DeletedTag/message/text()" equals "My Tag 1"                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/DeletedTag/tagger/name/text()" equals "geogigUser"              # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/DeletedTag/tagger/email/text()" equals "repo1_Owner@geogig.org" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/DeletedTag/tagger/timestamp" 1 times      # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/DeletedTag/tagger/timeZoneOffset" 1 times # WebAPICucumberHooks.checkXPathCadinality(String,int)
    When I call "GET /repos/repo1/tag"                                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                 # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                   # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Tag/id" 1 times                           # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xpath "/response/Tag/commitid/text()" equals "{@ObjectId|repo1|branch1}"         # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Tag/name/text()" equals "tag2"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Tag/message/text()" equals "My Tag 2"                           # WebAPICucumberHooks.checkXPathEquals(String,String)
@Commands
Feature: Transaction
  Transactions allow a user to perform work without affecting the main repository is supported through the "/repos/{repository}/beginTransaction" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method on begin transaction issues 405 "Method not allowed" # Transaction.feature:6
    Given There is an empty repository named repo1                                        # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/beginTransaction"                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                                      # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Beginning a transaction outside of a repository issues 404 "Not found" # Transaction.feature:12
    Given There is an empty multirepo server                                       # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/beginTransaction"                                # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                            # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                    # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method on end transaction issues 405 "Method not allowed" # Transaction.feature:19
    Given There is an empty repository named repo1                                      # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/endTransaction"                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                                            # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                                    # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Ending a transaction outside of a repository issues 404 "Not found" # Transaction.feature:25
    Given There is an empty multirepo server                                    # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/endTransaction"                               # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"                         # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"                 # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Ending a transaction outside of a transaction issues 500 "Transaction required" # Transaction.feature:32
    Given There is an empty repository named repo1                                          # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/endTransaction"                                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" contains "No transaction was specified"          # WebAPICucumberHooks.checkXPathValueContains(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Work on a transaction does not affect the main repository                     # Transaction.feature:38
    Given There is a repository with multiple branches named repo1                        # WebAPICucumberHooks.setUpMultipleBranches(String)
    When I call "GET /repos/repo1/beginTransaction"                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Transaction/ID"                        # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And I save the response "/response/Transaction/ID/text()" as "@txId"                  # WebAPICucumberHooks.saveResponseXPathValueAsVariable(String,String)
    When I have committed "Point.2" on the "repo1" repo in the "@txId" transaction        # WebAPICucumberHooks.I_have_committed(String,String,String)
    Then the variable "{@ObjectId|repo1|master:Points/Point.2}" equals ""                 # WebAPICucumberHooks.checkVariableEquals(String,String)
    And the variable "{@ObjectId|repo1|@txId|master~1}" equals "{@ObjectId|repo1|master}" # WebAPICucumberHooks.checkVariableEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Ending a transaction moves the work to the main repository                           # Transaction.feature:49
    Given There is a repository with multiple branches named repo1                               # WebAPICucumberHooks.setUpMultipleBranches(String)
    When I call "GET /repos/repo1/beginTransaction"                                              # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Transaction/ID"                               # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And I save the response "/response/Transaction/ID/text()" as "@txId"                         # WebAPICucumberHooks.saveResponseXPathValueAsVariable(String,String)
    When I have committed "Point.2" on the "repo1" repo in the "@txId" transaction               # WebAPICucumberHooks.I_have_committed(String,String,String)
    Then the variable "{@ObjectId|repo1|master:Points/Point.2}" equals ""                        # WebAPICucumberHooks.checkVariableEquals(String,String)
    And the variable "{@ObjectId|repo1|@txId|master~1}" equals "{@ObjectId|repo1|master}"        # WebAPICucumberHooks.checkVariableEquals(String,String)
    When I call "GET /repos/repo1/endTransaction?transactionId={@txId}"                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Transaction/ID/text()" equals "{@txId}"                             # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|master:Points/Point.2}"          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/feature/id/text()" equals "{@ObjectId|repo1|master:Points/Point.2}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/feature/attribute" 3 times                    # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "StringProp1_2"                                         # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "2000"                                                  # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "POINT (-10 -10)"                                       # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Canceling a transaction leaves the main repository without changes            # Transaction.feature:72
    Given There is a repository with multiple branches named repo1                        # WebAPICucumberHooks.setUpMultipleBranches(String)
    When I call "GET /repos/repo1/beginTransaction"                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Transaction/ID"                        # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And I save the response "/response/Transaction/ID/text()" as "@txId"                  # WebAPICucumberHooks.saveResponseXPathValueAsVariable(String,String)
    When I have committed "Point.2" on the "repo1" repo in the "@txId" transaction        # WebAPICucumberHooks.I_have_committed(String,String,String)
    Then the variable "{@ObjectId|repo1|master:Points/Point.2}" equals ""                 # WebAPICucumberHooks.checkVariableEquals(String,String)
    And the variable "{@ObjectId|repo1|@txId|master~1}" equals "{@ObjectId|repo1|master}" # WebAPICucumberHooks.checkVariableEquals(String,String)
    When I call "GET /repos/repo1/endTransaction?transactionId={@txId}&cancel=true"       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                              # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Transaction/ID/text()" equals "{@txId}"                      # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo1|master:Points/Point.2}" equals ""                  # WebAPICucumberHooks.checkVariableEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Ending a transaction with conflicting changes returns details of the conflict                      # Transaction.feature:88
    Given There is a repository with multiple branches named repo1                                             # WebAPICucumberHooks.setUpMultipleBranches(String)
    When I call "GET /repos/repo1/beginTransaction"                                                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Transaction/ID"                                             # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And I save the response "/response/Transaction/ID/text()" as "@txId"                                       # WebAPICucumberHooks.saveResponseXPathValueAsVariable(String,String)
    And I have removed "Point.1_modified" on the "repo1" repo in the "@txId" transaction                       # WebAPICucumberHooks.I_have_removed(String,String,String)
    And I have committed "Point.1" on the "repo1" repo in the "" transaction                                   # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo1/endTransaction?transactionId={@txId}"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/theirs/text()" equals "{@ObjectId|repo1|master}"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ours/text()" equals "{@ObjectId|repo1|@txId|master}"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ancestor/text()" equals "{@ObjectId|repo1|master~1}"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/conflicts/text()" equals "1"                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/change/text()" equals "CONFLICT"                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/id/text()" equals "Points/Point.1"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/ourvalue/text()" equals "0000000000000000000000000000000000000000"  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/theirvalue/text()" equals "{@ObjectId|repo1|master:Points/Point.1}" # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Fixing transaction conflicts and ending again is successful                                        # Transaction.feature:109
    Given There is a repository with multiple branches named repo1                                             # WebAPICucumberHooks.setUpMultipleBranches(String)
    When I call "GET /repos/repo1/beginTransaction"                                                            # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/Transaction/ID"                                             # WebAPICucumberHooks.checkResponseContainsXPath(String)
    And I save the response "/response/Transaction/ID/text()" as "@txId"                                       # WebAPICucumberHooks.saveResponseXPathValueAsVariable(String,String)
    And I have removed "Point.1_modified" on the "repo1" repo in the "@txId" transaction                       # WebAPICucumberHooks.I_have_removed(String,String,String)
    And I have committed "Point.1" on the "repo1" repo in the "" transaction                                   # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo1/endTransaction?transactionId={@txId}"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/theirs/text()" equals "{@ObjectId|repo1|master}"                            # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ours/text()" equals "{@ObjectId|repo1|@txId|master}"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/ancestor/text()" equals "{@ObjectId|repo1|master~1}"                        # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/conflicts/text()" equals "1"                                                # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/change/text()" equals "CONFLICT"                                    # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/id/text()" equals "Points/Point.1"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/ourvalue/text()" equals "0000000000000000000000000000000000000000"  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Merge/Feature/theirvalue/text()" equals "{@ObjectId|repo1|master:Points/Point.1}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    Then I have committed "Point.1" on the "repo1" repo in the "@txId" transaction                             # WebAPICucumberHooks.I_have_committed(String,String,String)
    When I call "GET /repos/repo1/endTransaction?transactionId={@txId}"                                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/Transaction/ID/text()" equals "{@txId}"                                           # WebAPICucumberHooks.checkXPathEquals(String,String)
    When I call "GET /repos/repo1/cat?objectid={@ObjectId|repo1|master:Points/Point.1}"                        # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/feature/id/text()" equals "{@ObjectId|repo1|master:Points/Point.1}"               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/feature/attribute" 3 times                                  # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the response body should contain "StringProp1_1"                                                       # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "1000"                                                                # WebAPICucumberHooks.checkResponseTextContains(String)
    And the response body should contain "POINT (0 0)"                                                         # WebAPICucumberHooks.checkResponseTextContains(String)
@Commands
Feature: UpdateRef
  The UpdateRef command allows a user to manually change the value of a ref and is supported through the "/repos/{repository}/updateref" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # UpdateRef.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/updateref"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: UpdateRef outside of a repository issues 404 "Not found" # UpdateRef.feature:12
    Given There is an empty multirepo server                         # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/updateref?name=master"             # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"              # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"      # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling UpdateRef without a ref name issues a 500 status code                       # UpdateRef.feature:19
    Given There is an empty repository named repo1                                              # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/updateref"                                                    # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                    # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Required parameter 'name' was not provided." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling UpdateRef without a new value or delete specified issues a 500 status code                                                # UpdateRef.feature:25
    Given There is an empty repository named repo1                                                                                            # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/updateref?name=master"                                                                                      # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                                                                                  # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Nothing specified to update with, must specify either deletion or new value to update to." # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Calling UpdateRef without a nonexistent name issues a 500 status code # UpdateRef.feature:31
    Given There is an empty repository named repo1                                # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/updateref?name=nonexistent&delete=true"         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '500'                                      # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/error/text()" equals "Invalid name: nonexistent"     # WebAPICucumberHooks.checkXPathEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling UpdateRef with a new value updates the ref                              # UpdateRef.feature:37
    Given There is a default multirepo server                                               # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/updateref?name=master&newValue={@ObjectId|repo1|branch1}" # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                  # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/ChangedRef/name/text()" equals "refs/heads/master"             # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/ChangedRef/objectId/text()" equals "{@ObjectId|repo1|branch1}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo1|master}" equals "{@ObjectId|repo1|branch1}"          # WebAPICucumberHooks.checkVariableEquals(String,String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo2

  Scenario: Calling UpdateRef with the delete parameter deletes the ref                        # UpdateRef.feature:46
    Given There is a default multirepo server                                                  # WebAPICucumberHooks.setUpDefaultMultiRepo()
    When I call "GET /repos/repo1/updateref?name=branch1&delete=true"                          # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                                   # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                                     # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/ChangedRef/name/text()" equals "refs/heads/branch1"               # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xpath "/response/ChangedRef/objectId/text()" equals "{@ObjectId|repo1|master^1^2}" # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the variable "{@ObjectId|repo1|branch1}" equals ""                                     # WebAPICucumberHooks.checkVariableEquals(String,String)
@Version
Feature: Version
  The Version command allows a user to see the geogig version and is supported through the "/repos/{repository}/version" endpoint
  The command must be executed using the HTTP GET method
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Verify wrong HTTP method issues 405 "Method not allowed" # Version.feature:6
    Given There is an empty repository named repo1                   # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "PUT /repos/repo1/version"                           # WebAPICucumberHooks.callURL(String)
    Then the response status should be '405'                         # WebAPICucumberHooks.checkStatusCode(int)
    And the response allowed methods should be "GET"                 # WebAPICucumberHooks.checkResponseAllowedMethods(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Version outside of a repository issues 404 "Not found" # Version.feature:12
    Given There is an empty multirepo server                       # WebAPICucumberHooks.setUpEmptyMultiRepo()
    When I call "GET /repos/repo1/version"                         # WebAPICucumberHooks.callURL(String)
    Then the response status should be '404'                       # WebAPICucumberHooks.checkStatusCode(int)
    And the response ContentType should be "text/plain"            # WebAPICucumberHooks.checkContentType(String)
    And the response body should contain "Repository not found"    # WebAPICucumberHooks.checkResponseTextContains(String)
[main] INFO org.locationtech.geogig.web.MultiRepositoryProvider - Loading repository repo1

  Scenario: Version returns geogig version details                               # Version.feature:19
    Given There is an empty repository named repo1                               # WebAPICucumberHooks.setUpEmptyRepo(String)
    When I call "GET /repos/repo1/version"                                       # WebAPICucumberHooks.callURL(String)
    Then the response status should be '200'                                     # WebAPICucumberHooks.checkStatusCode(int)
    And the xpath "/response/success/text()" equals "true"                       # WebAPICucumberHooks.checkXPathEquals(String,String)
    And the xml response should contain "/response/ProjectVersion" 1 times       # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/BuildTime" 1 times            # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/BuildUserName" 1 times        # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/BuildUserEmail" 1 times       # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/GitBranch" 1 times            # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/GitCommitID" 1 times          # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/GitCommitTime" 1 times        # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/GitCommitAuthorName" 1 times  # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/GitCommitAuthorEmail" 1 times # WebAPICucumberHooks.checkXPathCadinality(String,int)
    And the xml response should contain "/response/GitCommitMessage" 1 times     # WebAPICucumberHooks.checkXPathCadinality(String,int)

360 Scenarios (360 passed)
2791 Steps (2791 passed)
2m24.887s

Tests run: 3151, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 147.464 sec - in org.geogig.web.functional.RunFunctionalTest

Results :

Tests run: 3152, Failures: 0, Errors: 0, Skipped: 0

[JENKINS] Recording test results
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ geogig-web-api-functional-tests ---
[WARNING] JAR will be empty - no content was marked for inclusion!
[INFO] Building jar: /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/target/geogig-web-api-functional-tests-1.1.0.jar
[INFO] 
[INFO] --- maven-jar-plugin:2.4:test-jar (default) @ geogig-web-api-functional-tests ---
[INFO] Building jar: /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/target/geogig-web-api-functional-tests-1.1.0-tests.jar
[INFO] 
[INFO] >>> maven-source-plugin:2.2.1:jar (attach-sources) > generate-sources @ geogig-web-api-functional-tests >>>
[INFO] 
[INFO] --- git-commit-id-plugin:2.1.8:revision (default) @ geogig-web-api-functional-tests ---
[WARNING] Failed to getClass for org.apache.maven.plugin.source.SourceJarMojo
[INFO] 
[INFO] <<< maven-source-plugin:2.2.1:jar (attach-sources) < generate-sources @ geogig-web-api-functional-tests <<<
[INFO] 
[INFO] --- maven-source-plugin:2.2.1:jar (attach-sources) @ geogig-web-api-functional-tests ---
[INFO] No sources in project. Archive not created.
[INFO] 
[INFO] >>> maven-source-plugin:2.2.1:test-jar (attach-sources) > generate-sources @ geogig-web-api-functional-tests >>>
[INFO] 
[INFO] --- git-commit-id-plugin:2.1.8:revision (default) @ geogig-web-api-functional-tests ---
[WARNING] Failed to getClass for org.apache.maven.plugin.source.TestSourceJarMojo
[INFO] 
[INFO] <<< maven-source-plugin:2.2.1:test-jar (attach-sources) < generate-sources @ geogig-web-api-functional-tests <<<
[INFO] 
[INFO] --- maven-source-plugin:2.2.1:test-jar (attach-sources) @ geogig-web-api-functional-tests ---
[INFO] Building jar: /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/target/geogig-web-api-functional-tests-1.1.0-test-sources.jar
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ geogig-web-api-functional-tests ---
[INFO] Installing /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/target/geogig-web-api-functional-tests-1.1.0.jar to /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/.repository/org/locationtech/geogig/geogig-web-api-functional-tests/1.1.0/geogig-web-api-functional-tests-1.1.0.jar
[INFO] Installing /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/pom.xml to /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/.repository/org/locationtech/geogig/geogig-web-api-functional-tests/1.1.0/geogig-web-api-functional-tests-1.1.0.pom
[INFO] Installing /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/target/geogig-web-api-functional-tests-1.1.0-tests.jar to /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/.repository/org/locationtech/geogig/geogig-web-api-functional-tests/1.1.0/geogig-web-api-functional-tests-1.1.0-tests.jar
[INFO] Installing /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/src/web/functional/target/geogig-web-api-functional-tests-1.1.0-test-sources.jar to /home/hudson/genie.geogig/.jenkins/jobs/geogig-release/workspace/.repository/org/locationtech/geogig/geogig-web-api-functional-tests/1.1.0/geogig-web-api-functional-tests-1.1.0-test-sources.jar
[JENKINS] Archiving disabled