Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/project_spec.rb')
-rw-r--r--spec/models/project_spec.rb113
1 files changed, 106 insertions, 7 deletions
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 2e5c5af4eb0..3a8768ff463 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe Project, factory_default: :keep do
describe 'associations' do
it { is_expected.to belong_to(:group) }
it { is_expected.to belong_to(:namespace) }
- it { is_expected.to belong_to(:project_namespace).class_name('Namespaces::ProjectNamespace').with_foreign_key('project_namespace_id').inverse_of(:project) }
+ it { is_expected.to belong_to(:project_namespace).class_name('Namespaces::ProjectNamespace').with_foreign_key('project_namespace_id') }
it { is_expected.to belong_to(:creator).class_name('User') }
it { is_expected.to belong_to(:pool_repository) }
it { is_expected.to have_many(:users) }
@@ -191,7 +191,7 @@ RSpec.describe Project, factory_default: :keep do
# using delete rather than destroy due to `delete` skipping AR hooks/callbacks
# so it's ensured to work at the DB level. Uses AFTER DELETE trigger.
let_it_be(:project) { create(:project) }
- let_it_be(:project_namespace) { create(:project_namespace, project: project) }
+ let_it_be(:project_namespace) { project.project_namespace }
it 'also deletes the associated ProjectNamespace' do
project.delete
@@ -233,6 +233,58 @@ RSpec.describe Project, factory_default: :keep do
expect(project.project_setting).to be_an_instance_of(ProjectSetting)
expect(project.project_setting).to be_new_record
end
+
+ context 'with project namespaces' do
+ it 'automatically creates a project namespace' do
+ project = build(:project, path: 'hopefully-valid-path1')
+ project.save!
+
+ expect(project).to be_persisted
+ expect(project.project_namespace).to be_persisted
+ expect(project.project_namespace).to be_in_sync_with_project(project)
+ end
+
+ context 'with FF disabled' do
+ before do
+ stub_feature_flags(create_project_namespace_on_project_create: false)
+ end
+
+ it 'does not create a project namespace' do
+ project = build(:project, path: 'hopefully-valid-path2')
+ project.save!
+
+ expect(project).to be_persisted
+ expect(project.project_namespace).to be_nil
+ end
+ end
+ end
+ end
+
+ context 'updating a project' do
+ context 'with project namespaces' do
+ it 'keeps project namespace in sync with project' do
+ project = create(:project)
+ project.update!(path: 'hopefully-valid-path1')
+
+ expect(project).to be_persisted
+ expect(project.project_namespace).to be_persisted
+ expect(project.project_namespace).to be_in_sync_with_project(project)
+ end
+
+ context 'with FF disabled' do
+ before do
+ stub_feature_flags(create_project_namespace_on_project_create: false)
+ end
+
+ it 'does not create a project namespace when project is updated' do
+ project = create(:project)
+ project.update!(path: 'hopefully-valid-path1')
+
+ expect(project).to be_persisted
+ expect(project.project_namespace).to be_nil
+ end
+ end
+ end
end
context 'updating cd_cd_settings' do
@@ -294,6 +346,7 @@ RSpec.describe Project, factory_default: :keep do
it { is_expected.to validate_presence_of(:namespace) }
it { is_expected.to validate_presence_of(:repository_storage) }
it { is_expected.to validate_numericality_of(:max_artifacts_size).only_integer.is_greater_than(0) }
+ it { is_expected.to validate_length_of(:suggestion_commit_message).is_at_most(255) }
it 'validates build timeout constraints' do
is_expected.to validate_numericality_of(:build_timeout)
@@ -322,6 +375,18 @@ RSpec.describe Project, factory_default: :keep do
create(:project)
end
+ context 'validates project namespace creation' do
+ it 'does not create project namespace if project is not created' do
+ project = build(:project, path: 'tree')
+
+ project.valid?
+
+ expect(project).not_to be_valid
+ expect(project).to be_new_record
+ expect(project.project_namespace).to be_new_record
+ end
+ end
+
context 'repository storages inclusion' do
let(:project2) { build(:project, repository_storage: 'missing') }
@@ -424,8 +489,9 @@ RSpec.describe Project, factory_default: :keep do
end
include_context 'invalid urls'
+ include_context 'valid urls with CRLF'
- it 'does not allow urls with CR or LF characters' do
+ it 'does not allow URLs with unencoded CR or LF characters' do
project = build(:project)
aggregate_failures do
@@ -437,6 +503,19 @@ RSpec.describe Project, factory_default: :keep do
end
end
end
+
+ it 'allow URLs with CR or LF characters' do
+ project = build(:project)
+
+ aggregate_failures do
+ valid_urls_with_CRLF.each do |url|
+ project.import_url = url
+
+ expect(project).to be_valid
+ expect(project.errors).to be_empty
+ end
+ end
+ end
end
describe 'project pending deletion' do
@@ -1714,13 +1793,19 @@ RSpec.describe Project, factory_default: :keep do
allow(::Gitlab::ServiceDeskEmail).to receive(:config).and_return(config)
end
- it 'returns custom address when project_key is set' do
- create(:service_desk_setting, project: project, project_key: 'key1')
+ context 'when project_key is set' do
+ it 'returns custom address including the project_key' do
+ create(:service_desk_setting, project: project, project_key: 'key1')
- expect(subject).to eq("foo+#{project.full_path_slug}-key1@bar.com")
+ expect(subject).to eq("foo+#{project.full_path_slug}-key1@bar.com")
+ end
end
- it_behaves_like 'with incoming email address'
+ context 'when project_key is not set' do
+ it 'returns custom address including the project full path' do
+ expect(subject).to eq("foo+#{project.full_path_slug}-#{project.project_id}-issue-@bar.com")
+ end
+ end
end
end
@@ -1780,6 +1865,20 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '.without_integration' do
+ it 'returns projects without the integration' do
+ project_1, project_2, project_3, project_4 = create_list(:project, 4)
+ instance_integration = create(:jira_integration, :instance)
+ create(:jira_integration, project: project_1, inherit_from_id: instance_integration.id)
+ create(:jira_integration, project: project_2, inherit_from_id: nil)
+ create(:jira_integration, group: create(:group), project: nil, inherit_from_id: nil)
+ create(:jira_integration, project: project_3, inherit_from_id: nil)
+ create(:integrations_slack, project: project_4, inherit_from_id: nil)
+
+ expect(Project.without_integration(instance_integration)).to contain_exactly(project_4)
+ end
+ end
+
context 'repository storage by default' do
let(:project) { build(:project) }