codeclimate-services 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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