From 64e6c29eb0af42ab3a8b070d58339f3f070e409c Mon Sep 17 00:00:00 2001 From: Stefan Frank Date: Thu, 19 Sep 2013 14:41:27 +0200 Subject: [PATCH] added a feature to test for the re-wiring of filtered parents also refactored the examples to get more focused examples for the tests. --- .../api/v2/planning_elements_controller.rb | 3 +- features/planning_elements/filter.feature | 87 +++++++++++++------ .../filter_performance.feature | 4 +- features/step_definitions/api_steps.rb | 9 ++ 4 files changed, 73 insertions(+), 30 deletions(-) diff --git a/app/controllers/api/v2/planning_elements_controller.rb b/app/controllers/api/v2/planning_elements_controller.rb index 0412362538..86e32a7b99 100644 --- a/app/controllers/api/v2/planning_elements_controller.rb +++ b/app/controllers/api/v2/planning_elements_controller.rb @@ -170,6 +170,7 @@ module Api def assign_planning_elements(projects = (@projects || [@project])) @planning_elements = WorkPackage.for_projects(projects).without_deleted @planning_elements = @planning_elements.where(type_id: params[:types].split(',')) if params[:types] + end # remove this and replace by calls it with calls @@ -204,7 +205,7 @@ module Api return if @planning_elements.class == Array # triggering full load to avoid separate queries for count or related models - @planning_elements = @planning_elements.all(:include => [:type, :project]) + @planning_elements = @planning_elements.all(:include => [:type, :status, :project]) # Replacing association proxies with already loaded instances to avoid # further db calls. diff --git a/features/planning_elements/filter.feature b/features/planning_elements/filter.feature index 1e482b9c58..1e72c095ea 100644 --- a/features/planning_elements/filter.feature +++ b/features/planning_elements/filter.feature @@ -35,8 +35,9 @@ Feature: Filtering work packages via the api And the project "sample_project" has the following types: | name | position | | Bug | 1 | - | Story | 2 | - | Epic | 3 | + | Task | 2 | + | Story | 3 | + | Epic | 4 | And there is a default issuepriority with: | name | Normal | And there is a issuepriority with: @@ -60,56 +61,86 @@ Feature: Filtering work packages via the api And there is 1 user with the following: | login | bob | And the user "bob" is a "member" in the project "sample_project" + And I am already logged in as "bob" - - And there are the following work packages in project "sample_project": + Scenario: Call the endpoint of the api without filters + Given there are the following work packages in project "sample_project": | subject | type | | work_package#1 | Bug | - | work_package#1.1 | Bug | | work_package#2 | Story | - | work_package#2.1 | Story | - | work_package#3 | Epic | - | work_package#3.1 | Story | - - And the work package "work_package#1" has the following children: - | work_package#1.1 | - - And the work package "work_package#2" has the following children: - | work_package#2.1 | - - And the work package "work_package#3" has the following children: - | work_package#3.1 | - - - And I am already logged in as "bob" - - Scenario: Call the endpoint of the api without filters When I call the work_package-api on project "sample_project" requesting format "json" without any filters - Then the json-response should include 6 work packages + Then the json-response should include 2 work packages And the json-response should contain a work_package "work_package#1" And the json-response should contain a work_package "work_package#2" Scenario: Call the api filtering for type + Given there are the following work packages in project "sample_project": + | subject | type | parent | + | work_package#1 | Bug | | + | work_package#1.1 | Bug | work_package#1 | + | work_package#2 | Story | | + | work_package#2.1 | Story | work_package#2 | + | work_package#3 | Epic | | + | work_package#3.1 | Story | work_package#3 | When I call the work_package-api on project "sample_project" requesting format "json" filtering for type "Bug" Then the json-response should include 2 work packages Then the json-response should not contain a work_package "work_package#2" And the json-response should contain a work_package "work_package#1" Scenario: Filtering multiple types - When I call the work_package-api on project "sample_project" requesting format "json" filtering for type "Bug,Phase" - Then the json-response should include 2 work packages - And the json-response should not contain a work_package "work_package#2" + Given there are the following work packages in project "sample_project": + | subject | type | parent | + | work_package#1 | Bug | | + | work_package#1.1 | Bug | work_package#1 | + | work_package#3 | Epic | | + | work_package#3.1 | Story | work_package#3 | + When I call the work_package-api on project "sample_project" requesting format "json" filtering for type "Bug,Epic" + Then the json-response should include 3 work packages And the json-response should contain a work_package "work_package#1" + And the json-response should contain a work_package "work_package#3" + And the json-response should not contain a work_package "work_package#3.1" Scenario: Filter out children of work packages, if they don't have the right type + Given there are the following work packages in project "sample_project": + | subject | type | parent | + | work_package#3 | Epic | | + | work_package#3.1 | Story | work_package#3 | When I call the work_package-api on project "sample_project" requesting format "json" filtering for type "Epic" Then the json-response should include 1 work package And the json-response should contain a work_package "work_package#3" And the json-response should not contain a work_package "work_package#3.1" Scenario: Filter out parents of work packages, if they don't have the right type + Given there are the following work packages in project "sample_project": + | subject | type | + | work_package#1 | Bug | + | work_package#2 | Story | When I call the work_package-api on project "sample_project" requesting format "json" filtering for type "Story" + Then the json-response should include 1 work package + And the json-response should not contain a work_package "work_package#1" + And the json-response should contain a work_package "work_package#2" + + + Scenario: correctly export parent-child-relations + Given there are the following work packages in project "sample_project": + | subject | type | parent | + | work_package#1 | Epic | | + | work_package#1.1 | Story | work_package#1 | + | work_package#2 | Task | work_package#1.1 | + When I call the work_package-api on project "sample_project" requesting format "json" without any filters Then the json-response should include 3 work packages - And the json-response should not contain a work_package "work_package#3" - And the json-response should contain a work_package "work_package#3.1" + And the json-response should say that "work_package#1" is parent of "work_package#1.1" + + Scenario: Move parent-relations up the ancestor-chain, when intermediate packages are fitered + Given there are the following work packages in project "sample_project": + | subject | type | parent | + | work_package#1 | Epic | | + | work_package#1.1 | Story | work_package#1 | + | work_package#1.1.1 | Task | work_package#1.1 | + When I call the work_package-api on project "sample_project" requesting format "json" filtering for type "Epic,Task" + Then the json-response should include 2 work packages + And the json-response should not contain a work_package "work_package#1.1" + And the json-response should contain a work_package "work_package#1" + And the json-response should contain a work_package "work_package#1.1.1" + And the json-response should say that "work_package#1" is parent of "work_package#1.1.1" diff --git a/features/planning_elements/filter_performance.feature b/features/planning_elements/filter_performance.feature index e2f5cdc153..0d36bd4913 100644 --- a/features/planning_elements/filter_performance.feature +++ b/features/planning_elements/filter_performance.feature @@ -66,17 +66,19 @@ Feature: Filtering work packages via the api And I am already logged in as "bob" + @benchmark Scenario: Benchmarking without filters When I call the work_package-api on project "sample_project" requesting format "json" without any filters Then the json-response should include 23 work packages And the time to get the unfiltered results should not exceed 0.1s - + @benchmark Scenario: Benchmarking the filtering for type When I call the work_package-api on project "sample_project" requesting format "json" filtering for type "Story" Then the json-response should include 3 work packages And the time to get the filtered results should not exceed 0.1s + @benchmark Scenario: Filtering should be faster than not filtering When I call the work_package-api on project "sample_project" requesting format "json" filtering for type "Story" When I call the work_package-api on project "sample_project" requesting format "json" without any filters diff --git a/features/step_definitions/api_steps.rb b/features/step_definitions/api_steps.rb index 009cfd2059..06954e842e 100644 --- a/features/step_definitions/api_steps.rb +++ b/features/step_definitions/api_steps.rb @@ -52,6 +52,12 @@ Then(/^the json\-response should( not)? contain a work_package "(.*?)"$/) do |ne end +And(/^the json\-response should say that "(.*?)" is parent of "(.*?)"$/) do |parent_name, child_name| + child = decoded_json["planning_elements"].select {|wp| wp["name"] == child_name}.first + expect(child["parent"]["name"]).to eql parent_name +end + + Then(/^I call the work_package\-api on project "(.*?)" requesting format "(.*?)" filtering for type "(.*?)"$/) do |project_name, format, type_names| types = Project.find_by_identifier(project_name).types.where(name: type_names.split(",")) @@ -69,12 +75,15 @@ And(/^there are (\d+) work packages of type "(.*?)" in project "(.*?)"$/) do |nr end + And(/^the time to get the unfiltered results should not exceed (\d+)\.(\d+)s$/) do |seconds,milliseconds| + puts "----Unfiltered Benchmark----" puts @unfiltered_benchmark @unfiltered_benchmark.total.should < "#{seconds}.#{milliseconds}".to_f end And(/^the time to get the filtered results should not exceed (\d+)\.(\d+)s$/) do |seconds, milliseconds| + puts "----Filtered Benchmark----" puts @filtered_benchmark @filtered_benchmark.total.should < "#{seconds}.#{milliseconds}".to_f end