Commit 392b7b9c2ce816d73ac5f21a1f217f13dd8400d5
1 parent
3db48ca3
Exists in
master
and in
1 other branch
adding support for Bitbucket issues with tests + small fix for gtalk icon
Conflicts: Gemfile app/assets/images/gtalk_inactive.png
Showing
10 changed files
with
164 additions
and
1 deletions
Show diff stats
Gemfile
@@ -33,10 +33,13 @@ gem 'rack-ssl-enforcer' | @@ -33,10 +33,13 @@ gem 'rack-ssl-enforcer' | ||
33 | gem 'fabrication', "~> 1.3.0" # Both for tests, and loading demo data | 33 | gem 'fabrication', "~> 1.3.0" # Both for tests, and loading demo data |
34 | gem 'rails_autolink', '~> 1.0.9' | 34 | gem 'rails_autolink', '~> 1.0.9' |
35 | gem 'campy' | 35 | gem 'campy' |
36 | +gem 'xmpp4r' | ||
37 | +gem 'hipchat-api' | ||
38 | +gem 'bitbucket_rest_api' | ||
36 | 39 | ||
37 | # Please don't update this to airbrake - We override the send_notice method | 40 | # Please don't update this to airbrake - We override the send_notice method |
38 | # to handle internal errors. | 41 | # to handle internal errors. |
39 | -gem 'hoptoad_notifier', "~> 2.4" | 42 | +gem 'hoptoad_notifier', '~> 2.4' |
40 | 43 | ||
41 | platform :ruby do | 44 | platform :ruby do |
42 | gem 'mongo', '= 1.6.2' | 45 | gem 'mongo', '= 1.6.2' |
Gemfile.lock
@@ -36,6 +36,13 @@ GEM | @@ -36,6 +36,13 @@ GEM | ||
36 | addressable (2.3.2) | 36 | addressable (2.3.2) |
37 | arel (3.0.2) | 37 | arel (3.0.2) |
38 | bcrypt-ruby (3.0.1) | 38 | bcrypt-ruby (3.0.1) |
39 | + bitbucket_rest_api (0.1.1) | ||
40 | + faraday (~> 0.8.1) | ||
41 | + faraday_middleware (~> 0.8.1) | ||
42 | + hashie (~> 1.2.0) | ||
43 | + multi_json (~> 1.3) | ||
44 | + nokogiri (~> 1.5.2) | ||
45 | + simple_oauth | ||
39 | bson (1.6.2) | 46 | bson (1.6.2) |
40 | bson_ext (1.6.2) | 47 | bson_ext (1.6.2) |
41 | bson (~> 1.6.2) | 48 | bson (~> 1.6.2) |
@@ -256,6 +263,7 @@ GEM | @@ -256,6 +263,7 @@ GEM | ||
256 | libwebsocket (~> 0.1.3) | 263 | libwebsocket (~> 0.1.3) |
257 | multi_json (~> 1.0) | 264 | multi_json (~> 1.0) |
258 | rubyzip | 265 | rubyzip |
266 | + simple_oauth (0.1.9) | ||
259 | slop (2.4.4) | 267 | slop (2.4.4) |
260 | sprockets (2.1.3) | 268 | sprockets (2.1.3) |
261 | hike (~> 1.2) | 269 | hike (~> 1.2) |
@@ -297,6 +305,7 @@ PLATFORMS | @@ -297,6 +305,7 @@ PLATFORMS | ||
297 | DEPENDENCIES | 305 | DEPENDENCIES |
298 | SystemTimer | 306 | SystemTimer |
299 | actionmailer_inline_css (~> 1.3.0) | 307 | actionmailer_inline_css (~> 1.3.0) |
308 | + bitbucket_rest_api | ||
300 | bson (= 1.6.2) | 309 | bson (= 1.6.2) |
301 | bson_ext (= 1.6.2) | 310 | bson_ext (= 1.6.2) |
302 | campy | 311 | campy |
2.54 KB
3.61 KB
1.95 KB
1.91 KB
@@ -0,0 +1,47 @@ | @@ -0,0 +1,47 @@ | ||
1 | +class IssueTrackers::BitbucketIssuesTracker < IssueTracker | ||
2 | + Label = "bitbucket" | ||
3 | + Note = 'Please configure your Bitbucket repository in the <strong>BITBUCKET REPO</strong> field above.' | ||
4 | + Fields = [ | ||
5 | + [:api_token, { | ||
6 | + :placeholder => "Your username on Bitbucket account", | ||
7 | + :label => "Username" | ||
8 | + }], | ||
9 | + [:project_id, { | ||
10 | + :placeholder => "Password for your Bitbucket account", | ||
11 | + :label => "Password" | ||
12 | + }] | ||
13 | + ] | ||
14 | + | ||
15 | + def check_params | ||
16 | + if Fields.detect {|f| self[f[0]].blank? } | ||
17 | + errors.add :base, 'You must specify your Bitbucket username and password' | ||
18 | + end | ||
19 | + end | ||
20 | + | ||
21 | + def repo_name | ||
22 | + app.bitbucket_repo | ||
23 | + end | ||
24 | + | ||
25 | + def create_issue(problem, reported_by = nil) | ||
26 | + bitbucket = BitBucket.new basic_auth: "#{api_token}:#{project_id}" | ||
27 | + | ||
28 | + begin | ||
29 | + issue = bitbucket.issues.create api_token, repo_name.split('/')[1], title: issue_title(problem), content: body_template.result(binding), priority: 'critical' | ||
30 | + problem.update_attributes( | ||
31 | + :issue_link => "https://bitbucket.org/#{repo_name}/issue/#{issue.local_id}/", | ||
32 | + :issue_type => Label | ||
33 | + ) | ||
34 | + rescue BitBucket::Error::Unauthorized | ||
35 | + raise IssueTrackers::AuthenticationError, "Could not authenticate with BitBucket. Please check your username and password." | ||
36 | + end | ||
37 | + end | ||
38 | + | ||
39 | + def body_template | ||
40 | + @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/bitbucket_issues_body.txt.erb")) | ||
41 | + end | ||
42 | + | ||
43 | + def url | ||
44 | + "https://www.bitbucket.org/#{repo_name}/issues" | ||
45 | + end | ||
46 | +end | ||
47 | + |
@@ -0,0 +1,58 @@ | @@ -0,0 +1,58 @@ | ||
1 | +[[<%= app_err_url problem.app, problem %>| [See this exception on Errbit]]] | ||
2 | + | ||
3 | +---- | ||
4 | + | ||
5 | +<% if notice = problem.notices.first %> | ||
6 | + <%= notice.message %> | ||
7 | + | ||
8 | +---- | ||
9 | + | ||
10 | + == Summary == | ||
11 | + <% if notice.request['url'].present? %> | ||
12 | + === URL === | ||
13 | + [[<%= notice.request['url'] %>]] | ||
14 | + <% end %> | ||
15 | + | ||
16 | +---- | ||
17 | + | ||
18 | + === Where === | ||
19 | + <%= notice.where %> | ||
20 | + | ||
21 | +---- | ||
22 | + | ||
23 | + === Occured === | ||
24 | + <%= notice.created_at.to_s(:micro) %> | ||
25 | + | ||
26 | +---- | ||
27 | + | ||
28 | + === Similar === | ||
29 | + <%= (notice.problem.notices_count - 1).to_s %> | ||
30 | + | ||
31 | +---- | ||
32 | + | ||
33 | + == Params == | ||
34 | +{{{ | ||
35 | +<%= pretty_hash(notice.params) %> | ||
36 | +}}} | ||
37 | + | ||
38 | +---- | ||
39 | + | ||
40 | + == Session == | ||
41 | +{{{ | ||
42 | +<%= pretty_hash(notice.session) %> | ||
43 | +}}} | ||
44 | + | ||
45 | +---- | ||
46 | + | ||
47 | + == Backtrace == | ||
48 | + <% for line in notice.backtrace %>| <%= line['number'] %>: | <%= line['file'].to_s.sub(/^\[PROJECT_ROOT\]/, '') %> -> **<%= line['method'] %>** | | ||
49 | + <% end %> | ||
50 | + | ||
51 | +---- | ||
52 | + | ||
53 | + == Environment == | ||
54 | + <% for key, val in notice.env_vars %> | ||
55 | + | <%= key %>: | <%= val %> | | ||
56 | + <% end %> | ||
57 | +<% end %> | ||
58 | + |
spec/fabricators/issue_tracker_fabricator.rb
@@ -24,3 +24,8 @@ Fabricator :github_issues_tracker, :from => :issue_tracker, :class_name => "Issu | @@ -24,3 +24,8 @@ Fabricator :github_issues_tracker, :from => :issue_tracker, :class_name => "Issu | ||
24 | project_id 'test_account/test_project' | 24 | project_id 'test_account/test_project' |
25 | username 'test_username' | 25 | username 'test_username' |
26 | end | 26 | end |
27 | + | ||
28 | +Fabricator :bitbucket_issues_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::BitbucketIssuesTracker" do | ||
29 | + project_id 'password' | ||
30 | + api_token 'test_username' | ||
31 | +end |
spec/models/issue_trackers/bitbucket_issues_tracker_spec.rb
0 → 100644
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | +require 'spec_helper' | ||
2 | + | ||
3 | +describe IssueTrackers::BitbucketIssuesTracker do | ||
4 | + it "should create an issue on BitBucket Issues with problem params, and set issue link for problem" do | ||
5 | + repo = "test_user/test_repo" | ||
6 | + notice = Fabricate :notice | ||
7 | + notice.app.bitbucket_repo = repo | ||
8 | + tracker = Fabricate :bitbucket_issues_tracker, :app => notice.app | ||
9 | + problem = notice.problem | ||
10 | + | ||
11 | + number = 123 | ||
12 | + @issue_link = "https://bitbucket.org/#{repo}/issue/#{number}/" | ||
13 | + body = <<EOF | ||
14 | +{ | ||
15 | + "status": "new", | ||
16 | + "priority": "critical", | ||
17 | + "title": "[production][foo#bar] FooError: Too Much Bar", | ||
18 | + "comment_count": 0, | ||
19 | + "content": "This is the content", | ||
20 | + "created_on": "2012-07-29 04:35:38", | ||
21 | + "local_id": 123, | ||
22 | + "follower_count": 0, | ||
23 | + "utc_created_on": "2012-07-29 02:35:38+00:00", | ||
24 | + "resource_uri": "/1.0/repositories/test_user/test_repo/issue/123/", | ||
25 | + "is_spam": false | ||
26 | +} | ||
27 | +EOF | ||
28 | + | ||
29 | + stub_request(:post, "https://#{tracker.api_token}:#{tracker.project_id}@bitbucket.org/api/1.0/repositories/test_username/test_repo/issues/").to_return(:status => 200, :headers => {}, :body => body ) | ||
30 | + | ||
31 | + problem.app.issue_tracker.create_issue(problem) | ||
32 | + problem.reload | ||
33 | + | ||
34 | + requested = have_requested(:post, "https://#{tracker.api_token}:#{tracker.project_id}@bitbucket.org/api/1.0/repositories/test_username/test_repo/issues/") | ||
35 | + WebMock.should requested.with(:title => /[production][foo#bar] FooError: Too Much Bar/) | ||
36 | + WebMock.should requested.with(:content => /See this exception on Errbit/) | ||
37 | + | ||
38 | + problem.issue_link.should == @issue_link | ||
39 | + end | ||
40 | +end | ||
41 | + |