diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2016-11-18 21:06:36 +0300 |
---|---|---|
committer | Kamil Trzciński <ayufan@ayufan.eu> | 2016-11-18 21:06:36 +0300 |
commit | ffc5fc6a38f4859f491b0669f939876afa865533 (patch) | |
tree | 40590bab2397e5f48b4a2c211127b81f30a669be /spec | |
parent | 03933cd279f0870a16f126619380ec386d68345a (diff) | |
parent | 1db1896ed2375481d53f74f7900d259fe068ef64 (diff) |
Merge branch 'zj-slash-commands-mattermost' into 'master'
Slash command for mattermost
Closes #22540
## Does this MR meet the acceptance criteria?
- [x] [Changelog entry](https://docs.gitlab.com/ce/development/changelog.html) added
- [ ] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)
- Tests
- [x] Added for this feature/bug
- [x] All builds are passing
- [x] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html)
- [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [x] Branch has no merge conflicts with `master` (if it does - rebase it please)
See merge request !7438
Diffstat (limited to 'spec')
-rw-r--r-- | spec/lib/gitlab/chat_commands/command_spec.rb | 55 | ||||
-rw-r--r-- | spec/lib/gitlab/chat_commands/issue_create_spec.rb | 52 | ||||
-rw-r--r-- | spec/lib/gitlab/chat_commands/issue_show_spec.rb | 40 | ||||
-rw-r--r-- | spec/lib/gitlab/import_export/all_models.yml | 4 | ||||
-rw-r--r-- | spec/models/project_services/chat_service_spec.rb | 15 | ||||
-rw-r--r-- | spec/models/project_services/mattermost_slash_commands_service_spec.rb | 99 | ||||
-rw-r--r-- | spec/models/project_spec.rb | 2 | ||||
-rw-r--r-- | spec/requests/api/services_spec.rb | 57 | ||||
-rw-r--r-- | spec/services/chat_names/find_user_service_spec.rb | 2 |
9 files changed, 324 insertions, 2 deletions
diff --git a/spec/lib/gitlab/chat_commands/command_spec.rb b/spec/lib/gitlab/chat_commands/command_spec.rb new file mode 100644 index 00000000000..8cedbb0240f --- /dev/null +++ b/spec/lib/gitlab/chat_commands/command_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' + +describe Gitlab::ChatCommands::Command, service: true do + let(:project) { create(:empty_project) } + let(:user) { create(:user) } + + subject { described_class.new(project, user, params).execute } + + describe '#execute' do + context 'when no command is available' do + let(:params) { { text: 'issue show 1' } } + let(:project) { create(:project, has_external_issue_tracker: true) } + + it 'displays 404 messages' do + expect(subject[:response_type]).to be(:ephemeral) + expect(subject[:text]).to start_with('404 not found') + end + end + + context 'when an unknown command is triggered' do + let(:params) { { command: '/gitlab', text: "unknown command 123" } } + + it 'displays the help message' do + expect(subject[:response_type]).to be(:ephemeral) + expect(subject[:text]).to start_with('Available commands') + expect(subject[:text]).to match('/gitlab issue show') + end + end + + context 'the user can not create an issue' do + let(:params) { { text: "issue create my new issue" } } + + it 'rejects the actions' do + expect(subject[:response_type]).to be(:ephemeral) + expect(subject[:text]).to start_with('Whoops! That action is not allowed') + end + end + + context 'issue is successfully created' do + let(:params) { { text: "issue create my new issue" } } + + before do + project.team << [user, :master] + end + + it 'presents the issue' do + expect(subject[:text]).to match("my new issue") + end + + it 'shows a link to the new issue' do + expect(subject[:text]).to match(/\/issues\/\d+/) + end + end + end +end diff --git a/spec/lib/gitlab/chat_commands/issue_create_spec.rb b/spec/lib/gitlab/chat_commands/issue_create_spec.rb new file mode 100644 index 00000000000..df0c317ccea --- /dev/null +++ b/spec/lib/gitlab/chat_commands/issue_create_spec.rb @@ -0,0 +1,52 @@ +require 'spec_helper' + +describe Gitlab::ChatCommands::IssueCreate, service: true do + describe '#execute' do + let(:project) { create(:empty_project) } + let(:user) { create(:user) } + let(:regex_match) { described_class.match("issue create bird is the word") } + + before do + project.team << [user, :master] + end + + subject do + described_class.new(project, user).execute(regex_match) + end + + context 'without description' do + it 'creates the issue' do + expect { subject }.to change { project.issues.count }.by(1) + + expect(subject.title).to eq('bird is the word') + end + end + + context 'with description' do + let(:description) { "Surfin bird" } + let(:regex_match) { described_class.match("issue create bird is the word\n#{description}") } + + it 'creates the issue with description' do + subject + + expect(Issue.last.description).to eq(description) + end + end + end + + describe '.match' do + it 'matches the title without description' do + match = described_class.match("issue create my title") + + expect(match[:title]).to eq('my title') + expect(match[:description]).to eq("") + end + + it 'matches the title with description' do + match = described_class.match("issue create my title\n\ndescription") + + expect(match[:title]).to eq('my title') + expect(match[:description]).to eq('description') + end + end +end diff --git a/spec/lib/gitlab/chat_commands/issue_show_spec.rb b/spec/lib/gitlab/chat_commands/issue_show_spec.rb new file mode 100644 index 00000000000..331a4604e9b --- /dev/null +++ b/spec/lib/gitlab/chat_commands/issue_show_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe Gitlab::ChatCommands::IssueShow, service: true do + describe '#execute' do + let(:issue) { create(:issue) } + let(:project) { issue.project } + let(:user) { issue.author } + let(:regex_match) { described_class.match("issue show #{issue.iid}") } + + before do + project.team << [user, :master] + end + + subject do + described_class.new(project, user).execute(regex_match) + end + + context 'the issue exists' do + it 'returns the issue' do + expect(subject.iid).to be issue.iid + end + end + + context 'the issue does not exist' do + let(:regex_match) { described_class.match("issue show 2343242") } + + it "returns nil" do + expect(subject).to be_nil + end + end + end + + describe 'self.match' do + it 'matches the iid' do + match = described_class.match("issue show 123") + + expect(match[:iid]).to eq("123") + end + end +end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 02b11bd999a..fe3c39e38db 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -116,6 +116,7 @@ project: - base_tags - tag_taggings - tags +- chat_services - creator - group - namespace @@ -127,6 +128,7 @@ project: - emails_on_push_service - builds_email_service - pipelines_email_service +- mattermost_slash_commands_service - irker_service - pivotaltracker_service - hipchat_service @@ -188,4 +190,4 @@ award_emoji: - awardable - user priorities: -- label
\ No newline at end of file +- label diff --git a/spec/models/project_services/chat_service_spec.rb b/spec/models/project_services/chat_service_spec.rb new file mode 100644 index 00000000000..c6a45a3e1be --- /dev/null +++ b/spec/models/project_services/chat_service_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe ChatService, models: true do + describe "Associations" do + it { is_expected.to have_many :chat_names } + end + + describe '#valid_token?' do + subject { described_class.new } + + it 'is false as it has no token' do + expect(subject.valid_token?('wer')).to be_falsey + end + end +end diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb new file mode 100644 index 00000000000..4a1037e950b --- /dev/null +++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb @@ -0,0 +1,99 @@ +require 'spec_helper' + +describe MattermostSlashCommandsService, models: true do + describe "Associations" do + it { is_expected.to respond_to :token } + 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: service) } + let(:service) do + project.create_mattermost_slash_commands_service( + properties: { token: 'token' } + ) + end + let(:params) { { token: 'token', team_id: chat_name.team_id, user_id: chat_name.chat_id } } + + it 'triggers the command' do + expect_any_instance_of(Gitlab::ChatCommands::Command).to receive(:execute) + + service.trigger(params) + end + end + end + end +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 42aa617cb1e..33b5d8388c8 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -20,6 +20,7 @@ describe Project, models: true do it { is_expected.to have_many(:deploy_keys) } it { is_expected.to have_many(:hooks).dependent(:destroy) } it { is_expected.to have_many(:protected_branches).dependent(:destroy) } + it { is_expected.to have_many(:chat_services) } it { is_expected.to have_one(:forked_project_link).dependent(:destroy) } it { is_expected.to have_one(:slack_service).dependent(:destroy) } it { is_expected.to have_one(:pushover_service).dependent(:destroy) } @@ -35,6 +36,7 @@ describe Project, models: true do it { is_expected.to have_one(:hipchat_service).dependent(:destroy) } it { is_expected.to have_one(:flowdock_service).dependent(:destroy) } it { is_expected.to have_one(:assembla_service).dependent(:destroy) } + it { is_expected.to have_one(:mattermost_slash_commands_service).dependent(:destroy) } it { is_expected.to have_one(:gemnasium_service).dependent(:destroy) } it { is_expected.to have_one(:buildkite_service).dependent(:destroy) } it { is_expected.to have_one(:bamboo_service).dependent(:destroy) } diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb index 2aadab3cbe1..ce9c96ace21 100644 --- a/spec/requests/api/services_spec.rb +++ b/spec/requests/api/services_spec.rb @@ -88,4 +88,61 @@ describe API::API, api: true do end end end + + describe 'POST /projects/:id/services/:slug/trigger' do + let!(:project) { create(:empty_project) } + let(:service_name) { 'mattermost_slash_commands' } + + context 'no service is available' do + it 'returns a not found message' do + post api("/projects/#{project.id}/services/idonotexist/trigger") + + expect(response).to have_http_status(404) + expect(json_response["message"]).to eq("404 Service Not Found") + end + end + + context 'the service exists' do + let(:params) { { token: 'token' } } + + context 'the service is not active' do + let!(:inactive_service) do + project.create_mattermost_slash_commands_service( + active: false, + properties: { token: 'token' } + ) + end + + it 'when the service is inactive' do + post api("/projects/#{project.id}/services/mattermost_slash_commands/trigger") + + expect(response).to have_http_status(404) + end + end + + context 'the service is active' do + let!(:active_service) do + project.create_mattermost_slash_commands_service( + active: true, + properties: { token: 'token' } + ) + end + + it 'retusn status 200' do + post api("/projects/#{project.id}/services/mattermost_slash_commands/trigger"), params + + expect(response).to have_http_status(200) + end + end + + context 'when the project can not be found' do + it 'returns a generic 404' do + post api("/projects/404/services/mattermost_slash_commands/trigger"), params + + expect(response).to have_http_status(404) + expect(json_response["message"]).to eq("404 Service Not Found") + end + end + end + end end diff --git a/spec/services/chat_names/find_user_service_spec.rb b/spec/services/chat_names/find_user_service_spec.rb index 5b885b2c657..51441e8f3be 100644 --- a/spec/services/chat_names/find_user_service_spec.rb +++ b/spec/services/chat_names/find_user_service_spec.rb @@ -13,7 +13,7 @@ describe ChatNames::FindUserService, services: true do context 'when existing user is requested' do let(:params) { { team_id: chat_name.team_id, user_id: chat_name.chat_id } } - it 'returns existing user' do + it 'returns the existing user' do is_expected.to eq(user) end |