From c5a3d84c5b90748188a12a0cef600ed6991352af Mon Sep 17 00:00:00 2001 From: David Calavera Date: Tue, 9 Sep 2014 16:52:06 -0700 Subject: [PATCH 1/7] Use `receive_snapshot` to send notifications to Slack. This will send one message with an extract of the information rather than sending one message per change/improvement. --- lib/cc/formatters/snapshot_formatter.rb | 107 ++++++++++++++++++++++++ lib/cc/helpers/quality_helper.rb | 17 +++- lib/cc/service/helper.rb | 6 +- lib/cc/services/slack.rb | 75 ++++++++++++++++- 4 files changed, 195 insertions(+), 10 deletions(-) create mode 100644 lib/cc/formatters/snapshot_formatter.rb diff --git a/lib/cc/formatters/snapshot_formatter.rb b/lib/cc/formatters/snapshot_formatter.rb new file mode 100644 index 0000000..b44eda8 --- /dev/null +++ b/lib/cc/formatters/snapshot_formatter.rb @@ -0,0 +1,107 @@ +module CC::Formatters + module SnapshotFormatter + # Simple Comparator for rating letters. + class Rating + include Comparable + + def initialize(letter) + @letter = letter + end + + def <=>(other) + other.to_s <=> to_s + end + + def hash + @letter.hash + end + + def eql?(other) + to_s == other.to_s + end + + def inspect + "" + end + + def to_s + @letter.to_s + end + end + + C = Rating.new("C") + D = Rating.new("D") + + # SnapshotFormatter::Base takes the quality information from the payload and divides it + # between alerts and improvements. + # + # The information in the payload must be a comparison in time between two quality reports, aka snapshot. + # This information is in the payload when the service receive a `receive_snapshot` and also + # when it receives a `receive_test`. In this latest case, the comparison is between today and seven days ago. + class Base + attr_reader :alert_constants_payload, :improved_constants_payload, :details_url, :compare_url + + def initialize(repo, payload) + @repo = repo + + new_constants = Array(payload["new_constants"]) + changed_constants = Array(payload["changed_constants"]) + + alert_constants = new_constants.select(new_constants_selector) + alert_constants += changed_constants.select(decreased_constants_selector) + + improved_constants = changed_constants.select(improved_constants_selector) + + data = { + from: { commit_sha: payload["previous_commit_sha"] }, + to: { commit_sha: payload["commit_sha"] } + } + + @alert_constants_payload = data.merge(constants: alert_constants) if alert_constants.any? + @improved_constants_payload = data.merge(constants: improved_constants) if improved_constants.any? + end + + private + + def new_constant_selector + Proc.new { |constant| to_rating(constant) < C } + end + + def decreased_constants_selector + Proc.new { |constant| from_rating(constant) > D && to_rating(constant) < C } + end + + def improved_constants_selector + Proc.new { |constant| from_rating(constant) < C && to_rating(constant) > from_rating(constant) } + end + + def repo_identifier + repo.human_name + end + + def to_rating(constant) + Rating.new(constant["to"]["rating"]) + end + + def from_rating(constant) + Rating.new(constant["from"]["rating"]) + end + end + + # Override the base snapshot formatter for be more lax grouping information. + # This is useful to show more information for testing the service. + class Sample < Base + def new_constant_selector + Proc.new { |_| true } + end + + def decreased_constants_selector + Proc.new { |constant| to_rating(constant) < from_rating(constant) } + end + + def improved_constants_selector + Proc.new { |constant| to_rating(constant) > from_rating(constant) } + end + end + end +end diff --git a/lib/cc/helpers/quality_helper.rb b/lib/cc/helpers/quality_helper.rb index 46b8fb1..126a022 100644 --- a/lib/cc/helpers/quality_helper.rb +++ b/lib/cc/helpers/quality_helper.rb @@ -23,13 +23,22 @@ def previous_remediation_cost payload.fetch("previous_remediation_cost", 0) end - def with_article(letter) + def with_article(letter, bold = false) letter ||= '?' - if %w( A F ).include?(letter) - "an #{letter}" + text = bold ? "*#{letter}*" : letter + if %w( A F ).include?(letter.to_s) + "an #{text}" else - "a #{letter}" + "a #{text}" + end + end + + def constant_basename(name) + if name.include?(".") + file.basename(name) + else + name end end end diff --git a/lib/cc/service/helper.rb b/lib/cc/service/helper.rb index 2bcecff..d6d2598 100644 --- a/lib/cc/service/helper.rb +++ b/lib/cc/service/helper.rb @@ -1,4 +1,6 @@ module CC::Service::Helper + GREEN_HEX = "#38ae6f" + RED_HEX = "#ed2f00" def repo_name payload["repo_name"] @@ -30,9 +32,9 @@ def color def hex_color if improved? - "#38ae6f" + GREEN_HEX else - "#ed2f00" + RED_HEX end end diff --git a/lib/cc/services/slack.rb b/lib/cc/services/slack.rb index f982447..4b4f21d 100644 --- a/lib/cc/services/slack.rb +++ b/lib/cc/services/slack.rb @@ -1,3 +1,5 @@ + # encoding: UTF-8 + class CC::Service::Slack < CC::Service class Config < CC::Service::Config attribute :webhook_url, String, @@ -13,17 +15,20 @@ class Config < CC::Service::Config def receive_test speak(formatter.format_test) + # payloads for test receivers include the weekly quality report. + send_snapshot_to_slack(CC::Formatters::SnapshotFormatter::Test.new(repo, payload)) + { ok: true, message: "Test message sent" } rescue => ex { ok: false, message: ex.message } end - def receive_coverage - speak(formatter.format_coverage, hex_color) + def receive_snapshot + send_snapshot_to_slack(CC::Formatters::SnapshotFormatter::Base.new(repo, payload)) end - def receive_quality - speak(formatter.format_quality, hex_color) + def receive_coverage + speak(formatter.format_coverage, hex_color) end def receive_vulnerability @@ -51,4 +56,66 @@ def speak(message, color = nil) http.headers['Content-Type'] = 'application/json' http_post(config.webhook_url, body.to_json) end + + def send_snapshot_to_slack(payload, sample = false) + snapshot = SnapshotEventFormatter.new(repo, payload, sample) + + if formatter.alert_constants_payload + speak(alerts_message(snapshot), RED_HEX) + end + + if formatter.improved_constants_payload + speak(improvements_message(snapshot), GREEN_HEX) + end + end + + def alert_message(snapshot) + constants = snapshot.alert_constants_payload + + message = ["Quality alert triggered for *#{repo_identifier}* (<#{compare_url}|Compare>)\n"] + + constants[0..2].each do |constant| + object_identifier = constant_basename(constant["name"]) + + if constant["from"] + from_rating = from_rating(constant) + to_rating = to_rating(constant) + + message << "• _#{object_identifier}_ just declined from #{with_article(from_rating, :bold)} to #{with_article(to_rating, :bold)}" + else + rating = to_rating(constant) + + message << "• _#{object_identifier}_ was just created and is #{with_article(rating, :bold)} *#{rating}*" + end + end + + if constants.size > 3 + remaining = constants.size - 3 + message << "\nAnd <#{details_url}|#{remaining} other #{"change".pluralize(remaining)}>" + end + + message.join("\n") + end + + def improvement_message(snapshot) + constants = snapshot.improved_constants_payload + + message = ["Quality improvements in *#{repo_identifier}* (<#{compare_url}|Compare>)\n"] + + constants[0..2].each do |constant| + object_identifier = constant_basename(constant["name"]) + from_rating = from_rating(constant) + to_rating = to_rating(constant) + + message << "• _#{object_identifier}_ just improved from #{with_article(from_rating, :bold)} to #{with_article(to_rating, :bold)}" + end + + if constants.size > 3 + remaining = constants.size - 3 + message << "\nAnd <#{details_url}|#{remaining} other #{"improvement".pluralize(remaining)}>" + end + + message.join("\n") + end +end end From 369809ee63fa77f6632078a5a8a21a2e89d82230 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Tue, 9 Sep 2014 17:03:19 -0700 Subject: [PATCH 2/7] Remove unused tests. --- lib/cc/services/slack.rb | 1 - test/slack_test.rb | 22 ---------------------- 2 files changed, 23 deletions(-) diff --git a/lib/cc/services/slack.rb b/lib/cc/services/slack.rb index 4b4f21d..f24a3bd 100644 --- a/lib/cc/services/slack.rb +++ b/lib/cc/services/slack.rb @@ -118,4 +118,3 @@ def improvement_message(snapshot) message.join("\n") end end -end diff --git a/test/slack_test.rb b/test/slack_test.rb index 473c943..db67008 100644 --- a/test/slack_test.rb +++ b/test/slack_test.rb @@ -31,28 +31,6 @@ def test_coverage_declined ].join(" ")) end - def test_quality_improved - e = event(:quality, to: "A", from: "B") - - assert_slack_receives("#38ae6f", e, [ - "[Example]", - "", - "has improved from a B to an A", - "()" - ].join(" ")) - end - - def test_quality_declined_without_compare_url - e = event(:quality, to: "D", from: "C") - - assert_slack_receives("#ed2f00", e, [ - "[Example]", - "", - "has declined from a C to a D", - "()" - ].join(" ")) - end - def test_single_vulnerability e = event(:vulnerability, vulnerabilities: [ { "warning_type" => "critical" } From c9f9f88a9c53155fc1214ee0e03156273c63d9d3 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Tue, 9 Sep 2014 17:11:55 -0700 Subject: [PATCH 3/7] Fix `new_constants_selector` method name. --- lib/cc/formatters/snapshot_formatter.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cc/formatters/snapshot_formatter.rb b/lib/cc/formatters/snapshot_formatter.rb index b44eda8..0a6845d 100644 --- a/lib/cc/formatters/snapshot_formatter.rb +++ b/lib/cc/formatters/snapshot_formatter.rb @@ -63,7 +63,7 @@ def initialize(repo, payload) private - def new_constant_selector + def new_constants_selector Proc.new { |constant| to_rating(constant) < C } end @@ -91,7 +91,7 @@ def from_rating(constant) # Override the base snapshot formatter for be more lax grouping information. # This is useful to show more information for testing the service. class Sample < Base - def new_constant_selector + def new_constants_selector Proc.new { |_| true } end From 555fb08bbcc50aeae6687786f12c114098bedf2d Mon Sep 17 00:00:00 2001 From: David Calavera Date: Tue, 9 Sep 2014 17:34:33 -0700 Subject: [PATCH 4/7] Add test for the snapshot formatters. --- Rakefile | 3 +- lib/cc/formatters/snapshot_formatter.rb | 18 ++++----- lib/cc/services/slack.rb | 2 +- test/formatters/snapshot_formatter_test.rb | 47 ++++++++++++++++++++++ 4 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 test/formatters/snapshot_formatter_test.rb diff --git a/Rakefile b/Rakefile index 3ff612b..0dd2636 100644 --- a/Rakefile +++ b/Rakefile @@ -3,7 +3,8 @@ require 'rake/testtask' Rake::TestTask.new do |t| t.libs.push "lib" - t.test_files = FileList['test/*_test.rb'] + t.libs.push "test" + t.test_files = FileList['test/**/*_test.rb'] t.verbose = true end diff --git a/lib/cc/formatters/snapshot_formatter.rb b/lib/cc/formatters/snapshot_formatter.rb index 0a6845d..856a355 100644 --- a/lib/cc/formatters/snapshot_formatter.rb +++ b/lib/cc/formatters/snapshot_formatter.rb @@ -44,17 +44,17 @@ class Base def initialize(repo, payload) @repo = repo - new_constants = Array(payload["new_constants"]) - changed_constants = Array(payload["changed_constants"]) + new_constants = Array(payload[:new_constants]) + changed_constants = Array(payload[:changed_constants]) - alert_constants = new_constants.select(new_constants_selector) - alert_constants += changed_constants.select(decreased_constants_selector) + alert_constants = new_constants.select(&new_constants_selector) + alert_constants += changed_constants.select(&decreased_constants_selector) - improved_constants = changed_constants.select(improved_constants_selector) + improved_constants = changed_constants.select(&improved_constants_selector) data = { - from: { commit_sha: payload["previous_commit_sha"] }, - to: { commit_sha: payload["commit_sha"] } + from: { commit_sha: payload[:previous_commit_sha] }, + to: { commit_sha: payload[:commit_sha] } } @alert_constants_payload = data.merge(constants: alert_constants) if alert_constants.any? @@ -80,11 +80,11 @@ def repo_identifier end def to_rating(constant) - Rating.new(constant["to"]["rating"]) + Rating.new(constant[:to][:rating]) end def from_rating(constant) - Rating.new(constant["from"]["rating"]) + Rating.new(constant[:from][:rating]) end end diff --git a/lib/cc/services/slack.rb b/lib/cc/services/slack.rb index f24a3bd..c163a9a 100644 --- a/lib/cc/services/slack.rb +++ b/lib/cc/services/slack.rb @@ -16,7 +16,7 @@ def receive_test speak(formatter.format_test) # payloads for test receivers include the weekly quality report. - send_snapshot_to_slack(CC::Formatters::SnapshotFormatter::Test.new(repo, payload)) + send_snapshot_to_slack(CC::Formatters::SnapshotFormatter::Sample.new(repo, payload)) { ok: true, message: "Test message sent" } rescue => ex diff --git a/test/formatters/snapshot_formatter_test.rb b/test/formatters/snapshot_formatter_test.rb new file mode 100644 index 0000000..9bc5c12 --- /dev/null +++ b/test/formatters/snapshot_formatter_test.rb @@ -0,0 +1,47 @@ +require "helper" + +class TestSnapshotFormatter < Test::Unit::TestCase + def described_class + CC::Formatters::SnapshotFormatter::Base + end + + def test_quality_alert_with_new_constants + f = described_class.new(nil, {new_constants: [{to: {rating: "D"}}], changed_constants: []}) + refute_nil f.alert_constants_payload + end + + def test_quality_alert_with_decreased_constants + f = described_class.new(nil, {new_constants: [], + changed_constants: [{to: {rating: "D"}, from: {rating: "A"}}] + }) + refute_nil f.alert_constants_payload + end + + def test_quality_improvements_with_better_ratings + f = described_class.new(nil, {new_constants: [], + changed_constants: [{to: {rating: "A"}, from: {rating: "D"}}] + }) + refute_nil f.improved_constants_payload + end + + def test_nothing_set_without_changes + f = described_class.new(nil, {new_constants: [], changed_constants: []}) + assert_nil f.alert_constants_payload + assert_nil f.improved_constants_payload + end + + def test_snapshot_formatter_test_with_relaxed_constraints + f = CC::Formatters::SnapshotFormatter::Sample.new(nil, { + new_constants: [{name: "foo", to: {rating: "A"}}, {name: "bar", to: {rating: "A"}}], + changed_constants: [ + {from: {rating: "B"}, to: {rating: "C"}}, + {from: {rating: "D"}, to: {rating: "D"}}, + {from: {rating: "D"}, to: {rating: "D"}}, + {from: {rating: "A"}, to: {rating: "B"}}, + {from: {rating: "C"}, to: {rating: "B"}} + ]}) + + refute_nil f.alert_constants_payload + refute_nil f.improved_constants_payload + end +end From 48d07a3bd3029fb5906888f345ac8689ef0ed7e7 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Tue, 9 Sep 2014 18:31:40 -0700 Subject: [PATCH 5/7] Remove repo dependency. --- lib/cc/formatters/snapshot_formatter.rb | 8 +------- lib/cc/services/slack.rb | 4 ++-- test/formatters/snapshot_formatter_test.rb | 10 +++++----- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/lib/cc/formatters/snapshot_formatter.rb b/lib/cc/formatters/snapshot_formatter.rb index 856a355..06a615c 100644 --- a/lib/cc/formatters/snapshot_formatter.rb +++ b/lib/cc/formatters/snapshot_formatter.rb @@ -41,9 +41,7 @@ def to_s class Base attr_reader :alert_constants_payload, :improved_constants_payload, :details_url, :compare_url - def initialize(repo, payload) - @repo = repo - + def initialize(payload) new_constants = Array(payload[:new_constants]) changed_constants = Array(payload[:changed_constants]) @@ -75,10 +73,6 @@ def improved_constants_selector Proc.new { |constant| from_rating(constant) < C && to_rating(constant) > from_rating(constant) } end - def repo_identifier - repo.human_name - end - def to_rating(constant) Rating.new(constant[:to][:rating]) end diff --git a/lib/cc/services/slack.rb b/lib/cc/services/slack.rb index c163a9a..ecbb70f 100644 --- a/lib/cc/services/slack.rb +++ b/lib/cc/services/slack.rb @@ -16,7 +16,7 @@ def receive_test speak(formatter.format_test) # payloads for test receivers include the weekly quality report. - send_snapshot_to_slack(CC::Formatters::SnapshotFormatter::Sample.new(repo, payload)) + send_snapshot_to_slack(CC::Formatters::SnapshotFormatter::Sample.new(payload)) { ok: true, message: "Test message sent" } rescue => ex @@ -24,7 +24,7 @@ def receive_test end def receive_snapshot - send_snapshot_to_slack(CC::Formatters::SnapshotFormatter::Base.new(repo, payload)) + send_snapshot_to_slack(CC::Formatters::SnapshotFormatter::Base.new(payload)) end def receive_coverage diff --git a/test/formatters/snapshot_formatter_test.rb b/test/formatters/snapshot_formatter_test.rb index 9bc5c12..707821b 100644 --- a/test/formatters/snapshot_formatter_test.rb +++ b/test/formatters/snapshot_formatter_test.rb @@ -6,32 +6,32 @@ def described_class end def test_quality_alert_with_new_constants - f = described_class.new(nil, {new_constants: [{to: {rating: "D"}}], changed_constants: []}) + f = described_class.new({new_constants: [{to: {rating: "D"}}], changed_constants: []}) refute_nil f.alert_constants_payload end def test_quality_alert_with_decreased_constants - f = described_class.new(nil, {new_constants: [], + f = described_class.new({new_constants: [], changed_constants: [{to: {rating: "D"}, from: {rating: "A"}}] }) refute_nil f.alert_constants_payload end def test_quality_improvements_with_better_ratings - f = described_class.new(nil, {new_constants: [], + f = described_class.new({new_constants: [], changed_constants: [{to: {rating: "A"}, from: {rating: "D"}}] }) refute_nil f.improved_constants_payload end def test_nothing_set_without_changes - f = described_class.new(nil, {new_constants: [], changed_constants: []}) + f = described_class.new({new_constants: [], changed_constants: []}) assert_nil f.alert_constants_payload assert_nil f.improved_constants_payload end def test_snapshot_formatter_test_with_relaxed_constraints - f = CC::Formatters::SnapshotFormatter::Sample.new(nil, { + f = CC::Formatters::SnapshotFormatter::Sample.new({ new_constants: [{name: "foo", to: {rating: "A"}}, {name: "bar", to: {rating: "A"}}], changed_constants: [ {from: {rating: "B"}, to: {rating: "C"}}, From daccb23145d7905521c8e0713eb699106ecb0510 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Wed, 10 Sep 2014 09:54:48 -0700 Subject: [PATCH 6/7] Make sure the format for the Slack notifications is correct. --- lib/cc/formatters/snapshot_formatter.rb | 16 ++-- lib/cc/helpers/quality_helper.rb | 2 +- lib/cc/services/slack.rb | 40 +++++----- test/formatters/snapshot_formatter_test.rb | 26 +++---- test/slack_test.rb | 90 ++++++++++++++++++++++ 5 files changed, 131 insertions(+), 43 deletions(-) diff --git a/lib/cc/formatters/snapshot_formatter.rb b/lib/cc/formatters/snapshot_formatter.rb index 06a615c..e8f7704 100644 --- a/lib/cc/formatters/snapshot_formatter.rb +++ b/lib/cc/formatters/snapshot_formatter.rb @@ -42,8 +42,8 @@ class Base attr_reader :alert_constants_payload, :improved_constants_payload, :details_url, :compare_url def initialize(payload) - new_constants = Array(payload[:new_constants]) - changed_constants = Array(payload[:changed_constants]) + new_constants = Array(payload["new_constants"]) + changed_constants = Array(payload["changed_constants"]) alert_constants = new_constants.select(&new_constants_selector) alert_constants += changed_constants.select(&decreased_constants_selector) @@ -51,12 +51,12 @@ def initialize(payload) improved_constants = changed_constants.select(&improved_constants_selector) data = { - from: { commit_sha: payload[:previous_commit_sha] }, - to: { commit_sha: payload[:commit_sha] } + "from" => { "commit_sha" => payload["previous_commit_sha"] }, + "to" => { "commit_sha" => payload["commit_sha"] } } - @alert_constants_payload = data.merge(constants: alert_constants) if alert_constants.any? - @improved_constants_payload = data.merge(constants: improved_constants) if improved_constants.any? + @alert_constants_payload = data.merge("constants" => alert_constants) if alert_constants.any? + @improved_constants_payload = data.merge("constants" => improved_constants) if improved_constants.any? end private @@ -74,11 +74,11 @@ def improved_constants_selector end def to_rating(constant) - Rating.new(constant[:to][:rating]) + Rating.new(constant["to"]["rating"]) end def from_rating(constant) - Rating.new(constant[:from][:rating]) + Rating.new(constant["from"]["rating"]) end end diff --git a/lib/cc/helpers/quality_helper.rb b/lib/cc/helpers/quality_helper.rb index 126a022..ffb0205 100644 --- a/lib/cc/helpers/quality_helper.rb +++ b/lib/cc/helpers/quality_helper.rb @@ -36,7 +36,7 @@ def with_article(letter, bold = false) def constant_basename(name) if name.include?(".") - file.basename(name) + File.basename(name) else name end diff --git a/lib/cc/services/slack.rb b/lib/cc/services/slack.rb index ecbb70f..605dd80 100644 --- a/lib/cc/services/slack.rb +++ b/lib/cc/services/slack.rb @@ -1,6 +1,8 @@ # encoding: UTF-8 class CC::Service::Slack < CC::Service + include CC::Service::QualityHelper + class Config < CC::Service::Config attribute :webhook_url, String, label: "Webhook URL", @@ -57,35 +59,32 @@ def speak(message, color = nil) http_post(config.webhook_url, body.to_json) end - def send_snapshot_to_slack(payload, sample = false) - snapshot = SnapshotEventFormatter.new(repo, payload, sample) - - if formatter.alert_constants_payload - speak(alerts_message(snapshot), RED_HEX) + def send_snapshot_to_slack(snapshot) + if snapshot.alert_constants_payload + speak(alerts_message(snapshot.alert_constants_payload), RED_HEX) end - if formatter.improved_constants_payload - speak(improvements_message(snapshot), GREEN_HEX) + if snapshot.improved_constants_payload + speak(improvements_message(snapshot.improved_constants_payload), GREEN_HEX) end end - def alert_message(snapshot) - constants = snapshot.alert_constants_payload - - message = ["Quality alert triggered for *#{repo_identifier}* (<#{compare_url}|Compare>)\n"] + def alerts_message(constants_payload) + constants = constants_payload["constants"] + message = ["Quality alert triggered for *#{repo_name}* (<#{compare_url}|Compare>)\n"] constants[0..2].each do |constant| object_identifier = constant_basename(constant["name"]) if constant["from"] - from_rating = from_rating(constant) - to_rating = to_rating(constant) + from_rating = constant["from"]["rating"] + to_rating = constant["to"]["rating"] message << "• _#{object_identifier}_ just declined from #{with_article(from_rating, :bold)} to #{with_article(to_rating, :bold)}" else - rating = to_rating(constant) + rating = constant["to"]["rating"] - message << "• _#{object_identifier}_ was just created and is #{with_article(rating, :bold)} *#{rating}*" + message << "• _#{object_identifier}_ was just created and is #{with_article(rating, :bold)}" end end @@ -97,15 +96,14 @@ def alert_message(snapshot) message.join("\n") end - def improvement_message(snapshot) - constants = snapshot.improved_constants_payload - - message = ["Quality improvements in *#{repo_identifier}* (<#{compare_url}|Compare>)\n"] + def improvements_message(constants_payload) + constants = constants_payload["constants"] + message = ["Quality improvements in *#{repo_name}* (<#{compare_url}|Compare>)\n"] constants[0..2].each do |constant| object_identifier = constant_basename(constant["name"]) - from_rating = from_rating(constant) - to_rating = to_rating(constant) + from_rating = constant["from"]["rating"] + to_rating = constant["to"]["rating"] message << "• _#{object_identifier}_ just improved from #{with_article(from_rating, :bold)} to #{with_article(to_rating, :bold)}" end diff --git a/test/formatters/snapshot_formatter_test.rb b/test/formatters/snapshot_formatter_test.rb index 707821b..c6b729c 100644 --- a/test/formatters/snapshot_formatter_test.rb +++ b/test/formatters/snapshot_formatter_test.rb @@ -6,39 +6,39 @@ def described_class end def test_quality_alert_with_new_constants - f = described_class.new({new_constants: [{to: {rating: "D"}}], changed_constants: []}) + f = described_class.new({"new_constants" => [{"to" => {"rating" => "D"}}], "changed_constants" => []}) refute_nil f.alert_constants_payload end def test_quality_alert_with_decreased_constants - f = described_class.new({new_constants: [], - changed_constants: [{to: {rating: "D"}, from: {rating: "A"}}] + f = described_class.new({"new_constants" => [], + "changed_constants" => [{"to" => {"rating" => "D"}, "from" => {"rating" => "A"}}] }) refute_nil f.alert_constants_payload end def test_quality_improvements_with_better_ratings - f = described_class.new({new_constants: [], - changed_constants: [{to: {rating: "A"}, from: {rating: "D"}}] + f = described_class.new({"new_constants" => [], + "changed_constants" => [{"to" => {"rating" => "A"}, "from" => {"rating" => "D"}}] }) refute_nil f.improved_constants_payload end def test_nothing_set_without_changes - f = described_class.new({new_constants: [], changed_constants: []}) + f = described_class.new({"new_constants" => [], "changed_constants" => []}) assert_nil f.alert_constants_payload assert_nil f.improved_constants_payload end def test_snapshot_formatter_test_with_relaxed_constraints f = CC::Formatters::SnapshotFormatter::Sample.new({ - new_constants: [{name: "foo", to: {rating: "A"}}, {name: "bar", to: {rating: "A"}}], - changed_constants: [ - {from: {rating: "B"}, to: {rating: "C"}}, - {from: {rating: "D"}, to: {rating: "D"}}, - {from: {rating: "D"}, to: {rating: "D"}}, - {from: {rating: "A"}, to: {rating: "B"}}, - {from: {rating: "C"}, to: {rating: "B"}} + "new_constants" => [{"name" => "foo", "to" => {"rating" => "A"}}, {"name" => "bar", "to" => {"rating" => "A"}}], + "changed_constants" => [ + {"from" => {"rating" => "B"}, "to" => {"rating" => "C"}}, + {"from" => {"rating" => "D"}, "to" => {"rating" => "D"}}, + {"from" => {"rating" => "D"}, "to" => {"rating" => "D"}}, + {"from" => {"rating" => "A"}, "to" => {"rating" => "B"}}, + {"from" => {"rating" => "C"}, "to" => {"rating" => "B"}} ]}) refute_nil f.alert_constants_payload diff --git a/test/slack_test.rb b/test/slack_test.rb index db67008..1ff0ef5 100644 --- a/test/slack_test.rb +++ b/test/slack_test.rb @@ -72,6 +72,96 @@ def test_multiple_vulnerabilities ].join(" ")) end + def test_quality_alert_with_new_constants + data = { "name" => "snapshot", "repo_name" => "Rails", + "new_constants" => [{"name" => "Foo", "to" => {"rating" => "D"}}, {"name" => "bar.js", "to" => {"rating" => "F"}}], + "changed_constants" => [], + "compare_url" => "https://codeclimate.com/repos/1/compare/a...z" } + + assert_slack_receives(CC::Service::Slack::RED_HEX, data, +"""Quality alert triggered for *Rails* () + +• _Foo_ was just created and is a *D* +• _bar.js_ was just created and is an *F*""") + end + + def test_quality_alert_with_new_constants_and_declined_constants + data = { "name" => "snapshot", "repo_name" => "Rails", + "new_constants" => [{"name" => "Foo", "to" => {"rating" => "D"}}], + "changed_constants" => [{"name" => "bar.js", "from" => {"rating" => "A"}, "to" => {"rating" => "F"}}], + "compare_url" => "https://codeclimate.com/repos/1/compare/a...z" } + + assert_slack_receives(CC::Service::Slack::RED_HEX, data, +"""Quality alert triggered for *Rails* () + +• _Foo_ was just created and is a *D* +• _bar.js_ just declined from an *A* to an *F*""") + end + + def test_quality_alert_with_new_constants_and_declined_constants_overflown + data = { "name" => "snapshot", "repo_name" => "Rails", + "new_constants" => [{"name" => "Foo", "to" => {"rating" => "D"}}], + "changed_constants" => [ + {"name" => "bar.js", "from" => {"rating" => "A"}, "to" => {"rating" => "F"}}, + {"name" => "baz.js", "from" => {"rating" => "B"}, "to" => {"rating" => "D"}}, + {"name" => "Qux", "from" => {"rating" => "A"}, "to" => {"rating" => "D"}} + ], + "compare_url" => "https://codeclimate.com/repos/1/compare/a...z", + "details_url" => "https://codeclimate.com/repos/1/feed" + } + + + assert_slack_receives(CC::Service::Slack::RED_HEX, data, +"""Quality alert triggered for *Rails* () + +• _Foo_ was just created and is a *D* +• _bar.js_ just declined from an *A* to an *F* +• _baz.js_ just declined from a *B* to a *D* + +And """) + end + + def test_quality_improvements + data = { "name" => "snapshot", "repo_name" => "Rails", + "new_constants" => [], + "changed_constants" => [ + {"name" => "bar.js", "from" => {"rating" => "F"}, "to" => {"rating" => "A"}}, + ], + "compare_url" => "https://codeclimate.com/repos/1/compare/a...z", + "details_url" => "https://codeclimate.com/repos/1/feed" + } + + + assert_slack_receives(CC::Service::Slack::GREEN_HEX, data, +"""Quality improvements in *Rails* () + +• _bar.js_ just improved from an *F* to an *A*""") + end + + def test_quality_improvements_overflown + data = { "name" => "snapshot", "repo_name" => "Rails", + "new_constants" => [], + "changed_constants" => [ + {"name" => "Foo", "from" => {"rating" => "F"}, "to" => {"rating" => "A"}}, + {"name" => "bar.js", "from" => {"rating" => "D"}, "to" => {"rating" => "B"}}, + {"name" => "baz.js", "from" => {"rating" => "D"}, "to" => {"rating" => "A"}}, + {"name" => "Qux", "from" => {"rating" => "F"}, "to" => {"rating" => "A"}}, + ], + "compare_url" => "https://codeclimate.com/repos/1/compare/a...z", + "details_url" => "https://codeclimate.com/repos/1/feed" + } + + + assert_slack_receives(CC::Service::Slack::GREEN_HEX, data, +"""Quality improvements in *Rails* () + +• _Foo_ just improved from an *F* to an *A* +• _bar.js_ just improved from a *D* to a *B* +• _baz.js_ just improved from a *D* to an *A* + +And """) + end + private def assert_slack_receives(color, event_data, expected_body) From 6ce43cdd2b12f1f05df01528b4e2336e443e41f1 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Wed, 10 Sep 2014 10:12:57 -0700 Subject: [PATCH 7/7] Set the right encoding for the Slack tests on 1.9.3. --- test/slack_test.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/slack_test.rb b/test/slack_test.rb index 1ff0ef5..9db6098 100644 --- a/test/slack_test.rb +++ b/test/slack_test.rb @@ -1,3 +1,5 @@ +# encoding: UTF-8 + require File.expand_path('../helper', __FILE__) class TestSlack < CC::Service::TestCase