summaryrefslogtreecommitdiff
path: root/spec/models/project_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/project_spec.rb')
-rw-r--r--spec/models/project_spec.rb271
1 files changed, 93 insertions, 178 deletions
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 5f8b51c250d..9ec306d297e 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -79,6 +79,7 @@ describe Project do
it { is_expected.to have_many(:ci_refs) }
it { is_expected.to have_many(:builds) }
it { is_expected.to have_many(:build_trace_section_names)}
+ it { is_expected.to have_many(:build_report_results) }
it { is_expected.to have_many(:runner_projects) }
it { is_expected.to have_many(:runners) }
it { is_expected.to have_many(:variables) }
@@ -117,6 +118,7 @@ describe Project do
it { is_expected.to have_many(:jira_imports) }
it { is_expected.to have_many(:metrics_users_starred_dashboards).inverse_of(:project) }
it { is_expected.to have_many(:repository_storage_moves) }
+ it { is_expected.to have_many(:reviews).inverse_of(:project) }
it_behaves_like 'model with repository' do
let_it_be(:container) { create(:project, :repository, path: 'somewhere') }
@@ -181,9 +183,9 @@ describe Project do
expect(project.pages_metadatum).to be_persisted
end
- it 'automatically creates a project setting row' do
+ it 'automatically builds a project setting row' do
expect(project.project_setting).to be_an_instance_of(ProjectSetting)
- expect(project.project_setting).to be_persisted
+ expect(project.project_setting).to be_new_record
end
end
@@ -770,7 +772,7 @@ describe Project do
describe 'last_activity_date' do
it 'returns the creation date of the project\'s last event if present' do
- new_event = create(:event, :closed, project: project, created_at: Time.now)
+ new_event = create(:event, :closed, project: project, created_at: Time.current)
project.reload
expect(project.last_activity_at.to_i).to eq(new_event.created_at.to_i)
@@ -2836,48 +2838,6 @@ describe Project do
end
end
- describe '#change_repository_storage' do
- let(:project) { create(:project, :repository) }
- let(:read_only_project) { create(:project, :repository, repository_read_only: true) }
-
- before do
- stub_storage_settings('test_second_storage' => { 'path' => 'tmp/tests/extra_storage' })
- end
-
- it 'schedules the transfer of the repository to the new storage and locks the project' do
- expect(ProjectUpdateRepositoryStorageWorker).to receive(:perform_async).with(project.id, 'test_second_storage', anything)
-
- project.change_repository_storage('test_second_storage')
- project.save!
-
- expect(project).to be_repository_read_only
- expect(project.repository_storage_moves.last).to have_attributes(
- source_storage_name: "default",
- destination_storage_name: "test_second_storage"
- )
- end
-
- it "doesn't schedule the transfer if the repository is already read-only" do
- expect(ProjectUpdateRepositoryStorageWorker).not_to receive(:perform_async)
-
- read_only_project.change_repository_storage('test_second_storage')
- read_only_project.save!
- end
-
- it "doesn't lock or schedule the transfer if the storage hasn't changed" do
- expect(ProjectUpdateRepositoryStorageWorker).not_to receive(:perform_async)
-
- project.change_repository_storage(project.repository_storage)
- project.save!
-
- expect(project).not_to be_repository_read_only
- end
-
- it 'throws an error if an invalid repository storage is provided' do
- expect { project.change_repository_storage('unknown') }.to raise_error(ArgumentError)
- end
- end
-
describe '#pushes_since_gc' do
let(:project) { create(:project) }
@@ -3620,7 +3580,7 @@ describe Project do
expect(project).not_to receive(:visibility_level_allowed_as_fork).and_call_original
expect(project).not_to receive(:visibility_level_allowed_by_group).and_call_original
- project.update(updated_at: Time.now)
+ project.update(updated_at: Time.current)
end
end
@@ -3766,7 +3726,7 @@ describe Project do
context 'when feature is private' do
let(:project) { create(:project, :public, :merge_requests_private) }
- context 'when user does not has access to the feature' do
+ context 'when user does not have access to the feature' do
it 'does not return projects with the project feature private' do
is_expected.not_to include(project)
end
@@ -4302,8 +4262,7 @@ describe Project do
describe '#auto_devops_enabled?' do
before do
- allow(Feature).to receive(:enabled?).and_call_original
- Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(0)
+ Feature.enable_percentage_of_actors(:force_autodevops_on_by_default, 0)
end
let_it_be(:project, reload: true) { create(:project) }
@@ -4505,8 +4464,7 @@ describe Project do
let_it_be(:project, reload: true) { create(:project) }
before do
- allow(Feature).to receive(:enabled?).and_call_original
- Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(0)
+ Feature.enable_percentage_of_actors(:force_autodevops_on_by_default, 0)
end
context 'when explicitly disabled' do
@@ -4552,7 +4510,7 @@ describe Project do
before do
create(:project_auto_devops, project: project, enabled: false)
- Feature.get(:force_autodevops_on_by_default).enable_percentage_of_actors(100)
+ Feature.enable_percentage_of_actors(:force_autodevops_on_by_default, 100)
end
it 'does not have auto devops implicitly disabled' do
@@ -4854,6 +4812,32 @@ describe Project do
end
end
+ describe '#execute_services' do
+ let(:service) { create(:slack_service, push_events: true, merge_requests_events: false, active: true) }
+
+ it 'executes services with the specified scope' do
+ data = 'any data'
+
+ expect(SlackService).to receive(:allocate).and_wrap_original do |method|
+ method.call.tap do |instance|
+ expect(instance).to receive(:async_execute).with(data).once
+ end
+ end
+
+ service.project.execute_services(data, :push_hooks)
+ end
+
+ it 'does not execute services that don\'t match the specified scope' do
+ expect(SlackService).not_to receive(:allocate).and_wrap_original do |method|
+ method.call.tap do |instance|
+ expect(instance).not_to receive(:async_execute)
+ end
+ end
+
+ service.project.execute_services(anything, :merge_request_hooks)
+ end
+ end
+
describe '#has_active_hooks?' do
let_it_be(:project) { create(:project) }
@@ -5241,25 +5225,21 @@ describe Project do
end
end
- describe "#find_or_initialize_services" do
- subject { build(:project) }
-
+ describe '#find_or_initialize_services' do
it 'returns only enabled services' do
- allow(Service).to receive(:available_services_names).and_return(%w(prometheus pushover))
- allow(subject).to receive(:disabled_services).and_return(%w(prometheus))
+ allow(Service).to receive(:available_services_names).and_return(%w[prometheus pushover teamcity])
+ allow(subject).to receive(:disabled_services).and_return(%w[prometheus])
services = subject.find_or_initialize_services
- expect(services.count).to eq 1
- expect(services).to include(PushoverService)
+ expect(services.count).to eq(2)
+ expect(services.map(&:title)).to eq(['JetBrains TeamCity CI', 'Pushover'])
end
end
- describe "#find_or_initialize_service" do
- subject { build(:project) }
-
+ describe '#find_or_initialize_service' do
it 'avoids N+1 database queries' do
- allow(Service).to receive(:available_services_names).and_return(%w(prometheus pushover))
+ allow(Service).to receive(:available_services_names).and_return(%w[prometheus pushover])
control_count = ActiveRecord::QueryRecorder.new { subject.find_or_initialize_service('prometheus') }.count
@@ -5268,11 +5248,51 @@ describe Project do
expect { subject.find_or_initialize_service('prometheus') }.not_to exceed_query_limit(control_count)
end
- it 'returns nil if service is disabled' do
- allow(subject).to receive(:disabled_services).and_return(%w(prometheus))
+ it 'returns nil if integration is disabled' do
+ allow(subject).to receive(:disabled_services).and_return(%w[prometheus])
expect(subject.find_or_initialize_service('prometheus')).to be_nil
end
+
+ context 'with an existing integration' do
+ subject { create(:project) }
+
+ before do
+ create(:prometheus_service, project: subject, api_url: 'https://prometheus.project.com/')
+ end
+
+ it 'retrieves the integration' do
+ expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.project.com/')
+ end
+ end
+
+ context 'with an instance-level and template integrations' do
+ before do
+ create(:prometheus_service, :instance, api_url: 'https://prometheus.instance.com/')
+ create(:prometheus_service, :template, api_url: 'https://prometheus.template.com/')
+ end
+
+ it 'builds the service from the instance if exists' do
+ expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.instance.com/')
+ end
+ end
+
+ context 'with an instance-level and template integrations' do
+ before do
+ create(:prometheus_service, :template, api_url: 'https://prometheus.template.com/')
+ end
+
+ it 'builds the service from the template if instance does not exists' do
+ expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.template.com/')
+ end
+ end
+
+ context 'without an exisiting integration, nor instance-level or template' do
+ it 'builds the service if instance or template does not exists' do
+ expect(subject.find_or_initialize_service('prometheus')).to be_a(PrometheusService)
+ expect(subject.find_or_initialize_service('prometheus').api_url).to be_nil
+ end
+ end
end
describe '.for_group' do
@@ -6005,119 +6025,6 @@ describe Project do
end
end
- describe '#validate_jira_import_settings!' do
- include JiraServiceHelper
-
- let_it_be(:project, reload: true) { create(:project) }
-
- shared_examples 'raise Jira import error' do |message|
- it 'returns error' do
- expect { subject }.to raise_error(Projects::ImportService::Error, message)
- end
- end
-
- shared_examples 'jira configuration base checks' do
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(jira_issue_import: false)
- end
-
- it_behaves_like 'raise Jira import error', 'Jira import feature is disabled.'
- end
-
- context 'when feature flag is enabled' do
- before do
- stub_feature_flags(jira_issue_import: true)
- end
-
- context 'when Jira service was not setup' do
- it_behaves_like 'raise Jira import error', 'Jira integration not configured.'
- end
-
- context 'when Jira service exists' do
- let!(:jira_service) { create(:jira_service, project: project, active: true) }
-
- context 'when Jira connection is not valid' do
- before do
- WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo')
- .to_raise(JIRA::HTTPError.new(double(message: 'Some failure.')))
- end
-
- it_behaves_like 'raise Jira import error', 'Unable to connect to the Jira instance. Please check your Jira integration configuration.'
- end
- end
- end
- end
-
- before do
- stub_jira_service_test
- end
-
- context 'without user param' do
- subject { project.validate_jira_import_settings! }
-
- it_behaves_like 'jira configuration base checks'
-
- context 'when jira connection is valid' do
- let!(:jira_service) { create(:jira_service, project: project, active: true) }
-
- it 'does not return any error' do
- expect { subject }.not_to raise_error
- end
- end
- end
-
- context 'with user param provided' do
- let_it_be(:user) { create(:user) }
-
- subject { project.validate_jira_import_settings!(user: user) }
-
- context 'when user has permission to run import' do
- before do
- project.add_maintainer(user)
- end
-
- it_behaves_like 'jira configuration base checks'
- end
-
- context 'when feature flag is enabled' do
- before do
- stub_feature_flags(jira_issue_import: true)
- end
-
- context 'when user does not have permissions to run the import' do
- before do
- create(:jira_service, project: project, active: true)
-
- project.add_developer(user)
- end
-
- it_behaves_like 'raise Jira import error', 'You do not have permissions to run the import.'
- end
-
- context 'when user has permission to run import' do
- before do
- project.add_maintainer(user)
- end
-
- let!(:jira_service) { create(:jira_service, project: project, active: true) }
-
- context 'when issues feature is disabled' do
- let_it_be(:project, reload: true) { create(:project, :issues_disabled) }
-
- it_behaves_like 'raise Jira import error', 'Cannot import because issues are not available in this project.'
- end
-
- context 'when everything is ok' do
- it 'does not return any error' do
- expect { subject }.not_to raise_error
- end
- end
- end
- end
- end
- end
-
describe '#design_management_enabled?' do
let(:project) { build(:project) }
@@ -6157,6 +6064,14 @@ describe Project do
it { is_expected.not_to include(user) }
end
+ describe "#metrics_setting" do
+ let(:project) { build(:project) }
+
+ it 'creates setting if it does not exist' do
+ expect(project.metrics_setting).to be_an_instance_of(ProjectMetricsSetting)
+ end
+ end
+
def finish_job(export_job)
export_job.start
export_job.finish