diff options
Diffstat (limited to 'spec/requests/api/graphql/project/work_items_spec.rb')
-rw-r--r-- | spec/requests/api/graphql/project/work_items_spec.rb | 132 |
1 files changed, 117 insertions, 15 deletions
diff --git a/spec/requests/api/graphql/project/work_items_spec.rb b/spec/requests/api/graphql/project/work_items_spec.rb index f49165a88ea..628a2117e9d 100644 --- a/spec/requests/api/graphql/project/work_items_spec.rb +++ b/spec/requests/api/graphql/project/work_items_spec.rb @@ -120,24 +120,55 @@ RSpec.describe 'getting a work item list for a project', feature_category: :team end context 'when querying WorkItemWidgetHierarchy' do - let_it_be(:children) { create_list(:work_item, 3, :task, project: project) } + let_it_be(:children) { create_list(:work_item, 4, :task, project: project) } let_it_be(:child_link1) { create(:parent_link, work_item_parent: item1, work_item: children[0]) } + let_it_be(:child_link2) { create(:parent_link, work_item_parent: item1, work_item: children[1]) } let(:fields) do <<~GRAPHQL - nodes { - widgets { - type - ... on WorkItemWidgetHierarchy { - hasChildren - parent { id } - children { nodes { id } } - } + nodes { + id + widgets { + type + ... on WorkItemWidgetHierarchy { + hasChildren + parent { id } + children { nodes { id } } } } + } GRAPHQL end + context 'with ordered children' do + let(:items_data) { graphql_data['project']['workItems']['nodes'] } + let(:work_item_data) { items_data.find { |item| item['id'] == item1.to_gid.to_s } } + let(:work_item_widget) { work_item_data["widgets"].find { |widget| widget.key?("children") } } + let(:children_ids) { work_item_widget.dig("children", "nodes").pluck("id") } + + let(:first_child) { children[0].to_gid.to_s } + let(:second_child) { children[1].to_gid.to_s } + + it 'returns children ordered by created_at by default' do + post_graphql(query, current_user: current_user) + + expect(children_ids).to eq([first_child, second_child]) + end + + context 'when ordered by relative position' do + before do + child_link1.update!(relative_position: 20) + child_link2.update!(relative_position: 10) + end + + it 'returns children in correct order' do + post_graphql(query, current_user: current_user) + + expect(children_ids).to eq([second_child, first_child]) + end + end + end + it 'executes limited number of N+1 queries' do post_graphql(query, current_user: current_user) # warm-up @@ -146,13 +177,11 @@ RSpec.describe 'getting a work item list for a project', feature_category: :team end parent_work_items = create_list(:work_item, 2, project: project) - create(:parent_link, work_item_parent: parent_work_items[0], work_item: children[1]) - create(:parent_link, work_item_parent: parent_work_items[1], work_item: children[2]) + create(:parent_link, work_item_parent: parent_work_items[0], work_item: children[2]) + create(:parent_link, work_item_parent: parent_work_items[1], work_item: children[3]) - # There are 2 extra queries for fetching the children field - # See: https://gitlab.com/gitlab-org/gitlab/-/issues/363569 expect { post_graphql(query, current_user: current_user) } - .not_to exceed_query_limit(control).with_threshold(2) + .not_to exceed_query_limit(control) end it 'avoids N+1 queries when children are added to a work item' do @@ -162,8 +191,8 @@ RSpec.describe 'getting a work item list for a project', feature_category: :team post_graphql(query, current_user: current_user) end - create(:parent_link, work_item_parent: item1, work_item: children[1]) create(:parent_link, work_item_parent: item1, work_item: children[2]) + create(:parent_link, work_item_parent: item1, work_item: children[3]) expect { post_graphql(query, current_user: current_user) } .not_to exceed_query_limit(control) @@ -313,6 +342,79 @@ RSpec.describe 'getting a work item list for a project', feature_category: :team end end + context 'when fetching work item notifications widget' do + let(:fields) do + <<~GRAPHQL + nodes { + widgets { + type + ... on WorkItemWidgetNotifications { + subscribed + } + } + } + GRAPHQL + end + + it 'executes limited number of N+1 queries', :use_sql_query_cache do + control = ActiveRecord::QueryRecorder.new(skip_cached: false) do + post_graphql(query, current_user: current_user) + end + + create_list(:work_item, 3, project: project) + + # Performs 1 extra query per item to fetch subscriptions + expect { post_graphql(query, current_user: current_user) } + .not_to exceed_all_query_limit(control).with_threshold(3) + expect_graphql_errors_to_be_empty + end + end + + context 'when fetching work item award emoji widget' do + let(:fields) do + <<~GRAPHQL + nodes { + widgets { + type + ... on WorkItemWidgetAwardEmoji { + awardEmoji { + nodes { + name + emoji + user { id } + } + } + upvotes + downvotes + } + } + } + GRAPHQL + end + + before do + create(:award_emoji, name: 'star', user: current_user, awardable: item1) + create(:award_emoji, :upvote, awardable: item1) + create(:award_emoji, :downvote, awardable: item1) + end + + it 'executes limited number of N+1 queries', :use_sql_query_cache do + control = ActiveRecord::QueryRecorder.new(skip_cached: false) do + post_graphql(query, current_user: current_user) + end + + create_list(:work_item, 2, project: project) do |item| + create(:award_emoji, name: 'rocket', awardable: item) + create_list(:award_emoji, 2, :upvote, awardable: item) + create_list(:award_emoji, 2, :downvote, awardable: item) + end + + expect { post_graphql(query, current_user: current_user) } + .not_to exceed_all_query_limit(control) + expect_graphql_errors_to_be_empty + end + end + def item_ids graphql_dig_at(items_data, :node, :id) end |