codeclimate-services 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +7 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +121 -0
  8. data/Rakefile +11 -0
  9. data/bin/bundler +16 -0
  10. data/bin/coderay +16 -0
  11. data/bin/nokogiri +16 -0
  12. data/bin/pry +16 -0
  13. data/bin/rake +16 -0
  14. data/codeclimate-services.gemspec +29 -0
  15. data/config/cacert.pem +4026 -0
  16. data/config/load.rb +4 -0
  17. data/lib/axiom/types/password.rb +7 -0
  18. data/lib/cc/formatters/linked_formatter.rb +60 -0
  19. data/lib/cc/formatters/plain_formatter.rb +36 -0
  20. data/lib/cc/formatters/snapshot_formatter.rb +101 -0
  21. data/lib/cc/formatters/ticket_formatter.rb +27 -0
  22. data/lib/cc/helpers/coverage_helper.rb +25 -0
  23. data/lib/cc/helpers/issue_helper.rb +9 -0
  24. data/lib/cc/helpers/quality_helper.rb +44 -0
  25. data/lib/cc/helpers/vulnerability_helper.rb +31 -0
  26. data/lib/cc/presenters/github_pull_requests_presenter.rb +54 -0
  27. data/lib/cc/service/config.rb +4 -0
  28. data/lib/cc/service/formatter.rb +34 -0
  29. data/lib/cc/service/helper.rb +54 -0
  30. data/lib/cc/service/http.rb +87 -0
  31. data/lib/cc/service/invocation/invocation_chain.rb +15 -0
  32. data/lib/cc/service/invocation/with_error_handling.rb +45 -0
  33. data/lib/cc/service/invocation/with_metrics.rb +37 -0
  34. data/lib/cc/service/invocation/with_retries.rb +17 -0
  35. data/lib/cc/service/invocation/with_return_values.rb +18 -0
  36. data/lib/cc/service/invocation.rb +57 -0
  37. data/lib/cc/service/response_check.rb +42 -0
  38. data/lib/cc/service.rb +127 -0
  39. data/lib/cc/services/asana.rb +90 -0
  40. data/lib/cc/services/campfire.rb +55 -0
  41. data/lib/cc/services/flowdock.rb +61 -0
  42. data/lib/cc/services/github_issues.rb +80 -0
  43. data/lib/cc/services/github_pull_requests.rb +210 -0
  44. data/lib/cc/services/hipchat.rb +57 -0
  45. data/lib/cc/services/jira.rb +93 -0
  46. data/lib/cc/services/lighthouse.rb +79 -0
  47. data/lib/cc/services/pivotal_tracker.rb +78 -0
  48. data/lib/cc/services/slack.rb +124 -0
  49. data/lib/cc/services/version.rb +5 -0
  50. data/lib/cc/services.rb +9 -0
  51. data/pull_request_test.rb +47 -0
  52. data/service_test.rb +86 -0
  53. data/test/asana_test.rb +85 -0
  54. data/test/axiom/types/password_test.rb +22 -0
  55. data/test/campfire_test.rb +144 -0
  56. data/test/fixtures.rb +68 -0
  57. data/test/flowdock_test.rb +148 -0
  58. data/test/formatters/snapshot_formatter_test.rb +47 -0
  59. data/test/github_issues_test.rb +96 -0
  60. data/test/github_pull_requests_test.rb +293 -0
  61. data/test/helper.rb +50 -0
  62. data/test/hipchat_test.rb +130 -0
  63. data/test/invocation_error_handling_test.rb +51 -0
  64. data/test/invocation_return_values_test.rb +21 -0
  65. data/test/invocation_test.rb +167 -0
  66. data/test/jira_test.rb +80 -0
  67. data/test/lighthouse_test.rb +74 -0
  68. data/test/pivotal_tracker_test.rb +73 -0
  69. data/test/presenters/github_pull_requests_presenter_test.rb +49 -0
  70. data/test/service_test.rb +63 -0
  71. data/test/slack_test.rb +222 -0
  72. data/test/support/fake_logger.rb +11 -0
  73. data/test/with_metrics_test.rb +19 -0
  74. metadata +263 -0
data/service_test.rb ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Ad-hoc script for sending the test event to service classes
4
+ #
5
+ # Usage:
6
+ #
7
+ # $ <SERVICE>_<CONFIG_ATTR_1>="..." \
8
+ # <SERVICE>_<CONFIG_ATTR_2>="..." \
9
+ # ... ... bundle exec ruby service_test.rb
10
+ #
11
+ # Example:
12
+ #
13
+ # $ SLACK_WEBHOOK_URL="http://..." bundle exec ruby service_test.rb
14
+ # $ GITHUBPULLREQUESTS_UPDATE_STATUS=false GITHUBPULLREQUESTS_ADD_COMMENT=true GITHUBPULLREQUESTS_OAUTH_TOKEN=06083a4a060d358ca709939b1f00645777661c44 bundle exec ruby service_test.rb
15
+ #
16
+ # Other Environment variables used:
17
+ #
18
+ # REPO_NAME Defaults to "App"
19
+ #
20
+ ###
21
+ require 'cc/services'
22
+ CC::Service.load_services
23
+
24
+ class WithResponseLogging
25
+ def initialize(invocation)
26
+ @invocation = invocation
27
+ end
28
+
29
+ def call
30
+ @invocation.call.tap { |r| p r }
31
+ end
32
+ end
33
+
34
+ class ServiceTest
35
+ def initialize(klass, *params)
36
+ @klass = klass
37
+ @params = params
38
+ end
39
+
40
+ def test(payload = {})
41
+ config = {}
42
+
43
+ puts "-"*80
44
+ puts @klass
45
+
46
+ @params.each do |param|
47
+ if var = ENV[to_env_var(param)]
48
+ config[param] = var
49
+ else
50
+ puts " -> skipping"
51
+ return false
52
+ end
53
+ end
54
+
55
+ puts " -> testing"
56
+ puts " -> #{config.inspect}"
57
+ print " => "
58
+
59
+ test_service(@klass, config, payload)
60
+ end
61
+
62
+ private
63
+
64
+ def to_env_var(param)
65
+ "#{@klass.to_s.split("::").last}_#{param}".upcase
66
+ end
67
+
68
+ def test_service(klass, config, payload)
69
+ repo_name = ENV["REPO_NAME"] || "App"
70
+
71
+ service = klass.new(
72
+ config,
73
+ { name: :test, repo_name: repo_name }.merge(payload)
74
+ )
75
+
76
+ CC::Service::Invocation.new(service) do |i|
77
+ i.wrap(WithResponseLogging)
78
+ end
79
+ end
80
+ end
81
+
82
+ ServiceTest.new(CC::Service::Slack, :webhook_url).test
83
+ ServiceTest.new(CC::Service::Flowdock, :api_token).test
84
+ ServiceTest.new(CC::Service::Jira, :username, :password, :domain, :project_id).test
85
+ ServiceTest.new(CC::Service::Asana, :api_key, :workspace_id, :project_id).test
86
+ ServiceTest.new(CC::Service::GitHubPullRequests, :oauth_token, :update_status, :add_comment).test({ github_slug: "codeclimate/codeclimate" })
@@ -0,0 +1,85 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestAsana < CC::Service::TestCase
4
+ def test_quality
5
+ assert_asana_receives(
6
+ event(:quality, to: "D", from: "C"),
7
+ "Refactor User from a D on Code Climate - https://codeclimate.com/repos/1/feed"
8
+ )
9
+ end
10
+
11
+ def test_vulnerability
12
+ assert_asana_receives(
13
+ event(:vulnerability, vulnerabilities: [{
14
+ "warning_type" => "critical",
15
+ "location" => "app/user.rb line 120"
16
+ }]),
17
+ "New critical issue found in app/user.rb line 120 - https://codeclimate.com/repos/1/feed"
18
+ )
19
+ end
20
+
21
+ def test_issue
22
+ payload = {
23
+ issue: {
24
+ "check_name" => "Style/LongLine",
25
+ "description" => "Line is too long [1000/80]"
26
+ },
27
+ constant_name: "foo.rb",
28
+ details_url: "http://example.com/repos/id/foo.rb#issue_123"
29
+ }
30
+
31
+ assert_asana_receives(
32
+ event(:issue, payload),
33
+ "Fix \"Style/LongLine\" issue in foo.rb",
34
+ "Line is too long [1000/80]\n\nhttp://example.com/repos/id/foo.rb#issue_123"
35
+ )
36
+ end
37
+
38
+ def test_successful_post
39
+ @stubs.post '/api/1.0/tasks' do |env|
40
+ [200, {}, '{"data":{"id":"2"}}']
41
+ end
42
+
43
+ response = receive_event
44
+
45
+ assert_equal "2", response[:id]
46
+ assert_equal "https://app.asana.com/0/1/2", response[:url]
47
+ end
48
+
49
+ def test_receive_test
50
+ @stubs.post '/api/1.0/tasks' do |env|
51
+ [200, {}, '{"data":{"id":"4"}}']
52
+ end
53
+
54
+ response = receive_event(name: "test")
55
+
56
+ assert_equal "Ticket <a href='https://app.asana.com/0/1/4'>4</a> created.", response[:message]
57
+ end
58
+
59
+ private
60
+
61
+ def assert_asana_receives(event_data, name, notes = nil)
62
+ @stubs.post '/api/1.0/tasks' do |env|
63
+ body = JSON.parse(env[:body])
64
+ data = body["data"]
65
+
66
+ assert_equal "1", data["workspace"]
67
+ assert_equal "2", data["projects"].first
68
+ assert_equal "jim@asana.com", data["assignee"]
69
+ assert_equal name, data["name"]
70
+ assert_equal notes, data["notes"]
71
+
72
+ [200, {}, '{"data":{"id":4}}']
73
+ end
74
+
75
+ receive_event(event_data)
76
+ end
77
+
78
+ def receive_event(event_data = nil)
79
+ receive(
80
+ CC::Service::Asana,
81
+ { api_key: "abc123", workspace_id: "1", project_id: "2", assignee: "jim@asana.com" },
82
+ event_data || event(:quality, to: "D", from: "C")
83
+ )
84
+ end
85
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path('../../../helper', __FILE__)
2
+
3
+ class Axiom::Types::PasswordTest < CC::Service::TestCase
4
+ class TestConfiguration < CC::Service::Config
5
+ attribute :password_attribute, Password
6
+ attribute :string_attribute, String
7
+ end
8
+
9
+ def test_password_type_inference
10
+ assert_equal(
11
+ Axiom::Types::Password,
12
+ TestConfiguration.attribute_set[:password_attribute].type
13
+ )
14
+ end
15
+
16
+ def test_string_type_inference
17
+ assert_equal(
18
+ Axiom::Types::String,
19
+ TestConfiguration.attribute_set[:string_attribute].type
20
+ )
21
+ end
22
+ end
@@ -0,0 +1,144 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestCampfire < CC::Service::TestCase
4
+ def test_config
5
+ assert_raises CC::Service::ConfigurationError do
6
+ service(CC::Service::Campfire, {}, {name: "test"})
7
+ end
8
+ end
9
+
10
+ def test_test_hook
11
+ assert_campfire_receives(
12
+ { name: "test", repo_name: "Rails" },
13
+ "[Code Climate][Rails] This is a test of the Campfire service hook"
14
+ )
15
+ end
16
+
17
+ def test_coverage_improved
18
+ e = event(:coverage, to: 90.2, from: 80)
19
+
20
+ assert_campfire_receives(e, [
21
+ "[Code Climate][Example] :sunny:",
22
+ "Test coverage has improved to 90.2% (+10.2%).",
23
+ "(https://codeclimate.com/repos/1/feed)"
24
+ ].join(" "))
25
+ end
26
+
27
+ def test_coverage_declined
28
+ e = event(:coverage, to: 88.6, from: 94.6)
29
+
30
+ assert_campfire_receives(e, [
31
+ "[Code Climate][Example] :umbrella:",
32
+ "Test coverage has declined to 88.6% (-6.0%).",
33
+ "(https://codeclimate.com/repos/1/feed)"
34
+ ].join(" "))
35
+ end
36
+
37
+ def test_quality_improved
38
+ e = event(:quality, to: "A", from: "B")
39
+
40
+ assert_campfire_receives(e, [
41
+ "[Code Climate][Example] :sunny:",
42
+ "User has improved from a B to an A.",
43
+ "(https://codeclimate.com/repos/1/feed)"
44
+ ].join(" "))
45
+ end
46
+
47
+ def test_quality_declined
48
+ e = event(:quality, to: "D", from: "C")
49
+
50
+ assert_campfire_receives(e, [
51
+ "[Code Climate][Example] :umbrella:",
52
+ "User has declined from a C to a D.",
53
+ "(https://codeclimate.com/repos/1/feed)"
54
+ ].join(" "))
55
+ end
56
+
57
+ def test_single_vulnerability
58
+ e = event(:vulnerability, vulnerabilities: [
59
+ { "warning_type" => "critical" }
60
+ ])
61
+
62
+ assert_campfire_receives(e, [
63
+ "[Code Climate][Example]",
64
+ "New critical issue found.",
65
+ "Details: https://codeclimate.com/repos/1/feed"
66
+ ].join(" "))
67
+ end
68
+
69
+ def test_single_vulnerability_with_location
70
+ e = event(:vulnerability, vulnerabilities: [{
71
+ "warning_type" => "critical",
72
+ "location" => "app/user.rb line 120"
73
+ }])
74
+
75
+ assert_campfire_receives(e, [
76
+ "[Code Climate][Example]",
77
+ "New critical issue found",
78
+ "in app/user.rb line 120.",
79
+ "Details: https://codeclimate.com/repos/1/feed"
80
+ ].join(" "))
81
+ end
82
+
83
+ def test_multiple_vulnerabilities
84
+ e = event(:vulnerability, warning_type: "critical", vulnerabilities: [{
85
+ "warning_type" => "unused",
86
+ "location" => "unused"
87
+ }, {
88
+ "warning_type" => "unused",
89
+ "location" => "unused"
90
+ }])
91
+
92
+ assert_campfire_receives(e, [
93
+ "[Code Climate][Example]",
94
+ "2 new critical issues found.",
95
+ "Details: https://codeclimate.com/repos/1/feed"
96
+ ].join(" "))
97
+ end
98
+
99
+ def test_receive_test
100
+ @stubs.post request_url do |env|
101
+ [200, {}, '']
102
+ end
103
+
104
+ response = receive_event(name: "test")
105
+
106
+ assert_equal "Test message sent", response[:message]
107
+ end
108
+
109
+ private
110
+
111
+ def speak_uri
112
+ "https://#{subdomain}.campfirenow.com#{request_url}"
113
+ end
114
+
115
+ def request_url
116
+ "/room/#{room}/speak.json"
117
+ end
118
+
119
+ def subdomain
120
+ "sub"
121
+ end
122
+
123
+ def room
124
+ "123"
125
+ end
126
+
127
+ def assert_campfire_receives(event_data, expected_body)
128
+ @stubs.post request_url do |env|
129
+ body = JSON.parse(env[:body])
130
+ assert_equal expected_body, body["message"]["body"]
131
+ [200, {}, '']
132
+ end
133
+
134
+ receive_event(event_data)
135
+ end
136
+
137
+ def receive_event(event_data = nil)
138
+ receive(
139
+ CC::Service::Campfire,
140
+ { token: "token", subdomain: subdomain, room_id: room},
141
+ event_data || event(:quality, to: "D", from: "C")
142
+ )
143
+ end
144
+ end
data/test/fixtures.rb ADDED
@@ -0,0 +1,68 @@
1
+ class EventFixtures
2
+ attr_reader :options
3
+
4
+ REMEDIATIONS = {
5
+ "A" => 0,
6
+ "B" => 10,
7
+ "C" => 15,
8
+ "D" => 20,
9
+ "F" => 25,
10
+ }
11
+
12
+ def initialize(options)
13
+ @options = {
14
+ repo_name: "Example",
15
+ details_url: "https://codeclimate.com/repos/1/feed",
16
+ compare_url: "https://codeclimate.com/repos/1/compare",
17
+ }.merge(options)
18
+ end
19
+
20
+ # Options: to, from
21
+ def coverage
22
+ to = options.delete(:to)
23
+ from = options.delete(:from)
24
+ delta = (to - from).round(1)
25
+
26
+ options.merge(
27
+ name: "coverage",
28
+ covered_percent: to,
29
+ previous_covered_percent: from,
30
+ covered_percent_delta: delta
31
+ )
32
+ end
33
+
34
+ # Options: to, from
35
+ def quality
36
+ to = options.delete(:to)
37
+ from = options.delete(:from)
38
+
39
+ options.merge(
40
+ name: "quality",
41
+ constant_name: "User",
42
+ rating: to,
43
+ previous_rating: from,
44
+ remediation_cost: REMEDIATIONS[to],
45
+ previous_remediation_cost: REMEDIATIONS[from]
46
+ )
47
+ end
48
+
49
+ # Options: warning_type, vulnerabilities
50
+ def vulnerability
51
+ options.merge(name: "vulnerability")
52
+ end
53
+
54
+ def issue
55
+ options.merge(name: "issue")
56
+ end
57
+
58
+ end
59
+
60
+ def event(name, options = {})
61
+ fixtures = EventFixtures.new(options)
62
+
63
+ if fixtures.respond_to?(name)
64
+ fixtures.send(name)
65
+ else
66
+ raise ArgumentError, "No such fixture: #{name}"
67
+ end
68
+ end
@@ -0,0 +1,148 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestFlowdock < CC::Service::TestCase
4
+ def test_valid_project_parameter
5
+ @stubs.post '/v1/messages/team_inbox/token' do |env|
6
+ body = Hash[URI.decode_www_form(env[:body])]
7
+ assert_equal "Exampleorg", body["project"]
8
+ [200, {}, '']
9
+ end
10
+
11
+ receive(
12
+ CC::Service::Flowdock,
13
+ { api_token: "token" },
14
+ { name: "test", repo_name: "Example.org" }
15
+ )
16
+ end
17
+
18
+ def test_test_hook
19
+ assert_flowdock_receives(
20
+ "Test",
21
+ { name: "test", repo_name: "Example" },
22
+ "This is a test of the Flowdock service hook"
23
+ )
24
+ end
25
+
26
+ def test_coverage_improved
27
+ e = event(:coverage, to: 90.2, from: 80)
28
+
29
+ assert_flowdock_receives("Coverage", e, [
30
+ "<a href=\"https://codeclimate.com/repos/1/feed\">Test coverage</a>",
31
+ "has improved to 90.2% (+10.2%)",
32
+ "(<a href=\"https://codeclimate.com/repos/1/compare\">Compare</a>)"
33
+ ].join(" "))
34
+ end
35
+
36
+ def test_coverage_declined
37
+ e = event(:coverage, to: 88.6, from: 94.6)
38
+
39
+ assert_flowdock_receives("Coverage", e, [
40
+ "<a href=\"https://codeclimate.com/repos/1/feed\">Test coverage</a>",
41
+ "has declined to 88.6% (-6.0%)",
42
+ "(<a href=\"https://codeclimate.com/repos/1/compare\">Compare</a>)"
43
+ ].join(" "))
44
+ end
45
+
46
+ def test_quality_improved
47
+ e = event(:quality, to: "A", from: "B")
48
+
49
+ assert_flowdock_receives("Quality", e, [
50
+ "<a href=\"https://codeclimate.com/repos/1/feed\">User</a>",
51
+ "has improved from a B to an A",
52
+ "(<a href=\"https://codeclimate.com/repos/1/compare\">Compare</a>)"
53
+ ].join(" "))
54
+ end
55
+
56
+ def test_quality_declined
57
+ e = event(:quality, to: "D", from: "C")
58
+
59
+ assert_flowdock_receives("Quality", e, [
60
+ "<a href=\"https://codeclimate.com/repos/1/feed\">User</a>",
61
+ "has declined from a C to a D",
62
+ "(<a href=\"https://codeclimate.com/repos/1/compare\">Compare</a>)"
63
+ ].join(" "))
64
+ end
65
+
66
+ def test_single_vulnerability
67
+ e = event(:vulnerability, vulnerabilities: [
68
+ { "warning_type" => "critical" }
69
+ ])
70
+
71
+ assert_flowdock_receives("Vulnerability", e, [
72
+ "New <a href=\"https://codeclimate.com/repos/1/feed\">critical</a>",
73
+ "issue found",
74
+ ].join(" "))
75
+ end
76
+
77
+ def test_single_vulnerability_with_location
78
+ e = event(:vulnerability, vulnerabilities: [{
79
+ "warning_type" => "critical",
80
+ "location" => "app/user.rb line 120"
81
+ }])
82
+
83
+ assert_flowdock_receives("Vulnerability", e, [
84
+ "New <a href=\"https://codeclimate.com/repos/1/feed\">critical</a>",
85
+ "issue found in app/user.rb line 120",
86
+ ].join(" "))
87
+ end
88
+
89
+ def test_multiple_vulnerabilities
90
+ e = event(:vulnerability, warning_type: "critical", vulnerabilities: [{
91
+ "warning_type" => "unused",
92
+ "location" => "unused"
93
+ }, {
94
+ "warning_type" => "unused",
95
+ "location" => "unused"
96
+ }])
97
+
98
+ assert_flowdock_receives("Vulnerability", e, [
99
+ "2 new <a href=\"https://codeclimate.com/repos/1/feed\">critical</a>",
100
+ "issues found",
101
+ ].join(" "))
102
+ end
103
+
104
+ def test_receive_test
105
+ @stubs.post request_url do |env|
106
+ [200, {}, '']
107
+ end
108
+
109
+ response = receive_event(name: "test", repo_name: "foo")
110
+
111
+ assert_equal "Test message sent", response[:message]
112
+ end
113
+
114
+ private
115
+
116
+ def endpoint_url
117
+ "https://api.flowdock.com#{request_url}"
118
+ end
119
+
120
+ def request_url
121
+ "/v1/messages/team_inbox/#{token}"
122
+ end
123
+
124
+ def token
125
+ "token"
126
+ end
127
+
128
+ def assert_flowdock_receives(subject, event_data, expected_body)
129
+ @stubs.post request_url do |env|
130
+ body = Hash[URI.decode_www_form(env[:body])]
131
+ assert_equal "Code Climate", body["source"]
132
+ assert_equal "hello@codeclimate.com", body["from_address"]
133
+ assert_equal "Code Climate", body["from_name"]
134
+ assert_equal "html", body["format"]
135
+ assert_equal subject, body["subject"]
136
+ assert_equal "Example", body["project"]
137
+ assert_equal expected_body, body["content"]
138
+ assert_equal "https://codeclimate.com", body["link"]
139
+ [200, {}, '']
140
+ end
141
+
142
+ receive_event(event_data)
143
+ end
144
+
145
+ def receive_event(event_data = nil)
146
+ receive(CC::Service::Flowdock, { api_token: "token" }, event_data || event(:quality, from: "D", to: "C"))
147
+ end
148
+ end
@@ -0,0 +1,47 @@
1
+ require "helper"
2
+
3
+ class TestSnapshotFormatter < Test::Unit::TestCase
4
+ def described_class
5
+ CC::Formatters::SnapshotFormatter::Base
6
+ end
7
+
8
+ def test_quality_alert_with_new_constants
9
+ f = described_class.new({"new_constants" => [{"to" => {"rating" => "D"}}], "changed_constants" => []})
10
+ refute_nil f.alert_constants_payload
11
+ end
12
+
13
+ def test_quality_alert_with_decreased_constants
14
+ f = described_class.new({"new_constants" => [],
15
+ "changed_constants" => [{"to" => {"rating" => "D"}, "from" => {"rating" => "A"}}]
16
+ })
17
+ refute_nil f.alert_constants_payload
18
+ end
19
+
20
+ def test_quality_improvements_with_better_ratings
21
+ f = described_class.new({"new_constants" => [],
22
+ "changed_constants" => [{"to" => {"rating" => "A"}, "from" => {"rating" => "D"}}]
23
+ })
24
+ refute_nil f.improved_constants_payload
25
+ end
26
+
27
+ def test_nothing_set_without_changes
28
+ f = described_class.new({"new_constants" => [], "changed_constants" => []})
29
+ assert_nil f.alert_constants_payload
30
+ assert_nil f.improved_constants_payload
31
+ end
32
+
33
+ def test_snapshot_formatter_test_with_relaxed_constraints
34
+ f = CC::Formatters::SnapshotFormatter::Sample.new({
35
+ "new_constants" => [{"name" => "foo", "to" => {"rating" => "A"}}, {"name" => "bar", "to" => {"rating" => "A"}}],
36
+ "changed_constants" => [
37
+ {"from" => {"rating" => "B"}, "to" => {"rating" => "C"}},
38
+ {"from" => {"rating" => "D"}, "to" => {"rating" => "D"}},
39
+ {"from" => {"rating" => "D"}, "to" => {"rating" => "D"}},
40
+ {"from" => {"rating" => "A"}, "to" => {"rating" => "B"}},
41
+ {"from" => {"rating" => "C"}, "to" => {"rating" => "B"}}
42
+ ]})
43
+
44
+ refute_nil f.alert_constants_payload
45
+ refute_nil f.improved_constants_payload
46
+ end
47
+ end
@@ -0,0 +1,96 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestGitHubIssues < CC::Service::TestCase
4
+ def test_creation_success
5
+ id = 1234
6
+ number = 123
7
+ url = "https://github.com/#{project}/pulls/#{number}"
8
+ stub_http(request_url, [201, {}, %<{"id": #{id}, "number": #{number}, "html_url":"#{url}"}>])
9
+
10
+ response = receive_event
11
+
12
+ assert_equal id, response[:id]
13
+ assert_equal number, response[:number]
14
+ assert_equal url, response[:url]
15
+ end
16
+
17
+ def test_quality
18
+ assert_github_receives(
19
+ event(:quality, to: "D", from: "C"),
20
+ "Refactor User from a D on Code Climate",
21
+ "https://codeclimate.com/repos/1/feed"
22
+ )
23
+ end
24
+
25
+ def test_issue
26
+ payload = {
27
+ issue: {
28
+ "check_name" => "Style/LongLine",
29
+ "description" => "Line is too long [1000/80]"
30
+ },
31
+ constant_name: "foo.rb",
32
+ details_url: "http://example.com/repos/id/foo.rb#issue_123"
33
+ }
34
+
35
+ assert_github_receives(
36
+ event(:issue, payload),
37
+ "Fix \"Style/LongLine\" issue in foo.rb",
38
+ "Line is too long [1000/80]\n\nhttp://example.com/repos/id/foo.rb#issue_123"
39
+ )
40
+ end
41
+
42
+ def test_vulnerability
43
+ assert_github_receives(
44
+ event(:vulnerability, vulnerabilities: [{
45
+ "warning_type" => "critical",
46
+ "location" => "app/user.rb line 120"
47
+ }]),
48
+ "New critical issue found in app/user.rb line 120",
49
+ "A critical vulnerability was found by Code Climate in app/user.rb line 120.\n\nhttps://codeclimate.com/repos/1/feed"
50
+ )
51
+ end
52
+
53
+ def test_receive_test
54
+ @stubs.post request_url do |env|
55
+ [200, {}, '{"number": 2, "html_url": "http://foo.bar"}']
56
+ end
57
+
58
+ response = receive_event(name: "test")
59
+
60
+ assert_equal "Issue <a href='http://foo.bar'>#2</a> created.", response[:message]
61
+ end
62
+
63
+ private
64
+
65
+ def project
66
+ "brynary/test_repo"
67
+ end
68
+
69
+ def oauth_token
70
+ "123"
71
+ end
72
+
73
+ def request_url
74
+ "repos/#{project}/issues"
75
+ end
76
+
77
+ def assert_github_receives(event_data, title, ticket_body)
78
+ @stubs.post request_url do |env|
79
+ body = JSON.parse(env[:body])
80
+ assert_equal "token #{oauth_token}", env[:request_headers]["Authorization"]
81
+ assert_equal title, body["title"]
82
+ assert_equal ticket_body, body["body"]
83
+ [200, {}, '{}']
84
+ end
85
+
86
+ receive_event(event_data)
87
+ end
88
+
89
+ def receive_event(event_data = nil)
90
+ receive(
91
+ CC::Service::GitHubIssues,
92
+ { oauth_token: "123", project: project },
93
+ event_data || event(:quality, from: "D", to: "C")
94
+ )
95
+ end
96
+ end