Maintenance: Cop to replace .not_to have_ to .to have_no_

This commit is contained in:
Mantas Masalskis 2020-08-26 14:31:33 +02:00 committed by Thorsten Eckel
parent 8886d7bada
commit 8b70f5703c
10 changed files with 88 additions and 25 deletions

View file

@ -0,0 +1,62 @@
require 'capybara/rspec/matchers'
module RuboCop
module Cop
module Zammad
# This cop is used to identify usages of `have_*` RSpec matcher together with `not_to`.
# `have_no_*` with `to` is preferred
#
# @example
# # bad
# expect(page).not_to have_css('#elem')
#
# # good
# expect(page).to have_no_css('#elem')
class HaveNoOverNotTo < Base
extend AutoCorrector
MSG = 'Prefer `.to %<replacement>s` over `.not_to %<original>s`.'.freeze
def_node_matcher :on_have_not_no, '(send (send nil? :expect ...) :not_to (send nil? #matcher_to_replace? ...))'
def matcher_to_replace?(matcher_name)
have_not_no?(matcher_name) && capybara_matcher?(matcher_name)
end
def have_not_no?(matcher_name)
matcher_name.match?(/^have_(?!no)/)
end
def capybara_matcher?(matcher_name)
Capybara::RSpecMatchers.instance_methods.include?(matcher_name)
end
def on_send(node)
on_have_not_no(node) do
add_offense(node, message: message(node)) do |corrector|
corrector.replace(original_matcher_node(node).loc.selector, alternative_matcher(node))
corrector.replace(node.loc.selector, 'to')
end
end
end
def original_matcher_node(node)
node.children[2]
end
def original_matcher(node)
original_matcher_node(node).method_name
end
def alternative_matcher(node)
original_matcher(node).to_s.sub 'have_', 'have_no_'
end
def message(node)
message = format(MSG, replacement: alternative_matcher(node), original: original_matcher(node))
end
end
end
end
end

View file

@ -1,3 +1,4 @@
require_relative 'cop/zammad/exists_condition' require_relative 'cop/zammad/exists_condition'
require_relative 'cop/zammad/have_no_over_not_to'
require_relative 'cop/zammad/no_to_sym_on_string' require_relative 'cop/zammad/no_to_sym_on_string'
require_relative 'cop/zammad/prefer_negated_if_over_unless' require_relative 'cop/zammad/prefer_negated_if_over_unless'

View file

@ -16,7 +16,7 @@ RSpec.describe 'Manage > Channels > Email', type: :system do
expect(page).to have_css('#c-account h3', text: 'Inbound') expect(page).to have_css('#c-account h3', text: 'Inbound')
expect(page).to have_css('#c-account h3', text: 'Outbound') expect(page).to have_css('#c-account h3', text: 'Outbound')
expect(page).not_to have_css('.js-editInbound, .js-editOutbound', text: 'Edit') expect(page).to have_no_css('.js-editInbound, .js-editOutbound', text: 'Edit')
end end
end end
end end

View file

@ -23,7 +23,7 @@ RSpec.describe 'Public Knowledge Base for guest', type: :system, authenticated_a
it 'does not show answer' do it 'does not show answer' do
within '.main' do within '.main' do
expect(page).not_to have_selector(:link_containing, published_answer.translation.title) expect(page).to have_no_selector(:link_containing, published_answer.translation.title)
end end
end end
end end
@ -41,13 +41,13 @@ RSpec.describe 'Public Knowledge Base for guest', type: :system, authenticated_a
it 'does not show draft answer' do it 'does not show draft answer' do
within '.main' do within '.main' do
expect(page).not_to have_selector(:link_containing, draft_answer.translation.title) expect(page).to have_no_selector(:link_containing, draft_answer.translation.title)
end end
end end
it 'does not show internal answer' do it 'does not show internal answer' do
within '.main' do within '.main' do
expect(page).not_to have_selector(:link_containing, internal_answer.translation.title) expect(page).to have_no_selector(:link_containing, internal_answer.translation.title)
end end
end end
@ -93,7 +93,7 @@ RSpec.describe 'Public Knowledge Base for guest', type: :system, authenticated_a
it { expect(page).to have_text(published_answer.translation_primary.title) } it { expect(page).to have_text(published_answer.translation_primary.title) }
it { expect(page).to have_text('only available in these languages') } it { expect(page).to have_text('only available in these languages') }
it { expect(page).not_to have_selector('h1', text: published_answer.translation_primary.title) } it { expect(page).to have_no_selector('h1', text: published_answer.translation_primary.title) }
context 'follow primary locale' do context 'follow primary locale' do
before { click_on published_answer.translation_primary.title } before { click_on published_answer.translation_primary.title }

View file

@ -19,7 +19,7 @@ RSpec.describe 'Public Knowledge Base menu items', type: :system, authenticated_
end end
it "doesn't show footer link in header" do it "doesn't show footer link in header" do
expect(page).not_to have_css('header .menu-item', text: menu_item_3.title) expect(page).to have_no_css('header .menu-item', text: menu_item_3.title)
end end
it 'shows footer public link' do it 'shows footer public link' do
@ -27,7 +27,7 @@ RSpec.describe 'Public Knowledge Base menu items', type: :system, authenticated_
end end
it "doesn't show footer link of another locale" do it "doesn't show footer link of another locale" do
expect(page).not_to have_css('footer .menu-item', text: menu_item_4.title) expect(page).to have_no_css('footer .menu-item', text: menu_item_4.title)
end end
it 'shows public links in given order' do it 'shows public links in given order' do

View file

@ -39,7 +39,7 @@ RSpec.describe 'Login Message', type: :system, authenticated_as: false do
it 'does not show message' do it 'does not show message' do
open_login_page open_login_page
expect(page).not_to have_text(message) expect(page).to have_no_text(message)
end end
it 'shows message on the go' do it 'shows message on the go' do

View file

@ -13,6 +13,6 @@ RSpec.describe 'Profile > Devices', type: :system, authenticated_as: true do
.click .click
end end
wait(5).until { expect(page).to have_no_css('td', text: device.name) } expect(page).to have_no_css('td', text: device.name)
end end
end end

View file

@ -14,7 +14,7 @@ RSpec.describe 'Ticket Create', type: :system do
visit 'ticket/create' visit 'ticket/create'
use_template(template) use_template(template)
expect(page).not_to have_selector 'select[name="group_id"]' expect(page).to have_no_selector 'select[name="group_id"]'
end end
end end
@ -38,16 +38,16 @@ RSpec.describe 'Ticket Create', type: :system do
within(:active_content) do within(:active_content) do
use_template(template) use_template(template)
expect(page).not_to have_css('div.js-securityEncrypt.btn--active', wait: 5) expect(page).to have_no_css('div.js-securityEncrypt.btn--active')
expect(page).not_to have_css('div.js-securitySign.btn--active', wait: 5) expect(page).to have_no_css('div.js-securitySign.btn--active')
click '.js-submit' click '.js-submit'
expect(page).to have_css('.ticket-article-item', count: 1) expect(page).to have_css('.ticket-article-item', count: 1)
open_article_meta open_article_meta
expect(page).not_to have_css('span', text: 'Signed') expect(page).to have_no_css('span', text: 'Signed')
expect(page).not_to have_css('span', text: 'Encrypted') expect(page).to have_no_css('span', text: 'Encrypted')
security_result = Ticket::Article.last.preferences['security'] security_result = Ticket::Article.last.preferences['security']
expect(security_result['encryption']['success']).to be nil expect(security_result['encryption']['success']).to be nil
@ -99,8 +99,8 @@ RSpec.describe 'Ticket Create', type: :system do
open_article_meta open_article_meta
expect(page).not_to have_css('span', text: 'Signed') expect(page).to have_no_css('span', text: 'Signed')
expect(page).not_to have_css('span', text: 'Encrypted') expect(page).to have_no_css('span', text: 'Encrypted')
security_result = Ticket::Article.last.preferences['security'] security_result = Ticket::Article.last.preferences['security']
expect(security_result['encryption']['success']).to be nil expect(security_result['encryption']['success']).to be nil
@ -128,7 +128,7 @@ RSpec.describe 'Ticket Create', type: :system do
open_article_meta open_article_meta
expect(page).to have_css('span', text: 'Signed') expect(page).to have_css('span', text: 'Signed')
expect(page).not_to have_css('span', text: 'Encrypted') expect(page).to have_no_css('span', text: 'Encrypted')
security_result = Ticket::Article.last.preferences['security'] security_result = Ticket::Article.last.preferences['security']
expect(security_result['encryption']['success']).to be nil expect(security_result['encryption']['success']).to be nil
@ -155,7 +155,7 @@ RSpec.describe 'Ticket Create', type: :system do
open_article_meta open_article_meta
expect(page).not_to have_css('span', text: 'Signed') expect(page).to have_no_css('span', text: 'Signed')
expect(page).to have_css('span', text: 'Encrypted') expect(page).to have_css('span', text: 'Encrypted')
security_result = Ticket::Article.last.preferences['security'] security_result = Ticket::Article.last.preferences['security']

View file

@ -105,7 +105,7 @@ RSpec.describe 'Ticket Update', type: :system do
click('.js-openDropdownMacro') click('.js-openDropdownMacro')
click(".js-dropdownActionMacro[data-id=\"#{macro.id}\"]") click(".js-dropdownActionMacro[data-id=\"#{macro.id}\"]")
expect(page).not_to have_css('.js-submitDropdown .js-submit[disabled]', wait: 2) expect(page).to have_no_css('.js-submitDropdown .js-submit[disabled]')
end end
expect(page).to have_field(attribute.name, with: attribute_value, visible: :hidden) expect(page).to have_field(attribute.name, with: attribute_value, visible: :hidden)
@ -150,7 +150,7 @@ RSpec.describe 'Ticket Update', type: :system do
click('.js-openDropdownMacro') click('.js-openDropdownMacro')
click(".js-dropdownActionMacro[data-id=\"#{macro.id}\"]") click(".js-dropdownActionMacro[data-id=\"#{macro.id}\"]")
expect(page).not_to have_css('.js-submitDropdown .js-submit[disabled]', wait: 2) expect(page).to have_no_css('.js-submitDropdown .js-submit[disabled]')
end end
expect(page).to have_selector('.content.active .article-content', text: 'test body') expect(page).to have_selector('.content.active .article-content', text: 'test body')

View file

@ -194,7 +194,7 @@ RSpec.describe 'Ticket zoom', type: :system do
# wait till input box expands completely # wait till input box expands completely
find('.attachmentPlaceholder-label').in_fixed_position find('.attachmentPlaceholder-label').in_fixed_position
expect(page).not_to have_css('.attachmentPlaceholder-hint', wait: 0) expect(page).to have_no_css('.attachmentPlaceholder-hint')
find('.articleNewEdit-body').send_keys('Some reply') find('.articleNewEdit-body').send_keys('Some reply')
click '.js-submit' click '.js-submit'
@ -534,7 +534,7 @@ RSpec.describe 'Ticket zoom', type: :system do
create(:smime_certificate, :with_private, fixture: system_email_address) create(:smime_certificate, :with_private, fixture: system_email_address)
visit "#ticket/zoom/#{ticket.id}" visit "#ticket/zoom/#{ticket.id}"
expect(page).not_to have_css('.article-content', text: 'somebody with some text') expect(page).to have_no_css('.article-content', text: 'somebody with some text')
click '.js-securityRetryProcess' click '.js-securityRetryProcess'
expect(page).to have_css('.article-content', text: 'somebody with some text') expect(page).to have_css('.article-content', text: 'somebody with some text')
end end
@ -911,9 +911,9 @@ RSpec.describe 'Ticket zoom', type: :system do
refresh # refresh to have assets generated for ticket refresh # refresh to have assets generated for ticket
expect(page).to have_select('state_id', options: %w[new open closed]) expect(page).to have_select('state_id', options: %w[new open closed])
expect(page).not_to have_select('priority_id') expect(page).to have_no_select('priority_id')
expect(page).not_to have_select('owner_id') expect(page).to have_no_select('owner_id')
expect(page).not_to have_css('div.tabsSidebar-tab[data-tab=customer]') expect(page).to have_no_css('div.tabsSidebar-tab[data-tab=customer]')
end end
end end