Commit 28830848 authored by Albert Salim's avatar Albert Salim

Introduce Gitlab/EventStoreSubscriber cop

This cop checks that a worker that
includes `Gitlab::EventStore::Subscriber`
implements `#handle_event` and does not override `#perform`.
parent 077f5a82
...@@ -291,6 +291,12 @@ Gitlab/AvoidUploadedFileFromParams: ...@@ -291,6 +291,12 @@ Gitlab/AvoidUploadedFileFromParams:
- 'spec/**/*' - 'spec/**/*'
- 'ee/spec/**/*' - 'ee/spec/**/*'
Gitlab/EventStoreSubscriber:
Enabled: true
Exclude:
- 'spec/**/*'
- 'ee/spec/**/*'
GitlabSecurity/PublicSend: GitlabSecurity/PublicSend:
Enabled: true Enabled: true
Exclude: Exclude:
......
# frozen_string_literal: true
module RuboCop
module Cop
module Gitlab
# Cop that checks the implementation of Gitlab::EventStore::Subscriber
#
# A worker that implements Gitlab::EventStore::Subscriber
# must implement the method #handle_event(event) and
# must not override the method #perform(*args)
#
# # bad
# class MySubscriber
# include Gitlab::EventStore::Subscriber
#
# def perform(*args)
# end
# end
#
# # bad
# class MySubscriber
# include Gitlab::EventStore::Subscriber
# end
#
# # good
# class MySubscriber
# include Gitlab::EventStore::Subscriber
#
# def handle_event(event)
# end
# end
#
class EventStoreSubscriber < RuboCop::Cop::Cop
SUBSCRIBER_MODULE_NAME = 'Gitlab::EventStore::Subscriber'
FORBID_PERFORM_OVERRIDE = "Do not override `perform` in a `#{SUBSCRIBER_MODULE_NAME}`."
REQUIRE_HANDLE_EVENT = "A `#{SUBSCRIBER_MODULE_NAME}` must implement `#handle_event(event)`."
def_node_matcher :includes_subscriber?, <<~PATTERN
(send nil? :include (const (const (const nil? :Gitlab) :EventStore) :Subscriber))
PATTERN
def on_send(node)
return unless includes_subscriber?(node)
self.is_subscriber ||= true
self.include_subscriber_node ||= node
end
def on_def(node)
if is_subscriber && node.method_name == :perform
add_offense(node, message: FORBID_PERFORM_OVERRIDE)
end
self.implements_handle_event ||= true if node.method_name == :handle_event
end
def on_investigation_end
super
if is_subscriber && !implements_handle_event
add_offense(include_subscriber_node, message: REQUIRE_HANDLE_EVENT)
end
end
private
attr_accessor :is_subscriber, :include_subscriber_node, :implements_handle_event
end
end
end
end
# frozen_string_literal: true
require 'fast_spec_helper'
require_relative '../../../../rubocop/cop/gitlab/event_store_subscriber'
RSpec.describe RuboCop::Cop::Gitlab::EventStoreSubscriber do
subject(:cop) { described_class.new }
context 'when an event store subscriber overrides #perform' do
it 'registers an offense' do
expect_offense(<<~WORKER)
class SomeWorker
include Gitlab::EventStore::Subscriber
def perform(*args)
^^^^^^^^^^^^^^^^^^ Do not override `perform` in a `Gitlab::EventStore::Subscriber`.
end
def handle_event(event); end
end
WORKER
end
end
context 'when an event store subscriber does not override #perform' do
it 'does not register an offense' do
expect_no_offenses(<<~WORKER)
class SomeWorker
include Gitlab::EventStore::Subscriber
def handle_event(event); end
end
WORKER
end
end
context 'when an event store subscriber does not implement #handle_event' do
it 'registers an offense' do
expect_offense(<<~WORKER)
class SomeWorker
include Gitlab::EventStore::Subscriber
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A `Gitlab::EventStore::Subscriber` must implement `#handle_event(event)`.
end
WORKER
end
end
context 'when a Sidekiq worker overrides #perform' do
it 'does not register an offense' do
expect_no_offenses(<<~WORKER)
class SomeWorker
include ApplicationWorker
def perform(*args); end
end
WORKER
end
end
context 'when a Sidekiq worker implements #handle_event' do
it 'does not register an offense' do
expect_no_offenses(<<~WORKER)
class SomeWorker
include ApplicationWorker
def handle_event(event); end
end
WORKER
end
end
context 'a non worker class' do
it 'does not register an offense' do
expect_no_offenses(<<~MODEL)
class Model < ApplicationRecord
include ActiveSupport::Concern
end
MODEL
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment