diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-14 03:08:10 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-14 03:08:10 +0300 |
commit | c77ea1f6860ba657eefd5a06e46db8d212b21f08 (patch) | |
tree | 9330894c4c318e04a71f38ce85c82d3a23192fcb /spec | |
parent | 04cc87ee46c1c0b6b4eb7df964b3115dd2578877 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
9 files changed, 214 insertions, 22 deletions
diff --git a/spec/factories/organizations/organizations.rb b/spec/factories/organizations/organizations.rb index c916b966abc..f88ef046248 100644 --- a/spec/factories/organizations/organizations.rb +++ b/spec/factories/organizations/organizations.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +# When adding or changing attributes, consider changing the database importer as well +# lib/gitlab/database_importers/default_organization_importer.rb FactoryBot.define do factory :organization, class: 'Organizations::Organization' do sequence(:name) { |n| "Organization ##{n}" } diff --git a/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml index 6afd8baa0e8..56941fcc6d5 100644 --- a/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml +++ b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml @@ -1,3 +1,10 @@ +# invalid include:rules +include: + - local: builds.yml + rules: + - if: '$INCLUDE_BUILDS == "true"' + when: on_success + # invalid trigger:include trigger missing file property: stage: prepare diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml index c00ab0d464a..fffdda8e6d6 100644 --- a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml +++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml @@ -5,8 +5,8 @@ stages: include: - local: builds.yml rules: - - if: '$INCLUDE_BUILDS == "true"' - when: always + - if: '$INCLUDE_BUILDS == "false"' + when: never # valid trigger:include trigger:include accepts project and file properties: diff --git a/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb b/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb index 6116fbced2b..10c1d92e209 100644 --- a/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb @@ -3,7 +3,7 @@ require 'fast_spec_helper' require_dependency 'active_model' -RSpec.describe Gitlab::Ci::Config::Entry::Include::Rules::Rule do +RSpec.describe Gitlab::Ci::Config::Entry::Include::Rules::Rule, feature_category: :pipeline_composition do let(:factory) do Gitlab::Config::Entry::Factory.new(described_class) .value(config) @@ -24,6 +24,12 @@ RSpec.describe Gitlab::Ci::Config::Entry::Include::Rules::Rule do let(:config) { { if: '$THIS || $THAT' } } it { is_expected.to be_valid } + + context 'with when:' do + let(:config) { { if: '$THIS || $THAT', when: 'never' } } + + it { is_expected.to be_valid } + end end context 'when specifying an exists: clause' do @@ -90,6 +96,14 @@ RSpec.describe Gitlab::Ci::Config::Entry::Include::Rules::Rule do it 'returns the config' do expect(subject).to eq(if: '$THIS || $THAT') end + + context 'with when:' do + let(:config) { { if: '$THIS || $THAT', when: 'never' } } + + it 'returns the config' do + expect(subject).to eq(if: '$THIS || $THAT', when: 'never') + end + end end context 'when specifying an exists: clause' do diff --git a/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb b/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb index 5195567ebb4..4da3e7e51a7 100644 --- a/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb +++ b/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb @@ -18,6 +18,7 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper::Filter, feature_category: : describe '#process' do let(:locations) do [{ local: 'config/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1' }] }, + { remote: 'https://testing.com/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1', when: 'never' }] }, { remote: 'https://example.com/.gitlab-ci.yml', rules: [{ if: '$VARIABLE2' }] }] end @@ -28,5 +29,18 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper::Filter, feature_category: : [{ local: 'config/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1' }] }] ) end + + context 'when FF `ci_support_include_rules_when_never` is disabled' do + before do + stub_feature_flags(ci_support_include_rules_when_never: false) + end + + it 'filters locations according to rules ignoring when:' do + is_expected.to eq( + [{ local: 'config/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1' }] }, + { remote: 'https://testing.com/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1', when: 'never' }] }] + ) + end + end end end diff --git a/spec/lib/gitlab/ci/config/external/rules_spec.rb b/spec/lib/gitlab/ci/config/external/rules_spec.rb index cc73338b5a8..3cb9dedbefe 100644 --- a/spec/lib/gitlab/ci/config/external/rules_spec.rb +++ b/spec/lib/gitlab/ci/config/external/rules_spec.rb @@ -3,43 +3,42 @@ require 'spec_helper' RSpec.describe Gitlab::Ci::Config::External::Rules, feature_category: :pipeline_composition do - let(:rule_hashes) {} + # Remove `project` property when FF `ci_support_include_rules_when_never` is removed + let(:context) { double(variables_hash: {}, project: nil) } + let(:rule_hashes) { [{ if: '$MY_VAR == "hello"' }] } subject(:rules) { described_class.new(rule_hashes) } describe '#evaluate' do - let(:context) { double(variables_hash: {}) } - subject(:result) { rules.evaluate(context).pass? } context 'when there is no rule' do + let(:rule_hashes) {} + it { is_expected.to eq(true) } end - context 'when there is a rule with if' do - let(:rule_hashes) { [{ if: '$MY_VAR == "hello"' }] } + shared_examples 'when there is a rule with if' do |rule_matched_result = true, rule_not_matched_result = false| + # Remove this `before` block when FF `ci_support_include_rules_when_never` is removed + before do + allow(context).to receive(:project).and_return(nil) + end context 'when the rule matches' do let(:context) { double(variables_hash: { 'MY_VAR' => 'hello' }) } - it { is_expected.to eq(true) } + it { is_expected.to eq(rule_matched_result) } end context 'when the rule does not match' do let(:context) { double(variables_hash: { 'MY_VAR' => 'invalid' }) } - it { is_expected.to eq(false) } + it { is_expected.to eq(rule_not_matched_result) } end end - context 'when there is a rule with exists' do + shared_examples 'when there is a rule with exists' do |file_exists_result = true, file_not_exists_result = false| let(:project) { create(:project, :repository) } - let(:context) { double(project: project, sha: project.repository.tree.sha, top_level_worktree_paths: ['test.md']) } - let(:rule_hashes) { [{ exists: 'Dockerfile' }] } - - context 'when the file does not exist' do - it { is_expected.to eq(false) } - end context 'when the file exists' do let(:context) { double(project: project, sha: project.repository.tree.sha, top_level_worktree_paths: ['Dockerfile']) } @@ -48,16 +47,83 @@ RSpec.describe Gitlab::Ci::Config::External::Rules, feature_category: :pipeline_ project.repository.create_file(project.first_owner, 'Dockerfile', "commit", message: 'test', branch_name: "master") end - it { is_expected.to eq(true) } + it { is_expected.to eq(file_exists_result) } + end + + context 'when the file does not exist' do + let(:context) { double(project: project, sha: project.repository.tree.sha, top_level_worktree_paths: ['test.md']) } + + it { is_expected.to eq(file_not_exists_result) } end end + it_behaves_like 'when there is a rule with if' + + context 'when there is a rule with exists' do + let(:rule_hashes) { [{ exists: 'Dockerfile' }] } + + it_behaves_like 'when there is a rule with exists' + end + context 'when there is a rule with if and when' do - let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: 'on_success' }] } + context 'with when: never' do + let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: 'never' }] } - it 'raises an error' do - expect { result }.to raise_error(described_class::InvalidIncludeRulesError, - 'invalid include rule: {:if=>"$MY_VAR == \"hello\"", :when=>"on_success"}') + it_behaves_like 'when there is a rule with if', false, false + + context 'when FF `ci_support_include_rules_when_never` is disabled' do + before do + stub_feature_flags(ci_support_include_rules_when_never: false) + end + + it_behaves_like 'when there is a rule with if' + end + end + + context 'with when: <invalid string>' do + let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: 'on_success' }] } + + it 'raises an error' do + expect { result }.to raise_error(described_class::InvalidIncludeRulesError, + 'invalid include rule: {:if=>"$MY_VAR == \"hello\"", :when=>"on_success"}') + end + end + + context 'with when: null' do + let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: nil }] } + + it_behaves_like 'when there is a rule with if' + end + end + + context 'when there is a rule with exists and when' do + context 'with when: never' do + let(:rule_hashes) { [{ exists: 'Dockerfile', when: 'never' }] } + + it_behaves_like 'when there is a rule with exists', false, false + + context 'when FF `ci_support_include_rules_when_never` is disabled' do + before do + stub_feature_flags(ci_support_include_rules_when_never: false) + end + + it_behaves_like 'when there is a rule with exists' + end + end + + context 'with when: <invalid string>' do + let(:rule_hashes) { [{ exists: 'Dockerfile', when: 'on_success' }] } + + it 'raises an error' do + expect { result }.to raise_error(described_class::InvalidIncludeRulesError, + 'invalid include rule: {:exists=>"Dockerfile", :when=>"on_success"}') + end + end + + context 'with when: null' do + let(:rule_hashes) { [{ exists: 'Dockerfile', when: nil }] } + + it_behaves_like 'when there is a rule with exists' end end diff --git a/spec/lib/gitlab/database_importers/default_organization_importer_spec.rb b/spec/lib/gitlab/database_importers/default_organization_importer_spec.rb new file mode 100644 index 00000000000..41a8aaca699 --- /dev/null +++ b/spec/lib/gitlab/database_importers/default_organization_importer_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::DatabaseImporters::DefaultOrganizationImporter, feature_category: :cell do + describe '#create_default_organization' do + let(:default_id) { Organizations::Organization::DEFAULT_ORGANIZATION_ID } + + subject { described_class.create_default_organization } + + context 'when default organization does not exists' do + it 'creates a default organization' do + expect(Organizations::Organization.find_by(id: default_id)).to be_nil + + subject + + default_org = Organizations::Organization.find(default_id) + + expect(default_org.name).to eq('Default') + expect(default_org.path).to eq('default') + end + end + + context 'when default organization exists' do + let!(:default_org) { create(:organization, :default) } + + it 'does not create another organization' do + expect { subject }.not_to change { Organizations::Organization.count } + end + end + end +end diff --git a/spec/migrations/20230605095810_ensure_default_organization_spec.rb b/spec/migrations/20230605095810_ensure_default_organization_spec.rb new file mode 100644 index 00000000000..97e9a4c54e7 --- /dev/null +++ b/spec/migrations/20230605095810_ensure_default_organization_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe EnsureDefaultOrganization, feature_category: :cell do + let(:organization) { table(:organizations) } + + it "creates default organization if needed" do + reversible_migration do |migration| + migration.before -> { + expect(organization.where(id: 1, name: 'Default', path: 'default')).to be_empty + } + migration.after -> { + expect(organization.where(id: 1, name: 'Default', path: 'default')).not_to be_empty + } + end + end + + context 'when default organization already exists' do + it "does not creates default organization if needed" do + reversible_migration do |migration| + migration.before -> { + organization.create!(id: 1, name: 'Default', path: 'default') + + expect(organization.where(id: 1, name: 'Default', path: 'default')).not_to be_empty + } + migration.after -> { + expect(organization.where(id: 1, name: 'Default', path: 'default')).not_to be_empty + } + end + end + end + + context 'when the path is in use by another organization' do + before do + organization.create!(id: 1000, name: 'Default', path: 'default') + end + + it "adds a random hash to the path" do + reversible_migration do |migration| + migration.after -> { + default_organization = organization.where(id: 1) + + expect(default_organization.first.path).to match(/default-\w{6}/) + } + end + end + end +end diff --git a/spec/models/organizations/organization_spec.rb b/spec/models/organizations/organization_spec.rb index cc2262634e3..4a75f352b6f 100644 --- a/spec/models/organizations/organization_spec.rb +++ b/spec/models/organizations/organization_spec.rb @@ -58,6 +58,12 @@ RSpec.describe Organizations::Organization, type: :model, feature_category: :cel end end + describe '.default_organization' do + it 'returns the default organization' do + expect(described_class.default_organization).to eq(default_organization) + end + end + describe '#id' do context 'when organization is default' do it 'has id 1' do |