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

pulibrary / orangelight / eb80f8d4-6d50-4046-9c51-eb5bed369cb3

06 Sep 2023 06:25PM UTC coverage: 95.401% (+0.006%) from 95.395%
eb80f8d4-6d50-4046-9c51-eb5bed369cb3

push

circleci

sandbergja
Match existing advanced search form formatting

5580 of 5849 relevant lines covered (95.4%)

1418.75 hits per line

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

99.32
/app/controllers/catalog_controller.rb
1
# frozen_string_literal: false
2

3
class CatalogController < ApplicationController
3✔
4
  include BlacklightAdvancedSearch::Controller
3✔
5
  include Blacklight::Catalog
3✔
6
  include BlacklightUnapi::ControllerExtension
3✔
7

8
  # include Blacklight::Marc::Catalog
9
  include BlacklightRangeLimit::ControllerOverride
3✔
10
  include Orangelight::Catalog
3✔
11
  include Orangelight::Stackmap
3✔
12
  include BlacklightHelper
3✔
13

14
  before_action :redirect_browse
3✔
15

16
  rescue_from Blacklight::Exceptions::RecordNotFound do
3✔
17
    alma_id = "99#{params[:id]}3506421"
9✔
18
    search_service.fetch(alma_id)
9✔
19
    redirect_to solr_document_path(id: alma_id)
3✔
20
  rescue Blacklight::Exceptions::RecordNotFound
21
    redirect_to '/404'
6✔
22
  end
23

24
  rescue_from ActionController::InvalidAuthenticityToken do
3✔
25
    redirect_to solr_document_path(params[:id])
×
26
  end
27

28
  rescue_from BlacklightRangeLimit::InvalidRange do
3✔
29
    redirect_to '/', flash: { error: 'The start year must be before the end year.' }
2✔
30
  end
31

32
  configure_blacklight do |config|
3✔
33
    config.raw_endpoint.enabled = true
3✔
34

35
    config.json_solr_path = 'advanced'
3✔
36

37
    # default advanced config values
38
    config.advanced_search ||= Blacklight::OpenStructWithHashAccess.new
3✔
39
    config.advanced_search[:url_key] ||= 'advanced'
3✔
40
    config.advanced_search[:query_parser] ||= 'edismax'
3✔
41
    config.advanced_search[:form_solr_parameters] ||= {}
3✔
42
    config.advanced_search[:form_solr_parameters]['facet.field'] ||= %w[access_facet format language_facet advanced_location_s]
3✔
43
    config.advanced_search[:form_solr_parameters]['facet.query'] ||= ''
3✔
44
    config.advanced_search[:form_solr_parameters]['facet.limit'] ||= -1
3✔
45
    config.advanced_search[:form_solr_parameters]['facet.pivot'] ||= ''
3✔
46
    config.advanced_search[:form_solr_parameters]['f.language_facet.facet.limit'] ||= -1
3✔
47
    config.advanced_search[:form_solr_parameters]['f.language_facet.facet.sort'] ||= 'index'
3✔
48

49
    config.numismatics_search ||= Blacklight::OpenStructWithHashAccess.new
3✔
50
    config.numismatics_search[:facet_fields] ||= %w[issue_metal_s issue_city_s issue_state_s issue_region_s issue_denomination_s
3✔
51
                                                    issue_ruler_s issue_artists_s find_place_s donor_s issue_object_type_s]
52

53
    ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params
54

55
    # solr path which will be added to solr base url before the other solr params.
56
    # config.solr_path = 'select'
57

58
    # items to show per page, each number in the array represent another option to choose from.
59
    # config.per_page = [10,20,50,100]
60
    config.default_per_page = 20
3✔
61

62
    ## Default parameters to send on single-document requests to Solr. These settings are the Blackligt defaults (see SolrHelper#solr_doc_params) or
63
    ## parameters included in the Blacklight-jetty document requestHandler.
64
    #
65

66
    # config.default_document_solr_params = {
67
    #  :qt => 'document',
68
    #  ## These are hard-coded in the blacklight 'document' requestHandler
69
    #  # :fl => '*',
70
    #  # :rows => 1
71
    #   :q => query
72
    # }
73

74
    config.add_show_tools_partial(:bookmark, partial: 'bookmark_control', if: :render_bookmarks_control?)
3✔
75
    config.add_show_tools_partial(:email, callback: :email_action, validator: :validate_email_params)
3✔
76
    config.add_show_tools_partial(:sms, if: :render_sms_action?, callback: :sms_action, validator: :validate_sms_params)
3✔
77
    config.add_show_tools_partial(:citation)
3✔
78

79
    config.navbar.partials.delete(:search_history)
3✔
80
    config.add_nav_action(:bookmark, partial: 'blacklight/nav/bookmark')
3✔
81

82
    # solr field configuration for search results/index views
83
    config.index.title_field = 'title_display'
3✔
84
    config.index.partials = %i[index_header show_identifiers thumbnail index]
3✔
85
    config.index.display_type_field = 'format'
3✔
86

87
    # solr field configuration for document/show views
88
    config.show.partials = %i[show_identifiers show]
3✔
89
    # config.show.title_field = 'title_display'
90
    # config.show.display_type_field = 'format'
91

92
    # solr fields that will be treated as facets by the blacklight application
93
    #   The ordering of the field names is the order of the display
94
    #
95
    # Setting a limit will trigger Blacklight's 'more' facet values link.
96
    # * If left unset, then all facet values returned by solr will be displayed.
97
    # * If set to an integer, then "f.somefield.facet.limit" will be added to
98
    # solr request, with actual solr request being +1 your configured limit --
99
    # you configure the number of items you actually want _displayed_ in a page.
100
    # * If set to 'true', then no additional parameters will be sent to solr,
101
    # but any 'sniffed' request limit parameters will be used for paging, with
102
    # paging at requested limit -1. Can sniff from facet.limit or
103
    # f.specific_field.facet.limit solr request params. This 'true' config
104
    # can be used if you set limits in :default_solr_params, or as defaults
105
    # on the solr side in the request handler itself. Request handler defaults
106
    # sniffing requires solr requests to be made with "echoParams=all", for
107
    # app code to actually have it echo'd back to see it.
108
    #
109
    # :show may be set to false if you don't want the facet to be drawn in the
110
    # facet bar
111
    config.add_facet_field 'access_facet', label: 'Access', sort: 'index', collapse: false, home: true
3✔
112
    config.add_facet_field 'location', label: 'Library', limit: 20, sort: 'index',
3✔
113
                                       home: true, solr_params: { 'facet.mincount' => Blacklight.blacklight_yml['mincount'] || 1 }
114
    config.add_facet_field 'format', label: 'Format', partial: 'facet_format', sort: 'index', limit: 15,
3✔
115
                                     collapse: false, home: true, solr_params: { 'facet.mincount' => Blacklight.blacklight_yml['mincount'] || 1 }
116

117
    # num_segments and segments set to defaults here, included to show customizable features
118
    config.add_facet_field 'pub_date_start_sort', label: 'Publication year', single: true, range: {
3✔
119
      num_segments: 10,
120
      assumed_boundaries: [1100, Time.now.year + 1],
121
      segments: true
122
    }
123
    config.add_facet_field 'language_facet', label: 'Language', limit: true
3✔
124
    config.add_facet_field 'subject_topic_facet', label: 'Subject: Topic', limit: true
3✔
125
    config.add_facet_field 'genre_facet', label: 'Subject: Genre', limit: true
3✔
126
    config.add_facet_field 'subject_era_facet', label: 'Subject: Era', limit: true
3✔
127
    config.add_facet_field 'recently_added_facet', label: 'Recently added', home: true, query: {
3✔
128
      weeks_1: { label: 'Within 1 week', fq: 'cataloged_tdt:[NOW/DAY-7DAYS TO NOW/DAY+1DAY]' },
129
      weeks_2: { label: 'Within 2 weeks', fq: 'cataloged_tdt:[NOW/DAY-14DAYS TO NOW/DAY+1DAY]' },
130
      weeks_3: { label: 'Within 3 weeks', fq: 'cataloged_tdt:[NOW/DAY-21DAYS TO NOW/DAY+1DAY]' },
131
      months_1: { label: 'Within 1 month', fq: 'cataloged_tdt:[NOW/DAY-1MONTH TO NOW/DAY+1DAY]' },
132
      months_2: { label: 'Within 2 months', fq: 'cataloged_tdt:[NOW/DAY-2MONTHS TO NOW/DAY+1DAY]' },
133
      months_3: { label: 'Within 3 months', fq: 'cataloged_tdt:[NOW/DAY-3MONTHS TO NOW/DAY+1DAY]' },
134
      months_6: { label: 'Within 6 months', fq: 'cataloged_tdt:[NOW/DAY-6MONTHS TO NOW/DAY+1DAY]' }
135
    }
136

137
    config.add_facet_field 'instrumentation_facet', label: 'Instrumentation', limit: true
3✔
138
    config.add_facet_field 'publication_place_facet', label: 'Place of publication', limit: true
3✔
139
    config.add_facet_field 'classification_pivot_field', label: 'Classification', pivot: %w[lc_1letter_facet lc_rest_facet], collapsing: true, icons: {
3✔
140
      hide: '<i class="icon toggle"></i>'.html_safe,
141
      show: '<i class="icon toggle collapsed"></i>'.html_safe
142
    }
143
    config.add_facet_field 'sudoc_facet', label: 'SuDocs', limit: true, sort: 'index'
3✔
144

145
    # The following facet configurations are purely for display purposes. They
146
    # will not show up in the facet bar, but without them the labels and other
147
    # configuration which show up when a user clicks that field in the show page
148
    # will be wrong.
149
    config.add_facet_field 'lc_1letter_facet', label: 'Classification', limit: 25, include_in_request: false, sort: 'index'
3✔
150
    config.add_facet_field 'author_s', label: 'Author', limit: true, include_in_request: false
3✔
151
    config.add_facet_field 'class_year_s', label: 'PU class year', limit: true, include_in_request: false
3✔
152
    config.add_facet_field 'lc_rest_facet', label: 'Full call number code', limit: 25, include_in_request: false, sort: 'index'
3✔
153
    config.add_facet_field 'call_number_browse_s', label: 'Call number', include_in_request: false
3✔
154

155
    config.add_facet_field 'call_number_scheme_facet', label: 'Call number scheme', limit: 25, include_in_request: false, sort: 'index'
3✔
156
    config.add_facet_field 'call_number_group_facet', label: 'Call number group', limit: 25, include_in_request: false, sort: 'index'
3✔
157
    config.add_facet_field 'call_number_full_facet', label: 'Full call number', limit: 25, include_in_request: false, sort: 'index'
3✔
158
    config.add_facet_field 'advanced_location_s', label: 'Holding location', include_in_request: false,
3✔
159
                                                  helper_method: :render_location_code
160
    config.add_facet_field 'name_title_browse_s', label: 'Author-title heading', include_in_request: false
3✔
161
    config.add_facet_field 'subject_facet', show: false
3✔
162

163
    # Numismatics facets
164
    config.add_facet_field 'numismatic_collection_s', label: 'Numismatic Collection', include_in_request: false
3✔
165
    config.add_facet_field 'issue_date_s', label: 'Date', include_in_request: false
3✔
166
    config.add_facet_field 'issue_artists_s', label: 'Artist', include_in_request: false
3✔
167
    config.add_facet_field 'issue_subject_s', label: 'Subject', include_in_request: false
3✔
168
    config.add_facet_field 'numismatic_accession_s', label: 'Accession', include_in_request: false
3✔
169
    config.add_facet_field 'numismatic_provenance_s', label: 'Provenance', include_in_request: false
3✔
170
    config.add_facet_field 'issue_number_s', label: 'Issue', include_in_request: false
3✔
171
    config.add_facet_field 'issue_monogram_title_s', label: 'Monogram', include_in_request: false
3✔
172
    config.add_facet_field 'issue_citations_s', label: 'Citations', include_in_request: false
3✔
173
    config.add_facet_field 'issue_references_s', label: 'References', include_in_request: false
3✔
174
    config.add_facet_field 'donor_s', label: 'Donor', include_in_request: false
3✔
175
    config.add_facet_field 'analysis_s', label: 'Analysis', include_in_request: false
3✔
176
    config.add_facet_field 'counter_stamp_s', label: 'Counter Stamp', include_in_request: false
3✔
177
    config.add_facet_field 'die_axis_s', label: 'Die Axis', include_in_request: false
3✔
178
    config.add_facet_field 'find_date_s', label: 'Find Date', include_in_request: false
3✔
179
    config.add_facet_field 'find_description_s', label: 'Find Description', include_in_request: false
3✔
180
    config.add_facet_field 'find_feature_s', label: 'Find Feature', include_in_request: false
3✔
181
    config.add_facet_field 'find_locus_s', label: 'Find Locus', include_in_request: false
3✔
182
    config.add_facet_field 'find_number_s', label: 'Find Number', include_in_request: false
3✔
183
    config.add_facet_field 'find_place_s', label: 'Find Place', include_in_request: false
3✔
184
    config.add_facet_field 'issue_color_s', label: 'Color', include_in_request: false
3✔
185
    config.add_facet_field 'issue_denomination_s', label: 'Denomination', include_in_request: false
3✔
186
    config.add_facet_field 'issue_edge_s', label: 'Edge', include_in_request: false
3✔
187
    config.add_facet_field 'issue_era_s', label: 'Era', include_in_request: false
3✔
188
    config.add_facet_field 'issue_master_s', label: 'Master', include_in_request: false
3✔
189
    config.add_facet_field 'issue_metal_s', label: 'Metal', include_in_request: false
3✔
190
    config.add_facet_field 'issue_city_s', label: 'City', include_in_request: false
3✔
191
    config.add_facet_field 'issue_state_s', label: 'State', include_in_request: false
3✔
192
    config.add_facet_field 'issue_region_s', label: 'Region', include_in_request: false
3✔
193
    config.add_facet_field 'issue_object_type_s', label: 'Object Type', include_in_request: false
3✔
194
    config.add_facet_field 'issue_obverse_attributes_s', label: 'Obverse Attributes', include_in_request: false
3✔
195
    config.add_facet_field 'issue_obverse_figure_description_s', label: 'Obverse Figure Description', include_in_request: false
3✔
196
    config.add_facet_field 'issue_obverse_figure_relationship_s', label: 'Obverse Figure Relationship', include_in_request: false
3✔
197
    config.add_facet_field 'issue_obverse_figure_s', label: 'Obverse Figure', include_in_request: false
3✔
198
    config.add_facet_field 'issue_obverse_legend_s', label: 'Obverse Legend', include_in_request: false
3✔
199
    config.add_facet_field 'issue_obverse_orientation_s', label: 'Obverse Orientation', include_in_request: false
3✔
200
    config.add_facet_field 'issue_obverse_part_s', label: 'Obverse Part', include_in_request: false
3✔
201
    config.add_facet_field 'issue_obverse_symbol_s', label: 'Obverse Symbol', include_in_request: false
3✔
202
    config.add_facet_field 'issue_reverse_attributes_s', label: 'Reverse Attributes', include_in_request: false
3✔
203
    config.add_facet_field 'issue_reverse_figure_description_s', label: 'Reverse Figure Description', include_in_request: false
3✔
204
    config.add_facet_field 'issue_reverse_figure_relationship_s', label: 'Reverse Figure Relationship', include_in_request: false
3✔
205
    config.add_facet_field 'issue_reverse_figure_s', label: 'Reverse Figure', include_in_request: false
3✔
206
    config.add_facet_field 'issue_reverse_legend_s', label: 'Reverse Legend', include_in_request: false
3✔
207
    config.add_facet_field 'issue_reverse_orientation_s', label: 'Reverse Orientation', include_in_request: false
3✔
208
    config.add_facet_field 'issue_reverse_part_s', label: 'Reverse Part', include_in_request: false
3✔
209
    config.add_facet_field 'issue_reverse_symbol_s', label: 'Reverse Symbol', include_in_request: false
3✔
210
    config.add_facet_field 'issue_ruler_s', label: 'Ruler', include_in_request: false
3✔
211
    config.add_facet_field 'issue_series_s', label: 'Series', include_in_request: false
3✔
212
    config.add_facet_field 'issue_shape_s', label: 'Shape', include_in_request: false
3✔
213
    config.add_facet_field 'issue_workshop_s', label: 'Workshop', include_in_request: false
3✔
214
    config.add_facet_field 'size_s', label: 'Size', include_in_request: false
3✔
215
    config.add_facet_field 'technique_s', label: 'Technique', include_in_request: false
3✔
216
    config.add_facet_field 'weight_s', label: 'Weight', include_in_request: false
3✔
217
    config.add_facet_field 'coin_citations_s', label: 'Citations', include_in_request: false
3✔
218
    config.add_facet_field 'coin_references_s', label: 'References', include_in_request: false
3✔
219

220
    # Have BL send all facet field names to Solr, which has been the default
221
    # previously. Simply remove these lines if you'd rather use Solr request
222
    # handler defaults, or have no facets.
223
    config.add_facet_fields_to_solr_request!
3✔
224

225
    # solr fields to be displayed in the index (search results) view
226
    #   The ordering of the field names is the order of the display
227
    # NOTE: Most of these are added with show: false so they show up in the JSON
228
    #   output for bento search. If you need to add a field to JSON display
229
    #   (catalog.json), add it here!
230
    config.add_index_field 'series_display', label: 'Series', helper_method: :series_results
3✔
231
    config.add_index_field 'author_display', label: 'Author/Artist', browse_link: :name
3✔
232
    config.add_index_field 'pub_created_display', label: 'Published/Created'
3✔
233
    config.add_index_field 'format', label: 'Format', helper_method: :format_icon
3✔
234
    config.add_index_field 'holdings_1display', show: false
3✔
235
    config.add_index_field 'contained_in_s', show: false
3✔
236
    config.add_index_field 'isbn_t', show: false
3✔
237
    config.add_index_field 'score', show: false
3✔
238
    config.add_index_field 'marc_relator_display', show: false
3✔
239
    config.add_index_field 'title_display', show: false
3✔
240
    config.add_index_field 'title_vern_display', show: false
3✔
241
    config.add_index_field 'isbn_s', show: false
3✔
242
    config.add_index_field 'oclc_s', show: false
3✔
243
    config.add_index_field 'lccn_s', show: false
3✔
244
    config.add_index_field 'electronic_access_1display', show: false
3✔
245
    config.add_index_field 'cataloged_tdt', show: false
3✔
246
    config.add_index_field 'electronic_portfolio_s', show: false
3✔
247

248
    # solr fields to be displayed in the show (single result) view
249
    #   The ordering of the field names is the order of the display
250
    # config.add_show_field 'title_display', :label => 'Title'
251
    # config.add_show_field 'title_vern_display', :label => 'Title'
252
    # config.add_show_field 'subtitle_display', :label => 'Subtitle'
253
    # config.add_show_field 'subtitle_vern_display', :label => 'Subtitle'
254

255
    # Top fields in show page / prioritized information
256
    # Top fields must include `if: false`, or they will be duplicated in the Details section
257
    # They should be designated with either `default_top_field: true`, `coin_top_field: true` or both
258
    config.add_show_field 'author_display', label: "Author/\u200BArtist", browse_link: :name, if: false, default_top_field: true
3✔
259
    # For uniform titles from 240 field - when there is both an author and uniform title
260
    config.add_show_field 'name_uniform_title_1display', label: 'Uniform title', helper_method: :name_title_hierarchy, if: false, default_top_field: true
3✔
261
    # For uniform titles from 130 field - when there is only a uniform title, and no author
262
    config.add_show_field 'uniform_title_1display', label: 'Uniform title', helper_method: :title_hierarchy, if: false, default_top_field: true
3✔
263
    config.add_show_field 'format', label: 'Format', helper_method: :format_render, if: false, coin_top_field: true, default_top_field: true
3✔
264
    config.add_show_field 'language_name_display', label: 'Language', if: false, default_top_field: true
3✔
265
    config.add_show_field 'edition_display', label: 'Εdition', if: false, default_top_field: true
3✔
266
    config.add_show_field 'pub_created_display', label: "Published/\u200BCreated", if: false, default_top_field: true
3✔
267
    config.add_show_field 'description_display', label: 'Description', if: false, default_top_field: true
3✔
268

269
    # Senior Thesis linked fields
270
    config.add_show_field 'advisor_display', label: 'Advisor(s)', browse_link: :name
3✔
271
    config.add_show_field 'contributor_display', label: 'Contributor(s)', browse_link: :name
3✔
272
    config.add_show_field 'department_display', label: 'Department', browse_link: :name
3✔
273
    config.add_show_field 'certificate_display', label: 'Certificate', browse_link: :name
3✔
274

275
    config.add_show_field 'class_year_s', label: 'Class year', link_to_search_value: true
3✔
276
    # Linked fields pushed to top of supplemental info
277
    config.add_show_field 'lc_subject_display', label: 'Subject(s)', helper_method: :subjectify
3✔
278
    config.add_show_field 'siku_subject_display', label: 'Chinese traditional subject(s)', helper_method: :subjectify
3✔
279
    config.add_show_field 'homoit_subject_display', label: 'Homosaurus term(s)', helper_method: :subjectify
3✔
280
    config.add_show_field 'related_name_json_1display', hash: true
3✔
281
    config.add_show_field 'lcgft_s', label: 'Library of Congress genre(s)', helper_method: :subjectify
3✔
282
    config.add_show_field 'homoit_genre_s', label: 'Homosaurus genre(s)', helper_method: :subjectify
3✔
283
    config.add_show_field 'rbgenr_s', label: 'Rare books genre', helper_method: :subjectify
3✔
284
    config.add_show_field 'aat_s', label: 'Getty AAT genre', helper_method: :subjectify
3✔
285
    config.add_show_field 'related_works_1display', label: 'Related work(s)', helper_method: :name_title_hierarchy
3✔
286
    config.add_show_field 'series_display', label: 'Series', series_link: true
3✔
287
    config.add_show_field 'contains_1display', label: 'Contains', helper_method: :name_title_hierarchy
3✔
288
    config.add_show_field 'data_source_display', label: 'Data source', browse_link: :name_title
3✔
289
    config.add_show_field 'contained_in_s', label: 'Contained in', link_field: 'id'
3✔
290
    config.add_show_field 'related_record_s', label: 'Related record(s)', link_field: 'id'
3✔
291
    config.add_show_field 'other_editions_s', label: 'Other available editions', link_field: 'id'
3✔
292
    config.add_show_field 'translation_of_display', label: 'Translation of', browse_link: :name_title
3✔
293
    config.add_show_field 'translated_as_display', label: 'Translated as', browse_link: :name_title
3✔
294
    config.add_show_field 'issued_with_display', label: 'Issued with', browse_link: :name_title
3✔
295
    config.add_show_field 'continues_display', label: 'Continues', browse_link: :name_title
3✔
296
    config.add_show_field 'continues_in_part_display', label: 'Continues in part', browse_link: :name_title
3✔
297
    config.add_show_field 'formed_from_display', label: 'Formed from', browse_link: :name_title
3✔
298
    config.add_show_field 'absorbed_display', label: 'Absorbed', browse_link: :name_title
3✔
299
    config.add_show_field 'absorbed_in_part_display', label: 'Absorbed in part', browse_link: :name_title
3✔
300
    config.add_show_field 'separated_from_display', label: 'Separated from', browse_link: :name_title
3✔
301
    config.add_show_field 'continued_by_display', label: 'Continued by', browse_link: :name_title
3✔
302
    config.add_show_field 'continued_in_part_by_display', label: 'Continued in part by', browse_link: :name_title
3✔
303
    config.add_show_field 'absorbed_by_display', label: 'Absorbed by', browse_link: :name_title
3✔
304
    config.add_show_field 'absorbed_in_part_by_display', label: 'Absorbed in part by', browse_link: :name_title
3✔
305
    config.add_show_field 'split_into_display', label: 'Split into', browse_link: :name_title
3✔
306
    config.add_show_field 'merged_to_form_display', label: 'Merged to form', browse_link: :name_title
3✔
307
    config.add_show_field 'changed_back_to_display', label: 'Changed back to', browse_link: :name_title
3✔
308
    config.add_show_field 'subseries_of_display', label: 'Subseries of', browse_link: :name_title
3✔
309
    config.add_show_field 'has_subseries_display', label: 'Has subseries', browse_link: :name_title
3✔
310
    config.add_show_field 'has_supplement_display', label: 'Has supplement', browse_link: :name_title
3✔
311
    config.add_show_field 'supplement_to_display', label: 'Supplement to', browse_link: :name_title
3✔
312

313
    # Fields that are not links
314
    config.add_show_field 'url_fulltext_display', label: 'URL'
3✔
315
    config.add_show_field 'url_suppl_display', label: 'More information'
3✔
316
    config.add_show_field 'compiled_created_display', label: "Compiled/\u200BCreated"
3✔
317
    config.add_show_field 'medium_support_display', label: "Medium/\u200BSupport"
3✔
318
    config.add_show_field 'numbering_pec_notes_display', label: 'Numbering peculiarities'
3✔
319
    config.add_show_field 'arrangement_display', label: 'Arrangement'
3✔
320
    config.add_show_field 'frequency_display', label: 'Frequency'
3✔
321
    config.add_show_field 'former_frequency_display', label: 'Former frequency'
3✔
322
    config.add_show_field 'linking_notes_display', label: 'Linking notes'
3✔
323
    config.add_show_field 'restrictions_note_display', label: 'Restrictions note', mark_as_safe: true
3✔
324
    config.add_show_field 'biographical_historical_note_display', label: "Biographical/\u200BHistorical note"
3✔
325
    config.add_show_field 'summary_note_display', label: 'Summary note'
3✔
326
    config.add_show_field 'notes_display', label: 'Notes'
3✔
327
    config.add_show_field 'holdings_1display', label: 'Location has', if: :online_holding_note?, helper_method: :location_has
3✔
328
    config.add_show_field 'with_notes_display', label: 'With'
3✔
329
    config.add_show_field 'bibliographic_notes_display', label: 'Bibliographic history'
3✔
330
    config.add_show_field 'dissertation_notes_display', label: 'Dissertation note'
3✔
331
    config.add_show_field 'bib_ref_notes_display', label: 'Bibliographic references'
3✔
332
    config.add_show_field 'scale_notes_display', label: 'Scale'
3✔
333
    config.add_show_field 'credits_notes_display', label: "Creation/\u200BProduction credits"
3✔
334
    config.add_show_field 'type_period_notes_display', label: 'Type of report and period covered'
3✔
335
    config.add_show_field 'data_quality_notes_display', label: 'Data quality'
3✔
336
    config.add_show_field 'type_comp_data_notes_display', label: 'Type of data'
3✔
337
    config.add_show_field 'date_place_event_notes_display', label: 'Time and place of event'
3✔
338
    config.add_show_field 'target_aud_notes_display', label: 'Target audience'
3✔
339
    config.add_show_field 'geo_cov_notes_display', label: 'Geographic coverage'
3✔
340
    config.add_show_field 'time_period_notes_display', label: 'Time period of content'
3✔
341
    config.add_show_field 'supplement_notes_display', label: 'Supplement note'
3✔
342
    config.add_show_field 'study_prog_notes_display', label: 'Study program information'
3✔
343
    config.add_show_field 'censorship_notes_display', label: 'Censorship note'
3✔
344
    config.add_show_field 'reproduction_notes_display', label: 'Reproduction note'
3✔
345
    config.add_show_field 'original_version_notes_display', label: 'Original version'
3✔
346
    config.add_show_field 'location_originals_notes_display', label: 'Location of originals'
3✔
347
    config.add_show_field 'funding_info_notes_display', label: 'Funding information'
3✔
348
    config.add_show_field 'source_data_notes_display', label: 'Source of data'
3✔
349
    config.add_show_field 'system_details_notes_display', label: 'System details'
3✔
350
    config.add_show_field 'related_copyright_notes_display', label: 'Copyright note'
3✔
351
    config.add_show_field 'location_other_arch_notes_display', label: 'Location of other archival materials'
3✔
352
    config.add_show_field 'former_title_complex_notes_display', label: 'Former title complexity'
3✔
353
    config.add_show_field 'issuing_body_notes_display', label: 'Issuing body'
3✔
354
    config.add_show_field 'info_document_notes_display', label: 'Information about documentation'
3✔
355
    config.add_show_field 'copy_version_notes_display', label: 'Copy and version identification'
3✔
356
    config.add_show_field 'case_file_notes_display', label: 'Case file characteristics'
3✔
357
    config.add_show_field 'methodology_notes_display', label: 'Methodology note'
3✔
358
    config.add_show_field 'editor_notes_display', label: 'Editor note'
3✔
359
    config.add_show_field 'action_notes_1display', label: 'Action note', helper_method: :action_notes_display
3✔
360
    config.add_show_field 'accumulation_notes_display', label: 'Accumulation and frequency of use'
3✔
361
    config.add_show_field 'awards_notes_display', label: 'Awards'
3✔
362
    config.add_show_field 'source_desc_notes_display', label: 'Source of description'
3✔
363
    config.add_show_field 'binding_note_display', label: 'Binding note'
3✔
364
    config.add_show_field 'local_notes_display', label: 'Local notes'
3✔
365
    config.add_show_field 'rights_reproductions_note_display', label: 'Rights and reproductions note', mark_as_safe: true
3✔
366
    config.add_show_field 'exhibitions_note_display', label: 'Exhibitions note'
3✔
367
    config.add_show_field 'participant_performer_display', label: "Participant(s)/\u200BPerformer(s)"
3✔
368
    config.add_show_field 'language_display', label: 'Language note'
3✔
369
    config.add_show_field 'script_display', label: 'Script'
3✔
370
    config.add_show_field 'contents_display', label: 'Contents', component: DisplayMoreFieldComponent, maxInitialDisplay: 3
3✔
371
    config.add_show_field 'incomplete_contents_display', label: 'Incomplete contents'
3✔
372
    config.add_show_field 'partial_contents_display', label: 'Partial contents'
3✔
373
    config.add_show_field 'provenance_display', label: 'Provenance'
3✔
374
    config.add_show_field 'source_acquisition_display', label: 'Source acquisition'
3✔
375
    config.add_show_field 'publications_about_display', label: 'Publications about'
3✔
376
    config.add_show_field 'indexed_in_display', label: 'Indexed in'
3✔
377
    config.add_show_field 'references_url_display', label: 'References', references_url: true
3✔
378
    config.add_show_field 'cite_as_display', label: 'Cite as'
3✔
379
    config.add_show_field 'other_format_display', label: 'Other format(s)'
3✔
380
    config.add_show_field 'indexes_display', label: 'Indexes'
3✔
381
    config.add_show_field 'finding_aid_display', label: 'Finding aid'
3✔
382
    config.add_show_field 'cumulative_index_finding_aid_display', label: "Cumulative index/\u200BFinding aid"
3✔
383
    config.add_show_field 'place_name_display', label: 'Place name(s)'
3✔
384
    config.add_show_field 'other_title_display', label: 'Other title(s)'
3✔
385
    config.add_show_field 'other_title_1display', hash: true
3✔
386
    config.add_show_field 'in_display', label: 'In'
3✔
387
    config.add_show_field 'other_editions_display', label: 'Other editions'
3✔
388
    config.add_show_field 'isbn_display', label: 'ISBN'
3✔
389
    config.add_show_field 'issn_display', label: 'ISSN'
3✔
390
    config.add_show_field 'sudoc_no_display', label: 'SuDoc no.'
3✔
391
    config.add_show_field 'tech_report_no_display', label: 'Tech. report no.'
3✔
392
    config.add_show_field 'publisher_no_display', label: 'Publisher no.'
3✔
393
    config.add_show_field 'lccn_display', label: 'LCCN'
3✔
394
    config.add_show_field 'oclc_s', label: 'OCLC'
3✔
395
    config.add_show_field 'coden_display', label: 'Coden designation'
3✔
396
    config.add_show_field 'standard_no_1display', hash: true
3✔
397
    config.add_show_field 'original_language_display', label: 'Original language'
3✔
398
    config.add_show_field 'recap_notes_display', label: 'RCP'
3✔
399

400
    # Numismatics fields
401
    ## Issue Description
402
    config.add_show_field 'numismatic_collection_s', label: 'Numismatic Collection', link_to_search_value: true, if: false, coin_top_field: true
3✔
403
    config.add_show_field 'issue_number_s', label: 'Issue', link_to_search_value: true, if: false, coin_top_field: true
3✔
404
    config.add_show_field 'issue_object_type_s', label: 'Object Type', link_to_search_value: true
3✔
405
    config.add_show_field 'issue_denomination_s', label: 'Denomination', link_to_search_value: true
3✔
406
    config.add_show_field 'issue_metal_s', label: 'Metal', link_to_search_value: true
3✔
407
    config.add_show_field 'issue_region_s', label: 'Region', link_to_search_value: true
3✔
408
    config.add_show_field 'issue_state_s', label: 'State', link_to_search_value: true
3✔
409
    config.add_show_field 'issue_city_s', label: 'City', link_to_search_value: true
3✔
410
    config.add_show_field 'issue_ruler_s', label: 'Ruler', link_to_search_value: true
3✔
411
    config.add_show_field 'issue_date_s', label: 'Date', link_to_search_value: true
3✔
412
    config.add_show_field 'issue_obverse_description_s', label: 'Obverse Figure Description', link_to_search_value: true
3✔
413
    config.add_show_field 'issue_obverse_legend_s', label: 'Obverse Legend', link_to_search_value: true
3✔
414
    config.add_show_field 'issue_obverse_attributes_s', label: 'Obverse Attributes', link_to_search_value: true
3✔
415
    config.add_show_field 'issue_obverse_figure_relationship_s', label: 'Obverse Figure Relationship', link_to_search_value: true
3✔
416
    config.add_show_field 'issue_obverse_symbol_s', label: 'Obverse Symbol', link_to_search_value: true
3✔
417
    config.add_show_field 'issue_reverse_description_s', label: 'Reverse Figure Description', link_to_search_value: true
3✔
418
    config.add_show_field 'issue_reverse_legend_s', label: 'Reverse Legend', link_to_search_value: true
3✔
419
    config.add_show_field 'issue_reverse_attributes_s', label: 'Reverse Attributes', link_to_search_value: true
3✔
420
    config.add_show_field 'issue_reverse_figure_relationship_s', label: 'Reverse Figure Relationship', link_to_search_value: true
3✔
421
    config.add_show_field 'issue_reverse_symbol_s', label: 'Reverse Symbol', link_to_search_value: true
3✔
422
    config.add_show_field 'issue_era_s', label: 'Era', link_to_search_value: true
3✔
423
    config.add_show_field 'issue_master_s', label: 'Master', link_to_search_value: true
3✔
424
    config.add_show_field 'issue_workshop_s', label: 'Workshop', link_to_search_value: true
3✔
425
    config.add_show_field 'issue_series_s', label: 'Series', link_to_search_value: true
3✔
426
    config.add_show_field 'issue_artists_s', label: 'Artist', link_to_search_value: true
3✔
427
    config.add_show_field 'issue_subject_s', label: 'Subject', link_to_search_value: true
3✔
428
    config.add_show_field 'issue_citations_s', label: 'Citations', link_to_search_value: true
3✔
429
    config.add_show_field 'issue_references_s', label: 'References', link_to_search_value: true
3✔
430

431
    ## Coin Description
432
    config.add_show_field 'size_s', label: 'Size', link_to_facet: true, coin_description: true
3✔
433
    config.add_show_field 'die_axis_s', label: 'Die Axis', link_to_facet: true, coin_description: true
3✔
434
    config.add_show_field 'weight_s', label: 'Weight', link_to_facet: true, coin_description: true
3✔
435
    config.add_show_field 'numismatic_accession_s', label: 'Accession', link_to_facet: true, coin_description: true
3✔
436
    config.add_show_field 'find_place_s', label: 'Find Place', link_to_facet: true, coin_description: true
3✔
437
    config.add_show_field 'find_number_s', label: 'Find Number', link_to_facet: true, coin_description: true
3✔
438
    config.add_show_field 'find_date_s', label: 'Find Date', link_to_facet: true, coin_description: true
3✔
439
    config.add_show_field 'find_locus_s', label: 'Find Locus', link_to_facet: true, coin_description: true
3✔
440
    config.add_show_field 'find_feature_s', label: 'Find Feature', link_to_facet: true, coin_description: true
3✔
441
    config.add_show_field 'find_description_s', label: 'Find Description', link_to_facet: true, coin_description: true
3✔
442
    config.add_show_field 'technique_s', label: 'Technique', link_to_facet: true, coin_description: true
3✔
443
    config.add_show_field 'issue_shape_s', label: 'Shape', link_to_facet: true, coin_description: true
3✔
444
    config.add_show_field 'issue_edge_s', label: 'Edge', link_to_facet: true, coin_description: true
3✔
445
    config.add_show_field 'issue_color_s', label: 'Color', link_to_facet: true, coin_description: true
3✔
446
    config.add_show_field 'counter_stamp_s', label: 'Counter Stamp', link_to_facet: true, coin_description: true
3✔
447
    config.add_show_field 'analysis_s', label: 'Analysis', link_to_facet: true, coin_description: true
3✔
448
    config.add_show_field 'coin_citations_s', label: 'Citations', link_to_facet: true, coin_description: true
3✔
449
    config.add_show_field 'coin_references_s', label: 'References', link_to_facet: true, coin_description: true
3✔
450

451
    ## Provenance
452
    config.add_show_field 'numismatic_provenance_s', label: 'Provenance'
3✔
453

454
    #     "fielded" search configuration. Used by pulldown among other places.
455
    #     For supported keys in hash, see rdoc for Blacklight::SearchFields
456

457
    #     Search fields will inherit the :qt solr request handler from
458
    #     config[:default_solr_parameters], OR can specify a different one
459
    #     with a :qt key/value. Below examples inherit, except for subject
460
    #     that specifies the same :qt as default for our own internal
461
    #     testing purposes.
462
    #
463
    # The :key is what will be used to identify this BL search field internally,
464
    # as well as in URLs -- so changing it after deployment may break bookmarked
465
    # urls.  A display label will be automatically calculated from the :key,
466
    # or can be specified manually to be different.
467

468
    # This one uses all the defaults set by the solr request handler. Which
469
    # solr request handler? The one set in config[:default_solr_parameters][:qt],
470
    # since we aren't specifying it otherwise.
471

472
    # To add an advanced option only search field:
473
    #   config.add_search_field("advanced_field") do |field|
474
    #   field.include_in_simple_select = false
475
    #   field.solr_parameters = { :qf => "advanced_field_solrname" }
476
    # end
477
    # if the request handler ends up being different for advanced fields, they must be
478
    # specifically included, while at the same time be removed from simple search:
479
    #   :include_in_advanced_search => true
480
    #   field.include_in_simple_select = false
481

482
    config.add_search_field 'all_fields', label: 'Keyword'
3✔
483

484
    # Now we see how to over-ride Solr request handler defaults, in this
485
    # case for a BL "search field", which is really a dismax aggregate
486
    # of Solr search fields.
487

488
    config.add_search_field('title') do |field|
3✔
489
      # solr_parameters hash are sent to Solr as ordinary url query params.
490
      field.solr_parameters = {
3✔
491
        'spellcheck.dictionary': 'title',
492
        qf: '${title_qf}',
493
        pf: '${title_pf}'
494
      }
495
      field.dropdown_label = 'Title (keyword)'
3✔
496
      field.solr_adv_parameters = {
3✔
497
        qf: '$title_qf',
498
        pf: '$title_pf'
499
      }
500
    end
501

502
    config.add_search_field('author') do |field|
3✔
503
      field.solr_parameters = {
3✔
504
        'spellcheck.dictionary' => 'author',
505
        qf: '${author_qf}',
506
        pf: '${author_pf}'
507
      }
508
      field.dropdown_label = 'Author (keyword)'
3✔
509
      field.label = 'Author/Creator'
3✔
510
      field.solr_adv_parameters = {
3✔
511
        qf: '$author_qf',
512
        pf: '$author_pf'
513
      }
514
    end
515

516
    # Specifying a :qt only to show it's possible, and so our internal automated
517
    # tests can test it. In this case it's the same as
518
    # config[:default_solr_parameters][:qt], so isn't actually neccesary.
519
    config.add_search_field('subject') do |field|
3✔
520
      field.solr_parameters = {
3✔
521
        'spellcheck.dictionary': 'subject',
522
        qf: '${subject_qf}',
523
        pf: '${subject_pf}'
524
      }
525
      field.dropdown_label = 'Subject (keyword)'
3✔
526
      field.qt = 'search'
3✔
527
      field.solr_adv_parameters = {
3✔
528
        qf: '$subject_qf',
529
        pf: '$subject_pf'
530
      }
531
    end
532

533
    config.add_search_field('left_anchor') do |field|
3✔
534
      field.label = 'Title starts with'
3✔
535
      field.solr_parameters = {
3✔
536
        qf: '${left_anchor_qf}',
537
        pf: '${left_anchor_pf}'
538
      }
539
      field.solr_adv_parameters = {
3✔
540
        qf: '$left_anchor_qf',
541
        pf: '$left_anchor_pf'
542
      }
543
    end
544

545
    config.add_search_field('publisher') do |field|
3✔
546
      field.include_in_simple_select = false
3✔
547
      field.label = 'Publisher'
3✔
548
      field.solr_adv_parameters = {
3✔
549
        qf: '$publisher_qf',
550
        pf: '$publisher_pf'
551
      }
552
    end
553

554
    config.add_search_field('in_series') do |field|
3✔
555
      field.include_in_advanced_search = false
3✔
556
      field.include_in_simple_select = false
3✔
557
      field.label = 'Series starts with'
3✔
558
      field.solr_adv_parameters = {
3✔
559
        qf: '$in_series_qf',
560
        pf: '$in_series_pf'
561
      }
562
    end
563

564
    config.add_search_field('notes') do |field|
3✔
565
      field.include_in_simple_select = false
3✔
566
      field.label = 'Notes'
3✔
567
      field.solr_adv_parameters = {
3✔
568
        qf: '$notes_qf',
569
        pf: '$notes_pf'
570
      }
571
    end
572

573
    config.add_search_field('series_title') do |field|
3✔
574
      field.include_in_simple_select = false
3✔
575
      field.label = 'Series title'
3✔
576
      field.solr_adv_parameters = {
3✔
577
        qf: '$series_title_qf',
578
        pf: '$series_title_pf'
579
      }
580
    end
581

582
    config.add_search_field('isbn') do |field|
3✔
583
      field.include_in_simple_select = false
3✔
584
      field.label = 'ISBN'
3✔
585
      field.solr_adv_parameters = {
3✔
586
        qf: 'isbn_t'
587
      }
588
      field.solr_parameters = {
3✔
589
        qf: 'isbn_t'
590
      }
591
    end
592

593
    config.add_search_field('issn') do |field|
3✔
594
      field.include_in_simple_select = false
3✔
595
      field.label = 'ISSN'
3✔
596
      field.solr_adv_parameters = {
3✔
597
        qf: 'issn_s'
598
      }
599
      field.solr_parameters = {
3✔
600
        qf: 'issn_s'
601
      }
602
    end
603

604
    config.add_search_field('lccn') do |field|
3✔
605
      field.include_in_simple_select = false
3✔
606
      field.include_in_advanced_search = false
3✔
607
      field.label = 'LCCN'
3✔
608
      field.solr_adv_parameters = {
3✔
609
        qf: 'lccn_s'
610
      }
611
      field.solr_parameters = {
3✔
612
        qf: 'lccn_s'
613
      }
614
    end
615

616
    config.add_search_field('oclc') do |field|
3✔
617
      field.include_in_simple_select = false
3✔
618
      field.include_in_advanced_search = false
3✔
619
      field.label = 'OCLC'
3✔
620
      field.solr_adv_parameters = {
3✔
621
        qf: 'oclc_s'
622
      }
623
      field.solr_adv_parameters = {
3✔
624
        qf: 'oclc_s'
625
      }
626
    end
627

628
    config.add_search_field('browse_subject') do |field|
3✔
629
      field.include_in_advanced_search = false
3✔
630
      field.label = 'Subject (browse)'
3✔
631
    end
632
    config.add_search_field('browse_name') do |field|
3✔
633
      field.include_in_advanced_search = false
3✔
634
      field.label = 'Author (browse)'
3✔
635
      field.placeholder_text = 'Last name, first name'
3✔
636
    end
637
    config.add_search_field('name_title') do |field|
3✔
638
      field.include_in_advanced_search = false
3✔
639
      field.label = 'Author (sorted by title)'
3✔
640
      field.placeholder_text = 'Last name, first name. Title'
3✔
641
    end
642
    config.add_search_field('browse_cn') do |field|
3✔
643
      field.include_in_advanced_search = false
3✔
644
      field.label = 'Call number (browse)'
3✔
645
      field.placeholder_text = 'e.g. P19.737.3'
3✔
646
    end
647

648
    # "sort results by" select (pulldown)
649
    # label in pulldown is followed by the name of the SOLR field to sort by and
650
    # whether the sort is ascending or descending (it must be asc or desc
651
    # except in the relevancy case).
652
    config.add_sort_field 'score desc, pub_date_start_sort desc, title_sort asc', label: 'relevance'
3✔
653
    config.add_sort_field 'pub_date_start_sort desc, title_sort asc, score desc', label: 'year (newest first)'
3✔
654
    config.add_sort_field 'pub_date_start_sort asc, title_sort asc, score desc', label: 'year (oldest first)'
3✔
655
    config.add_sort_field 'author_sort asc, title_sort asc, score desc', label: 'author'
3✔
656
    config.add_sort_field 'title_sort asc, pub_date_start_sort desc, score desc', label: 'title'
3✔
657
    config.add_sort_field 'cataloged_tdt desc, title_sort asc, score desc', label: 'date cataloged'
3✔
658

659
    # If there are more than this many search results, no spelling ("did you
660
    # mean") suggestion is offered.
661
    config.spell_max = 0
3✔
662

663
    # Add bookmark all widget
664
    config.add_results_collection_tool(:bookmark_all)
3✔
665

666
    config.add_results_document_tool(:bookmark, partial: 'bookmark_control')
3✔
667

668
    config.unapi = {
3✔
669
      'ris' => { content_type: 'application/x-research-info-systems' }
670
    }
671
    config.filter_search_state_fields = true
3✔
672
    config.search_state_fields = config.search_state_fields + [
3✔
673
      :advanced_type, :f1, :f2, :f3,
674
      :op1, :op2, :op3,
675
      :q1, :q2, :q3
676
    ]
677

678
    config.index.constraints_component = Orangelight::ConstraintsComponent
3✔
679
  end
680

681
  def render_search_results_as_json
3✔
682
    { response: { docs: @document_list, facets: search_facets_as_json, pages: pagination_info(@response) } }
×
683
  end
684

685
  def index
3✔
686
    if home_page?
121✔
687
      render_empty_search
24✔
688
    else
689
      super
97✔
690
    end
691
  rescue ActionController::BadRequest
692
    render file: Rails.public_path.join('x400.html'), layout: true, status: :bad_request
1✔
693
  end
694

695
  def numismatics
3✔
696
    unless request.method == :post
4✔
697
      @response = search_service.search_results do |search_builder|
4✔
698
        search_builder.except(:add_advanced_search_to_solr).append(:facets_for_advanced_search_form)
4✔
699
      end.first
700
    end
701
    respond_to do |format|
4✔
702
      format.html { render "advanced/numismatics" }
7✔
703
      format.json { render plain: "Format not supported", status: :bad_request }
5✔
704
    end
705
  end
706

707
  private
3✔
708

709
    def render_empty_search
3✔
710
      # This code is a copy of Blacklight::Catalog.index() method but adapted to use
711
      # a cached version of the data rather than requesting the data from Solr.
712
      # See https://github.com/projectblacklight/blacklight/blob/v7.0.1/app/controllers/concerns/blacklight/catalog.rb#L25-L41
713
      @response = empty_solr_response
24✔
714
      @document_list = @response.documents
24✔
715
      respond_to do |format|
24✔
716
        format.html { store_preferred_view }
48✔
717
        format.rss  { render layout: false }
24✔
718
        format.atom { render layout: false }
24✔
719
        format.json do
24✔
720
          @presenter = Blacklight::JsonPresenter.new(@response, blacklight_config)
×
721
        end
722
        additional_response_formats(format)
24✔
723
        document_export_formats(format)
24✔
724
      end
725
    end
726

727
    def home_page?
3✔
728
      # When only the "controller" and "action" keys are in the request (i.e. no query or facets)
729
      # we consider it the home page.
730
      params.keys.count == 2
121✔
731
    end
732

733
    def empty_solr_response
3✔
734
      raw_response = JSON.parse(empty_raw_response)
24✔
735
      Blacklight::Solr::Response.new(raw_response, raw_response["responseHeader"]["params"], blacklight_config: @blacklight_config)
24✔
736
    end
737

738
    def empty_raw_response
3✔
739
      Rails.cache.fetch("home_page_empty_raw_response", expires_in: 3.hours) do
24✔
740
        Rails.logger.info "Cached home page results"
23✔
741
        # We cannot cache the Blacklight::Solr::Response as-is so we convert it to JSON first
742
        (response, _deprecated_document_list) = search_service.search_results
23✔
743
        response.to_json
23✔
744
      end
745
    end
746
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