From 0f2776287a7d9b0fde9ff54ef8d9f74e2f844a09 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 16 Dec 2016 15:08:10 +0100 Subject: Use Slack::Notifier::LinkFormatter to convert markdown links to slack compat --- .../support/chat_slash_commands_shared_examples.rb | 97 ++++++ ...ack_mattermost_notifications_shared_examples.rb | 328 +++++++++++++++++++++ spec/support/slack_mattermost_shared_examples.rb | 328 --------------------- 3 files changed, 425 insertions(+), 328 deletions(-) create mode 100644 spec/support/chat_slash_commands_shared_examples.rb create mode 100644 spec/support/slack_mattermost_notifications_shared_examples.rb delete mode 100644 spec/support/slack_mattermost_shared_examples.rb (limited to 'spec/support') diff --git a/spec/support/chat_slash_commands_shared_examples.rb b/spec/support/chat_slash_commands_shared_examples.rb new file mode 100644 index 00000000000..96130b45235 --- /dev/null +++ b/spec/support/chat_slash_commands_shared_examples.rb @@ -0,0 +1,97 @@ +RSpec.shared_examples 'chat slash commands' do + describe "Associations" do + it { is_expected.to respond_to :token } + it { is_expected.to have_many :chat_names } + end + + describe '#valid_token?' do + subject { described_class.new } + + context 'when the token is empty' do + it 'is false' do + expect(subject.valid_token?('wer')).to be_falsey + end + end + + context 'when there is a token' do + before do + subject.token = '123' + end + + it 'accepts equal tokens' do + expect(subject.valid_token?('123')).to be_truthy + end + end + end + + describe '#trigger' do + subject { described_class.new } + + context 'no token is passed' do + let(:params) { Hash.new } + + it 'returns nil' do + expect(subject.trigger(params)).to be_nil + end + end + + context 'with a token passed' do + let(:project) { create(:empty_project) } + let(:params) { { token: 'token' } } + + before do + allow(subject).to receive(:token).and_return('token') + end + + context 'no user can be found' do + context 'when no url can be generated' do + it 'responds with the authorize url' do + response = subject.trigger(params) + + expect(response[:response_type]).to eq :ephemeral + expect(response[:text]).to start_with ":sweat_smile: Couldn't identify you" + end + end + + context 'when an auth url can be generated' do + let(:params) do + { + team_domain: 'http://domain.tld', + team_id: 'T3423423', + user_id: 'U234234', + user_name: 'mepmep', + token: 'token' + } + end + + let(:service) do + project.create_mattermost_slash_commands_service( + properties: { token: 'token' } + ) + end + + it 'generates the url' do + response = service.trigger(params) + + expect(response[:text]).to start_with(':wave: Hi there!') + end + end + end + + context 'when the user is authenticated' do + let!(:chat_name) { create(:chat_name, service: subject) } + let(:params) { { token: 'token', team_id: chat_name.team_id, user_id: chat_name.chat_id } } + + subject do + described_class.create(project: project, properties: { token: 'token' }) + end + + it 'triggers the command' do + expect_any_instance_of(Gitlab::ChatCommands::Command).to receive(:execute) + + subject.trigger(params) + end + end + end + end +end diff --git a/spec/support/slack_mattermost_notifications_shared_examples.rb b/spec/support/slack_mattermost_notifications_shared_examples.rb new file mode 100644 index 00000000000..8582aea5fe5 --- /dev/null +++ b/spec/support/slack_mattermost_notifications_shared_examples.rb @@ -0,0 +1,328 @@ +Dir[Rails.root.join("app/models/project_services/chat_message/*.rb")].each { |f| require f } + +RSpec.shared_examples 'slack or mattermost notifications' do + let(:chat_service) { described_class.new } + let(:webhook_url) { 'https://example.gitlab.com/' } + + describe "Associations" do + it { is_expected.to belong_to :project } + it { is_expected.to have_one :service_hook } + end + + describe 'Validations' do + context 'when service is active' do + before { subject.active = true } + + it { is_expected.to validate_presence_of(:webhook) } + it_behaves_like 'issue tracker service URL attribute', :webhook + end + + context 'when service is inactive' do + before { subject.active = false } + + it { is_expected.not_to validate_presence_of(:webhook) } + end + end + + describe "#execute" do + let(:user) { create(:user) } + let(:project) { create(:project) } + let(:username) { 'slack_username' } + let(:channel) { 'slack_channel' } + + let(:push_sample_data) do + Gitlab::DataBuilder::Push.build_sample(project, user) + end + + before do + allow(chat_service).to receive_messages( + project: project, + project_id: project.id, + service_hook: true, + webhook: webhook_url + ) + + WebMock.stub_request(:post, webhook_url) + + opts = { + title: 'Awesome issue', + description: 'please fix' + } + + issue_service = Issues::CreateService.new(project, user, opts) + @issue = issue_service.execute + @issues_sample_data = issue_service.hook_data(@issue, 'open') + + opts = { + title: 'Awesome merge_request', + description: 'please fix', + source_branch: 'feature', + target_branch: 'master' + } + merge_service = MergeRequests::CreateService.new(project, + user, opts) + @merge_request = merge_service.execute + @merge_sample_data = merge_service.hook_data(@merge_request, + 'open') + + opts = { + title: "Awesome wiki_page", + content: "Some text describing some thing or another", + format: "md", + message: "user created page: Awesome wiki_page" + } + + wiki_page_service = WikiPages::CreateService.new(project, user, opts) + @wiki_page = wiki_page_service.execute + @wiki_page_sample_data = wiki_page_service.hook_data(@wiki_page, 'create') + end + + it "calls Slack/Mattermost API for push events" do + chat_service.execute(push_sample_data) + + expect(WebMock).to have_requested(:post, webhook_url).once + end + + it "calls Slack/Mattermost API for issue events" do + chat_service.execute(@issues_sample_data) + + expect(WebMock).to have_requested(:post, webhook_url).once + end + + it "calls Slack/Mattermost API for merge requests events" do + chat_service.execute(@merge_sample_data) + + expect(WebMock).to have_requested(:post, webhook_url).once + end + + it "calls Slack/Mattermost API for wiki page events" do + chat_service.execute(@wiki_page_sample_data) + + expect(WebMock).to have_requested(:post, webhook_url).once + end + + it 'uses the username as an option for slack when configured' do + allow(chat_service).to receive(:username).and_return(username) + + expect(Slack::Notifier).to receive(:new). + with(webhook_url, username: username, channel: chat_service.default_channel). + and_return( + double(:slack_service).as_null_object + ) + + chat_service.execute(push_sample_data) + end + + it 'uses the channel as an option when it is configured' do + allow(chat_service).to receive(:channel).and_return(channel) + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: channel). + and_return( + double(:slack_service).as_null_object + ) + chat_service.execute(push_sample_data) + end + + context "event channels" do + it "uses the right channel for push event" do + chat_service.update_attributes(push_channel: "random") + + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: "random"). + and_return( + double(:slack_service).as_null_object + ) + + chat_service.execute(push_sample_data) + end + + it "uses the right channel for merge request event" do + chat_service.update_attributes(merge_request_channel: "random") + + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: "random"). + and_return( + double(:slack_service).as_null_object + ) + + chat_service.execute(@merge_sample_data) + end + + it "uses the right channel for issue event" do + chat_service.update_attributes(issue_channel: "random") + + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: "random"). + and_return( + double(:slack_service).as_null_object + ) + + chat_service.execute(@issues_sample_data) + end + + it "uses the right channel for wiki event" do + chat_service.update_attributes(wiki_page_channel: "random") + + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: "random"). + and_return( + double(:slack_service).as_null_object + ) + + chat_service.execute(@wiki_page_sample_data) + end + + context "note event" do + let(:issue_note) do + create(:note_on_issue, project: project, note: "issue note") + end + + it "uses the right channel" do + chat_service.update_attributes(note_channel: "random") + + note_data = Gitlab::DataBuilder::Note.build(issue_note, user) + + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: "random"). + and_return( + double(:slack_service).as_null_object + ) + + chat_service.execute(note_data) + end + end + end + end + + describe "Note events" do + let(:user) { create(:user) } + let(:project) { create(:project, creator_id: user.id) } + + before do + allow(chat_service).to receive_messages( + project: project, + project_id: project.id, + service_hook: true, + webhook: webhook_url + ) + + WebMock.stub_request(:post, webhook_url) + end + + context 'when commit comment event executed' do + let(:commit_note) do + create(:note_on_commit, author: user, + project: project, + commit_id: project.repository.commit.id, + note: 'a comment on a commit') + end + + it "calls Slack/Mattermost API for commit comment events" do + data = Gitlab::DataBuilder::Note.build(commit_note, user) + chat_service.execute(data) + + expect(WebMock).to have_requested(:post, webhook_url).once + end + end + + context 'when merge request comment event executed' do + let(:merge_request_note) do + create(:note_on_merge_request, project: project, + note: "merge request note") + end + + it "calls Slack API for merge request comment events" do + data = Gitlab::DataBuilder::Note.build(merge_request_note, user) + chat_service.execute(data) + + expect(WebMock).to have_requested(:post, webhook_url).once + end + end + + context 'when issue comment event executed' do + let(:issue_note) do + create(:note_on_issue, project: project, note: "issue note") + end + + it "calls Slack API for issue comment events" do + data = Gitlab::DataBuilder::Note.build(issue_note, user) + chat_service.execute(data) + + expect(WebMock).to have_requested(:post, webhook_url).once + end + end + + context 'when snippet comment event executed' do + let(:snippet_note) do + create(:note_on_project_snippet, project: project, + note: "snippet note") + end + + it "calls Slack API for snippet comment events" do + data = Gitlab::DataBuilder::Note.build(snippet_note, user) + chat_service.execute(data) + + expect(WebMock).to have_requested(:post, webhook_url).once + end + end + end + + describe 'Pipeline events' do + let(:user) { create(:user) } + let(:project) { create(:project) } + + let(:pipeline) do + create(:ci_pipeline, + project: project, status: status, + sha: project.commit.sha, ref: project.default_branch) + end + + before do + allow(chat_service).to receive_messages( + project: project, + service_hook: true, + webhook: webhook_url + ) + end + + shared_examples 'call Slack/Mattermost API' do + before do + WebMock.stub_request(:post, webhook_url) + end + + it 'calls Slack/Mattermost API for pipeline events' do + data = Gitlab::DataBuilder::Pipeline.build(pipeline) + chat_service.execute(data) + + expect(WebMock).to have_requested(:post, webhook_url).once + end + end + + context 'with failed pipeline' do + let(:status) { 'failed' } + + it_behaves_like 'call Slack/Mattermost API' + end + + context 'with succeeded pipeline' do + let(:status) { 'success' } + + context 'with default to notify_only_broken_pipelines' do + it 'does not call Slack/Mattermost API for pipeline events' do + data = Gitlab::DataBuilder::Pipeline.build(pipeline) + result = chat_service.execute(data) + + expect(result).to be_falsy + end + end + + context 'with setting notify_only_broken_pipelines to false' do + before do + chat_service.notify_only_broken_pipelines = false + end + + it_behaves_like 'call Slack/Mattermost API' + end + end + end +end diff --git a/spec/support/slack_mattermost_shared_examples.rb b/spec/support/slack_mattermost_shared_examples.rb deleted file mode 100644 index 56d4965f74d..00000000000 --- a/spec/support/slack_mattermost_shared_examples.rb +++ /dev/null @@ -1,328 +0,0 @@ -Dir[Rails.root.join("app/models/project_services/chat_message/*.rb")].each { |f| require f } - -RSpec.shared_examples 'slack or mattermost' do - let(:chat_service) { described_class.new } - let(:webhook_url) { 'https://example.gitlab.com/' } - - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe 'Validations' do - context 'when service is active' do - before { subject.active = true } - - it { is_expected.to validate_presence_of(:webhook) } - it_behaves_like 'issue tracker service URL attribute', :webhook - end - - context 'when service is inactive' do - before { subject.active = false } - - it { is_expected.not_to validate_presence_of(:webhook) } - end - end - - describe "#execute" do - let(:user) { create(:user) } - let(:project) { create(:project) } - let(:username) { 'slack_username' } - let(:channel) { 'slack_channel' } - - let(:push_sample_data) do - Gitlab::DataBuilder::Push.build_sample(project, user) - end - - before do - allow(chat_service).to receive_messages( - project: project, - project_id: project.id, - service_hook: true, - webhook: webhook_url - ) - - WebMock.stub_request(:post, webhook_url) - - opts = { - title: 'Awesome issue', - description: 'please fix' - } - - issue_service = Issues::CreateService.new(project, user, opts) - @issue = issue_service.execute - @issues_sample_data = issue_service.hook_data(@issue, 'open') - - opts = { - title: 'Awesome merge_request', - description: 'please fix', - source_branch: 'feature', - target_branch: 'master' - } - merge_service = MergeRequests::CreateService.new(project, - user, opts) - @merge_request = merge_service.execute - @merge_sample_data = merge_service.hook_data(@merge_request, - 'open') - - opts = { - title: "Awesome wiki_page", - content: "Some text describing some thing or another", - format: "md", - message: "user created page: Awesome wiki_page" - } - - wiki_page_service = WikiPages::CreateService.new(project, user, opts) - @wiki_page = wiki_page_service.execute - @wiki_page_sample_data = wiki_page_service.hook_data(@wiki_page, 'create') - end - - it "calls Slack/Mattermost API for push events" do - chat_service.execute(push_sample_data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - - it "calls Slack/Mattermost API for issue events" do - chat_service.execute(@issues_sample_data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - - it "calls Slack/Mattermost API for merge requests events" do - chat_service.execute(@merge_sample_data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - - it "calls Slack/Mattermost API for wiki page events" do - chat_service.execute(@wiki_page_sample_data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - - it 'uses the username as an option for slack when configured' do - allow(chat_service).to receive(:username).and_return(username) - - expect(Slack::Notifier).to receive(:new). - with(webhook_url, username: username, channel: chat_service.default_channel). - and_return( - double(:slack_service).as_null_object - ) - - chat_service.execute(push_sample_data) - end - - it 'uses the channel as an option when it is configured' do - allow(chat_service).to receive(:channel).and_return(channel) - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: channel). - and_return( - double(:slack_service).as_null_object - ) - chat_service.execute(push_sample_data) - end - - context "event channels" do - it "uses the right channel for push event" do - chat_service.update_attributes(push_channel: "random") - - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: "random"). - and_return( - double(:slack_service).as_null_object - ) - - chat_service.execute(push_sample_data) - end - - it "uses the right channel for merge request event" do - chat_service.update_attributes(merge_request_channel: "random") - - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: "random"). - and_return( - double(:slack_service).as_null_object - ) - - chat_service.execute(@merge_sample_data) - end - - it "uses the right channel for issue event" do - chat_service.update_attributes(issue_channel: "random") - - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: "random"). - and_return( - double(:slack_service).as_null_object - ) - - chat_service.execute(@issues_sample_data) - end - - it "uses the right channel for wiki event" do - chat_service.update_attributes(wiki_page_channel: "random") - - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: "random"). - and_return( - double(:slack_service).as_null_object - ) - - chat_service.execute(@wiki_page_sample_data) - end - - context "note event" do - let(:issue_note) do - create(:note_on_issue, project: project, note: "issue note") - end - - it "uses the right channel" do - chat_service.update_attributes(note_channel: "random") - - note_data = Gitlab::DataBuilder::Note.build(issue_note, user) - - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: "random"). - and_return( - double(:slack_service).as_null_object - ) - - chat_service.execute(note_data) - end - end - end - end - - describe "Note events" do - let(:user) { create(:user) } - let(:project) { create(:project, creator_id: user.id) } - - before do - allow(chat_service).to receive_messages( - project: project, - project_id: project.id, - service_hook: true, - webhook: webhook_url - ) - - WebMock.stub_request(:post, webhook_url) - end - - context 'when commit comment event executed' do - let(:commit_note) do - create(:note_on_commit, author: user, - project: project, - commit_id: project.repository.commit.id, - note: 'a comment on a commit') - end - - it "calls Slack/Mattermost API for commit comment events" do - data = Gitlab::DataBuilder::Note.build(commit_note, user) - chat_service.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - end - - context 'when merge request comment event executed' do - let(:merge_request_note) do - create(:note_on_merge_request, project: project, - note: "merge request note") - end - - it "calls Slack API for merge request comment events" do - data = Gitlab::DataBuilder::Note.build(merge_request_note, user) - chat_service.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - end - - context 'when issue comment event executed' do - let(:issue_note) do - create(:note_on_issue, project: project, note: "issue note") - end - - it "calls Slack API for issue comment events" do - data = Gitlab::DataBuilder::Note.build(issue_note, user) - chat_service.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - end - - context 'when snippet comment event executed' do - let(:snippet_note) do - create(:note_on_project_snippet, project: project, - note: "snippet note") - end - - it "calls Slack API for snippet comment events" do - data = Gitlab::DataBuilder::Note.build(snippet_note, user) - chat_service.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - end - end - - describe 'Pipeline events' do - let(:user) { create(:user) } - let(:project) { create(:project) } - - let(:pipeline) do - create(:ci_pipeline, - project: project, status: status, - sha: project.commit.sha, ref: project.default_branch) - end - - before do - allow(chat_service).to receive_messages( - project: project, - service_hook: true, - webhook: webhook_url - ) - end - - shared_examples 'call Slack/Mattermost API' do - before do - WebMock.stub_request(:post, webhook_url) - end - - it 'calls Slack/Mattermost API for pipeline events' do - data = Gitlab::DataBuilder::Pipeline.build(pipeline) - chat_service.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - end - - context 'with failed pipeline' do - let(:status) { 'failed' } - - it_behaves_like 'call Slack/Mattermost API' - end - - context 'with succeeded pipeline' do - let(:status) { 'success' } - - context 'with default to notify_only_broken_pipelines' do - it 'does not call Slack/Mattermost API for pipeline events' do - data = Gitlab::DataBuilder::Pipeline.build(pipeline) - result = chat_service.execute(data) - - expect(result).to be_falsy - end - end - - context 'with setting notify_only_broken_pipelines to false' do - before do - chat_service.notify_only_broken_pipelines = false - end - - it_behaves_like 'call Slack/Mattermost API' - end - end - end -end -- cgit v1.2.1 From 298d05a5c3cc3c2f1daa4d77c45f9c90b53248df Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 19 Dec 2016 15:40:06 +0100 Subject: Improve after feedback --- spec/support/chat_slash_commands_shared_examples.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec/support') diff --git a/spec/support/chat_slash_commands_shared_examples.rb b/spec/support/chat_slash_commands_shared_examples.rb index 96130b45235..4dfa29849ee 100644 --- a/spec/support/chat_slash_commands_shared_examples.rb +++ b/spec/support/chat_slash_commands_shared_examples.rb @@ -1,4 +1,4 @@ -RSpec.shared_examples 'chat slash commands' do +RSpec.shared_examples 'chat slash commands service' do describe "Associations" do it { is_expected.to respond_to :token } it { is_expected.to have_many :chat_names } -- cgit v1.2.1 From 103114e3d73819f76bed9d8ad1bbdb8964875579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Thu, 15 Dec 2016 17:31:14 +0100 Subject: Rename Gogs to Gitea, DRY the controller and improve views MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- .../githubish_import_controller_shared_context.rb | 10 + .../githubish_import_controller_shared_examples.rb | 228 +++++++++++++++++++++ spec/support/import_spec_helper.rb | 4 + 3 files changed, 242 insertions(+) create mode 100644 spec/support/githubish_import_controller_shared_context.rb create mode 100644 spec/support/githubish_import_controller_shared_examples.rb (limited to 'spec/support') diff --git a/spec/support/githubish_import_controller_shared_context.rb b/spec/support/githubish_import_controller_shared_context.rb new file mode 100644 index 00000000000..e71994edec6 --- /dev/null +++ b/spec/support/githubish_import_controller_shared_context.rb @@ -0,0 +1,10 @@ +shared_context 'a GitHub-ish import controller' do + let(:user) { create(:user) } + let(:token) { "asdasd12345" } + let(:access_params) { { github_access_token: token } } + + before do + sign_in(user) + allow(controller).to receive(:"#{provider}_import_enabled?").and_return(true) + end +end diff --git a/spec/support/githubish_import_controller_shared_examples.rb b/spec/support/githubish_import_controller_shared_examples.rb new file mode 100644 index 00000000000..aa2d8aed0bd --- /dev/null +++ b/spec/support/githubish_import_controller_shared_examples.rb @@ -0,0 +1,228 @@ +# Specifications for behavior common to all objects with an email attribute. +# Takes a list of email-format attributes and requires: +# - subject { "the object with a attribute= setter" } +# Note: You have access to `email_value` which is the email address value +# being currently tested). + +shared_examples 'a GitHub-ish import controller: POST personal_access_token' do + let(:status_import_url) { public_send("status_import_#{provider}_url") } + + it "updates access token" do + token = 'asdfasdf9876' + + allow_any_instance_of(Gitlab::GithubImport::Client). + to receive(:user).and_return(true) + + post :personal_access_token, personal_access_token: token + + expect(session[:access_token]).to eq(token) + expect(controller).to redirect_to(status_import_url) + end +end + +shared_examples 'a GitHub-ish import controller: GET new' do + let(:status_import_url) { public_send("status_import_#{provider}_url") } + + it "redirects to status if we already have a token" do + assign_session_token + allow(controller).to receive(:logged_in_with_provider?).and_return(false) + + get :new + + expect(controller).to redirect_to(status_import_url) + end + + it "renders the :new page if no token is present in session" do + get :new + + expect(response).to render_template(:new) + end +end + +shared_examples 'a GitHub-ish import controller: GET status' do + let(:new_import_url) { public_send("new_import_#{provider}_url") } + let(:user) { create(:user) } + let(:repo) { OpenStruct.new(login: 'vim', full_name: 'asd/vim') } + let(:org) { OpenStruct.new(login: 'company') } + let(:org_repo) { OpenStruct.new(login: 'company', full_name: 'company/repo') } + let(:extra_assign_expectations) { {} } + + before do + assign_session_token + end + + it "assigns variables" do + project = create(:empty_project, import_type: provider, creator_id: user.id) + stub_client(repos: [repo, org_repo], orgs: [org], org_repos: [org_repo]) + + get :status + + expect(assigns(:already_added_projects)).to eq([project]) + expect(assigns(:repos)).to eq([repo, org_repo]) + extra_assign_expectations.each do |key, value| + expect(assigns(key)).to eq(value) + end + end + + it "does not show already added project" do + project = create(:empty_project, import_type: provider, creator_id: user.id, import_source: 'asd/vim') + stub_client(repos: [repo], orgs: []) + + get :status + + expect(assigns(:already_added_projects)).to eq([project]) + expect(assigns(:repos)).to eq([]) + end + + it "handles an invalid access token" do + allow_any_instance_of(Gitlab::GithubImport::Client). + to receive(:repos).and_raise(Octokit::Unauthorized) + + get :status + + expect(session[:access_token]).to eq(nil) + expect(controller).to redirect_to(new_import_url) + expect(flash[:alert]).to eq("Access denied to your #{Gitlab::ImportSources.options.key(provider.to_s)} account.") + end +end + +shared_examples 'a GitHub-ish import controller: POST create' do + let(:user) { create(:user) } + let(:provider_username) { user.username } + let(:provider_user) { OpenStruct.new(login: provider_username) } + let(:provider_repo) do + OpenStruct.new( + name: 'vim', + full_name: "#{provider_username}/vim", + owner: OpenStruct.new(login: provider_username) + ) + end + + before do + stub_client(user: provider_user, repo: provider_repo) + assign_session_token + end + + context "when the repository owner is the Gitea user" do + context "when the Gitea user and GitLab user's usernames match" do + it "takes the current user's namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, format: :js + end + end + + context "when the Gitea user and GitLab user's usernames don't match" do + let(:provider_username) { "someone_else" } + + it "takes the current user's namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, format: :js + end + end + end + + context "when the repository owner is not the Gitea user" do + let(:other_username) { "someone_else" } + + before do + provider_repo.owner = OpenStruct.new(login: other_username) + assign_session_token + end + + context "when a namespace with the Gitea user's username already exists" do + let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } + + context "when the namespace is owned by the GitLab user" do + it "takes the existing namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, existing_namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, format: :js + end + end + + context "when the namespace is not owned by the GitLab user" do + before do + existing_namespace.owner = create(:user) + existing_namespace.save + end + + it "creates a project using user's namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, format: :js + end + end + end + + context "when a namespace with the Gitea user's username doesn't exist" do + context "when current user can create namespaces" do + it "creates the namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).and_return(double(execute: true)) + + expect { post :create, target_namespace: provider_repo.name, format: :js }.to change(Namespace, :count).by(1) + end + + it "takes the new namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, target_namespace: provider_repo.name, format: :js + end + end + + context "when current user can't create namespaces" do + before do + user.update_attribute(:can_create_group, false) + end + + it "doesn't create the namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).and_return(double(execute: true)) + + expect { post :create, format: :js }.not_to change(Namespace, :count) + end + + it "takes the current user's namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, format: :js + end + end + end + + context 'user has chosen a namespace and name for the project' do + let(:test_namespace) { create(:namespace, name: 'test_namespace', owner: user) } + let(:test_name) { 'test_name' } + + it 'takes the selected namespace and name' do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, { target_namespace: test_namespace.name, new_name: test_name, format: :js } + end + + it 'takes the selected name and default namespace' do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, { new_name: test_name, format: :js } + end + end + end +end diff --git a/spec/support/import_spec_helper.rb b/spec/support/import_spec_helper.rb index 6710962f082..cd25e05ac4b 100644 --- a/spec/support/import_spec_helper.rb +++ b/spec/support/import_spec_helper.rb @@ -30,4 +30,8 @@ module ImportSpecHelper ) allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider]) end + + def assign_session_token + session[:access_token] = 'asdasd12345' + end end -- cgit v1.2.1 From 99ddd1dcbed35b642d7bd8a52cc6e5e5453b9f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Thu, 15 Dec 2016 17:36:53 +0100 Subject: Modify GithubImport to support Gitea MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reason is that Gitea plan to be GitHub-compatible so it makes sense to just modify GitHubImport a bit for now, and hopefully we can change it to GitHubishImport once Gitea is 100%-compatible. Signed-off-by: Rémy Coutable --- .../githubish_import_controller_shared_context.rb | 10 + .../githubish_import_controller_shared_examples.rb | 228 +++++++++++++++++++++ .../githubish_import_controller_shared_context.rb | 10 - .../githubish_import_controller_shared_examples.rb | 228 --------------------- 4 files changed, 238 insertions(+), 238 deletions(-) create mode 100644 spec/support/controllers/githubish_import_controller_shared_context.rb create mode 100644 spec/support/controllers/githubish_import_controller_shared_examples.rb delete mode 100644 spec/support/githubish_import_controller_shared_context.rb delete mode 100644 spec/support/githubish_import_controller_shared_examples.rb (limited to 'spec/support') diff --git a/spec/support/controllers/githubish_import_controller_shared_context.rb b/spec/support/controllers/githubish_import_controller_shared_context.rb new file mode 100644 index 00000000000..e71994edec6 --- /dev/null +++ b/spec/support/controllers/githubish_import_controller_shared_context.rb @@ -0,0 +1,10 @@ +shared_context 'a GitHub-ish import controller' do + let(:user) { create(:user) } + let(:token) { "asdasd12345" } + let(:access_params) { { github_access_token: token } } + + before do + sign_in(user) + allow(controller).to receive(:"#{provider}_import_enabled?").and_return(true) + end +end diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb new file mode 100644 index 00000000000..e11ab802095 --- /dev/null +++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb @@ -0,0 +1,228 @@ +# Specifications for behavior common to all objects with an email attribute. +# Takes a list of email-format attributes and requires: +# - subject { "the object with a attribute= setter" } +# Note: You have access to `email_value` which is the email address value +# being currently tested). + +shared_examples 'a GitHub-ish import controller: POST personal_access_token' do + let(:status_import_url) { public_send("status_import_#{provider}_url") } + + it "updates access token" do + token = 'asdfasdf9876' + + allow_any_instance_of(Gitlab::GithubImport::Client). + to receive(:user).and_return(true) + + post :personal_access_token, personal_access_token: token + + expect(session[:access_token]).to eq(token) + expect(controller).to redirect_to(status_import_url) + end +end + +shared_examples 'a GitHub-ish import controller: GET new' do + let(:status_import_url) { public_send("status_import_#{provider}_url") } + + it "redirects to status if we already have a token" do + assign_session_token + allow(controller).to receive(:logged_in_with_provider?).and_return(false) + + get :new + + expect(controller).to redirect_to(status_import_url) + end + + it "renders the :new page if no token is present in session" do + get :new + + expect(response).to render_template(:new) + end +end + +shared_examples 'a GitHub-ish import controller: GET status' do + let(:new_import_url) { public_send("new_import_#{provider}_url") } + let(:user) { create(:user) } + let(:repo) { OpenStruct.new(login: 'vim', full_name: 'asd/vim') } + let(:org) { OpenStruct.new(login: 'company') } + let(:org_repo) { OpenStruct.new(login: 'company', full_name: 'company/repo') } + let(:extra_assign_expectations) { {} } + + before do + assign_session_token + end + + it "assigns variables" do + project = create(:empty_project, import_type: provider, creator_id: user.id) + stub_client(repos: [repo, org_repo], orgs: [org], org_repos: [org_repo]) + + get :status + + expect(assigns(:already_added_projects)).to eq([project]) + expect(assigns(:repos)).to eq([repo, org_repo]) + extra_assign_expectations.each do |key, value| + expect(assigns(key)).to eq(value) + end + end + + it "does not show already added project" do + project = create(:empty_project, import_type: provider, creator_id: user.id, import_source: 'asd/vim') + stub_client(repos: [repo], orgs: []) + + get :status + + expect(assigns(:already_added_projects)).to eq([project]) + expect(assigns(:repos)).to eq([]) + end + + it "handles an invalid access token" do + allow_any_instance_of(Gitlab::GithubImport::Client). + to receive(:repos).and_raise(Octokit::Unauthorized) + + get :status + + expect(session[:access_token]).to eq(nil) + expect(controller).to redirect_to(new_import_url) + expect(flash[:alert]).to eq("Access denied to your #{Gitlab::ImportSources.title(provider.to_s)} account.") + end +end + +shared_examples 'a GitHub-ish import controller: POST create' do + let(:user) { create(:user) } + let(:provider_username) { user.username } + let(:provider_user) { OpenStruct.new(login: provider_username) } + let(:provider_repo) do + OpenStruct.new( + name: 'vim', + full_name: "#{provider_username}/vim", + owner: OpenStruct.new(login: provider_username) + ) + end + + before do + stub_client(user: provider_user, repo: provider_repo) + assign_session_token + end + + context "when the repository owner is the Gitea user" do + context "when the Gitea user and GitLab user's usernames match" do + it "takes the current user's namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, format: :js + end + end + + context "when the Gitea user and GitLab user's usernames don't match" do + let(:provider_username) { "someone_else" } + + it "takes the current user's namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, format: :js + end + end + end + + context "when the repository owner is not the Gitea user" do + let(:other_username) { "someone_else" } + + before do + provider_repo.owner = OpenStruct.new(login: other_username) + assign_session_token + end + + context "when a namespace with the Gitea user's username already exists" do + let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } + + context "when the namespace is owned by the GitLab user" do + it "takes the existing namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, existing_namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, format: :js + end + end + + context "when the namespace is not owned by the GitLab user" do + before do + existing_namespace.owner = create(:user) + existing_namespace.save + end + + it "creates a project using user's namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, format: :js + end + end + end + + context "when a namespace with the Gitea user's username doesn't exist" do + context "when current user can create namespaces" do + it "creates the namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).and_return(double(execute: true)) + + expect { post :create, target_namespace: provider_repo.name, format: :js }.to change(Namespace, :count).by(1) + end + + it "takes the new namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, target_namespace: provider_repo.name, format: :js + end + end + + context "when current user can't create namespaces" do + before do + user.update_attribute(:can_create_group, false) + end + + it "doesn't create the namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).and_return(double(execute: true)) + + expect { post :create, format: :js }.not_to change(Namespace, :count) + end + + it "takes the current user's namespace" do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, format: :js + end + end + end + + context 'user has chosen a namespace and name for the project' do + let(:test_namespace) { create(:namespace, name: 'test_namespace', owner: user) } + let(:test_name) { 'test_name' } + + it 'takes the selected namespace and name' do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, { target_namespace: test_namespace.name, new_name: test_name, format: :js } + end + + it 'takes the selected name and default namespace' do + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) + + post :create, { new_name: test_name, format: :js } + end + end + end +end diff --git a/spec/support/githubish_import_controller_shared_context.rb b/spec/support/githubish_import_controller_shared_context.rb deleted file mode 100644 index e71994edec6..00000000000 --- a/spec/support/githubish_import_controller_shared_context.rb +++ /dev/null @@ -1,10 +0,0 @@ -shared_context 'a GitHub-ish import controller' do - let(:user) { create(:user) } - let(:token) { "asdasd12345" } - let(:access_params) { { github_access_token: token } } - - before do - sign_in(user) - allow(controller).to receive(:"#{provider}_import_enabled?").and_return(true) - end -end diff --git a/spec/support/githubish_import_controller_shared_examples.rb b/spec/support/githubish_import_controller_shared_examples.rb deleted file mode 100644 index aa2d8aed0bd..00000000000 --- a/spec/support/githubish_import_controller_shared_examples.rb +++ /dev/null @@ -1,228 +0,0 @@ -# Specifications for behavior common to all objects with an email attribute. -# Takes a list of email-format attributes and requires: -# - subject { "the object with a attribute= setter" } -# Note: You have access to `email_value` which is the email address value -# being currently tested). - -shared_examples 'a GitHub-ish import controller: POST personal_access_token' do - let(:status_import_url) { public_send("status_import_#{provider}_url") } - - it "updates access token" do - token = 'asdfasdf9876' - - allow_any_instance_of(Gitlab::GithubImport::Client). - to receive(:user).and_return(true) - - post :personal_access_token, personal_access_token: token - - expect(session[:access_token]).to eq(token) - expect(controller).to redirect_to(status_import_url) - end -end - -shared_examples 'a GitHub-ish import controller: GET new' do - let(:status_import_url) { public_send("status_import_#{provider}_url") } - - it "redirects to status if we already have a token" do - assign_session_token - allow(controller).to receive(:logged_in_with_provider?).and_return(false) - - get :new - - expect(controller).to redirect_to(status_import_url) - end - - it "renders the :new page if no token is present in session" do - get :new - - expect(response).to render_template(:new) - end -end - -shared_examples 'a GitHub-ish import controller: GET status' do - let(:new_import_url) { public_send("new_import_#{provider}_url") } - let(:user) { create(:user) } - let(:repo) { OpenStruct.new(login: 'vim', full_name: 'asd/vim') } - let(:org) { OpenStruct.new(login: 'company') } - let(:org_repo) { OpenStruct.new(login: 'company', full_name: 'company/repo') } - let(:extra_assign_expectations) { {} } - - before do - assign_session_token - end - - it "assigns variables" do - project = create(:empty_project, import_type: provider, creator_id: user.id) - stub_client(repos: [repo, org_repo], orgs: [org], org_repos: [org_repo]) - - get :status - - expect(assigns(:already_added_projects)).to eq([project]) - expect(assigns(:repos)).to eq([repo, org_repo]) - extra_assign_expectations.each do |key, value| - expect(assigns(key)).to eq(value) - end - end - - it "does not show already added project" do - project = create(:empty_project, import_type: provider, creator_id: user.id, import_source: 'asd/vim') - stub_client(repos: [repo], orgs: []) - - get :status - - expect(assigns(:already_added_projects)).to eq([project]) - expect(assigns(:repos)).to eq([]) - end - - it "handles an invalid access token" do - allow_any_instance_of(Gitlab::GithubImport::Client). - to receive(:repos).and_raise(Octokit::Unauthorized) - - get :status - - expect(session[:access_token]).to eq(nil) - expect(controller).to redirect_to(new_import_url) - expect(flash[:alert]).to eq("Access denied to your #{Gitlab::ImportSources.options.key(provider.to_s)} account.") - end -end - -shared_examples 'a GitHub-ish import controller: POST create' do - let(:user) { create(:user) } - let(:provider_username) { user.username } - let(:provider_user) { OpenStruct.new(login: provider_username) } - let(:provider_repo) do - OpenStruct.new( - name: 'vim', - full_name: "#{provider_username}/vim", - owner: OpenStruct.new(login: provider_username) - ) - end - - before do - stub_client(user: provider_user, repo: provider_repo) - assign_session_token - end - - context "when the repository owner is the Gitea user" do - context "when the Gitea user and GitLab user's usernames match" do - it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). - and_return(double(execute: true)) - - post :create, format: :js - end - end - - context "when the Gitea user and GitLab user's usernames don't match" do - let(:provider_username) { "someone_else" } - - it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). - and_return(double(execute: true)) - - post :create, format: :js - end - end - end - - context "when the repository owner is not the Gitea user" do - let(:other_username) { "someone_else" } - - before do - provider_repo.owner = OpenStruct.new(login: other_username) - assign_session_token - end - - context "when a namespace with the Gitea user's username already exists" do - let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } - - context "when the namespace is owned by the GitLab user" do - it "takes the existing namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, existing_namespace, user, access_params, type: provider). - and_return(double(execute: true)) - - post :create, format: :js - end - end - - context "when the namespace is not owned by the GitLab user" do - before do - existing_namespace.owner = create(:user) - existing_namespace.save - end - - it "creates a project using user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). - and_return(double(execute: true)) - - post :create, format: :js - end - end - end - - context "when a namespace with the Gitea user's username doesn't exist" do - context "when current user can create namespaces" do - it "creates the namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) - - expect { post :create, target_namespace: provider_repo.name, format: :js }.to change(Namespace, :count).by(1) - end - - it "takes the new namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider). - and_return(double(execute: true)) - - post :create, target_namespace: provider_repo.name, format: :js - end - end - - context "when current user can't create namespaces" do - before do - user.update_attribute(:can_create_group, false) - end - - it "doesn't create the namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) - - expect { post :create, format: :js }.not_to change(Namespace, :count) - end - - it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). - and_return(double(execute: true)) - - post :create, format: :js - end - end - end - - context 'user has chosen a namespace and name for the project' do - let(:test_namespace) { create(:namespace, name: 'test_namespace', owner: user) } - let(:test_name) { 'test_name' } - - it 'takes the selected namespace and name' do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider). - and_return(double(execute: true)) - - post :create, { target_namespace: test_namespace.name, new_name: test_name, format: :js } - end - - it 'takes the selected name and default namespace' do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider). - and_return(double(execute: true)) - - post :create, { new_name: test_name, format: :js } - end - end - end -end -- cgit v1.2.1 From e046e4c14d06a19cc30a679f4943c77b56ee6d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 16 Dec 2016 17:43:34 +0100 Subject: Namespace access token session key in `Import::GithubController` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- .../githubish_import_controller_shared_examples.rb | 28 ++++++++++++---------- spec/support/import_spec_helper.rb | 4 ---- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'spec/support') diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb index e11ab802095..d0fd2d52004 100644 --- a/spec/support/controllers/githubish_import_controller_shared_examples.rb +++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb @@ -4,6 +4,10 @@ # Note: You have access to `email_value` which is the email address value # being currently tested). +def assign_session_token(provider) + session[:"#{provider}_access_token"] = 'asdasd12345' +end + shared_examples 'a GitHub-ish import controller: POST personal_access_token' do let(:status_import_url) { public_send("status_import_#{provider}_url") } @@ -15,7 +19,7 @@ shared_examples 'a GitHub-ish import controller: POST personal_access_token' do post :personal_access_token, personal_access_token: token - expect(session[:access_token]).to eq(token) + expect(session[:"#{provider}_access_token"]).to eq(token) expect(controller).to redirect_to(status_import_url) end end @@ -24,7 +28,7 @@ shared_examples 'a GitHub-ish import controller: GET new' do let(:status_import_url) { public_send("status_import_#{provider}_url") } it "redirects to status if we already have a token" do - assign_session_token + assign_session_token(provider) allow(controller).to receive(:logged_in_with_provider?).and_return(false) get :new @@ -48,7 +52,7 @@ shared_examples 'a GitHub-ish import controller: GET status' do let(:extra_assign_expectations) { {} } before do - assign_session_token + assign_session_token(provider) end it "assigns variables" do @@ -80,7 +84,7 @@ shared_examples 'a GitHub-ish import controller: GET status' do get :status - expect(session[:access_token]).to eq(nil) + expect(session[:"#{provider}_access_token"]).to be_nil expect(controller).to redirect_to(new_import_url) expect(flash[:alert]).to eq("Access denied to your #{Gitlab::ImportSources.title(provider.to_s)} account.") end @@ -100,11 +104,11 @@ shared_examples 'a GitHub-ish import controller: POST create' do before do stub_client(user: provider_user, repo: provider_repo) - assign_session_token + assign_session_token(provider) end - context "when the repository owner is the Gitea user" do - context "when the Gitea user and GitLab user's usernames match" do + context "when the repository owner is the provider user" do + context "when the provider user and GitLab user's usernames match" do it "takes the current user's namespace" do expect(Gitlab::GithubImport::ProjectCreator). to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). @@ -114,7 +118,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do end end - context "when the Gitea user and GitLab user's usernames don't match" do + context "when the provider user and GitLab user's usernames don't match" do let(:provider_username) { "someone_else" } it "takes the current user's namespace" do @@ -127,15 +131,15 @@ shared_examples 'a GitHub-ish import controller: POST create' do end end - context "when the repository owner is not the Gitea user" do + context "when the repository owner is not the provider user" do let(:other_username) { "someone_else" } before do provider_repo.owner = OpenStruct.new(login: other_username) - assign_session_token + assign_session_token(provider) end - context "when a namespace with the Gitea user's username already exists" do + context "when a namespace with the provider user's username already exists" do let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } context "when the namespace is owned by the GitLab user" do @@ -164,7 +168,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do end end - context "when a namespace with the Gitea user's username doesn't exist" do + context "when a namespace with the provider user's username doesn't exist" do context "when current user can create namespaces" do it "creates the namespace" do expect(Gitlab::GithubImport::ProjectCreator). diff --git a/spec/support/import_spec_helper.rb b/spec/support/import_spec_helper.rb index cd25e05ac4b..6710962f082 100644 --- a/spec/support/import_spec_helper.rb +++ b/spec/support/import_spec_helper.rb @@ -30,8 +30,4 @@ module ImportSpecHelper ) allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider]) end - - def assign_session_token - session[:access_token] = 'asdasd12345' - end end -- cgit v1.2.1 From 5378302763e1a461bab5213aa379d5b9e6dc322c Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Sat, 17 Dec 2016 04:09:50 +0000 Subject: Add a ReactiveCaching concern for use in the KubernetesService --- spec/support/reactive_caching_helpers.rb | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 spec/support/reactive_caching_helpers.rb (limited to 'spec/support') diff --git a/spec/support/reactive_caching_helpers.rb b/spec/support/reactive_caching_helpers.rb new file mode 100644 index 00000000000..279db3c5748 --- /dev/null +++ b/spec/support/reactive_caching_helpers.rb @@ -0,0 +1,38 @@ +module ReactiveCachingHelpers + def reactive_cache_key(subject, *qualifiers) + ([subject.class.reactive_cache_key.call(subject)].flatten + qualifiers).join(':') + end + + def stub_reactive_cache(subject = nil, data = nil) + allow(ReactiveCachingWorker).to receive(:perform_async) + allow(ReactiveCachingWorker).to receive(:perform_in) + write_reactive_cache(subject, data) if data + end + + def read_reactive_cache(subject) + Rails.cache.read(reactive_cache_key(subject)) + end + + def write_reactive_cache(subject, data) + start_reactive_cache_lifetime(subject) + Rails.cache.write(reactive_cache_key(subject), data) + end + + def reactive_cache_alive?(subject) + Rails.cache.read(reactive_cache_key(subject, 'alive')) + end + + def invalidate_reactive_cache(subject) + Rails.cache.delete(reactive_cache_key(subject, 'alive')) + end + + def start_reactive_cache_lifetime(subject) + Rails.cache.write(reactive_cache_key(subject, 'alive'), true) + end + + def expect_reactive_cache_update_queued(subject) + expect(ReactiveCachingWorker). + to receive(:perform_in). + with(subject.class.reactive_cache_refresh_interval, subject.class, subject.id) + end +end -- cgit v1.2.1 From c3d972f4e861059312c2708dacb57999416fcc70 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 22 Nov 2016 19:55:56 +0000 Subject: Add terminals to the Kubernetes deployment service --- spec/support/kubernetes_helpers.rb | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 spec/support/kubernetes_helpers.rb (limited to 'spec/support') diff --git a/spec/support/kubernetes_helpers.rb b/spec/support/kubernetes_helpers.rb new file mode 100644 index 00000000000..6c4c246a68b --- /dev/null +++ b/spec/support/kubernetes_helpers.rb @@ -0,0 +1,52 @@ +module KubernetesHelpers + include Gitlab::Kubernetes + + def kube_discovery_body + { "kind" => "APIResourceList", + "resources" => [ + { "name" => "pods", "namespaced" => true, "kind" => "Pod" }, + ], + } + end + + def kube_pods_body(*pods) + { "kind" => "PodList", + "items" => [ kube_pod ], + } + end + + # This is a partial response, it will have many more elements in reality but + # these are the ones we care about at the moment + def kube_pod(app: "valid-pod-label") + { "metadata" => { + "name" => "kube-pod", + "creationTimestamp" => "2016-11-25T19:55:19Z", + "labels" => { "app" => app }, + }, + "spec" => { + "containers" => [ + { "name" => "container-0" }, + { "name" => "container-1" }, + ], + }, + "status" => { "phase" => "Running" }, + } + end + + def kube_terminals(service, pod) + pod_name = pod['metadata']['name'] + containers = pod['spec']['containers'] + + containers.map do |container| + terminal = { + selectors: { pod: pod_name, container: container['name'] }, + url: container_exec_url(service.api_url, service.namespace, pod_name, container['name']), + subprotocols: ['channel.k8s.io'], + headers: { 'Authorization' => ["Bearer #{service.token}"] }, + created_at: DateTime.parse(pod['metadata']['creationTimestamp']) + } + terminal[:ca_pem] = service.ca_pem if service.ca_pem.present? + terminal + end + end +end -- cgit v1.2.1 From c87d93d462bb83caebd22bd759d8a1ead845d6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Mon, 19 Dec 2016 16:26:59 +0100 Subject: Improve specs for Repositories API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- spec/support/api/status_shared_examples.rb | 42 ++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 spec/support/api/status_shared_examples.rb (limited to 'spec/support') diff --git a/spec/support/api/status_shared_examples.rb b/spec/support/api/status_shared_examples.rb new file mode 100644 index 00000000000..3481749a7f0 --- /dev/null +++ b/spec/support/api/status_shared_examples.rb @@ -0,0 +1,42 @@ +# Specs for status checking. +# +# Requires an API request: +# let(:request) { get api("/projects/#{project.id}/repository/branches", user) } +shared_examples_for '400 response' do + before do + # Fires the request + request + end + + it 'returns 400' do + expect(response).to have_http_status(400) + end +end + +shared_examples_for '403 response' do + before do + # Fires the request + request + end + + it 'returns 403' do + expect(response).to have_http_status(403) + end +end + +shared_examples_for '404 response' do + let(:message) { nil } + before do + # Fires the request + request + end + + it 'returns 404' do + expect(response).to have_http_status(404) + expect(json_response).to be_an Object + + if message.present? + expect(json_response['message']).to eq(message) + end + end +end -- cgit v1.2.1 From 0349e83aa74b42c3f564fd1bc34104300a41ddf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Tue, 20 Dec 2016 15:05:57 +0100 Subject: Improve specs for Files API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- spec/support/api/repositories_shared_context.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 spec/support/api/repositories_shared_context.rb (limited to 'spec/support') diff --git a/spec/support/api/repositories_shared_context.rb b/spec/support/api/repositories_shared_context.rb new file mode 100644 index 00000000000..ea38fe4f5b8 --- /dev/null +++ b/spec/support/api/repositories_shared_context.rb @@ -0,0 +1,10 @@ +shared_context 'disabled repository' do + before do + project.project_feature.update_attributes!( + repository_access_level: ProjectFeature::DISABLED, + merge_requests_access_level: ProjectFeature::DISABLED, + builds_access_level: ProjectFeature::DISABLED + ) + expect(project.feature_available?(:repository, current_user)).to be false + end +end -- cgit v1.2.1 From 9c623e3e5d7434f2e30f7c389d13e5af4ede770a Mon Sep 17 00:00:00 2001 From: James Edwards-Jones Date: Tue, 20 Dec 2016 14:48:04 +0000 Subject: Added QueryRecorder to test N+1 fix on Milestone#show --- spec/support/query_recorder.rb | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 spec/support/query_recorder.rb (limited to 'spec/support') diff --git a/spec/support/query_recorder.rb b/spec/support/query_recorder.rb new file mode 100644 index 00000000000..e40d5ebd9a8 --- /dev/null +++ b/spec/support/query_recorder.rb @@ -0,0 +1,40 @@ +module ActiveRecord + class QueryRecorder + attr_reader :log + + def initialize(&block) + @log = [] + ActiveSupport::Notifications.subscribed(method(:callback), 'sql.active_record', &block) + end + + def callback(name, start, finish, message_id, values) + return if %w(CACHE SCHEMA).include?(values[:name]) + @log << values[:sql] + end + + def count + @log.count + end + + def log_message + @log.join("\n\n") + end + end +end + +RSpec::Matchers.define :exceed_query_limit do |expected| + supports_block_expectations + + match do |block| + query_count(&block) > expected + end + + failure_message_when_negated do |actual| + "Expected a maximum of #{expected} queries, got #{@recorder.count}:\n\n#{@recorder.log_message}" + end + + def query_count(&block) + @recorder = ActiveRecord::QueryRecorder.new(&block) + @recorder.count + end +end -- cgit v1.2.1