<commit_before>module SpreeShipwire::Rates
  extend self

  def compute(address, line_items=[])
    rate = Shipwire::ShippingRate.new(address: map_address(address),
                                      items: map_line_items(line_items))

    response = rate.send
    raise_if_invalid(response)
    rate.parse_response

    rate.shipping_quotes
  end

private
  ADDRESS_WARNING  = 'Could not verify shipping address'
  CONNECTION_ERROR = 'Unable to connect to Shipwire'
  RATE_ERROR       = 'Unable to get shipping rates from Shipwire'

  def map_address(address)
    {address1: address.address1,
     address2: address.address2,
     city:     address.city,
     state:    address.state.try(:abbr) || address.state_name,
     country:  address.country.iso,
     zip:      address.zipcode}
  end

  def map_line_items(line_items)
    line_items.map do |line|
      {item: line.variant.sku, quantity: line.quantity}
    end
  end

  def raise_if_invalid(response)
    if response.is_a?(Faraday::Response)
      xml = Nokogiri::XML(response.body)
      warning = xml.xpath('//Warning').try(:text)

      raise SpreeShipwire::AddressError if warning == ADDRESS_WARNING
    else
      messages = response.join(', ')

      raise SpreeShipwire::ConnectionError.new(messages) if response.include?(CONNECTION_ERROR)
      raise SpreeShipwire::RateError.new(messages) if response.include?(RATE_ERROR)
    end
  end
end

<commit_msg>Extract response parsing to function<commit_after>module SpreeShipwire::Rates
  extend self

  def compute(address, line_items=[])
    rate = Shipwire::ShippingRate.new(address: map_address(address),
                                      items: map_line_items(line_items))

    response = rate.send
    raise_if_invalid(response)
    rate.parse_response

    rate.shipping_quotes
  end

private
  ADDRESS_WARNING  = 'Could not verify shipping address'
  CONNECTION_ERROR = 'Unable to connect to Shipwire'
  RATE_ERROR       = 'Unable to get shipping rates from Shipwire'

  def map_address(address)
    {address1: address.address1,
     address2: address.address2,
     city:     address.city,
     state:    address.state.try(:abbr) || address.state_name,
     country:  address.country.iso,
     zip:      address.zipcode}
  end

  def map_line_items(line_items)
    line_items.map do |line|
      {item: line.variant.sku, quantity: line.quantity}
    end
  end

  def raise_if_invalid(response)
    if response.is_a?(Faraday::Response)
      warning = parse_warning(response)

      raise SpreeShipwire::AddressError if warning == ADDRESS_WARNING
    else
      messages = response.join(', ')

      raise SpreeShipwire::ConnectionError.new(messages) if response.include?(CONNECTION_ERROR)
      raise SpreeShipwire::RateError.new(messages) if response.include?(RATE_ERROR)
    end
  end

  def parse_warning(response)
    xml = Nokogiri::XML(response.body)

    xml.xpath('//Warning').try(:text)
  end
end


{'fraction_non_alphanumeric': 0.09403747870528109, 'fraction_numerical': 0.00272572402044293, 'mean_word_length': 3.2736535662299855, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6785952', 'n_tokens_mistral': 918, 'n_tokens_neox': 900, 'n_words': 194}