codeforamerica/ohana-api

View on GitHub

Showing 170 of 170 total issues

StateProvinceValidator#validate_each refers to 'record' more than self (maybe move it to another class?)
Open

    return unless COUNTRIES_NEEDING_VALIDATION.include?(record.country)

    default_message = I18n.t('errors.messages.invalid_state_province')

    return if value.present? && value.size == 2

Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.

Feature Envy reduces the code's ability to communicate intent: code that "belongs" on one class but which is located in another can be hard to find, and may upset the "System of Names" in the host class.

Feature Envy also affects the design's flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application's domain, and creates a loss of cohesion in the unwilling host class.

Feature Envy often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.

Example

Running Reek on:

class Warehouse
  def sale_price(item)
    (item.price - item.rebate) * @vat
  end
end

would report:

Warehouse#total_price refers to item more than self (FeatureEnvy)

since this:

(item.price - item.rebate)

belongs to the Item class, not the Warehouse.

Denial of service via multipart parsing in Rack
Open

    rack (2.2.3.1)
Severity: Minor
Found in Gemfile.lock by bundler-audit

Advisory: CVE-2022-44572

URL: https://github.com/rack/rack/releases/tag/v3.0.4.1

Solution: upgrade to >= 2.0.9.2, ~> 2.0.9, >= 2.1.4.2, ~> 2.1.4, >= 2.2.6.1, ~> 2.2.6, >= 3.0.4.1

HolidayScheduleImporter#holiday_schedules contains iterators nested 2 deep
Open

      chunks.each { |row| result << HolidaySchedulePresenter.new(row).to_holiday_schedule }
Severity: Minor
Found in lib/holiday_schedule_importer.rb by reek

A Nested Iterator occurs when a block contains another block.

Example

Given

class Duck
  class << self
    def duck_names
      %i!tick trick track!.each do |surname|
        %i!duck!.each do |last_name|
          puts "full name is #{surname} #{last_name}"
        end
      end
    end
  end
end

Reek would report the following warning:

test.rb -- 1 warning:
  [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)

LocationFilter#validated_radius refers to 'radius' more than self (maybe move it to another class?)
Open

    return custom_radius if radius.blank?

    raise Exceptions::InvalidRadius if radius.to_f == 0.0

    # radius must be between 0.1 miles and 50 miles
Severity: Minor
Found in lib/location_filter.rb by reek

Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.

Feature Envy reduces the code's ability to communicate intent: code that "belongs" on one class but which is located in another can be hard to find, and may upset the "System of Names" in the host class.

Feature Envy also affects the design's flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application's domain, and creates a loss of cohesion in the unwilling host class.

Feature Envy often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.

Example

Running Reek on:

class Warehouse
  def sale_price(item)
    (item.price - item.rebate) * @vat
  end
end

would report:

Warehouse#total_price refers to item more than self (FeatureEnvy)

since this:

(item.price - item.rebate)

belongs to the Item class, not the Warehouse.

Improper neutralization of data URIs may allow XSS in rails-html-sanitizer
Open

    rails-html-sanitizer (1.4.2)
Severity: Minor
Found in Gemfile.lock by bundler-audit

Advisory: CVE-2022-23518

Criticality: Medium

URL: https://github.com/rails/rails-html-sanitizer/security/advisories/GHSA-mcvf-2q2m-x72m

Solution: upgrade to >= 1.4.4

ProgramImporter#programs contains iterators nested 2 deep
Open

      chunks.each { |row| result << ProgramPresenter.new(row).to_program }
Severity: Minor
Found in lib/program_importer.rb by reek

A Nested Iterator occurs when a block contains another block.

Example

Given

class Duck
  class << self
    def duck_names
      %i!tick trick track!.each do |surname|
        %i!duck!.each do |last_name|
          puts "full name is #{surname} #{last_name}"
        end
      end
    end
  end
end

Reek would report the following warning:

test.rb -- 1 warning:
  [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)

RegularScheduleImporter#regular_schedules contains iterators nested 2 deep
Open

      chunks.each { |row| result << RegularSchedulePresenter.new(row).to_regular_schedule }
Severity: Minor
Found in lib/regular_schedule_importer.rb by reek

A Nested Iterator occurs when a block contains another block.

Example

Given

class Duck
  class << self
    def duck_names
      %i!tick trick track!.each do |surname|
        %i!duck!.each do |last_name|
          puts "full name is #{surname} #{last_name}"
        end
      end
    end
  end
end

Reek would report the following warning:

test.rb -- 1 warning:
  [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)

PhoneImporter#phones contains iterators nested 2 deep
Open

      chunks.each { |row| result << PhonePresenter.new(row).to_phone }
Severity: Minor
Found in lib/phone_importer.rb by reek

A Nested Iterator occurs when a block contains another block.

Example

Given

class Duck
  class << self
    def duck_names
      %i!tick trick track!.each do |surname|
        %i!duck!.each do |last_name|
          puts "full name is #{surname} #{last_name}"
        end
      end
    end
  end
end

Reek would report the following warning:

test.rb -- 1 warning:
  [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)

SubdomainConstraints#matches? refers to 'request' more than self (maybe move it to another class?)
Open

      request.subdomain == @subdomain
    else
      request.subdomain.blank? || request.subdomain == 'www'
Severity: Minor
Found in lib/subdomain_constraints.rb by reek

Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.

Feature Envy reduces the code's ability to communicate intent: code that "belongs" on one class but which is located in another can be hard to find, and may upset the "System of Names" in the host class.

Feature Envy also affects the design's flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application's domain, and creates a loss of cohesion in the unwilling host class.

Feature Envy often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.

Example

Running Reek on:

class Warehouse
  def sale_price(item)
    (item.price - item.rebate) * @vat
  end
end

would report:

Warehouse#total_price refers to item more than self (FeatureEnvy)

since this:

(item.price - item.rebate)

belongs to the Item class, not the Warehouse.

ServiceImporter#services contains iterators nested 2 deep
Open

      chunks.each { |row| result << ServicePresenter.new(row).to_service }
Severity: Minor
Found in lib/service_importer.rb by reek

A Nested Iterator occurs when a block contains another block.

Example

Given

class Duck
  class << self
    def duck_names
      %i!tick trick track!.each do |surname|
        %i!duck!.each do |last_name|
          puts "full name is #{surname} #{last_name}"
        end
      end
    end
  end
end

Reek would report the following warning:

test.rb -- 1 warning:
  [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)

AdminMailer tests 'resource.is_a?(User)' at least 4 times
Open

    return t('titles.developer', brand: t('titles.brand')) if resource.is_a?(User)
  end

  def sign_in_url_for(resource)
    if resource.is_a?(Admin)
Severity: Minor
Found in app/mailers/admin_mailer.rb by reek

Repeated Conditional is a special case of Simulated Polymorphism. Basically it means you are checking the same value throughout a single class and take decisions based on this.

Example

Given

class RepeatedConditionals
  attr_accessor :switch

  def repeat_1
    puts "Repeat 1!" if switch
  end

  def repeat_2
    puts "Repeat 2!" if switch
  end

  def repeat_3
    puts "Repeat 3!" if switch
  end
end

Reek would emit the following warning:

test.rb -- 4 warnings:
  [5, 9, 13]:RepeatedConditionals tests switch at least 3 times (RepeatedConditional)

If you get this warning then you are probably not using the right abstraction or even more probable, missing an additional abstraction.

AdminMailer tests 'resource.is_a?(Admin)' at least 4 times
Open

    return t('titles.admin', brand: t('titles.brand')) if resource.is_a?(Admin)
    return t('titles.developer', brand: t('titles.brand')) if resource.is_a?(User)
  end

  def sign_in_url_for(resource)
Severity: Minor
Found in app/mailers/admin_mailer.rb by reek

Repeated Conditional is a special case of Simulated Polymorphism. Basically it means you are checking the same value throughout a single class and take decisions based on this.

Example

Given

class RepeatedConditionals
  attr_accessor :switch

  def repeat_1
    puts "Repeat 1!" if switch
  end

  def repeat_2
    puts "Repeat 2!" if switch
  end

  def repeat_3
    puts "Repeat 3!" if switch
  end
end

Reek would emit the following warning:

test.rb -- 4 warnings:
  [5, 9, 13]:RepeatedConditionals tests switch at least 3 times (RepeatedConditional)

If you get this warning then you are probably not using the right abstraction or even more probable, missing an additional abstraction.

Method regex_validate_each has 5 arguments (exceeds 4 allowed). Consider refactoring.
Open

  def regex_validate_each(regex, err_msg, record, attribute, value)
Severity: Minor
Found in app/validators/regex_validator.rb - About 35 mins to fix

    PrivateRegistration#create calls 'resource.errors' 2 times
    Open

          email_error = resource.errors[:email]
          resource.errors.delete(:email) if email_error.include?('has already been taken')

    Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

    Reek implements a check for Duplicate Method Call.

    Example

    Here's a very much simplified and contrived example. The following method will report a warning:

    def double_thing()
      @other.thing + @other.thing
    end

    One quick approach to silence Reek would be to refactor the code thus:

    def double_thing()
      thing = @other.thing
      thing + thing
    end

    A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

    class Other
      def double_thing()
        thing + thing
      end
    end

    The approach you take will depend on balancing other factors in your code.

    Search::ClassMethods#search calls 'params[:keyword]' 2 times
    Open

          return res unless params[:keyword] && params[:service_area]
    
          res.select("locations.*, #{rank_for(params[:keyword])}")
    Severity: Minor
    Found in app/models/concerns/search.rb by reek

    Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

    Reek implements a check for Duplicate Method Call.

    Example

    Here's a very much simplified and contrived example. The following method will report a warning:

    def double_thing()
      @other.thing + @other.thing
    end

    One quick approach to silence Reek would be to refactor the code thus:

    def double_thing()
      thing = @other.thing
      thing + thing
    end

    A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

    class Other
      def double_thing()
        thing + thing
      end
    end

    The approach you take will depend on balancing other factors in your code.

    ApiApplicationsController assumes too much for instance variable '@api_application'
    Open

    class ApiApplicationsController < ApplicationController

    Classes should not assume that instance variables are set or present outside of the current class definition.

    Good:

    class Foo
      def initialize
        @bar = :foo
      end
    
      def foo?
        @bar == :foo
      end
    end

    Good as well:

    class Foo
      def foo?
        bar == :foo
      end
    
      def bar
        @bar ||= :foo
      end
    end

    Bad:

    class Foo
      def go_foo!
        @bar = :foo
      end
    
      def foo?
        @bar == :foo
      end
    end

    Example

    Running Reek on:

    class Dummy
      def test
        @ivar
      end
    end

    would report:

    [1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar

    Note that this example would trigger this smell warning as well:

    class Parent
      def initialize(omg)
        @omg = omg
      end
    end
    
    class Child < Parent
      def foo
        @omg
      end
    end

    The way to address the smell warning is that you should create an attr_reader to use @omg in the subclass and not access @omg directly like this:

    class Parent
      attr_reader :omg
    
      def initialize(omg)
        @omg = omg
      end
    end
    
    class Child < Parent
      def foo
        omg
      end
    end

    Directly accessing instance variables is considered a smell because it breaks encapsulation and makes it harder to reason about code.

    If you don't want to expose those methods as public API just make them private like this:

    class Parent
      def initialize(omg)
        @omg = omg
      end
    
      private
      attr_reader :omg
    end
    
    class Child < Parent
      def foo
        omg
      end
    end

    Current Support in Reek

    An instance variable must:

    • be set in the constructor
    • or be accessed through a method with lazy initialization / memoization.

    If not, Instance Variable Assumption will be reported.

    PaginationHeaders#pages calls 'coll.current_page' 2 times
    Open

          pages[:prev]  = coll.empty? ? coll.total_pages : coll.current_page - 1
        end
    
        unless coll.last_page?
          pages[:last] = coll.total_pages

    Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

    Reek implements a check for Duplicate Method Call.

    Example

    Here's a very much simplified and contrived example. The following method will report a warning:

    def double_thing()
      @other.thing + @other.thing
    end

    One quick approach to silence Reek would be to refactor the code thus:

    def double_thing()
      thing = @other.thing
      thing + thing
    end

    A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

    class Other
      def double_thing()
        thing + thing
      end
    end

    The approach you take will depend on balancing other factors in your code.

    EmailFilter#match_regular_email calls 'domain_from(email)' 2 times
    Open

          email, "%#{domain_from(email)}%", "%#{domain_from(email)}%"
    Severity: Minor
    Found in lib/email_filter.rb by reek

    Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

    Reek implements a check for Duplicate Method Call.

    Example

    Here's a very much simplified and contrived example. The following method will report a warning:

    def double_thing()
      @other.thing + @other.thing
    end

    One quick approach to silence Reek would be to refactor the code thus:

    def double_thing()
      thing = @other.thing
      thing + thing
    end

    A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

    class Other
      def double_thing()
        thing + thing
      end
    end

    The approach you take will depend on balancing other factors in your code.

    OrganizationPresenter#to_org calls 'row[:id].to_i' 2 times
    Open

        org = Organization.find_or_initialize_by(id: row[:id].to_i)
        to_array(row, :accreditations, :licenses, :funding_sources)
        org.attributes = row
        org.id = row[:id].to_i
    Severity: Minor
    Found in lib/organization_presenter.rb by reek

    Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

    Reek implements a check for Duplicate Method Call.

    Example

    Here's a very much simplified and contrived example. The following method will report a warning:

    def double_thing()
      @other.thing + @other.thing
    end

    One quick approach to silence Reek would be to refactor the code thus:

    def double_thing()
      thing = @other.thing
      thing + thing
    end

    A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

    class Other
      def double_thing()
        thing + thing
      end
    end

    The approach you take will depend on balancing other factors in your code.

    Api::V1::SearchController#nearby calls 'locations_near(location)' 2 times
    Open

            render json: locations_near(location), each_serializer: NearbySerializer, status: :ok
            generate_pagination_headers(locations_near(location))

    Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

    Reek implements a check for Duplicate Method Call.

    Example

    Here's a very much simplified and contrived example. The following method will report a warning:

    def double_thing()
      @other.thing + @other.thing
    end

    One quick approach to silence Reek would be to refactor the code thus:

    def double_thing()
      thing = @other.thing
      thing + thing
    end

    A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

    class Other
      def double_thing()
        thing + thing
      end
    end

    The approach you take will depend on balancing other factors in your code.

    Severity
    Category
    Status
    Source
    Language