diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-22 12:08:47 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-22 12:08:47 +0000 |
commit | 6046a605fdbb6d180861c978d17fe3516b2e7507 (patch) | |
tree | 42cc483042b341475ba14d8fbfad6432a15327f4 /spec | |
parent | 5956978e1d2aa2b5b35c2d79f67f6b9706b8ec4e (diff) | |
download | gitlab-ce-6046a605fdbb6d180861c978d17fe3516b2e7507.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
33 files changed, 712 insertions, 528 deletions
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index bcd1a53bd47..72076fbecf9 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -237,7 +237,7 @@ RSpec.describe Projects::IssuesController do context 'external issue tracker' do let!(:service) do - create(:custom_issue_tracker_service, project: project, title: 'Custom Issue Tracker', new_issue_url: 'http://test.com') + create(:custom_issue_tracker_service, project: project, new_issue_url: 'http://test.com') end before do diff --git a/spec/controllers/projects/snippets/blobs_controller_spec.rb b/spec/controllers/projects/snippets/blobs_controller_spec.rb new file mode 100644 index 00000000000..ca656705e07 --- /dev/null +++ b/spec/controllers/projects/snippets/blobs_controller_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::Snippets::BlobsController do + using RSpec::Parameterized::TableSyntax + include SnippetHelpers + + let_it_be(:author) { create(:user) } + let_it_be(:developer) { create(:user) } + let_it_be(:other_user) { create(:user) } + + let(:visibility) { :public } + let(:project_visibility) { :public } + let(:project) { create(:project, project_visibility) } + let(:snippet) { create(:project_snippet, visibility, :repository, project: project, author: author) } + + before do + project.add_maintainer(author) + project.add_developer(developer) + end + + describe 'GET #raw' do + let(:filepath) { 'file1' } + let(:ref) { TestEnv::BRANCH_SHA['snippet/single-file'] } + let(:inline) { nil } + + subject do + get(:raw, + params: { + namespace_id: project.namespace, + project_id: project, + snippet_id: snippet, + path: filepath, + ref: ref, + inline: inline + }) + end + + context 'with a snippet without a repository' do + let(:snippet) { create(:project_snippet, visibility, project: project, author: author) } + + it_behaves_like 'raw snippet without repository', :not_found + end + + where(:project_visibility_level, :snippet_visibility_level, :user, :status) do + :public | :public | :author | :ok + :public | :public | :developer | :ok + :public | :public | :other_user | :ok + :public | :public | nil | :ok + + :public | :private | :author | :ok + :public | :private | :developer | :ok + :public | :private | :other_user | :not_found + :public | :private | nil | :not_found + + :private | :public | :author | :ok + :private | :public | :developer | :ok + :private | :public | :other_user | :not_found + :private | :public | nil | :redirect + + :private | :private | :author | :ok + :private | :private | :developer | :ok + :private | :private | :other_user | :not_found + :private | :private | nil | :redirect + end + + with_them do + let(:visibility) { snippet_visibility_level } + let(:project_visibility) { project_visibility_level } + + before do + sign_in_as(user) + + subject + end + + it 'responds with correct status' do + expect(response).to have_gitlab_http_status(status) + end + end + + it_behaves_like 'raw snippet blob' + end +end diff --git a/spec/controllers/snippets/blobs_controller_spec.rb b/spec/controllers/snippets/blobs_controller_spec.rb new file mode 100644 index 00000000000..b9f58587a58 --- /dev/null +++ b/spec/controllers/snippets/blobs_controller_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Snippets::BlobsController do + using RSpec::Parameterized::TableSyntax + include SnippetHelpers + + describe 'GET #raw' do + let_it_be(:author) { create(:user) } + let_it_be(:other_user) { create(:user) } + + let(:visibility) { :public } + let(:snippet) { create(:personal_snippet, visibility, :repository, author: author) } + let(:filepath) { 'file1' } + let(:ref) { TestEnv::BRANCH_SHA['snippet/single-file'] } + let(:inline) { nil } + + subject do + get(:raw, + params: { + snippet_id: snippet, + path: filepath, + ref: ref, + inline: inline + }) + end + + where(:snippet_visibility_level, :user, :status) do + :public | :author | :ok + :public | :other_user | :ok + :public | nil | :ok + + :private | :author | :ok + :private | :other_user | :not_found + :private | nil | :redirect + end + + with_them do + let(:visibility) { snippet_visibility_level } + + before do + sign_in_as(user) + + subject + end + + it 'responds with correct status' do + expect(response).to have_gitlab_http_status(status) + end + end + + it_behaves_like 'raw snippet blob' + + context 'with a snippet without a repository' do + let(:snippet) { create(:personal_snippet, visibility, author: author) } + + it_behaves_like 'raw snippet without repository', :redirect + end + end +end diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb index b78fc63b7dd..2322babcd53 100644 --- a/spec/db/schema_spec.rb +++ b/spec/db/schema_spec.rb @@ -174,7 +174,7 @@ RSpec.describe 'Database schema' do IGNORED_JSONB_COLUMNS = { "ApplicationSetting" => %w[repository_storages_weighted], "AlertManagement::Alert" => %w[payload], - "Ci::BuildMetadata" => %w[config_options config_variables secrets], # secrets has an EE-only validator + "Ci::BuildMetadata" => %w[config_options config_variables], "Geo::Event" => %w[payload], "GeoNodeStatus" => %w[status], "Operations::FeatureFlagScope" => %w[strategies], diff --git a/spec/fixtures/gitlab/import_export/corrupted_project_export.tar.gz b/spec/fixtures/gitlab/import_export/corrupted_project_export.tar.gz Binary files differindex cac16cf9cd8..e0830c290d1 100644 --- a/spec/fixtures/gitlab/import_export/corrupted_project_export.tar.gz +++ b/spec/fixtures/gitlab/import_export/corrupted_project_export.tar.gz diff --git a/spec/fixtures/gitlab/import_export/lightweight_project_export.tar.gz b/spec/fixtures/gitlab/import_export/lightweight_project_export.tar.gz Binary files differindex c01402954dd..0aa41734778 100644 --- a/spec/fixtures/gitlab/import_export/lightweight_project_export.tar.gz +++ b/spec/fixtures/gitlab/import_export/lightweight_project_export.tar.gz diff --git a/spec/fixtures/lib/gitlab/import_export/complex/project.json b/spec/fixtures/lib/gitlab/import_export/complex/project.json index 0785da9c1bf..f6a6671b7f1 100644 --- a/spec/fixtures/lib/gitlab/import_export/complex/project.json +++ b/spec/fixtures/lib/gitlab/import_export/complex/project.json @@ -7010,7 +7010,6 @@ "services": [ { "id": 101, - "title": "YouTrack", "project_id": 5, "created_at": "2016-06-14T15:01:51.327Z", "updated_at": "2016-06-14T15:01:51.327Z", @@ -7030,7 +7029,6 @@ }, { "id": 100, - "title": "JetBrains TeamCity CI", "project_id": 5, "created_at": "2016-06-14T15:01:51.315Z", "updated_at": "2016-06-14T15:01:51.315Z", @@ -7050,7 +7048,6 @@ }, { "id": 99, - "title": "Slack", "project_id": 5, "created_at": "2016-06-14T15:01:51.303Z", "updated_at": "2016-06-14T15:01:51.303Z", @@ -7072,7 +7069,6 @@ }, { "id": 98, - "title": "Redmine", "project_id": 5, "created_at": "2016-06-14T15:01:51.289Z", "updated_at": "2016-06-14T15:01:51.289Z", @@ -7092,7 +7088,6 @@ }, { "id": 97, - "title": "Pushover", "project_id": 5, "created_at": "2016-06-14T15:01:51.277Z", "updated_at": "2016-06-14T15:01:51.277Z", @@ -7112,7 +7107,6 @@ }, { "id": 96, - "title": "PivotalTracker", "project_id": 5, "created_at": "2016-06-14T15:01:51.267Z", "updated_at": "2016-06-14T15:01:51.267Z", @@ -7132,7 +7126,6 @@ }, { "id": 95, - "title": "Jira", "project_id": 5, "created_at": "2016-06-14T15:01:51.255Z", "updated_at": "2016-06-14T15:01:51.255Z", @@ -7155,7 +7148,6 @@ }, { "id": 94, - "title": "Irker (IRC gateway)", "project_id": 5, "created_at": "2016-06-14T15:01:51.232Z", "updated_at": "2016-06-14T15:01:51.232Z", @@ -7175,7 +7167,6 @@ }, { "id": 93, - "title": "HipChat", "project_id": 5, "created_at": "2016-06-14T15:01:51.219Z", "updated_at": "2016-06-14T15:01:51.219Z", @@ -7197,7 +7188,6 @@ }, { "id": 91, - "title": "Flowdock", "project_id": 5, "created_at": "2016-06-14T15:01:51.182Z", "updated_at": "2016-06-14T15:01:51.182Z", @@ -7217,7 +7207,6 @@ }, { "id": 90, - "title": "External Wiki", "project_id": 5, "created_at": "2016-06-14T15:01:51.166Z", "updated_at": "2016-06-14T15:01:51.166Z", @@ -7237,7 +7226,6 @@ }, { "id": 89, - "title": "Emails on push", "project_id": 5, "created_at": "2016-06-14T15:01:51.153Z", "updated_at": "2016-06-14T15:01:51.153Z", @@ -7257,7 +7245,6 @@ }, { "id": 88, - "title": "Drone CI", "project_id": 5, "created_at": "2016-06-14T15:01:51.139Z", "updated_at": "2016-06-14T15:01:51.139Z", @@ -7277,7 +7264,6 @@ }, { "id": 87, - "title": "Custom Issue Tracker", "project_id": 5, "created_at": "2016-06-14T15:01:51.125Z", "updated_at": "2016-06-14T15:01:51.125Z", @@ -7297,7 +7283,6 @@ }, { "id": 86, - "title": "Campfire", "project_id": 5, "created_at": "2016-06-14T15:01:51.113Z", "updated_at": "2016-06-14T15:01:51.113Z", @@ -7317,7 +7302,6 @@ }, { "id": 84, - "title": "Buildkite", "project_id": 5, "created_at": "2016-06-14T15:01:51.080Z", "updated_at": "2016-06-14T15:01:51.080Z", @@ -7337,7 +7321,6 @@ }, { "id": 83, - "title": "Atlassian Bamboo CI", "project_id": 5, "created_at": "2016-06-14T15:01:51.067Z", "updated_at": "2016-06-14T15:01:51.067Z", @@ -7357,7 +7340,6 @@ }, { "id": 82, - "title": "Assembla", "project_id": 5, "created_at": "2016-06-14T15:01:51.047Z", "updated_at": "2016-06-14T15:01:51.047Z", @@ -7377,7 +7359,6 @@ }, { "id": 81, - "title": "Asana", "project_id": 5, "created_at": "2016-06-14T15:01:51.031Z", "updated_at": "2016-06-14T15:01:51.031Z", diff --git a/spec/fixtures/lib/gitlab/import_export/complex/tree/project/services.ndjson b/spec/fixtures/lib/gitlab/import_export/complex/tree/project/services.ndjson index 6d6afd3af0b..e5d39512255 100644 --- a/spec/fixtures/lib/gitlab/import_export/complex/tree/project/services.ndjson +++ b/spec/fixtures/lib/gitlab/import_export/complex/tree/project/services.ndjson @@ -1,19 +1,19 @@ -{"id":101,"title":"YouTrack","project_id":5,"created_at":"2016-06-14T15:01:51.327Z","updated_at":"2016-06-14T15:01:51.327Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"YoutrackService","category":"issue_tracker","default":false,"wiki_page_events":true} -{"id":100,"title":"JetBrains TeamCity CI","project_id":5,"created_at":"2016-06-14T15:01:51.315Z","updated_at":"2016-06-14T15:01:51.315Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"TeamcityService","category":"ci","default":false,"wiki_page_events":true} -{"id":99,"title":"Slack","project_id":5,"created_at":"2016-06-14T15:01:51.303Z","updated_at":"2016-06-14T15:01:51.303Z","active":false,"properties":{"notify_only_broken_pipelines":true},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"pipeline_events":true,"type":"SlackService","category":"common","default":false,"wiki_page_events":true} -{"id":98,"title":"Redmine","project_id":5,"created_at":"2016-06-14T15:01:51.289Z","updated_at":"2016-06-14T15:01:51.289Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"RedmineService","category":"issue_tracker","default":false,"wiki_page_events":true} -{"id":97,"title":"Pushover","project_id":5,"created_at":"2016-06-14T15:01:51.277Z","updated_at":"2016-06-14T15:01:51.277Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"PushoverService","category":"common","default":false,"wiki_page_events":true} -{"id":96,"title":"PivotalTracker","project_id":5,"created_at":"2016-06-14T15:01:51.267Z","updated_at":"2016-06-14T15:01:51.267Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"PivotalTrackerService","category":"common","default":false,"wiki_page_events":true} -{"id":95,"title":"Jira","project_id":5,"created_at":"2016-06-14T15:01:51.255Z","updated_at":"2016-06-14T15:01:51.255Z","active":false,"properties":{"api_url":"","jira_issue_transition_id":"2"},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"JiraService","category":"issue_tracker","default":false,"wiki_page_events":true} -{"id":94,"title":"Irker (IRC gateway)","project_id":5,"created_at":"2016-06-14T15:01:51.232Z","updated_at":"2016-06-14T15:01:51.232Z","active":true,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"IrkerService","category":"common","default":false,"wiki_page_events":true} -{"id":93,"title":"HipChat","project_id":5,"created_at":"2016-06-14T15:01:51.219Z","updated_at":"2016-06-14T15:01:51.219Z","active":false,"properties":{"notify_only_broken_pipelines":true},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"pipeline_events":true,"type":"HipchatService","category":"common","default":false,"wiki_page_events":true} -{"id":91,"title":"Flowdock","project_id":5,"created_at":"2016-06-14T15:01:51.182Z","updated_at":"2016-06-14T15:01:51.182Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"FlowdockService","category":"common","default":false,"wiki_page_events":true} -{"id":90,"title":"External Wiki","project_id":5,"created_at":"2016-06-14T15:01:51.166Z","updated_at":"2016-06-14T15:01:51.166Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"ExternalWikiService","category":"common","default":false,"wiki_page_events":true} -{"id":89,"title":"Emails on push","project_id":5,"created_at":"2016-06-14T15:01:51.153Z","updated_at":"2016-06-14T15:01:51.153Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"EmailsOnPushService","category":"common","default":false,"wiki_page_events":true} -{"id":88,"title":"Drone CI","project_id":5,"created_at":"2016-06-14T15:01:51.139Z","updated_at":"2016-06-14T15:01:51.139Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"DroneCiService","category":"ci","default":false,"wiki_page_events":true} -{"id":87,"title":"Custom Issue Tracker","project_id":5,"created_at":"2016-06-14T15:01:51.125Z","updated_at":"2016-06-14T15:01:51.125Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"CustomIssueTrackerService","category":"issue_tracker","default":false,"wiki_page_events":true} -{"id":86,"title":"Campfire","project_id":5,"created_at":"2016-06-14T15:01:51.113Z","updated_at":"2016-06-14T15:01:51.113Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"CampfireService","category":"common","default":false,"wiki_page_events":true} -{"id":84,"title":"Buildkite","project_id":5,"created_at":"2016-06-14T15:01:51.080Z","updated_at":"2016-06-14T15:01:51.080Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"BuildkiteService","category":"ci","default":false,"wiki_page_events":true} -{"id":83,"title":"Atlassian Bamboo CI","project_id":5,"created_at":"2016-06-14T15:01:51.067Z","updated_at":"2016-06-14T15:01:51.067Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"BambooService","category":"ci","default":false,"wiki_page_events":true} -{"id":82,"title":"Assembla","project_id":5,"created_at":"2016-06-14T15:01:51.047Z","updated_at":"2016-06-14T15:01:51.047Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"AssemblaService","category":"common","default":false,"wiki_page_events":true} -{"id":81,"title":"Asana","project_id":5,"created_at":"2016-06-14T15:01:51.031Z","updated_at":"2016-06-14T15:01:51.031Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"AsanaService","category":"common","default":false,"wiki_page_events":true} +{"id":101,"project_id":5,"created_at":"2016-06-14T15:01:51.327Z","updated_at":"2016-06-14T15:01:51.327Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"YoutrackService","category":"issue_tracker","default":false,"wiki_page_events":true} +{"id":100,"project_id":5,"created_at":"2016-06-14T15:01:51.315Z","updated_at":"2016-06-14T15:01:51.315Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"TeamcityService","category":"ci","default":false,"wiki_page_events":true} +{"id":99,"project_id":5,"created_at":"2016-06-14T15:01:51.303Z","updated_at":"2016-06-14T15:01:51.303Z","active":false,"properties":{"notify_only_broken_pipelines":true},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"pipeline_events":true,"type":"SlackService","category":"common","default":false,"wiki_page_events":true} +{"id":98,"project_id":5,"created_at":"2016-06-14T15:01:51.289Z","updated_at":"2016-06-14T15:01:51.289Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"RedmineService","category":"issue_tracker","default":false,"wiki_page_events":true} +{"id":97,"project_id":5,"created_at":"2016-06-14T15:01:51.277Z","updated_at":"2016-06-14T15:01:51.277Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"PushoverService","category":"common","default":false,"wiki_page_events":true} +{"id":96,"project_id":5,"created_at":"2016-06-14T15:01:51.267Z","updated_at":"2016-06-14T15:01:51.267Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"PivotalTrackerService","category":"common","default":false,"wiki_page_events":true} +{"id":95,"project_id":5,"created_at":"2016-06-14T15:01:51.255Z","updated_at":"2016-06-14T15:01:51.255Z","active":false,"properties":{"api_url":"","jira_issue_transition_id":"2"},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"JiraService","category":"issue_tracker","default":false,"wiki_page_events":true} +{"id":94,"project_id":5,"created_at":"2016-06-14T15:01:51.232Z","updated_at":"2016-06-14T15:01:51.232Z","active":true,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"IrkerService","category":"common","default":false,"wiki_page_events":true} +{"id":93,"project_id":5,"created_at":"2016-06-14T15:01:51.219Z","updated_at":"2016-06-14T15:01:51.219Z","active":false,"properties":{"notify_only_broken_pipelines":true},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"pipeline_events":true,"type":"HipchatService","category":"common","default":false,"wiki_page_events":true} +{"id":91,"project_id":5,"created_at":"2016-06-14T15:01:51.182Z","updated_at":"2016-06-14T15:01:51.182Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"FlowdockService","category":"common","default":false,"wiki_page_events":true} +{"id":90,"project_id":5,"created_at":"2016-06-14T15:01:51.166Z","updated_at":"2016-06-14T15:01:51.166Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"ExternalWikiService","category":"common","default":false,"wiki_page_events":true} +{"id":89,"project_id":5,"created_at":"2016-06-14T15:01:51.153Z","updated_at":"2016-06-14T15:01:51.153Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"EmailsOnPushService","category":"common","default":false,"wiki_page_events":true} +{"id":88,"project_id":5,"created_at":"2016-06-14T15:01:51.139Z","updated_at":"2016-06-14T15:01:51.139Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"DroneCiService","category":"ci","default":false,"wiki_page_events":true} +{"id":87,"project_id":5,"created_at":"2016-06-14T15:01:51.125Z","updated_at":"2016-06-14T15:01:51.125Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"CustomIssueTrackerService","category":"issue_tracker","default":false,"wiki_page_events":true} +{"id":86,"project_id":5,"created_at":"2016-06-14T15:01:51.113Z","updated_at":"2016-06-14T15:01:51.113Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"CampfireService","category":"common","default":false,"wiki_page_events":true} +{"id":84,"project_id":5,"created_at":"2016-06-14T15:01:51.080Z","updated_at":"2016-06-14T15:01:51.080Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"BuildkiteService","category":"ci","default":false,"wiki_page_events":true} +{"id":83,"project_id":5,"created_at":"2016-06-14T15:01:51.067Z","updated_at":"2016-06-14T15:01:51.067Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"BambooService","category":"ci","default":false,"wiki_page_events":true} +{"id":82,"project_id":5,"created_at":"2016-06-14T15:01:51.047Z","updated_at":"2016-06-14T15:01:51.047Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"AssemblaService","category":"common","default":false,"wiki_page_events":true} +{"id":81,"project_id":5,"created_at":"2016-06-14T15:01:51.031Z","updated_at":"2016-06-14T15:01:51.031Z","active":false,"properties":{},"template":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"AsanaService","category":"common","default":false,"wiki_page_events":true} diff --git a/spec/fixtures/lib/gitlab/import_export/light/project.json b/spec/fixtures/lib/gitlab/import_export/light/project.json index 326a2cef9ff..cef78316361 100644 --- a/spec/fixtures/lib/gitlab/import_export/light/project.json +++ b/spec/fixtures/lib/gitlab/import_export/light/project.json @@ -144,7 +144,6 @@ "services": [ { "id": 100, - "title": "JetBrains TeamCity CI", "project_id": 5, "created_at": "2016-06-14T15:01:51.315Z", "updated_at": "2016-06-14T15:01:51.315Z", @@ -165,7 +164,6 @@ }, { "id": 101, - "title": "Jira", "project_id": 5, "created_at": "2016-06-14T15:01:51.315Z", "updated_at": "2016-06-14T15:01:51.315Z", diff --git a/spec/fixtures/lib/gitlab/import_export/light/tree/project/services.ndjson b/spec/fixtures/lib/gitlab/import_export/light/tree/project/services.ndjson index c5ae6bf4b04..414b68dacd7 100644 --- a/spec/fixtures/lib/gitlab/import_export/light/tree/project/services.ndjson +++ b/spec/fixtures/lib/gitlab/import_export/light/tree/project/services.ndjson @@ -1,2 +1,2 @@ -{"id":100,"title":"JetBrains TeamCity CI","project_id":5,"created_at":"2016-06-14T15:01:51.315Z","updated_at":"2016-06-14T15:01:51.315Z","active":false,"properties":{},"template":true,"instance":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"TeamcityService","category":"ci","default":false,"wiki_page_events":true} -{"id":101,"title":"Jira","project_id":5,"created_at":"2016-06-14T15:01:51.315Z","updated_at":"2016-06-14T15:01:51.315Z","active":false,"properties":{},"template":false,"instance":true,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"JiraService","category":"ci","default":false,"wiki_page_events":true} +{"id":100,"project_id":5,"created_at":"2016-06-14T15:01:51.315Z","updated_at":"2016-06-14T15:01:51.315Z","active":false,"properties":{},"template":true,"instance":false,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"TeamcityService","category":"ci","default":false,"wiki_page_events":true} +{"id":101,"project_id":5,"created_at":"2016-06-14T15:01:51.315Z","updated_at":"2016-06-14T15:01:51.315Z","active":false,"properties":{},"template":false,"instance":true,"push_events":true,"issues_events":true,"merge_requests_events":true,"tag_push_events":true,"note_events":true,"job_events":true,"type":"JiraService","category":"ci","default":false,"wiki_page_events":true} diff --git a/spec/frontend/editor/editor_lite_spec.js b/spec/frontend/editor/editor_lite_spec.js index cb07bcf8f28..92a136835bf 100644 --- a/spec/frontend/editor/editor_lite_spec.js +++ b/spec/frontend/editor/editor_lite_spec.js @@ -115,6 +115,76 @@ describe('Base editor', () => { }); }); + describe('extensions', () => { + const foo1 = jest.fn(); + const foo2 = jest.fn(); + const bar = jest.fn(); + const MyExt1 = { + foo: foo1, + }; + const MyExt2 = { + bar, + }; + const MyExt3 = { + foo: foo2, + }; + beforeEach(() => { + editor.createInstance({ el: editorEl, blobPath, blobContent }); + }); + + afterEach(() => { + editor.model.dispose(); + }); + + it('is extensible with the extensions', () => { + expect(editor.foo).toBeUndefined(); + + editor.use(MyExt1); + expect(editor.foo).toEqual(foo1); + }); + + it('does not fail if no extensions supplied', () => { + const spy = jest.spyOn(global.console, 'error'); + editor.use(); + + expect(spy).not.toHaveBeenCalled(); + }); + + it('is extensible with multiple extensions', () => { + expect(editor.foo).toBeUndefined(); + expect(editor.bar).toBeUndefined(); + + editor.use([MyExt1, MyExt2]); + + expect(editor.foo).toEqual(foo1); + expect(editor.bar).toEqual(bar); + }); + + it('uses the last definition of a method in case of an overlap', () => { + editor.use([MyExt1, MyExt2, MyExt3]); + expect(editor).toEqual( + expect.objectContaining({ + foo: foo2, + bar, + }), + ); + }); + + it('correctly resolves references withing extensions', () => { + const FunctionExt = { + inst() { + return this.instance; + }, + mod() { + return this.model; + }, + }; + editor.use(FunctionExt); + expect(editor.inst()).toEqual(editor.instance); + expect(editor.mod()).toEqual(editor.model); + }); + }); + describe('languages', () => { it('registers custom languages defined with Monaco', () => { expect(monacoLanguages.getLanguages()).toEqual( diff --git a/spec/frontend/fixtures/services.rb b/spec/frontend/fixtures/services.rb index 0877998cc9d..43230301296 100644 --- a/spec/frontend/fixtures/services.rb +++ b/spec/frontend/fixtures/services.rb @@ -8,7 +8,7 @@ RSpec.describe Projects::ServicesController, '(JavaScript fixtures)', type: :con let(:admin) { create(:admin) } let(:namespace) { create(:namespace, name: 'frontend-fixtures' )} let(:project) { create(:project_empty_repo, namespace: namespace, path: 'services-project') } - let!(:service) { create(:custom_issue_tracker_service, project: project, title: 'Custom Issue Tracker') } + let!(:service) { create(:custom_issue_tracker_service, project: project) } render_views diff --git a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb index 364e2aa6ca8..156e10e4270 100644 --- a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb +++ b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb @@ -63,7 +63,7 @@ describe Resolvers::Projects::JiraProjectsResolver do context 'when Jira connection is not valid' do before do - WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/project/search?maxResults=50&query=&startAt=0') + WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/project') .to_raise(JIRA::HTTPError.new(double(message: 'Some failure.'))) end diff --git a/spec/lib/gitlab/suggestions/file_suggestion_spec.rb b/spec/lib/gitlab/suggestions/file_suggestion_spec.rb index 6fbbad017c5..15bb8ae5979 100644 --- a/spec/lib/gitlab/suggestions/file_suggestion_spec.rb +++ b/spec/lib/gitlab/suggestions/file_suggestion_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Gitlab::Suggestions::FileSuggestion do - def create_suggestion(new_line, to_content) + def create_suggestion(new_line, to_content, lines_above = 0, lines_below = 0) position = Gitlab::Diff::Position.new(old_path: file_path, new_path: file_path, old_line: nil, @@ -18,6 +18,8 @@ describe Gitlab::Suggestions::FileSuggestion do create(:suggestion, :content_from_repo, note: diff_note, + lines_above: lines_above, + lines_below: lines_below, to_content: to_content) end @@ -39,27 +41,9 @@ describe Gitlab::Suggestions::FileSuggestion do create_suggestion(15, " *** SUGGESTION 2 ***\n") end - let(:file_suggestion) { described_class.new } + let(:suggestions) { [suggestion1, suggestion2] } - describe '#add_suggestion' do - it 'succeeds when adding a suggestion for the same file as the original' do - file_suggestion.add_suggestion(suggestion1) - - expect { file_suggestion.add_suggestion(suggestion2) }.not_to raise_error - end - - it 'raises an error when adding a suggestion for a different file' do - allow(suggestion2) - .to(receive_message_chain(:diff_file, :file_path) - .and_return('path/to/different/file')) - - file_suggestion.add_suggestion(suggestion1) - - expect { file_suggestion.add_suggestion(suggestion2) }.to( - raise_error(described_class::SuggestionForDifferentFileError) - ) - end - end + let(:file_suggestion) { described_class.new(file_path, suggestions) } describe '#line_conflict' do def stub_suggestions(line_index_spans) @@ -175,67 +159,296 @@ describe Gitlab::Suggestions::FileSuggestion do end describe '#new_content' do - it 'returns a blob with the suggestions applied to it' do - file_suggestion.add_suggestion(suggestion1) - file_suggestion.add_suggestion(suggestion2) + context 'with two suggestions' do + let(:suggestions) { [suggestion1, suggestion2] } - expected_content = <<-CONTENT.strip_heredoc - require 'fileutils' - require 'open3' + it 'returns a blob with the suggestions applied to it' do + expected_content = <<-CONTENT.strip_heredoc + require 'fileutils' + require 'open3' - module Popen - extend self + module Popen + extend self - def popen(cmd, path=nil) - unless cmd.is_a?(Array) - *** SUGGESTION 1 *** + def popen(cmd, path=nil) + unless cmd.is_a?(Array) + *** SUGGESTION 1 *** + end + + path ||= Dir.pwd + + vars = { + *** SUGGESTION 2 *** + } + + options = { + chdir: path + } + + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + + @cmd_output = "" + @cmd_status = 0 + + Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| + @cmd_output << stdout.read + @cmd_output << stderr.read + @cmd_status = wait_thr.value.exitstatus + end + + return @cmd_output, @cmd_status end + end + CONTENT - path ||= Dir.pwd + expect(file_suggestion.new_content).to eq(expected_content) + end + end - vars = { - *** SUGGESTION 2 *** - } + context 'when no suggestions have been added' do + let(:suggestions) { [] } - options = { - chdir: path - } + it 'returns an empty string' do + expect(file_suggestion.new_content).to eq('') + end + end + + context 'with multiline suggestions' do + let(:suggestions) { [multi_suggestion1, multi_suggestion2, multi_suggestion3] } + + context 'when the previous suggestion increases the line count' do + let!(:multi_suggestion1) do + create_suggestion(9, " *** SUGGESTION 1 ***\n *** SECOND LINE ***\n *** THIRD LINE ***\n") + end - unless File.directory?(path) - FileUtils.mkdir_p(path) + let!(:multi_suggestion2) do + create_suggestion(15, " *** SUGGESTION 2 ***\n *** SECOND LINE ***\n") + end + + let!(:multi_suggestion3) do + create_suggestion(19, " chdir: *** SUGGESTION 3 ***\n") + end + + it 'returns a blob with the suggestions applied to it' do + expected_content = <<-CONTENT.strip_heredoc + require 'fileutils' + require 'open3' + + module Popen + extend self + + def popen(cmd, path=nil) + unless cmd.is_a?(Array) + *** SUGGESTION 1 *** + *** SECOND LINE *** + *** THIRD LINE *** + end + + path ||= Dir.pwd + + vars = { + *** SUGGESTION 2 *** + *** SECOND LINE *** + } + + options = { + chdir: *** SUGGESTION 3 *** + } + + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + + @cmd_output = "" + @cmd_status = 0 + + Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| + @cmd_output << stdout.read + @cmd_output << stderr.read + @cmd_status = wait_thr.value.exitstatus + end + + return @cmd_output, @cmd_status end + end + CONTENT + + expect(file_suggestion.new_content).to eq(expected_content) + end + end - @cmd_output = "" - @cmd_status = 0 + context 'when the previous suggestion decreases and increases the line count' do + let!(:multi_suggestion1) do + create_suggestion(9, " *** SUGGESTION 1 ***\n", 1, 1) + end + + let!(:multi_suggestion2) do + create_suggestion(15, " *** SUGGESTION 2 ***\n *** SECOND LINE ***\n") + end + + let!(:multi_suggestion3) do + create_suggestion(19, " chdir: *** SUGGESTION 3 ***\n") + end + + it 'returns a blob with the suggestions applied to it' do + expected_content = <<-CONTENT.strip_heredoc + require 'fileutils' + require 'open3' + + module Popen + extend self + + def popen(cmd, path=nil) + *** SUGGESTION 1 *** - Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| - @cmd_output << stdout.read - @cmd_output << stderr.read - @cmd_status = wait_thr.value.exitstatus + path ||= Dir.pwd + + vars = { + *** SUGGESTION 2 *** + *** SECOND LINE *** + } + + options = { + chdir: *** SUGGESTION 3 *** + } + + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + + @cmd_output = "" + @cmd_status = 0 + + Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| + @cmd_output << stdout.read + @cmd_output << stderr.read + @cmd_status = wait_thr.value.exitstatus + end + + return @cmd_output, @cmd_status end + end + CONTENT + + expect(file_suggestion.new_content).to eq(expected_content) + end + end + + context 'when the previous suggestion replaces with the same number of lines' do + let!(:multi_suggestion1) do + create_suggestion(9, " *** SUGGESTION 1 ***\n *** SECOND LINE ***\n *** THIRD LINE ***\n", 1, 1) + end + + let!(:multi_suggestion2) do + create_suggestion(15, " *** SUGGESTION 2 ***\n") + end + + let!(:multi_suggestion3) do + create_suggestion(19, " chdir: *** SUGGESTION 3 ***\n") + end + + it 'returns a blob with the suggestions applied to it' do + expected_content = <<-CONTENT.strip_heredoc + require 'fileutils' + require 'open3' + + module Popen + extend self + + def popen(cmd, path=nil) + *** SUGGESTION 1 *** + *** SECOND LINE *** + *** THIRD LINE *** + + path ||= Dir.pwd + + vars = { + *** SUGGESTION 2 *** + } + + options = { + chdir: *** SUGGESTION 3 *** + } + + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + + @cmd_output = "" + @cmd_status = 0 + + Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| + @cmd_output << stdout.read + @cmd_output << stderr.read + @cmd_status = wait_thr.value.exitstatus + end - return @cmd_output, @cmd_status + return @cmd_output, @cmd_status + end end + CONTENT + + expect(file_suggestion.new_content).to eq(expected_content) end - CONTENT + end - expect(file_suggestion.new_content).to eq(expected_content) - end + context 'when the previous suggestion replaces multiple lines and the suggestions were applied out of order' do + let(:suggestions) { [multi_suggestion1, multi_suggestion3, multi_suggestion2] } - it 'returns an empty string when no suggestions have been added' do - expect(file_suggestion.new_content).to eq('') - end - end + let!(:multi_suggestion1) do + create_suggestion(9, " *** SUGGESTION 1 ***\n *** SECOND LINE ***\n *** THIRD LINE ***\n", 1, 1) + end - describe '#file_path' do - it 'returns the path of the file associated with the suggestions' do - file_suggestion.add_suggestion(suggestion1) + let!(:multi_suggestion3) do + create_suggestion(19, " *** SUGGESTION 3 ***\n", 1, 1) + end - expect(file_suggestion.file_path).to eq(file_path) - end + let!(:multi_suggestion2) do + create_suggestion(15, " *** SUGGESTION 2 ***\n", 1, 1) + end + + it 'returns a blob with the suggestions applied to it' do + expected_content = <<-CONTENT.strip_heredoc + require 'fileutils' + require 'open3' + + module Popen + extend self + + def popen(cmd, path=nil) + *** SUGGESTION 1 *** + *** SECOND LINE *** + *** THIRD LINE *** + + path ||= Dir.pwd + + *** SUGGESTION 2 *** + + *** SUGGESTION 3 *** + + unless File.directory?(path) + FileUtils.mkdir_p(path) + end + + @cmd_output = "" + @cmd_status = 0 - it 'returns nil if no suggestions have been added' do - expect(file_suggestion.file_path).to be(nil) + Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| + @cmd_output << stdout.read + @cmd_output << stderr.read + @cmd_status = wait_thr.value.exitstatus + end + + return @cmd_output, @cmd_status + end + end + CONTENT + + expect(file_suggestion.new_content).to eq(expected_content) + end + end end end end diff --git a/spec/lib/gitlab/suggestions/suggestion_set_spec.rb b/spec/lib/gitlab/suggestions/suggestion_set_spec.rb index 8c61e6c42a6..b664bb73176 100644 --- a/spec/lib/gitlab/suggestions/suggestion_set_spec.rb +++ b/spec/lib/gitlab/suggestions/suggestion_set_spec.rb @@ -87,11 +87,10 @@ describe Gitlab::Suggestions::SuggestionSet do it 'returns an array of hashes with proper key/value pairs' do first_action = suggestion_set.actions.first - file_path, file_suggestion = suggestion_set - .send(:suggestions_per_file).first + file_suggestion = suggestion_set.send(:suggestions_per_file).first expect(first_action[:action]).to be('update') - expect(first_action[:file_path]).to eq(file_path) + expect(first_action[:file_path]).to eq(file_suggestion.file_path) expect(first_action[:content]).to eq(file_suggestion.new_content) end end diff --git a/spec/models/ci/build_metadata_spec.rb b/spec/models/ci/build_metadata_spec.rb index 588e5872cc8..0f7fa5f8e60 100644 --- a/spec/models/ci/build_metadata_spec.rb +++ b/spec/models/ci/build_metadata_spec.rb @@ -92,4 +92,33 @@ describe Ci::BuildMetadata do end end end + + describe 'validations' do + context 'when attributes are valid' do + it 'returns no errors' do + metadata.secrets = { + DATABASE_PASSWORD: { + vault: { + engine: { name: 'kv-v2', path: 'kv-v2' }, + path: 'production/db', + field: 'password' + } + } + } + + expect(metadata).to be_valid + end + end + + context 'when data is invalid' do + it 'returns errors' do + metadata.secrets = { DATABASE_PASSWORD: { vault: {} } } + + aggregate_failures do + expect(metadata).to be_invalid + expect(metadata.errors.full_messages).to eq(["Secrets must be a valid json schema"]) + end + end + end + end end diff --git a/spec/models/project_services/bugzilla_service_spec.rb b/spec/models/project_services/bugzilla_service_spec.rb index ab939e0d2f8..6818db48fee 100644 --- a/spec/models/project_services/bugzilla_service_spec.rb +++ b/spec/models/project_services/bugzilla_service_spec.rb @@ -32,49 +32,4 @@ describe BugzillaService do it { is_expected.not_to validate_presence_of(:new_issue_url) } end end - - context 'overriding properties' do - let(:url) { 'http://bugzilla.example.com' } - let(:access_params) do - { project_url: url, issues_url: url, new_issue_url: url } - end - - # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 - context 'when data are stored in properties' do - let(:properties) { access_params.merge(title: title, description: description) } - let(:service) do - create(:bugzilla_service, :without_properties_callback, properties: properties) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when data are stored in separated fields' do - let(:service) do - create(:bugzilla_service, title: title, description: description, properties: access_params) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when data are stored in both properties and separated fields' do - let(:properties) { access_params.merge(title: 'wrong title', description: 'wrong description') } - let(:service) do - create(:bugzilla_service, :without_properties_callback, title: title, description: description, properties: properties) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when no title & description are set' do - let(:service) do - create(:bugzilla_service, properties: access_params) - end - - it 'returns default values' do - expect(service.title).to eq('Bugzilla') - expect(service.description).to eq('Bugzilla issue tracker') - end - end - end end diff --git a/spec/models/project_services/custom_issue_tracker_service_spec.rb b/spec/models/project_services/custom_issue_tracker_service_spec.rb index e749ea6eacc..f2232ae8e9a 100644 --- a/spec/models/project_services/custom_issue_tracker_service_spec.rb +++ b/spec/models/project_services/custom_issue_tracker_service_spec.rb @@ -31,66 +31,5 @@ describe CustomIssueTrackerService do it { is_expected.not_to validate_presence_of(:issues_url) } it { is_expected.not_to validate_presence_of(:new_issue_url) } end - - context 'title' do - let(:issue_tracker) { described_class.new(properties: {}) } - - it 'sets a default title' do - issue_tracker.title = nil - - expect(issue_tracker.title).to eq('Custom Issue Tracker') - end - - it 'sets the custom title' do - issue_tracker.title = 'test title' - - expect(issue_tracker.title).to eq('test title') - end - end - end - - context 'overriding properties' do - let(:url) { 'http://custom.example.com' } - let(:access_params) do - { project_url: url, issues_url: url, new_issue_url: url } - end - - # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 - context 'when data are stored in properties' do - let(:properties) { access_params.merge(title: title, description: description) } - let(:service) do - create(:custom_issue_tracker_service, :without_properties_callback, properties: properties) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when data are stored in separated fields' do - let(:service) do - create(:custom_issue_tracker_service, title: title, description: description, properties: access_params) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when data are stored in both properties and separated fields' do - let(:properties) { access_params.merge(title: 'wrong title', description: 'wrong description') } - let(:service) do - create(:custom_issue_tracker_service, :without_properties_callback, title: title, description: description, properties: properties) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when no title & description are set' do - let(:service) do - create(:custom_issue_tracker_service, properties: access_params) - end - - it 'returns default values' do - expect(service.title).to eq('Custom Issue Tracker') - expect(service.description).to eq('Custom issue tracker') - end - end end end diff --git a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb index 7f1c6224b7d..ba861aefe3c 100644 --- a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb +++ b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb @@ -51,49 +51,4 @@ describe GitlabIssueTrackerService do end end end - - context 'overriding properties' do - let(:url) { 'http://gitlab.example.com' } - let(:access_params) do - { project_url: url, issues_url: url, new_issue_url: url } - end - - # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 - context 'when data are stored in properties' do - let(:properties) { access_params.merge(title: title, description: description) } - let(:service) do - create(:gitlab_issue_tracker_service, :without_properties_callback, properties: properties) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when data are stored in separated fields' do - let(:service) do - create(:gitlab_issue_tracker_service, title: title, description: description, properties: access_params) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when data are stored in both properties and separated fields' do - let(:properties) { access_params.merge(title: 'wrong title', description: 'wrong description') } - let(:service) do - create(:gitlab_issue_tracker_service, :without_properties_callback, title: title, description: description, properties: properties) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when no title & description are set' do - let(:service) do - create(:gitlab_issue_tracker_service, properties: access_params) - end - - it 'returns default values' do - expect(service.title).to eq('GitLab') - expect(service.description).to eq('GitLab issue tracker') - end - end - end end diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb index 20e85f0fd4b..5e2dd5f3fc9 100644 --- a/spec/models/project_services/jira_service_spec.rb +++ b/spec/models/project_services/jira_service_spec.rb @@ -5,8 +5,6 @@ require 'spec_helper' describe JiraService do include AssetsHelpers - let(:title) { 'custom title' } - let(:description) { 'custom description' } let(:url) { 'http://jira.example.com' } let(:api_url) { 'http://api-jira.example.com' } let(:username) { 'jira-username' } @@ -93,7 +91,6 @@ describe JiraService do let(:params) do { project: create(:project), - title: 'custom title', description: 'custom description', url: url, api_url: api_url, username: username, password: password, jira_issue_transition_id: transition_id @@ -106,19 +103,6 @@ describe JiraService do expect(subject.properties).to be_nil end - it 'sets title correctly' do - service = subject - - expect(service.title).to eq('custom title') - end - - it 'sets service data correctly' do - service = subject - - expect(service.title).to eq('custom title') - expect(service.description).to eq('custom description') - end - it 'stores data in data_fields correcty' do service = subject @@ -209,7 +193,6 @@ describe JiraService do end it 'does not reset password if url "changed" to the same url as before' do - service.title = 'aaaaaa' service.url = 'http://jira.example.com' service.save @@ -318,46 +301,32 @@ describe JiraService do # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 context 'when data are stored in properties' do - let(:properties) { data_params.merge(title: title, description: description) } + let(:properties) { data_params } let!(:service) do create(:jira_service, :without_properties_callback, properties: properties.merge(additional: 'something')) end - it_behaves_like 'issue tracker fields' it_behaves_like 'handles jira fields' end context 'when data are stored in separated fields' do let(:service) do - create(:jira_service, data_params.merge(properties: {}, title: title, description: description)) + create(:jira_service, data_params.merge(properties: {})) end - it_behaves_like 'issue tracker fields' it_behaves_like 'handles jira fields' end context 'when data are stored in both properties and separated fields' do - let(:properties) { data_params.merge(title: title, description: description) } + let(:properties) { data_params } let(:service) do create(:jira_service, :without_properties_callback, active: false, properties: properties).tap do |service| create(:jira_tracker_data, data_params.merge(service: service)) end end - it_behaves_like 'issue tracker fields' it_behaves_like 'handles jira fields' end - - context 'when no title & description are set' do - let(:service) do - create(:jira_service, properties: access_params) - end - - it 'returns default values' do - expect(service.title).to eq('Jira') - expect(service.description).to eq(s_('JiraService|Jira issue tracker')) - end - end end describe '#close_issue' do @@ -704,59 +673,6 @@ describe JiraService do end end - describe 'description and title' do - let(:title) { 'Jira One' } - let(:description) { 'Jira One issue tracker' } - let(:properties) do - { - url: 'http://jira.example.com/web', - username: 'mic', - password: 'password', - title: title, - description: description - } - end - - context 'when it is not set' do - it 'default values are returned' do - service = create(:jira_service) - - expect(service.title).to eq('Jira') - expect(service.description).to eq(s_('JiraService|Jira issue tracker')) - end - end - - context 'when it is set in properties' do - it 'values from properties are returned' do - service = create(:jira_service, :without_properties_callback, properties: properties) - - expect(service.title).to eq(title) - expect(service.description).to eq(description) - end - end - - context 'when it is in title & description fields' do - it 'values from title and description fields are returned' do - service = create(:jira_service, title: title, description: description) - - expect(service.title).to eq(title) - expect(service.description).to eq(description) - end - end - - context 'when it is in both properites & title & description fields' do - it 'values from title and description fields are returned' do - title2 = 'Jira 2' - description2 = 'Jira description 2' - - service = create(:jira_service, title: title2, description: description2, properties: properties) - - expect(service.title).to eq(title2) - expect(service.description).to eq(description2) - end - end - end - describe 'project and issue urls' do context 'when gitlab.yml was initialized' do it 'is prepopulated with the settings' do diff --git a/spec/models/project_services/redmine_service_spec.rb b/spec/models/project_services/redmine_service_spec.rb index 6220d7b1fac..4024de38505 100644 --- a/spec/models/project_services/redmine_service_spec.rb +++ b/spec/models/project_services/redmine_service_spec.rb @@ -50,49 +50,4 @@ describe RedmineService do expect(described_class.reference_pattern.match('#123')[:issue]).to eq('123') end end - - context 'overriding properties' do - let(:url) { 'http://redmine.example.com' } - let(:access_params) do - { project_url: url, issues_url: url, new_issue_url: url } - end - - # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 - context 'when data are stored in properties' do - let(:properties) { access_params.merge(title: title, description: description) } - let(:service) do - create(:redmine_service, :without_properties_callback, properties: properties) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when data are stored in separated fields' do - let(:service) do - create(:redmine_service, title: title, description: description, properties: access_params) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when data are stored in both properties and separated fields' do - let(:properties) { access_params.merge(title: 'wrong title', description: 'wrong description') } - let(:service) do - create(:redmine_service, :without_properties_callback, title: title, description: description, properties: properties) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when no title & description are set' do - let(:service) do - create(:redmine_service, properties: access_params) - end - - it 'returns default values' do - expect(service.title).to eq('Redmine') - expect(service.description).to eq('Redmine issue tracker') - end - end - end end diff --git a/spec/models/project_services/youtrack_service_spec.rb b/spec/models/project_services/youtrack_service_spec.rb index b8fff635e99..c82a3cc1bcf 100644 --- a/spec/models/project_services/youtrack_service_spec.rb +++ b/spec/models/project_services/youtrack_service_spec.rb @@ -42,49 +42,4 @@ describe YoutrackService do expect(described_class.reference_pattern.match('yt-123')[:issue]).to eq('yt-123') end end - - context 'overriding properties' do - let(:url) { 'http://youtrack.example.com' } - let(:access_params) do - { project_url: url, issues_url: url, new_issue_url: url } - end - - # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 - context 'when data are stored in properties' do - let(:properties) { access_params.merge(title: title, description: description) } - let(:service) do - create(:youtrack_service, :without_properties_callback, properties: properties) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when data are stored in separated fields' do - let(:service) do - create(:youtrack_service, title: title, description: description, properties: access_params) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when data are stored in both properties and separated fields' do - let(:properties) { access_params.merge(title: 'wrong title', description: 'wrong description') } - let(:service) do - create(:youtrack_service, :without_properties_callback, title: title, description: description, properties: properties) - end - - it_behaves_like 'issue tracker fields' - end - - context 'when no title & description are set' do - let(:service) do - create(:youtrack_service, properties: access_params) - end - - it 'returns default values' do - expect(service.title).to eq('YouTrack') - expect(service.description).to eq(s_('IssueTracker|YouTrack issue tracker')) - end - end - end end diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb index ca6101364aa..8c914c6b74c 100644 --- a/spec/models/service_spec.rb +++ b/spec/models/service_spec.rb @@ -304,8 +304,6 @@ RSpec.describe Service do end describe 'build issue tracker from an integration' do - let(:title) { 'custom title' } - let(:description) { 'custom description' } let(:url) { 'http://jira.example.com' } let(:api_url) { 'http://api-jira.example.com' } let(:username) { 'jira-username' } @@ -322,8 +320,6 @@ RSpec.describe Service do service = described_class.build_from_integration(project.id, integration) expect(service).to be_active - expect(service.title).to eq(title) - expect(service.description).to eq(description) expect(service.url).to eq(url) expect(service.api_url).to eq(api_url) expect(service.username).to eq(username) @@ -335,7 +331,7 @@ RSpec.describe Service do # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 context 'when data are stored in properties' do - let(:properties) { data_params.merge(title: title, description: description) } + let(:properties) { data_params } let!(:integration) do create(:jira_service, :without_properties_callback, template: true, properties: properties.merge(additional: 'something')) end @@ -345,14 +341,14 @@ RSpec.describe Service do context 'when data are stored in separated fields' do let(:integration) do - create(:jira_service, :template, data_params.merge(properties: {}, title: title, description: description)) + create(:jira_service, :template, data_params.merge(properties: {})) end it_behaves_like 'service creation from an integration' end context 'when data are stored in both properties and separated fields' do - let(:properties) { data_params.merge(title: title, description: description) } + let(:properties) { data_params } let(:integration) do create(:jira_service, :without_properties_callback, active: true, template: true, properties: properties).tap do |service| create(:jira_tracker_data, data_params.merge(service: service)) @@ -514,7 +510,6 @@ RSpec.describe Service do let(:service) do GitlabIssueTrackerService.create( project: create(:project), - title: 'random title', project_url: 'http://gitlab.example.com' ) end @@ -523,10 +518,6 @@ RSpec.describe Service do expect { service }.not_to raise_error end - it 'sets title correctly' do - expect(service.title).to eq('random title') - end - it 'sets data correctly' do expect(service.data_fields.project_url).to eq('http://gitlab.example.com') end diff --git a/spec/requests/api/graphql/project/jira_projects_spec.rb b/spec/requests/api/graphql/project/jira_projects_spec.rb index d67c89f18c9..4d44d55f2de 100644 --- a/spec/requests/api/graphql/project/jira_projects_spec.rb +++ b/spec/requests/api/graphql/project/jira_projects_spec.rb @@ -80,34 +80,6 @@ describe 'query Jira projects' do it_behaves_like 'fetches first project' end - - context 'with before cursor' do - let(:projects_query) { 'projects(before: "Mg==", first: 1)' } - - it_behaves_like 'fetches first project' - end - - context 'with after cursor' do - let(:projects_query) { 'projects(after: "MA==", first: 1)' } - - it_behaves_like 'fetches first project' - end - end - - context 'with valid but inexistent after cursor' do - let(:projects_query) { 'projects(after: "MTk==")' } - - it 'retuns empty list of jira projects' do - expect(jira_projects.size).to eq(0) - end - end - - context 'with invalid after cursor' do - let(:projects_query) { 'projects(after: "invalid==")' } - - it 'treats the invalid cursor as no cursor and returns list of jira projects' do - expect(jira_projects.size).to eq(2) - end end end end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 7ae382d8aae..966d6f7b106 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -878,4 +878,12 @@ describe 'project routing' do expect(get('/gitlab/gitlabhq/-/design_management/designs/1/c6f00aa50b80887ada30a6fe517670be9f8f9ece/resized_image/small')).to route_to('application#route_not_found', unmatched_route: 'gitlab/gitlabhq/-/design_management/designs/1/c6f00aa50b80887ada30a6fe517670be9f8f9ece/resized_image/small') end end + + describe Projects::Snippets::BlobsController, "routing" do + it "to #raw" do + expect(get('/gitlab/gitlabhq/-/snippets/1/raw/master/lib/version.rb')) + .to route_to('projects/snippets/blobs#raw', namespace_id: 'gitlab', + project_id: 'gitlabhq', snippet_id: '1', ref: 'master', path: 'lib/version.rb') + end + end end diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb index 9c3d17f7d8f..5424f67f445 100644 --- a/spec/routing/routing_spec.rb +++ b/spec/routing/routing_spec.rb @@ -368,3 +368,10 @@ describe AutocompleteController, 'routing' do expect(get("/autocomplete/award_emojis")).to route_to('autocomplete#award_emojis') end end + +describe Snippets::BlobsController, "routing" do + it "to #raw" do + expect(get('/-/snippets/1/raw/master/lib/version.rb')) + .to route_to('snippets/blobs#raw', snippet_id: '1', ref: 'master', path: 'lib/version.rb') + end +end diff --git a/spec/services/gpg_keys/destroy_service_spec.rb b/spec/services/gpg_keys/destroy_service_spec.rb new file mode 100644 index 00000000000..82c7ab7adaa --- /dev/null +++ b/spec/services/gpg_keys/destroy_service_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe GpgKeys::DestroyService do + let(:user) { create(:user) } + + subject { described_class.new(user) } + + it 'destroys the GPG key' do + gpg_key = create(:gpg_key) + + expect { subject.execute(gpg_key) }.to change(GpgKey, :count).by(-1) + end +end diff --git a/spec/services/jira/requests/projects_spec.rb b/spec/services/jira/requests/projects_spec.rb index f7b9aa7c00c..42d09da138b 100644 --- a/spec/services/jira/requests/projects_spec.rb +++ b/spec/services/jira/requests/projects_spec.rb @@ -32,14 +32,6 @@ describe Jira::Requests::Projects do end context 'with jira_service' do - context 'when limit is invalid' do - let(:params) { { limit: 0 } } - - it 'returns a paylod with no projects returned' do - expect(subject.payload[:projects]).to be_empty - end - end - context 'when validations and params are ok' do let(:client) { double(options: { site: 'https://jira.example.com' }) } @@ -60,7 +52,7 @@ describe Jira::Requests::Projects do context 'when the request does not return any values' do before do - expect(client).to receive(:get).and_return({ 'someKey' => 'value' }) + expect(client).to receive(:get).and_return([]) end it 'returns a paylod with no projects returned' do @@ -74,19 +66,15 @@ describe Jira::Requests::Projects do context 'when the request returns values' do before do - expect(client).to receive(:get).and_return( - { 'values' => %w(project1 project2), 'isLast' => false } - ) - expect(JIRA::Resource::Project).to receive(:build).with(client, 'project1').and_return('jira_project1') - expect(JIRA::Resource::Project).to receive(:build).with(client, 'project2').and_return('jira_project2') + expect(client).to receive(:get).and_return([{ "key" => 'project1' }, { "key" => 'project2' }]) end it 'returns a paylod with jira projets' do payload = subject.payload expect(subject.success?).to be_truthy - expect(payload[:projects]).to eq(%w(jira_project1 jira_project2)) - expect(payload[:is_last]).to be_falsey + expect(payload[:projects].map(&:key)).to eq(%w(project1 project2)) + expect(payload[:is_last]).to be_truthy end end end diff --git a/spec/support/helpers/jira_service_helper.rb b/spec/support/helpers/jira_service_helper.rb index 198bedfe3bc..9072c41fe66 100644 --- a/spec/support/helpers/jira_service_helper.rb +++ b/spec/support/helpers/jira_service_helper.rb @@ -5,14 +5,13 @@ module JiraServiceHelper JIRA_API = JIRA_URL + "/rest/api/2" def jira_service_settings - title = "Jira tracker" url = JIRA_URL username = 'jira-user' password = 'my-secret-password' jira_issue_transition_id = '1' jira_tracker.update( - title: title, url: url, username: username, password: password, + url: url, username: username, password: password, jira_issue_transition_id: jira_issue_transition_id, active: true ) end diff --git a/spec/support/helpers/snippet_helpers.rb b/spec/support/helpers/snippet_helpers.rb new file mode 100644 index 00000000000..ead18792efb --- /dev/null +++ b/spec/support/helpers/snippet_helpers.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module SnippetHelpers + def sign_in_as(user) + sign_in(public_send(user)) if user + end +end diff --git a/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb b/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb index f0722beb3ed..3125f8ba315 100644 --- a/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb +++ b/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb @@ -74,6 +74,48 @@ shared_context 'jira projects request context' do }' end + let_it_be(:all_jira_projects_json) do + '[{ + "expand": "description,lead,issueTypes,url,projectKeys,permissions,insight", + "self": "https://gitlab-jira.atlassian.net/rest/api/2/project/10000", + "id": "10000", + "key": "EX", + "name": "Example", + "avatarUrls": { + "48x48": "https://gitlab-jira.atlassian.net/secure/projectavatar?pid=10000&avatarId=10425", + "24x24": "https://gitlab-jira.atlassian.net/secure/projectavatar?size=small&s=small&pid=10000&avatarId=10425", + "16x16": "https://gitlab-jira.atlassian.net/secure/projectavatar?size=xsmall&s=xsmall&pid=10000&avatarId=10425", + "32x32": "https://gitlab-jira.atlassian.net/secure/projectavatar?size=medium&s=medium&pid=10000&avatarId=10425" + }, + "projectTypeKey": "software", + "simplified": false, + "style": "classic", + "isPrivate": false, + "properties": { + } + }, + { + "expand": "description,lead,issueTypes,url,projectKeys,permissions,insight", + "self": "https://gitlab-jira.atlassian.net/rest/api/2/project/10001", + "id": "10001", + "key": "ABC", + "name": "Alphabetical", + "avatarUrls": { + "48x48": "https://gitlab-jira.atlassian.net/secure/projectavatar?pid=10001&avatarId=10405", + "24x24": "https://gitlab-jira.atlassian.net/secure/projectavatar?size=small&s=small&pid=10001&avatarId=10405", + "16x16": "https://gitlab-jira.atlassian.net/secure/projectavatar?size=xsmall&s=xsmall&pid=10001&avatarId=10405", + "32x32": "https://gitlab-jira.atlassian.net/secure/projectavatar?size=medium&s=medium&pid=10001&avatarId=10405" + }, + "projectTypeKey": "software", + "simplified": true, + "style": "next-gen", + "isPrivate": false, + "properties": { + }, + "entityId": "14935009-f8aa-481e-94bc-f7251f320b0e", + "uuid": "14935009-f8aa-481e-94bc-f7251f320b0e" + }]' + end let_it_be(:empty_jira_projects_json) do '{ "self": "https://your-domain.atlassian.net/rest/api/2/project/search?startAt=0&maxResults=2", @@ -86,10 +128,32 @@ shared_context 'jira projects request context' do }' end + let(:server_info_json) do + '{ + "baseUrl": "https://gitlab-jira.atlassian.net", + "version": "1001.0.0-SNAPSHOT", + "versionNumbers": [ + 1001, + 0, + 0 + ], + "deploymentType": "Cloud", + "buildNumber": 100128, + "buildDate": "2020-06-03T01:58:44.000-0700", + "serverTime": "2020-06-04T06:15:13.686-0700", + "scmInfo": "e736ab140ddb281c7cf5dcf9062c9ce2c08b3c1c", + "serverTitle": "Jira", + "defaultLocale": { + "locale": "en_US" + } + }' + end + let(:test_url) { "#{url}/rest/api/2/project/search?maxResults=50&query=&startAt=0" } let(:start_at_20_url) { "#{url}/rest/api/2/project/search?maxResults=50&query=&startAt=20" } let(:start_at_1_url) { "#{url}/rest/api/2/project/search?maxResults=50&query=&startAt=1" } let(:max_results_1_url) { "#{url}/rest/api/2/project/search?maxResults=1&query=&startAt=0" } + let(:all_projects_url) { "#{url}/rest/api/2/project" } before do WebMock.stub_request(:get, test_url).with(basic_auth: [username, password]) @@ -100,5 +164,9 @@ shared_context 'jira projects request context' do .to_return(body: jira_projects_json, headers: { "Content-Type": "application/json" }) WebMock.stub_request(:get, max_results_1_url).with(basic_auth: [username, password]) .to_return(body: jira_projects_json, headers: { "Content-Type": "application/json" }) + WebMock.stub_request(:get, all_projects_url).with(basic_auth: [username, password]) + .to_return(body: all_jira_projects_json, headers: { "Content-Type": "application/json" }) + WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo') + .to_return(status: 200, body: server_info_json, headers: {}) end end diff --git a/spec/support/shared_examples/controllers/snippet_blob_shared_examples.rb b/spec/support/shared_examples/controllers/snippet_blob_shared_examples.rb new file mode 100644 index 00000000000..c3e8f807afb --- /dev/null +++ b/spec/support/shared_examples/controllers/snippet_blob_shared_examples.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'raw snippet blob' do + context 'with valid params' do + before do + subject + end + + it 'delivers file with correct Workhorse headers' do + expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8') + expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq 'true' + expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:') + end + + it 'responds with status 200' do + expect(response).to have_gitlab_http_status(:ok) + end + end + + context 'with invalid file path' do + let(:filepath) { 'doesnotexist' } + + it_behaves_like 'returning response status', :not_found + end + + context 'with invalid ref' do + let(:ref) { 'doesnotexist' } + + it_behaves_like 'returning response status', :not_found + end + + it_behaves_like 'content disposition headers' +end + +RSpec.shared_examples 'raw snippet without repository' do |unauthorized_status| + context 'when authorized' do + it 'returns a 422' do + subject + + expect(response).to have_gitlab_http_status(:unprocessable_entity) + end + end + + context 'when unauthorized' do + let(:visibility) { :private } + + it_behaves_like 'returning response status', unauthorized_status + end +end diff --git a/spec/support/shared_examples/models/services_fields_shared_examples.rb b/spec/support/shared_examples/models/services_fields_shared_examples.rb deleted file mode 100644 index cb36f74460d..00000000000 --- a/spec/support/shared_examples/models/services_fields_shared_examples.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -RSpec.shared_examples 'issue tracker fields' do - let(:title) { 'custom title' } - let(:description) { 'custom description' } - let(:url) { 'http://issue_tracker.example.com' } - - context 'when data are stored in the properties' do - describe '#update' do - before do - service.update(title: 'new_title', description: 'new description') - end - - it 'removes title and description from properties' do - expect(service.reload.properties).not_to include('title', 'description') - end - - it 'stores title & description in services table' do - expect(service.read_attribute(:title)).to eq('new_title') - expect(service.read_attribute(:description)).to eq('new description') - end - end - - describe 'reading fields' do - it 'returns correct values' do - expect(service.title).to eq(title) - expect(service.description).to eq(description) - end - end - end -end |