diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-10 15:11:00 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-10 15:11:00 +0300 |
commit | 63c306d96043ff012510358037c19053a2102e8a (patch) | |
tree | bcb2874d81dc9b3748b37d250a83d9a91f8b38b0 /spec/graphql/resolvers | |
parent | 5adf6557e251c047ed68bac28cfecf9491ee6b41 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/graphql/resolvers')
-rw-r--r-- | spec/graphql/resolvers/concerns/resolves_ids_spec.rb | 43 | ||||
-rw-r--r-- | spec/graphql/resolvers/timelog_resolver_spec.rb | 309 |
2 files changed, 293 insertions, 59 deletions
diff --git a/spec/graphql/resolvers/concerns/resolves_ids_spec.rb b/spec/graphql/resolvers/concerns/resolves_ids_spec.rb new file mode 100644 index 00000000000..1dd27c0eff0 --- /dev/null +++ b/spec/graphql/resolvers/concerns/resolves_ids_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ResolvesIds do + # gid://gitlab/Project/6 + # gid://gitlab/Issue/6 + # gid://gitlab/Project/6 gid://gitlab/Issue/6 + context 'with a single project' do + let(:ids) { 'gid://gitlab/Project/6' } + let(:type) { ::Types::GlobalIDType[::Project] } + + it 'returns the correct array' do + expect(resolve_ids).to match_array(['6']) + end + end + + context 'with a single issue' do + let(:ids) { 'gid://gitlab/Issue/9' } + let(:type) { ::Types::GlobalIDType[::Issue] } + + it 'returns the correct array' do + expect(resolve_ids).to match_array(['9']) + end + end + + context 'with multiple users' do + let(:ids) { ['gid://gitlab/User/7', 'gid://gitlab/User/13', 'gid://gitlab/User/21'] } + let(:type) { ::Types::GlobalIDType[::User] } + + it 'returns the correct array' do + expect(resolve_ids).to match_array(%w[7 13 21]) + end + end + + def mock_resolver + Class.new(GraphQL::Schema::Resolver) { extend ResolvesIds } + end + + def resolve_ids + mock_resolver.resolve_ids(ids, type) + end +end diff --git a/spec/graphql/resolvers/timelog_resolver_spec.rb b/spec/graphql/resolvers/timelog_resolver_spec.rb index bb4938c751f..f45f528fe7e 100644 --- a/spec/graphql/resolvers/timelog_resolver_spec.rb +++ b/spec/graphql/resolvers/timelog_resolver_spec.rb @@ -5,115 +5,306 @@ require 'spec_helper' RSpec.describe Resolvers::TimelogResolver do include GraphqlHelpers + let_it_be(:current_user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, :empty_repo, :public, group: group) } + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:error_class) { Gitlab::Graphql::Errors::ArgumentError } + specify do expect(described_class).to have_non_null_graphql_type(::Types::TimelogType.connection_type) end - context "with a group" do - let_it_be(:current_user) { create(:user) } - let_it_be(:group) { create(:group) } - let_it_be(:project) { create(:project, :empty_repo, :public, group: group) } + shared_examples_for 'with a project' do + let_it_be(:merge_request) { create(:merge_request, source_project: project) } + let_it_be(:timelog1) { create(:issue_timelog, issue: issue, spent_at: 2.days.ago.beginning_of_day) } + let_it_be(:timelog2) { create(:issue_timelog, issue: issue, spent_at: 2.days.ago.end_of_day) } + let_it_be(:timelog3) { create(:merge_request_timelog, merge_request: merge_request, spent_at: 10.days.ago) } - describe '#resolve' do - let_it_be(:short_time_ago) { 5.days.ago.beginning_of_day } - let_it_be(:medium_time_ago) { 15.days.ago.beginning_of_day } + let(:args) { { start_time: 6.days.ago, end_time: 2.days.ago.noon } } - let_it_be(:issue) { create(:issue, project: project) } - let_it_be(:merge_request) { create(:merge_request, source_project: project) } + it 'finds all timelogs within given dates' do + timelogs = resolve_timelogs(**args) - let_it_be(:timelog1) { create(:issue_timelog, issue: issue, spent_at: short_time_ago.beginning_of_day) } - let_it_be(:timelog2) { create(:issue_timelog, issue: issue, spent_at: short_time_ago.end_of_day) } - let_it_be(:timelog3) { create(:merge_request_timelog, merge_request: merge_request, spent_at: medium_time_ago) } + expect(timelogs).to contain_exactly(timelog1) + end - let(:args) { { start_time: short_time_ago, end_time: short_time_ago.noon } } + context 'when no dates specified' do + let(:args) { {} } it 'finds all timelogs' do - timelogs = resolve_timelogs + timelogs = resolve_timelogs(**args) expect(timelogs).to contain_exactly(timelog1, timelog2, timelog3) end + end - it 'finds all timelogs within given dates' do + context 'when only start_time present' do + let(:args) { { start_time: 2.days.ago.noon } } + + it 'finds timelogs after the start_time' do + timelogs = resolve_timelogs(**args) + + expect(timelogs).to contain_exactly(timelog2) + end + end + + context 'when only end_time present' do + let(:args) { { end_time: 2.days.ago.noon } } + + it 'finds timelogs before the end_time' do + timelogs = resolve_timelogs(**args) + + expect(timelogs).to contain_exactly(timelog1, timelog3) + end + end + + context 'when start_time and end_date are present' do + let(:args) { { start_time: 6.days.ago, end_date: 2.days.ago } } + + it 'finds timelogs until the end of day of end_date' do + timelogs = resolve_timelogs(**args) + + expect(timelogs).to contain_exactly(timelog1, timelog2) + end + end + + context 'when start_date and end_time are present' do + let(:args) { { start_date: 6.days.ago, end_time: 2.days.ago.noon } } + + it 'finds all timelogs within start_date and end_time' do timelogs = resolve_timelogs(**args) expect(timelogs).to contain_exactly(timelog1) end + end - context 'when only start_date is present' do - let(:args) { { start_date: short_time_ago } } + it 'return nothing when user has insufficient permissions' do + project2 = create(:project, :empty_repo, :private) + issue2 = create(:issue, project: project2) + create(:issue_timelog, issue: issue2, spent_at: 2.days.ago.beginning_of_day) - it 'finds timelogs until the end of day of end_date' do - timelogs = resolve_timelogs(**args) + user = create(:user) - expect(timelogs).to contain_exactly(timelog1, timelog2) + expect(resolve_timelogs(user: user, obj: project2, **args)).to be_empty + end + + context 'when arguments are invalid' do + let_it_be(:error_class) { Gitlab::Graphql::Errors::ArgumentError } + + context 'when start_time and start_date are present' do + let(:args) { { start_time: 6.days.ago, start_date: 6.days.ago } } + + it 'returns correct error' do + expect { resolve_timelogs(**args) } + .to raise_error(error_class, /Provide either a start date or time, but not both/) end end - context 'when only end_date is present' do - let(:args) { { end_date: medium_time_ago } } + context 'when end_time and end_date are present' do + let(:args) { { end_time: 2.days.ago, end_date: 2.days.ago } } + + it 'returns correct error' do + expect { resolve_timelogs(**args) } + .to raise_error(error_class, /Provide either an end date or time, but not both/) + end + end - it 'finds timelogs until the end of day of end_date' do - timelogs = resolve_timelogs(**args) + context 'when start argument is after end argument' do + let(:args) { { start_time: 2.days.ago, end_time: 6.days.ago } } - expect(timelogs).to contain_exactly(timelog3) + it 'returns correct error' do + expect { resolve_timelogs(**args) } + .to raise_error(error_class, /Start argument must be before End argument/) end end + end + end - context 'when start_time and end_date are present' do - let(:args) { { start_time: short_time_ago, end_date: short_time_ago } } + shared_examples "with a group" do + let_it_be(:short_time_ago) { 5.days.ago.beginning_of_day } + let_it_be(:medium_time_ago) { 15.days.ago.beginning_of_day } - it 'finds timelogs until the end of day of end_date' do - timelogs = resolve_timelogs(**args) + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:merge_request) { create(:merge_request, source_project: project) } - expect(timelogs).to contain_exactly(timelog1, timelog2) - end + let_it_be(:timelog1) { create(:issue_timelog, issue: issue, spent_at: short_time_ago.beginning_of_day) } + let_it_be(:timelog2) { create(:issue_timelog, issue: issue, spent_at: short_time_ago.end_of_day) } + let_it_be(:timelog3) { create(:merge_request_timelog, merge_request: merge_request, spent_at: medium_time_ago) } + + let(:args) { { start_time: short_time_ago, end_time: short_time_ago.noon } } + + it 'finds all timelogs' do + timelogs = resolve_timelogs + + expect(timelogs).to contain_exactly(timelog1, timelog2, timelog3) + end + + it 'finds all timelogs within given dates' do + timelogs = resolve_timelogs(**args) + + expect(timelogs).to contain_exactly(timelog1) + end + + context 'when only start_date is present' do + let(:args) { { start_date: short_time_ago } } + + it 'finds timelogs until the end of day of end_date' do + timelogs = resolve_timelogs(**args) + + expect(timelogs).to contain_exactly(timelog1, timelog2) end + end - context 'when start_date and end_time are present' do - let(:args) { { start_date: short_time_ago, end_time: short_time_ago.noon } } + context 'when only end_date is present' do + let(:args) { { end_date: medium_time_ago } } - it 'finds all timelogs within start_date and end_time' do - timelogs = resolve_timelogs(**args) + it 'finds timelogs until the end of day of end_date' do + timelogs = resolve_timelogs(**args) - expect(timelogs).to contain_exactly(timelog1) - end + expect(timelogs).to contain_exactly(timelog3) end + end - context 'when arguments are invalid' do - let_it_be(:error_class) { Gitlab::Graphql::Errors::ArgumentError } + context 'when start_time and end_date are present' do + let(:args) { { start_time: short_time_ago, end_date: short_time_ago } } - context 'when start_time and start_date are present' do - let(:args) { { start_time: short_time_ago, start_date: short_time_ago } } + it 'finds timelogs until the end of day of end_date' do + timelogs = resolve_timelogs(**args) + + expect(timelogs).to contain_exactly(timelog1, timelog2) + end + end + + context 'when start_date and end_time are present' do + let(:args) { { start_date: short_time_ago, end_time: short_time_ago.noon } } + + it 'finds all timelogs within start_date and end_time' do + timelogs = resolve_timelogs(**args) + + expect(timelogs).to contain_exactly(timelog1) + end + end + + context 'when arguments are invalid' do + context 'when start_time and start_date are present' do + let(:args) { { start_time: short_time_ago, start_date: short_time_ago } } - it 'returns correct error' do - expect { resolve_timelogs(**args) } - .to raise_error(error_class, /Provide either a start date or time, but not both/) - end + it 'returns correct error' do + expect { resolve_timelogs(**args) } + .to raise_error(error_class, /Provide either a start date or time, but not both/) end + end - context 'when end_time and end_date are present' do - let(:args) { { end_time: short_time_ago, end_date: short_time_ago } } + context 'when end_time and end_date are present' do + let(:args) { { end_time: short_time_ago, end_date: short_time_ago } } - it 'returns correct error' do - expect { resolve_timelogs(**args) } - .to raise_error(error_class, /Provide either an end date or time, but not both/) - end + it 'returns correct error' do + expect { resolve_timelogs(**args) } + .to raise_error(error_class, /Provide either an end date or time, but not both/) end + end - context 'when start argument is after end argument' do - let(:args) { { start_time: short_time_ago, end_time: medium_time_ago } } + context 'when start argument is after end argument' do + let(:args) { { start_time: short_time_ago, end_time: medium_time_ago } } - it 'returns correct error' do - expect { resolve_timelogs(**args) } - .to raise_error(error_class, /Start argument must be before End argument/) - end + it 'returns correct error' do + expect { resolve_timelogs(**args) } + .to raise_error(error_class, /Start argument must be before End argument/) end end end end - def resolve_timelogs(user: current_user, **args) + shared_examples "with a user" do + let_it_be(:short_time_ago) { 5.days.ago.beginning_of_day } + let_it_be(:medium_time_ago) { 15.days.ago.beginning_of_day } + + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:merge_request) { create(:merge_request, source_project: project) } + + let_it_be(:timelog1) { create(:issue_timelog, issue: issue, user: current_user) } + let_it_be(:timelog2) { create(:issue_timelog, issue: issue, user: create(:user)) } + let_it_be(:timelog3) { create(:merge_request_timelog, merge_request: merge_request, user: current_user) } + + it 'blah' do + timelogs = resolve_timelogs(**args) + + expect(timelogs).to contain_exactly(timelog1, timelog3) + end + end + + context "on a project" do + let(:object) { project } + let(:extra_args) { {} } + + it_behaves_like 'with a project' + end + + context "with a project filter" do + let(:object) { nil } + let(:extra_args) { { project_id: project.to_global_id } } + + it_behaves_like 'with a project' + end + + context 'on a group' do + let(:object) { group } + let(:extra_args) { {} } + + it_behaves_like 'with a group' + end + + context 'with a group filter' do + let(:object) { nil } + let(:extra_args) { { group_id: group.to_global_id } } + + it_behaves_like 'with a group' + end + + context 'on a user' do + let(:object) { current_user } + let(:extra_args) { {} } + let(:args) { {} } + + it_behaves_like 'with a user' + end + + context 'with a user filter' do + let(:object) { nil } + let(:extra_args) { { username: current_user.username } } + let(:args) { {} } + + it_behaves_like 'with a user' + end + + context 'when > `default_max_page_size` records' do + let(:object) { nil } + let!(:timelog_list) { create_list(:timelog, 101, issue: issue) } + let(:args) { { project_id: "gid://gitlab/Project/#{project.id}" } } + let(:extra_args) { {} } + + it 'pagination returns `default_max_page_size` and sets `has_next_page` true' do + timelogs = resolve_timelogs(**args) + + expect(timelogs.items.count).to be(100) + expect(timelogs.has_next_page).to be(true) + end + end + + context 'when no object or arguments provided' do + let(:object) { nil } + let(:args) { {} } + let(:extra_args) { {} } + + it 'returns correct error' do + expect { resolve_timelogs(**args) } + .to raise_error(error_class, /Provide at least one argument/) + end + end + + def resolve_timelogs(user: current_user, obj: object, **args) context = { current_user: user } - resolve(described_class, obj: group, args: args, ctx: context) + resolve(described_class, obj: obj, args: args.merge(extra_args), ctx: context) end end |