diff options
Diffstat (limited to 'spec/requests/api/graphql/ci/inherited_ci_variables_spec.rb')
-rw-r--r-- | spec/requests/api/graphql/ci/inherited_ci_variables_spec.rb | 178 |
1 files changed, 147 insertions, 31 deletions
diff --git a/spec/requests/api/graphql/ci/inherited_ci_variables_spec.rb b/spec/requests/api/graphql/ci/inherited_ci_variables_spec.rb index 3b4014c178c..defddc64851 100644 --- a/spec/requests/api/graphql/ci/inherited_ci_variables_spec.rb +++ b/spec/requests/api/graphql/ci/inherited_ci_variables_spec.rb @@ -12,9 +12,15 @@ RSpec.describe 'Query.project(fullPath).inheritedCiVariables', feature_category: let(:query) do %( - query { + query($limit: Int, $sort: CiGroupVariablesSort) { project(fullPath: "#{project.full_path}") { - inheritedCiVariables { + inheritedCiVariables(first: $limit, sort: $sort) { + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + } nodes { id key @@ -32,6 +38,34 @@ RSpec.describe 'Query.project(fullPath).inheritedCiVariables', feature_category: ) end + let(:expected_var_b) do + { + 'id' => subgroup_var.to_global_id.to_s, + 'key' => 'SUBGROUP_VAR_B', + 'environmentScope' => '*', + 'groupName' => subgroup.name, + 'groupCiCdSettingsPath' => subgroup_var.group_ci_cd_settings_path, + 'masked' => true, + 'protected' => false, + 'raw' => false, + 'variableType' => 'FILE' + } + end + + let(:expected_var_a) do + { + 'id' => group_var.to_global_id.to_s, + 'key' => 'GROUP_VAR_A', + 'environmentScope' => 'production', + 'groupName' => group.name, + 'groupCiCdSettingsPath' => group_var.group_ci_cd_settings_path, + 'masked' => false, + 'protected' => true, + 'raw' => true, + 'variableType' => 'ENV_VAR' + } + end + def create_variables create(:ci_group_variable, group: group) create(:ci_group_variable, group: subgroup) @@ -50,45 +84,115 @@ RSpec.describe 'Query.project(fullPath).inheritedCiVariables', feature_category: end context 'when user is a project maintainer' do + let!(:group_var) do + create(:ci_group_variable, group: group, key: 'GROUP_VAR_A', + environment_scope: 'production', masked: false, protected: true, raw: true, created_at: 1.day.ago) + end + + let!(:subgroup_var) do + create(:ci_group_variable, group: subgroup, key: 'SUBGROUP_VAR_B', + masked: true, protected: false, raw: false, variable_type: 'file') + end + before do project.add_maintainer(user) end it "returns the project's CI variables inherited from its parent group and ancestors" do - group_var = create(:ci_group_variable, group: group, key: 'GROUP_VAR_A', - environment_scope: 'production', masked: false, protected: true, raw: true) - - subgroup_var = create(:ci_group_variable, group: subgroup, key: 'SUBGROUP_VAR_B', - masked: true, protected: false, raw: false, variable_type: 'file') - post_graphql(query, current_user: user) - expect(graphql_data.dig('project', 'inheritedCiVariables', 'nodes')).to eq([ - { - 'id' => group_var.to_global_id.to_s, - 'key' => 'GROUP_VAR_A', - 'environmentScope' => 'production', - 'groupName' => group.name, - 'groupCiCdSettingsPath' => group_var.group_ci_cd_settings_path, - 'masked' => false, - 'protected' => true, - 'raw' => true, - 'variableType' => 'ENV_VAR' - }, - { - 'id' => subgroup_var.to_global_id.to_s, - 'key' => 'SUBGROUP_VAR_B', - 'environmentScope' => '*', - 'groupName' => subgroup.name, - 'groupCiCdSettingsPath' => subgroup_var.group_ci_cd_settings_path, - 'masked' => true, - 'protected' => false, - 'raw' => false, - 'variableType' => 'FILE' - } + expect(graphql_data.dig('project', 'inheritedCiVariables', 'nodes')).to match_array([ + expected_var_b, expected_var_a ]) end + context 'when limiting the number of results' do + it 'returns pagination information' do + post_graphql(query, current_user: user, variables: { limit: 1 }) + + expect(has_next_page).to be_truthy + expect(has_prev_page).to be_falsey + + expect(graphql_data.dig('project', 'inheritedCiVariables', 'nodes')).to match_array([ + expected_var_b + ]) + end + end + + describe 'sorting behaviour' do + before do + post_graphql(query, current_user: user, variables: { sort: sort }) + end + + shared_examples_for 'unexpected sort parameter' do + it 'raises a NoData exception' do + expect { graphql_data }.to raise_error(GraphqlHelpers::NoData) + end + end + + context 'with sort by created_at ascenidng' do + let(:sort) { 'CREATED_ASC' } + + it 'returns variables ordered by created_at in ascending order' do + expect(graphql_data.dig('project', 'inheritedCiVariables', 'nodes')).to eq([ + expected_var_a, expected_var_b + ]) + end + end + + context 'with not existing sort parameter' do + let(:sort) { 'WRONG' } + + it_behaves_like 'unexpected sort parameter' + end + + context 'with empty sort parameter' do + let(:sort) { '' } + + it_behaves_like 'unexpected sort parameter' + end + + context 'with no sort parameter' do + let(:sort) { nil } + + it 'returns variables by default in descending order by created_at' do + expect(graphql_data.dig('project', 'inheritedCiVariables', 'nodes')).to eq([ + expected_var_b, expected_var_a + ]) + end + end + + context 'with sort by created_at descending' do + let(:sort) { 'CREATED_DESC' } + + it 'returns variables ordered by created_at in descending order' do + expect(graphql_data.dig('project', 'inheritedCiVariables', 'nodes')).to eq([ + expected_var_b, expected_var_a + ]) + end + end + + context 'with sort by key ascending' do + let(:sort) { 'KEY_ASC' } + + it 'returns variables ordered by key in ascending order' do + expect(graphql_data.dig('project', 'inheritedCiVariables', 'nodes')).to eq([ + expected_var_a, expected_var_b + ]) + end + end + + context 'with sort by key descending' do + let(:sort) { 'KEY_DESC' } + + it 'returns variables ordered by key in descending order' do + expect(graphql_data.dig('project', 'inheritedCiVariables', 'nodes')).to eq([ + expected_var_b, expected_var_a + ]) + end + end + end + it 'avoids N+1 database queries' do create_variables @@ -105,4 +209,16 @@ RSpec.describe 'Query.project(fullPath).inheritedCiVariables', feature_category: expect(multi).not_to exceed_query_limit(baseline) end end + + def pagination_info + graphql_data_at('project', 'inheritedCiVariables', 'pageInfo') + end + + def has_next_page + pagination_info['hasNextPage'] + end + + def has_prev_page + pagination_info['hasPreviousPage'] + end end |