snap-cloud/snapcon

View on GitHub
app/helpers/versions_helper.rb

Summary

Maintainability
C
7 hrs
Test Coverage
F
0%
# frozen_string_literal: true

module VersionsHelper
  ##
  # Groups functions related to change description
  ##
  def link_if_alive(version, link_text, link_url, conference)
    version.item && conference ? link_to(link_text, link_url) : "#{link_text} with ID #{version.item_id}"
  end

  def link_to_organization(organization_id)
    return 'deleted organization' unless organization_id

    org = Organization.find_by(id: organization_id)
    return current_or_last_object_state('Organization', organization_id).try(:name) unless org

    org.name.to_s
  end

  def link_to_conference(conference_id)
    return 'deleted conference' if conference_id.nil?

    conference = Conference.find_by(id: conference_id)
    if conference
      link_to conference.short_title,
              edit_admin_conference_path(conference.short_title)
    else
      short_title = current_or_last_object_state('Conference', conference_id).try(:short_title) || ''
      " #{short_title} with ID #{conference_id}"
    end
  end

  def link_to_user(user_id)
    return 'Someone (probably via the console)' unless user_id

    user = User.find_by(id: user_id)
    if user
      link_to user.name, admin_user_path(id: user_id)
    else
      name = current_or_last_object_state('User', user_id).try(:name) || PaperTrail::Version.where(item_type: 'User', item_id: user_id).last.changeset['name'].second if PaperTrail::Version.where(item_type: 'User', item_id: user_id).any?
      "#{name || 'Unknown user'} with ID #{user_id}"
    end
  end

  # Receives a model_name and id
  # Returns nil if model_name is invalid
  # Returns object in its current state if its alive
  # Otherwise Returns object state just before deletion
  def current_or_last_object_state(model_name, id)
    return nil unless id.present? && model_name.present?

    begin
      object = model_name.constantize.find_by(id: id)
    rescue NameError
      return nil
    end

    if object.nil?
      object_last_version = PaperTrail::Version.where(item_type: model_name, item_id: id).last
      object = object_last_version.reify if object_last_version
    end
    object
  end

  def subscription_change_description(version)
    user_id = current_or_last_object_state(version.item_type, version.item_id)&.user_id
    unless user_id
      if version.event == 'create'
        return 'subscribed (unkown user) to'
      else
        return 'unsubscribed (unknown user) from'
      end
    end
    user_name = User.find_by(id: user_id).try(:name) || current_or_last_object_state('User', user_id).try(:name) || PaperTrail::Version.where(item_type: 'User', item_id: user_id).last.changeset[:name].second unless user_id.to_s == version.whodunnit
    version.event == 'create' ? "subscribed #{user_name} to" : "unsubscribed #{user_name} from"
  end

  # rubocop:disable Metrics/CyclomaticComplexity:
  def registration_change_description(version)
    if version.item_type == 'Registration'
      user_id = current_or_last_object_state(version.item_type, version.item_id)&.user_id
    elsif version.item_type == 'EventsRegistration'
      registration_id = current_or_last_object_state(version.item_type, version.item_id).registration_id
      user_id = current_or_last_object_state('Registration', registration_id)&.user_id
    end
    user_name = User.find_by(id: user_id).try(:name) || current_or_last_object_state('User', user_id).try(:name) || PaperTrail::Version.where(item_type: 'User', item_id: user_id).last.changeset[:name].second

    unless user_id
      case version.event
      when 'create' then return 'registered to (unkown user)'
      when 'update' then return 'updated (unkown user) of the registration for'
      when 'destroy' then return 'unregistered from'
      end
    end

    if user_id.to_s == version.whodunnit
      case version.event
      when 'create' then 'registered to'
      when 'update' then "updated #{updated_attributes(version)} of the registration for"
      when 'destroy' then 'unregistered from'
      end
    else
      case version.event
      when 'create' then "registered #{user_name} to"
      when 'update' then "updated #{updated_attributes(version)} of  #{user_name}'s registration for"
      when 'destroy' then "unregistered #{user_name} from"
      end
    end
  end
  # rubocop:enable Metrics/CyclomaticComplexity:

  def comment_change_description(version)
    user = current_or_last_object_state(version.item_type, version.item_id).user
    if version.event == 'create'
      version.previous.nil? ? 'commented on' : "re-added #{user.name}'s comment on"
    else
      "deleted #{user.name}'s comment on"
    end
  end

  def vote_change_description(version)
    user = current_or_last_object_state(version.item_type, version.item_id).user
    if version.event == 'create'
      version.previous.nil? ? 'voted on' : "re-added #{user.name}'s vote on"
    elsif version.event == 'update'
      "updated #{user.name}'s vote on"
    else
      "deleted #{user.name}'s vote on"
    end
  end

  def general_change_description(version)
    if version.event == 'create'
      'created new'
    elsif version.event == 'update'
      "updated #{updated_attributes(version)} of"
    else
      'deleted'
    end
  end

  def event_change_description(version)
    if version.event == 'create'
      'submitted new'

    elsif version.changeset['state']
      case version.changeset['state'][1]
      when 'unconfirmed' then 'accepted'
      when 'withdrawn' then 'withdrew'
      when 'canceled', 'rejected', 'confirmed' then version.changeset['state'][1]
      when 'new' then 'resubmitted'
      end

    else
      "updated #{updated_attributes(version)} of"
    end
  end

  def event_schedule_change_description(version)
    case version.event
    when 'create' then 'scheduled'
    when 'update' then 'rescheduled'
    when 'destroy' then 'unscheduled'
    end
  end

  def user_change_description(version)
    if version.event == 'create'
      link_to_user(version.item_id) + ' signed up'
    elsif version.event == 'update'
      if version.changeset.keys.include?('reset_password_sent_at')
        'Someone requested password reset of'
      elsif version.changeset.keys.include?('confirmed_at') && version.changeset['confirmed_at'][0].nil?
        (version.whodunnit.nil? ? link_to_user(version.item_id) : link_to_user(version.whodunnit)) + ' confirmed account of'
      elsif version.changeset.keys.include?('confirmed_at') && version.changeset['confirmed_at'][1].nil?
        link_to_user(version.whodunnit) + ' unconfirmed account of'
      else
        link_to_user(version.whodunnit) + " updated #{updated_attributes(version)} of"
      end
    end
  end

  def users_role_change_description(version)
    version.event == 'create' ? 'added' : 'removed'
  end
end