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

benwbrum / fromthepage / 15140614916

20 May 2025 02:43PM UTC coverage: 60.303% (+0.04%) from 60.265%
15140614916

push

github

web-flow
Merge pull request #4659 from benwbrum/4657-works-list-problems

4657 - Works list problems fix

1577 of 3198 branches covered (49.31%)

Branch coverage included in aggregate %.

59 of 71 new or added lines in 2 files covered. (83.1%)

7185 of 11332 relevant lines covered (63.4%)

79.16 hits per line

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

82.55
/app/controllers/application_controller.rb
1
class ApplicationController < ActionController::Base
1✔
2
  DEFAULT_PER_PAGE = 200
1✔
3

4
  protect_from_forgery with: :exception, except: [:switch_locale, :saml]
1✔
5

6
  before_action do
1✔
7
    if current_user && current_user.admin
1,591✔
8
      Rack::MiniProfiler.authorize_request
212✔
9
    end
10
  end
11

12
  before_action :load_objects_from_params
1✔
13
  before_action :store_current_location, :unless => :devise_controller?
1✔
14
  before_action :load_html_blocks
1✔
15
  before_action :authorize_collection
1✔
16
  before_action :configure_permitted_parameters, if: :devise_controller?
1✔
17
  skip_before_action :verify_authenticity_token, if: (:devise_controller? && :codespaces_environment?)
1✔
18
  before_action :set_current_user_in_model
1✔
19
  before_action :masquerade_user!
1✔
20
  before_action :check_search_attempt
1✔
21
  after_action :track_action
1✔
22
  around_action :switch_locale
1✔
23

24
  layout :set_layout
1✔
25

26
  def switch_locale(&action)
1✔
27
    @dropdown_locales = I18n.available_locales.reject { |locale| locale.to_s.include? "-" }
12,440✔
28

29
    locale = nil
1,555✔
30

31
    # use user-record locale
32
    if user_signed_in? && !current_user.preferred_locale.blank?
1,555✔
33
      # the user has set their locale manually; use it.
×
34
      locale = current_user.preferred_locale
×
35
    end
36

37
    # if we can't find that, use session locale
38
    if locale.nil?
1,555!
39
      if session[:current_locale]
1,555!
40
        locale = session[:current_locale]
×
41
      end
42
    end
43

44
    # if we can't find that, use browser locale
45
    if locale.nil?
1,555!
46
      # the user might their locale set in the browser
1,555✔
47
      locale = http_accept_language.preferred_language_from(I18n.available_locales)
1,555✔
48
    end
49

50
    if locale.nil? || !I18n.available_locales.include?(locale.to_sym)
1,555✔
51
      # use the default if the above optiosn didn't work
1,201✔
52
      locale = I18n.default_locale
1,201✔
53
    end
54

55
    # append region to locale
56
    related_locales = http_accept_language.user_preferred_languages.select do |loc|
1,555✔
57
      loc.to_s.include?(locale.to_s) &&                              # is related to the chosen locale (is the locale, or is a regional version of it)
708✔
58
      I18n.available_locales.map{|e| e.to_s}.include?(loc.to_s) # is an available locale
4,956✔
59
    end
60

61
    unless related_locales.empty?
1,555✔
62
      # first preferred language from the related locales
354✔
63
      locale = http_accept_language.preferred_language_from(related_locales)
354✔
64
    end
65

66
    # execute the action with the locale
67
    I18n.with_locale(locale, &action)
1,555✔
68
  end
69

70
  # Set the current user in User
71
  def set_current_user_in_model
1✔
72
    User.current_user = current_user
1,588✔
73
  end
74

75
  def current_user
1✔
76
    super || guest_user
31,855✔
77
  end
78

79
  # find the guest user account if a guest user session is currently active
80
  def guest_user
1✔
81
    User.find_by(id: session[:guest_user_id])
1,457✔
82
  end
83

84
  # when the user chooses to transcribe as guest, find guest user id or create new guest user
85
  def guest_transcription
1✔
86
    return head(:forbidden) unless GUEST_TRANSCRIPTION_ENABLED
3✔
87

88
    if check_recaptcha(model: @page, :attribute => :errors)
2✔
89
      User.find(session[:guest_user_id].nil? ? session[:guest_user_id] = create_guest_user.id : session[:guest_user_id])
2!
90
      redirect_to :controller => 'transcribe', :action => 'display_page', :page_id => @page.id
2✔
91
    else
92
      # TODO: Get some kind of flash notification on failure
×
93
      flash[:error] = t('layouts.application.recaptcha_validation_failed')
×
94
      flash.keep
×
95
      redirect_to :controller => 'transcribe', :action => 'guest', :page_id => @page.id
×
96
    end
97

98
  end
99

100
  def create_guest_user
1✔
101
    user = User.new { |user| user.guest = true}
4✔
102
    user.email = "guest_#{Time.now.to_i}#{rand(99)}@example.com"
2✔
103
    user.save(:validate => false)
2✔
104
    user
2✔
105
  end
106

107
  def remove_col_id
1✔
108
    #if there's a col_id set, needs to be removed to prevent breadcrumb issues
109
    if session[:col_id]
263✔
110
      session[:col_id] = nil
9✔
111
    end
112
  end
113

114
  # See ActionController::RequestForgeryProtection for details
115
  # Uncomment the :secret if you're not using the cookie session store
116
  # protect_from_forgery :secret => 'I Hate InvalidAuthenticityToken'
117
  rescue_from ActiveRecord::RecordNotFound do |e|
1✔
118
    bad_record_id(e)
1✔
119
  end
120

121
  def load_objects_from_params
1✔
122
    # this needs to be ordered from the specific to the
123
    # general, so that parent_id will load the appropriate
124
    # object without being overridden by child_id.parent
125
    # whenever both are specified on the parameters
126

127
    if params[:article_id]
1,566✔
128
      @article = Article.find(params[:article_id])
55✔
129
      if session[:col_id] != nil
55✔
130
        @collection = set_friendly_collection(session[:col_id])
16✔
131
        session[:col_id] = nil
16✔
132
      else
39✔
133
        @collection = @article.collection
39✔
134
      end
135
    end
136
    if params[:page_id]
1,566✔
137
      @page = Page.find(params[:page_id])
362✔
138
      @work = @page.work
362✔
139
      if session[:col_id] != nil
362✔
140
        @collection = set_friendly_collection(session[:col_id])
130✔
141
        session[:col_id] = nil
130✔
142
      else
232✔
143
        @collection = @page.collection
232✔
144
      end
145
    end
146
    if params[:work_id]
1,566✔
147
      @work = Work.friendly.find(params[:work_id])
385✔
148
      @collection = @work.collection
385✔
149
    end
150
    if params[:document_set_id]
1,566✔
151
      @document_set = DocumentSet.friendly.find(params[:document_set_id])
13✔
152
      @collection = @document_set.collection
13✔
153
    end
154
    if params[:collection_id]
1,566✔
155
      @collection = set_friendly_collection(params[:collection_id])
750✔
156
    end
157

158
    if params[:user_id]
1,566✔
159
      @user = User.friendly.find(params[:user_id])
71✔
160
    end
161

162
    # category stuff may be orthogonal to collections and articles
163
    if params[:category_id]
1,565✔
164
      @category = Category.find(params[:category_id])
6✔
165
    end
166

167
    # consider loading work and collection from the versions
168
    if params[:page_version_id]
1,565!
169
      @page_version = PageVersion.find(params[:page_version_id])
×
170
      @page = @page_version.page
×
171
      @work = @page.work
×
172
      @collection = @work.collection
×
173
    end
174
    if params[:article_version_id]
1,565!
175
      @article_version = ArticleVersion.find(params[:article_version_id])
×
176
      @article = @article_version.article
×
177
      @collection = @article.collection
×
178
    end
179
    if params[:collection_ids]
1,565!
180
      @collection_ids = params[:collection_ids]
×
181
    end
182

183

184
    if self.class.module_parent == Thredded && @collection
1,565✔
185
      Thredded::Engine.routes.default_url_options = { user_slug: @collection.owner.slug, collection_id: @collection.slug }
1✔
186
    else
1,564✔
187
      Thredded::Engine.routes.default_url_options = { user_slug: 'nil', collection_id: 'nil' }
1,564✔
188
    end
189
  end
190

191
  def set_friendly_collection(id)
1✔
192
    if Collection.friendly.exists?(id)
896✔
193
      @collection = Collection.friendly.find(id)
780✔
194
    elsif DocumentSet.friendly.exists?(id)
116✔
195
      @collection = DocumentSet.friendly.find(id)
115✔
196
    elsif !DocumentSet.find_by(slug: id).nil?
1!
197
      @collection = DocumentSet.find_by(slug: id)
✔
198
    elsif !Collection.find_by(slug: id).nil?
1!
199
      @collection = Collection.find_by(slug: id)
×
200
    end
201

202
    # check to make sure URLs haven't gotten scrambled
203
    if @work
896✔
204
      if @work.collection != @collection
564✔
205
        # this could be a document set or a bad collection
65✔
206
        unless @collection.is_a? DocumentSet
65!
207
          @collection = @work.collection
×
208
        end
209
      end
210
    end
211
    return @collection
896✔
212
  end
213

214
  def bad_record_id(e)
1✔
215
    logger.error("Bad record ID exception for params=#{params.inspect}")
1✔
216
    logger.error(e.backtrace[2])
1✔
217
    if @collection
1!
218
      redirect_to :controller => 'collection', :action => 'show', :collection_id => @collection.id
×
219
    else
1✔
220
      redirect_to "/404"
1✔
221
    end
222

223
    return
224
  end
225

226
  def load_html_blocks
1✔
227
    @html_blocks = {}
1,557✔
228
    page_blocks =
229
      PageBlock.where(controller: controller_name, view: action_name)
1,557✔
230
    page_blocks.each do |b|
1,557✔
231
      if b && b.html
797✔
232
        b.rendered_html = render_to_string(:inline => b.html)
74✔
233
      else
723✔
234
        b.rendered_html = ''
723✔
235
      end
236
      @html_blocks[b.tag] = b
797✔
237
    end
238
  end
239

240
  def authorize_collection
1✔
241
    return unless @collection
1,590✔
242
    if self.class.module_parent.name == 'Thredded'
857✔
243
      unless @collection.messageboards_enabled
1!
244
        flash[:error] = t('message_boards_are_disabled', :project => @collection.title)
×
245
        redirect_to main_app.user_profile_path(@collection.owner)
×
246
      end
247
    end
248

249
    return unless @collection.restricted
857✔
250
    return if (params[:controller] == 'iiif')
49!
251

252
    unless @collection.show_to?(current_user)
49✔
253
      # second chance?
2✔
254
      unless set_fallback_collection
2!
255
        flash[:error] = t('unauthorized_collection', :project => @collection.title)
2✔
256
        redirect_to main_app.user_profile_path(@collection.owner)
2✔
257
      end
258
    end
259
  end
260

261
  def set_fallback_collection
1✔
262
    if @work && @work.collection.supports_document_sets
2✔
263
      alternative_set = @work.document_sets.unrestricted.first
2✔
264
      if alternative_set
2!
265
        @collection = alternative_set
×
266
        true
×
267
      else
2✔
268
        false
2✔
269
      end
270
    else
×
271
      false
×
272
    end
273
  end
274

275
  def configure_permitted_parameters
1✔
276
    devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:login, :email, :password, :password_confirmation, :display_name, :owner, :paid_date, :activity_email) }
71✔
277
    devise_parameter_sanitizer.permit(:sign_in) { |u| u.permit(:login_id, :login, :email, :password, :remember_me) }
93✔
278
    devise_parameter_sanitizer.permit(:account_update) { |u| u.permit(:login, :email, :password, :current_password, :password_confirmation, :real_name) }
71✔
279
  end
280

281
  # Redirect to admin or owner dashboard after sign in
282
  # Always send admins to admin dashboard
283
  # Everyone else should go back to where they came from if their previous page is set
284
  # Otherwise owners should go to their dashboards
285
  # And everyone else should go to user dashboard/watchlist
286
  def after_sign_in_path_for(resource)
1✔
287
    if current_user.admin
18✔
288
      admin_path
4✔
289
    elsif !session[:user_return_to].blank? && session[:user_return_to] != '/' && !session[:user_return_to].include?('/landing')
14✔
290
      session[:user_return_to]
2✔
291
    elsif current_user.owner
12✔
292
      if current_user.collections.any?
4✔
293
        dashboard_owner_path
2✔
294
      else
2✔
295
        dashboard_startproject_path
2✔
296
      end
8✔
297
    elsif current_user.deeds.any?
8✔
298
      dashboard_watchlist_path
3✔
299
    else
5✔
300
      landing_page_path
5✔
301
    end
302
  end
303

304
  # destroy guest user session if a user signs out, then redirect to root path
305
  def after_sign_out_path_for(resource)
1✔
306
    if session[:guest_user_id]
×
307
      session[:guest_user_id] = nil
×
308
    end
309
    root_path
×
310
  end
311

312
  # Wrapper around redirect_to for modal ajax forms
313
  def ajax_redirect_to(options={}, response_status={})
1✔
314
    if request.xhr?
52✔
315
      head :created, location: url_for(options)
8✔
316
    else
44✔
317
      redirect_to options, response_status
44✔
318
    end
319
  end
320

321
  private
1✔
322

323
  def set_layout
1✔
324
    request.xhr? ? false : nil
2,266✔
325
  end
326

327
  def per_page
1✔
328
    return @per_page if defined?(@per_page)
23✔
329

330
    @per_page = if params[:per_page].present?
12✔
331
                  params[:per_page].to_i
3✔
332
                else
9✔
333
                  default_per_page
9✔
334
                end
335

336
    @per_page
12✔
337
  end
338

339
  def default_per_page
1✔
340
    # Override in controller for custom defaults
341
    DEFAULT_PER_PAGE
9✔
342
  end
343
end
344

345
def page_params(page)
1✔
346
  if @collection
642✔
347
    collection = @collection
642✔
348
  else
×
NEW
349
    collection = page.work.access_object(current_user) || page.work.collection
×
350
  end
351

352
  if page.status_new?
642✔
353
    if user_signed_in?
315✔
354
      collection_transcribe_page_path(page.work.collection.owner, collection, page.work, page)
300✔
355
    else
15✔
356
      collection_guest_page_path(page.work.collection.owner, collection, page.work, page)
15✔
357
    end
358
  else
327✔
359
    collection_display_page_path(page.work.collection.owner, collection, page.work, page)
327✔
360
  end
361
end
362

363
def track_action
1✔
364
  extras = {}
1,568✔
365
  if @collection
1,568✔
366
    if @collection.is_a? DocumentSet
1,088✔
367
      extras[:document_set_id] = @collection.id
117✔
368
      extras[:document_set_title] = @collection.title
117✔
369
      extras[:collection_id] = @collection.collection.id
117✔
370
      extras[:collection_title] = @collection.collection.title
117✔
371
    else
971✔
372
      extras[:collection_id] = @collection.id
971✔
373
      extras[:collection_title] = @collection.title
971✔
374
    end
375
  end
376
  extras[:work_id] = @work.id if @work
1,568✔
377
  extras[:work_title] = @work.title if @work
1,568✔
378
  extras[:page_id] = @page.id if @page
1,568✔
379
  extras[:page_title] = @page.title if @page
1,568✔
380
  extras[:article_id] = @article.id if @article
1,568✔
381
  extras[:article_title] = @article.title if @article
1,568✔
382
  ahoy.track("#{controller_name}##{action_name}", extras) unless action_name == "still_editing"
1,568✔
383
end
384

385
def check_api_access
1✔
386
  if (defined? @collection) && @collection
4✔
387
    if @collection.restricted && !@collection.api_access
2!
NEW
388
      if @api_user.nil? || !(@api_user.like_owner?(@collection))
×
NEW
389
        render :status => 403, :plain => 'This collection is private.  The collection owner must enable API access to it or make it public for it to appear.'
×
390
      end
391
    end
392
  end
393
end
394

395
def set_api_user
1✔
396
  authenticate_with_http_token do |token, options|
16✔
397
    @api_user = User.find_by(api_key: token)
12✔
398
  end
399
end
400

401
def check_search_attempt
1✔
402
  if session[:search_attempt_id]
1,588!
NEW
403
    your_profile = controller_name == "user" && @user == current_user
×
NEW
404
    if ["dashboard", "static"].include?(controller_name) || your_profile
×
NEW
405
      session[:search_attempt_id] = nil
×
406
    end
407
  end
408
end
409

410
def update_search_attempt_contributions
1✔
411
  if session[:search_attempt_id]
73!
NEW
412
    search_attempt = SearchAttempt.find(session[:search_attempt_id])
×
NEW
413
    search_attempt.increment!(:contributions)
×
414
  end
415
end
416

417
def update_search_attempt_user(user, session_var)
1✔
418
  if session_var[:search_attempt_id]
454!
NEW
419
    search_attempt = SearchAttempt.find(session_var[:search_attempt_id])
×
NEW
420
    search_attempt.user = user
×
NEW
421
    search_attempt.owner = user.owner
×
NEW
422
    search_attempt.save
×
423
  end
424
end
425

426
private
1✔
427

428
def store_current_location
1✔
429
  store_location_for(:user, request.url)
1,231✔
430
end
431

432
def check_recaptcha(options)
1✔
433
  return verify_recaptcha(options) if RECAPTCHA_ENABLED
2!
434

435
  true
2✔
436
end
437

438
def codespaces_environment?
1✔
439
  Rails.env.development? && ENV["CODESPACES"] == "true"
713✔
440
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

© 2026 Coveralls, Inc