• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pulibrary / orangelight / 59e88ea0-d448-4bea-8a13-a79290fbd382

04 Nov 2025 05:53PM UTC coverage: 95.401% (-0.02%) from 95.417%
59e88ea0-d448-4bea-8a13-a79290fbd382

Pull #5333

circleci

sandbergja
Add documentation about how to check the asset bundle sizes that we send to the client

Closes #5330
Pull Request #5333: Add documentation about how to check the asset bundle sizes that we send to the client

6203 of 6502 relevant lines covered (95.4%)

1458.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.35
/app/controllers/requests/form_controller.rb
1
# frozen_string_literal: true
2
require 'faraday'
3✔
3

4
include Requests::ApplicationHelper
3✔
5

6
module Requests
3✔
7
  class FormController < ApplicationController
3✔
8
    before_action :authenticate_user!, except: [:index], unless: -> { aeon? }
116✔
9

10
    def index
3✔
11
      redirect_to('/')
1✔
12
    end
13

14
    def generate
3✔
15
      # Patron can be slow to load, start loading it early
16
      @user = current_or_guest_user
66✔
17
      patron_request = Thread.new { Patron.authorize(user: @user) }
132✔
18

19
      system_id = sanitize(params[:system_id])
66✔
20
      mfhd = sanitize(params[:mfhd])
66✔
21
      params.require(:mfhd) unless system_id.starts_with?("SCSB") # there are not multiple locations for shared items so no MFHD is passed
66✔
22
      @back_to_record_url = BackToRecordUrl.new(params)
66✔
23

24
      @title = "Request ID: #{system_id}"
66✔
25

26
      # needed to see if we can suppress login for this item
27
      @request = FormDecorator.new(Requests::Form.new(system_id:, mfhd:, patron_request:), view_context, @back_to_record_url)
66✔
28
      @patron = patron_request.value
66✔
29
      patron_errors = @patron.errors
66✔
30
      flash.now[:error] = patron_errors.join(", ") if patron_errors.present?
66✔
31
    rescue ActionController::ParameterMissing
32
      render 'requests/form/no_location_specified'
×
33
    end
34

35
    def aeon?
3✔
36
      return true if params["aeon"] == 'true'
113✔
37

38
      false
112✔
39
    end
40

41
    # will post and a JSON document of selected "requestable" objects with selection parameters and
42
    # user information for further processing and distribution to various request endpoints.
43
    def submit
3✔
44
      @submission = Requests::Submission.new(sanitize_submission(params), Patron.new(user: current_or_guest_user))
44✔
45

46
      valid = @submission.valid?
44✔
47
      @services = @submission.process_submission if valid
44✔
48

49
      response_data = if valid && @submission.service_errors.blank?
44✔
50
                        respond_to_submit_success(@submission)
36✔
51
                      elsif valid # submission was valid, but service failed
8✔
52
                        respond_to_service_error(@services)
4✔
53
                      else
54
                        respond_to_validation_error(@submission)
4✔
55
                      end
56

57
      render json: response_data
44✔
58
    end
59

60
    private
3✔
61

62
      def mode
3✔
63
        return 'standard' if params[:mode].nil?
×
64
        sanitize(params[:mode])
×
65
      end
66

67
      # trusted params
68
      def request_params
3✔
69
        params.permit(:id, :system_id, :mfhd, :user_name, :email, :loc_code, :user, :requestable, :request, :barcode, :isbns).permit!
×
70
      end
71

72
      def sanitize_submission(params)
3✔
73
        params[:requestable].each do |requestable|
44✔
74
          params['user_supplied_enum'] = sanitize(requestable['user_supplied_enum']) if requestable.key? 'user_supplied_enum'
214✔
75
        end
76
        lparams = params.permit(bib: [:id, :title, :author, :isbn, :date])
44✔
77
        lparams[:requestable] = params[:requestable].map do |requestable|
44✔
78
          json_pick_up = requestable[:pick_up]
214✔
79
          requestable = requestable.merge(JSON.parse(json_pick_up)) if json_pick_up.present?
214✔
80
          requestable.permit!
214✔
81
        end
82
        lparams
44✔
83
      end
84

85
      # :reek:UncommunicativeVariableName { accept: ['e'] }
86
      # :reek:TooManyStatements
87
      def respond_to_submit_success(submission)
3✔
88
        success_message = submission.success_messages.join(' ')
36✔
89
        flash.now[:success] = success_message
36✔
90
        logger.info "Request Sent"
36✔
91

92
        {
36✔
93
          success: true,
94
          message: success_message
95
        }
96
      end
97

98
      # :reek:UncommunicativeVariableName { accept: ['e'] }
99
      def respond_to_service_error(services)
3✔
100
        errors = services.map(&:errors).flatten
4✔
101
        error_types = errors.pluck(:type).uniq
4✔
102
        flash_now_error = if error_types.include?("digitize")
4✔
103
                            errors[error_types.index("digitize")][:error]
3✔
104
                          else
105
                            I18n.t('requests.submit.service_error')
1✔
106
                          end
107
        flash.now[:error] = flash_now_error
4✔
108
        logger.error "Request Service Error"
4✔
109
        service_errors = services.map(&:error_hash).inject(:merge)
4✔
110
        send_error_email(service_errors, @submission)
4✔
111

112
        {
4✔
113
          success: false,
114
          message: flash_now_error,
115
          errors: service_errors
116
        }
117
      end
118

119
      # :reek:TooManyStatements
120
      def respond_to_validation_error(submission)
3✔
121
        error_message = I18n.t('requests.submit.error')
4✔
122
        error_messages = submission.errors.messages
4✔
123

124
        flash.now[:error] = error_message
4✔
125
        logger.error "Request Submission #{error_messages.as_json}"
4✔
126

127
        {
4✔
128
          success: false,
129
          message: error_message,
130
          errors: format_validation_errors(error_messages)
131
        }
132
      end
133

134
      def sanitize(str)
3✔
135
        str.gsub(/[^A-Za-z0-9@\-_\.]/, '') if str.is_a? String
141✔
136
        str
141✔
137
      end
138

139
      # :reek:NestedIterators
140
      # :reek:TooManyStatements
141
      # :reek:UtilityFunction
142
      def format_validation_errors(error_messages)
3✔
143
        formatted_errors = {}
7✔
144

145
        error_messages.each do |key, values|
7✔
146
          formatted_errors[key] = if key == :items
9✔
147
                                    # Handle special items field format
148
                                    values.map do |value|
6✔
149
                                      if value.is_a?(Hash)
6✔
150
                                        first_value = value.values.first
5✔
151
                                        {
152
                                          key: value.keys.first,
5✔
153
                                          type: first_value['type'],
154
                                          text: first_value['text']
155
                                        }
156
                                      else
157
                                        { text: value }
1✔
158
                                      end
159
                                    end
160
                                  else
161
                                    # Handle regular validation errors
162
                                    values
3✔
163
                                  end
164
        end
165
        formatted_errors
7✔
166
      end
167

168
      # This has to be a utility function to prevent ActiveJob from trying to serialize too many objects
169
      # :reek:UtilityFunction
170
      def send_error_email(errors, submission)
3✔
171
        Requests::RequestMailer.send("service_error_email", errors, submission.to_h).deliver_later
4✔
172
      end
173
  end
174
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc