82 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
module Gitlab
 | 
						|
  module EndpointAttributes
 | 
						|
    class Config
 | 
						|
      RequestUrgency = Struct.new(:name, :duration)
 | 
						|
      REQUEST_URGENCIES = [
 | 
						|
        RequestUrgency.new(:high, 0.25),
 | 
						|
        RequestUrgency.new(:medium, 0.5),
 | 
						|
        RequestUrgency.new(:default, 1),
 | 
						|
        RequestUrgency.new(:low, 5)
 | 
						|
      ].index_by(&:name).freeze
 | 
						|
      SUPPORTED_ATTRIBUTES = %i[feature_category urgency].freeze
 | 
						|
 | 
						|
      def initialize
 | 
						|
        @default_attributes = {}
 | 
						|
        @action_attributes = {}
 | 
						|
      end
 | 
						|
 | 
						|
      def defined_actions
 | 
						|
        @action_attributes.keys
 | 
						|
      end
 | 
						|
 | 
						|
      def set(actions, attributes)
 | 
						|
        sanitize_attributes!(attributes)
 | 
						|
 | 
						|
        if actions.empty?
 | 
						|
          conflicted = conflicted_attributes(attributes, @default_attributes)
 | 
						|
          raise ArgumentError, "Attributes already defined: #{conflicted.join(", ")}" if conflicted.present?
 | 
						|
 | 
						|
          @default_attributes.merge!(attributes)
 | 
						|
        else
 | 
						|
          set_attributes_for_actions(actions, attributes)
 | 
						|
        end
 | 
						|
 | 
						|
        nil
 | 
						|
      end
 | 
						|
 | 
						|
      def attribute_for_action(action, attribute_name)
 | 
						|
        value = @action_attributes.dig(action.to_s, attribute_name) || @default_attributes[attribute_name]
 | 
						|
        # Translate urgency to a representative struct
 | 
						|
        value = REQUEST_URGENCIES[value] if attribute_name == :urgency
 | 
						|
        value
 | 
						|
      end
 | 
						|
 | 
						|
      private
 | 
						|
 | 
						|
      def sanitize_attributes!(attributes)
 | 
						|
        unsupported_attributes = (attributes.keys - SUPPORTED_ATTRIBUTES).present?
 | 
						|
        raise ArgumentError, "Attributes not supported: #{unsupported_attributes.join(", ")}" if unsupported_attributes
 | 
						|
 | 
						|
        if attributes[:urgency].present? && !REQUEST_URGENCIES.key?(attributes[:urgency])
 | 
						|
          raise ArgumentError, "Urgency not supported: #{attributes[:urgency]}"
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      def set_attributes_for_actions(actions, attributes)
 | 
						|
        conflicted = conflicted_attributes(attributes, @default_attributes)
 | 
						|
        if conflicted.present?
 | 
						|
          raise ArgumentError, "#{conflicted.join(", ")} are already defined for all actions, but re-defined for #{actions.join(", ")}"
 | 
						|
        end
 | 
						|
 | 
						|
        actions.each do |action|
 | 
						|
          action = action.to_s
 | 
						|
          if @action_attributes[action].blank?
 | 
						|
            @action_attributes[action] = attributes.dup
 | 
						|
          else
 | 
						|
            conflicted = conflicted_attributes(attributes, @action_attributes[action])
 | 
						|
            raise ArgumentError, "Attributes re-defined for action #{action}: #{conflicted.join(", ")}" if conflicted.present?
 | 
						|
 | 
						|
            @action_attributes[action].merge!(attributes)
 | 
						|
          end
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      def conflicted_attributes(attributes, existing_attributes)
 | 
						|
        attributes.keys.filter { |attr| existing_attributes[attr].present? && existing_attributes[attr] != attributes[attr] }
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |