diff --git a/.gitignore b/.gitignore index f6e2720e..f2d0b214 100644 --- a/.gitignore +++ b/.gitignore @@ -40,9 +40,10 @@ yarn-debug.log* /public/uploads ### Rails specific ### +.byebug_history /public/system /coverage/ -/spec/tmp +tmp # Ignore files specific to the development environment fc.json diff --git a/.rubocop.yml b/.rubocop.yml index 85503400..e0613b4c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -16,113 +16,145 @@ Layout/LineLength: - config/**/* - test/**/* -Metrics/ClassLength: - Exclude: - - test/**/* - -Metrics/BlockLength: - Max: 30 - Exclude: - - test/**/* - - lib/tasks/**/* +Layout/EmptyLinesAroundAttributeAccessor: + Enabled: true -Metrics/MethodLength: - Exclude: - - lib/tasks/location.rake +Layout/SpaceAroundMethodCallOperator: + Enabled: true -Style/FormatStringToken: - Enabled: false +Lint/DeprecatedOpenSSLConstant: + Enabled: true -Rails/OutputSafety: - Exclude: - - app/presenters/*.rb +Lint/DuplicateElsifCondition: + Enabled: true -Style/HashEachMethods: +Lint/MixedRegexpCaptureTypes: Enabled: true -Style/HashTransformKeys: +Lint/RaiseException: Enabled: true -Style/HashTransformValues: +Lint/StructNewOverride: Enabled: true Metrics/AbcSize: Exclude: - lib/tasks/location.rake +Metrics/BlockLength: + Max: 30 + Exclude: + - test/**/* + - lib/tasks/**/* + +Metrics/ClassLength: + CountAsOne: ['array', 'hash', 'heredoc', 'method_call'] + Exclude: + - test/**/* + Metrics/CyclomaticComplexity: Exclude: - lib/tasks/location.rake -Layout/SpaceAroundMethodCallOperator: +Metrics/MethodLength: + CountAsOne: ['array', 'hash', 'heredoc', 'method_call'] + Exclude: + - lib/tasks/location.rake + +Rails/ActiveRecordCallbacksOrder: Enabled: true -Layout/EmptyLinesAroundAttributeAccessor: + +Rails/FindById: Enabled: true -Lint/DeprecatedOpenSSLConstant: + +Rails/I18nLocaleAssignment: Enabled: true -Lint/MixedRegexpCaptureTypes: + Exclude: + - test/**/* +Rails/Inquiry: Enabled: true -Lint/RaiseException: + +Rails/MailerName: Enabled: true -Lint/StructNewOverride: + +Rails/MatchRoute: Enabled: true -Style/ExponentialNotation: + +Rails/NegateInclude: Enabled: true -Style/RedundantFetchBlock: + +Rails/Pluck: Enabled: true -Style/RedundantRegexpCharacterClass: + +Rails/PluckInWhere: Enabled: true -Style/RedundantRegexpEscape: + +Rails/RenderInline: Enabled: true -Style/SlicingWithRange: + +Rails/RenderPlainText: Enabled: true -Lint/DuplicateElsifCondition: + +Rails/ShortI18n: Enabled: true + +Rails/WhereExists: + Enabled: true + +Rails/OutputSafety: + Exclude: + - app/presenters/*.rb + Style/AccessorGrouping: Enabled: true + Style/ArrayCoercion: Enabled: true + Style/BisectedAttrAccessor: Enabled: true + Style/CaseLikeIf: Enabled: true -Style/HashAsLastArrayItem: - Enabled: true -Style/HashLikeCase: - Enabled: true -Style/RedundantAssignment: - Enabled: true -Style/RedundantFileExtensionInRequire: - Enabled: true -Rails/ActiveRecordCallbacksOrder: - Enabled: true -Rails/FindById: + +Style/ExponentialNotation: Enabled: true -Rails/Inquiry: + +Style/FormatStringToken: + Enabled: false + +Style/HashAsLastArrayItem: Enabled: true -Rails/MailerName: + +Style/HashEachMethods: Enabled: true -Rails/MatchRoute: + +Style/HashLikeCase: Enabled: true -Rails/NegateInclude: + +Style/HashTransformKeys: Enabled: true -Rails/Pluck: + +Style/HashTransformValues: Enabled: true -Rails/PluckInWhere: + +Style/RedundantAssignment: Enabled: true -Rails/RenderInline: + +Style/RedundantFetchBlock: Enabled: true -Rails/RenderPlainText: + +Style/RedundantFileExtensionInRequire: Enabled: true -Rails/ShortI18n: + +Style/RedundantRegexpCharacterClass: Enabled: true -Rails/WhereExists: + +Style/RedundantRegexpEscape: Enabled: true -Rails/I18nLocaleAssignment: +Style/SlicingWithRange: Enabled: true - Exclude: - - test/**/* Style/OpenStructUse: Enabled: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 4425c155..f39ae373 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,29 +2,71 @@ ## 1.7.5 - 2024-08 +- (Jon) Exposed `instrument_internal_error(exception)` metric to the + `ExceptionsController` to provide a count of internal errors + [GH-142](https://github.com/epimorphics/hmlr-linked-data/issues/142) +- (Jon) Added puma.stats to footer template in development environment only, + again as per the approach in the [`LR_Common_Styles` + gem](https://github.com/epimorphics/lr_common_styles/releases/tag/1.9.6) +- (Jon) Adjusted footer `link_to` helpers to only appending the lang parameter + to the url only if it exists for "internal" links as per the approach in the + [`LR_Common_Styles` + gem](https://github.com/epimorphics/lr_common_styles/releases/tag/1.9.6) +- (Jon) Adjusted fix for visual contrast in the location selection menu via + additional styling and updated 3rd-party element use specific to ticket + [GH-408](https://github.com/epimorphics/ukhpi/issues/408) alongside adding + missing aria-attributes required for assisted use +- (Jon) Implements revised approach to page titles mirrored on other suite apps, + as well as fixes white space typo in some concatenated page titles +- (Jon) Added `process_threads` guage to prometheus metrics alongside isolating + thread counts to specific status' as per the Rails thread documentation as + well as updating the approach to resolve + [GH-142](https://github.com/epimorphics/hmlr-linked-data/issues/142) +- (Jon) Excluded prometheus metrics from the testing environment to reduce noise + in the logs +- (Jon) Added `puma-metrics` gem to provide base metrics for the Puma web server +- (Jon) Updated .rubocop.yml primarily reorganising the rules alphabetically as + well as adding `CountAsOne` to both `Metrics/ClassLength` and + `Metrics/MethodLength`; includes files with removed earlier disabling of said + rules! +- (Jon) Updated `.gitignore` to include ignoring byebug history as well as sets + the tmp directory ignore to be anywhere, not just at the project root +- (Bogdan) Fixed a bug where CSS was being applied to the wrong element + [GH-412](https://github.com/epimorphics/ukhpi/issues/412) +- (Bogdan) Fixed type in aria-label text + [GH-416](https://github.com/epimorphics/ukhpi/issues/416) - (Dan) Adds message for screenreaders for guidance on how to use tables [Gh-405](https://github.com/epimorphics/ukhpi/issues/405) - (Dan) Fixed aria-label in compare locations form [GH-416](https://github.com/epimorphics/ukhpi/issues/416) - (Dan) Adds `aria-label` link attributes on the about page to SPARQL link [GH-413](https://github.com/epimorphics/ukhpi/issues/413) -- (Bogdan) Fixed a bug where CSS was being applied to the wrong element [GH-412](https://github.com/epimorphics/ukhpi/issues/412) +- (Bogdan) Fixed a bug where CSS was being applied to the wrong element + [GH-412](https://github.com/epimorphics/ukhpi/issues/412) +- (Bogdan) Fixed type in aria-label text [GH-416](https://github.com/epimorphics/ukhpi/issues/416) - (Bogdan) Fixed a duplicate character bug when selecting dates -- (Bogdan) Added page titles for each individual view [GH-409](https://github.com/epimorphics/ukhpi/issues/409) +- (Bogdan) Added page titles for each individual view + [GH-409](https://github.com/epimorphics/ukhpi/issues/409) - (Bogdan) Set correct values for `aria-label` link attributes on the about page [GH-413](https://github.com/epimorphics/ukhpi/issues/413) -- (Bogdan) Increased contrast for compare location dropdowns [GH-412](https://github.com/epimorphics/ukhpi/issues/412) +- (Bogdan) Increased contrast for compare location dropdowns + [GH-412](https://github.com/epimorphics/ukhpi/issues/412) - (Bogdan) Increased contrast for search location results, as well as when they are being focused [GH-412](https://github.com/epimorphics/ukhpi/issues/412) - (Bogdan) CSS Refactoring -- (Bogdan) Fixed a bug where CSS was applied to the wrong element, causing search - location results to be displayed incorrectly -- (Bogdan) Increased focusable area for close button on modal and hide graph button - [GH-411](https://github.com/epimorphics/ukhpi/issues/411) -- (Bogdan) Increased contrast for search location input and map elements, as well - as all modal buttons [GH-408](https://github.com/epimorphics/ukhpi/issues/408) -- (Bogdan) Increased contrast of modal warning message [GH-407](https://github.com/epimorphics/ukhpi/issues/407) -- (Bogdan) Increased contrast for modal close button and body [GH-407](https://github.com/epimorphics/ukhpi/issues/407) -- (Bogdan) Landing page links should now be more visible [GH-406](https://github.com/epimorphics/ukhpi/issues/406) -- (Bogdan) Added alt text to application logo [GH-404](https://github.com/epimorphics/ukhpi/issues/404) +- (Bogdan) Fixed a bug where CSS was applied to the wrong element, causing + search location results to be displayed incorrectly +- (Bogdan) Increased focusable area for close button on modal and hide graph + button [GH-411](https://github.com/epimorphics/ukhpi/issues/411) +- (Bogdan) Increased contrast for search location input and map elements, as + well as all modal buttons + [GH-408](https://github.com/epimorphics/ukhpi/issues/408) +- (Bogdan) Increased contrast of modal warning message + [GH-407](https://github.com/epimorphics/ukhpi/issues/407) +- (Bogdan) Increased contrast for modal close button and body + [GH-407](https://github.com/epimorphics/ukhpi/issues/407) +- (Bogdan) Landing page links should now be more visible + [GH-406](https://github.com/epimorphics/ukhpi/issues/406) +- (Bogdan) Added alt text to application logo + [GH-404](https://github.com/epimorphics/ukhpi/issues/404) ## 1.7.4 - 2024-04-19 diff --git a/Gemfile b/Gemfile index 91c45ccc..e5c746ba 100644 --- a/Gemfile +++ b/Gemfile @@ -32,6 +32,7 @@ gem 'get_process_mem', '~> 0.2.7' gem 'http_accept_language' gem 'prometheus-client', '~> 4.0' gem 'puma' +gem 'puma-metrics' gem 'rdf-turtle' gem 'rubocop-rails' gem 'sentry-rails', '~> 5.7' diff --git a/Gemfile.lock b/Gemfile.lock index d98662c5..c69f14bf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -183,7 +183,6 @@ GEM matrix (0.4.2) method_source (1.0.0) mini_mime (1.1.2) - mini_portile2 (2.8.4) minitest (5.18.1) minitest-rails (6.1.0) minitest (~> 5.10) @@ -196,8 +195,7 @@ GEM mocha (1.13.0) multipart-post (2.3.0) nio4r (2.5.9) - nokogiri (1.13.10) - mini_portile2 (~> 2.8.0) + nokogiri (1.13.10-x86_64-darwin) racc (~> 1.4) oj (3.14.2) parallel (1.22.1) @@ -207,6 +205,9 @@ GEM public_suffix (5.0.3) puma (6.3.1) nio4r (~> 2.0) + puma-metrics (1.2.5) + prometheus-client (>= 0.10) + puma (>= 5.0) racc (1.7.1) rack (2.2.7) rack-proxy (0.7.6) @@ -361,7 +362,7 @@ GEM railties PLATFORMS - ruby + x86_64-darwin-21 DEPENDENCIES byebug @@ -388,6 +389,7 @@ DEPENDENCIES oj (= 3.14.2) prometheus-client (~> 4.0) puma + puma-metrics rails (~> 6.0) rdf-turtle rubocop diff --git a/app/assets/stylesheets/_data-view-download.scss b/app/assets/stylesheets/_data-view-download.scss index c8e09e53..30825f78 100644 --- a/app/assets/stylesheets/_data-view-download.scss +++ b/app/assets/stylesheets/_data-view-download.scss @@ -13,14 +13,32 @@ text-decoration: none; } - &__button, &__button:visited, &__button:link, &__button:focus, &__button:link:focus { - color: white; - background-color: $dark-blue; + &__button{ + &:visited, &:link { + color: white; + background-color: $dark-blue; + &:hover, &:focus, &:visited { + color: white; + background-color: $dark-blue-hover; + } + } } } .c-compare__download-link { @extend .button; + color: white; background-color: $dark-blue; font-size: 1.5rem; + &:hover, &:focus, &:visited { + color: white; + background-color: $dark-blue-hover; + } +} + +.c-compare__print-link { + color: $dark-blue; + &:hover, &:focus, &:visited { + color: $dark-blue-hover; + } } diff --git a/app/assets/stylesheets/_element-rails.scss b/app/assets/stylesheets/_element-rails.scss index d1c3132c..c9f1d6a9 100644 --- a/app/assets/stylesheets/_element-rails.scss +++ b/app/assets/stylesheets/_element-rails.scss @@ -20,8 +20,8 @@ } .el-table .cell { - word-break: normal; -ms-word-break: normal; + word-break: normal; } .el-button--default { @@ -30,6 +30,11 @@ .el-button--primary { background-color: $dark-blue; + border-color: $dark-blue; + &:any-link, &:focus, &:hover { + background-color: $dark-blue-hover; + border-color: $dark-blue-hover; + } } .el-date-editor { @@ -57,6 +62,7 @@ table.el-month-table { color: white; } &.hover:not(.selected) { - background-color: #e6e6e6; + background-color: $dark-blue-hover; + color: white; } } diff --git a/app/assets/stylesheets/_gov_uk.scss b/app/assets/stylesheets/_gov_uk.scss index a1be390f..fef7be08 100644 --- a/app/assets/stylesheets/_gov_uk.scss +++ b/app/assets/stylesheets/_gov_uk.scss @@ -17,8 +17,12 @@ @import 'elements/reset'; @import "elements/helpers"; // Helper functions and classes +$govuk-brand-colour: #1d70b8; +$govuk-brand-hover-colour: #003078; + $grey-8: #f0f0f0; -$dark-blue: #003078; +$dark-blue: $govuk-brand-colour; +$dark-blue-hover: $govuk-brand-hover-colour; @import "elements/govuk-template-base"; // HTML elements, set by the GOV.UK template diff --git a/app/assets/stylesheets/_leaflet-rrose.scss b/app/assets/stylesheets/_leaflet-rrose.scss index 5a93df15..41bd2a1a 100644 --- a/app/assets/stylesheets/_leaflet-rrose.scss +++ b/app/assets/stylesheets/_leaflet-rrose.scss @@ -103,9 +103,9 @@ a.leaflet-rrose-close-button:hover { .leaflet-rrose-content-wrapper, .leaflet-rrose-tip { background: white; - box-shadow: 0 3px 10px #888; -moz-box-shadow: 0 3px 10px #888; -webkit-box-shadow: 0 3px 14px #999; + box-shadow: 0 3px 10px #888; } .leaflet-rrose-content-wrapper { diff --git a/app/assets/stylesheets/_lr-common.scss b/app/assets/stylesheets/_lr-common.scss index cd3fd652..c814c092 100644 --- a/app/assets/stylesheets/_lr-common.scss +++ b/app/assets/stylesheets/_lr-common.scss @@ -38,8 +38,8 @@ ol.numbered { input[type=checkbox], input[type=radio] { - transform: scale(1.5); -webkit-transform: scale(1.5); + transform: scale(1.5); } /* objects */ @@ -261,3 +261,4 @@ input[type=radio] { :focus, a:focus { outline: 2px solid $focus-colour !important; } + diff --git a/app/assets/stylesheets/a11y.scss b/app/assets/stylesheets/a11y.scss new file mode 100644 index 00000000..0acb004c --- /dev/null +++ b/app/assets/stylesheets/a11y.scss @@ -0,0 +1,101 @@ +/* Created in 2024-08 accessibility review ~ JRH */ +$govuk-brand-colour: #1d70b8; +$govuk-brand-hover-colour: #003078; +$govuk-brand-disabled-colour: lighten( $govuk-brand-colour, 40% ); + + +@mixin disabled-button { + color: #606266; + background-color: $govuk-brand-disabled-colour; + border-color: $govuk-brand-disabled-colour; + opacity: 0.4; + cursor: not-allowed; +} + +@mixin hidden-radio { + opacity: 0; + outline: 0; + position: absolute; + z-index: -1; +} + +button, +.button{ + &.el-button { + &--primary{ + background-color: $govuk-brand-colour; + border-color: $govuk-brand-colour; + &:hover, + &:focus { + background-color: $govuk-brand-hover-colour; + border-color: $govuk-brand-hover-colour; + } + &.is-disabled { + @include disabled-button; + &:active, + &:focus, + &:hover { + @include disabled-button; + } + } + } + } +} + +div { + &.el-radio-group { + &[role="radiogroup"] { + [role="radio"]{ + &.el-radio-button { + position: relative; + display: inline-block; + width: 100%; + outline: 0; + width: 100%; + margin: 0; + padding: 0; + &.is-checked { + .el-radio__label { + color: #FFF; + background-color: $govuk-brand-colour; + } + } + + .el-radio__input { + @include hidden-radio; + .el-radio__inner{ + display: none; + } + } + .el-radio__label { + width: 100%; + border: 0; + border-radius: 0; + color: #000000; + display: inline-block; + line-height: 2.0; + text-align: center; + padding: 0.75rem 1.4rem; + font-size: calc(1.0rem + 0.2vw); // maintain text size relative to viewport width + background-color: #FFF; + font-weight: 500; + text-align: center; + box-sizing: border-box; + &:hover, &:focus, &:visited { + background-color: $govuk-brand-hover-colour; + color: #FFF; + } + &:active { + background-color: $govuk-brand-hover-colour; + color: $govuk-brand-colour; + } + } + [aria-hidden="true"] { + @include hidden-radio; + } + } + } + } + } +} + diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 5672fe70..a135d04d 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -24,4 +24,5 @@ 'ukhpi-location-select', 'actions', 'skip_to_main', - 'cookie-banner'; + 'cookie-banner', + 'a11y'; diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c2acf040..34285f77 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,9 +6,30 @@ class ApplicationController < ActionController::Base # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception - before_action :set_locale, :change_default_caching_policy + before_action :set_locale + before_action :change_default_caching_policy around_action :log_request_result + + # Set the user's preferred locale. An explicit locale set via + # the URL param `lang` is preeminent, otherwise we look to the + # user's preferred language specified via browser headers + def set_locale + user_locale = params['lang'] + user_locale ||= http_accept_language.compatible_language_from(I18n.available_locales) + + I18n.locale = user_locale if Rails.application.config.welsh_language_enabled + end + + # * Set cache control headers for HMLR apps to be public and cacheable + # * UHPI needs to be shorter to avoid delay (in users cache) on the + # * publication deadline so it is set for 2 minutes (120 seconds) + # Sets the default `Cache-Control` header for all requests, + # unless overridden in the action + def change_default_caching_policy + expires_in 2.minutes, public: true, must_revalidate: true if Rails.env.production? + end + def log_request_result start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond) yield @@ -18,7 +39,7 @@ def log_request_result private - # rubocop:disable Metrics/MethodLength, Metrics/AbcSize + # rubocop:disable Metrics/AbcSize def detailed_request_log(duration) env = request.env @@ -38,7 +59,7 @@ def detailed_request_log(duration) case response.status when 500..599 - log_fields[:message] = env['action_dispatch.exception'] + log_fields[:message] = env['action_dispatch.exception'].to_s Rails.logger.error(JSON.generate(log_fields)) when 400..499 Rails.logger.warn(JSON.generate(log_fields)) @@ -46,25 +67,14 @@ def detailed_request_log(duration) Rails.logger.info(JSON.generate(log_fields)) end end - # rubocop:enable Metrics/MethodLength, Metrics/AbcSize - - # Set the user's preferred locale. An explicit locale set via - # the URL param `lang` is preeminent, otherwise we look to the - # user's preferred language specified via browser headers - def set_locale - user_locale = - params['lang'] || - http_accept_language.compatible_language_from(I18n.available_locales) + # rubocop:enable Metrics/AbcSize - I18n.locale = user_locale if Rails.application.config.welsh_language_enabled - end - - # * Set cache control headers for HMLR apps to be public and cacheable - # * UHPI needs to be shorter to avoid delay (in users cache) on the - # * publication deadline so it is set for 2 minutes (120 seconds) - # Set the default `Cache-Control` header for all requests, - # unless overridden in the action - def change_default_caching_policy - expires_in 2.minutes, public: true, must_revalidate: true if Rails.env.production? + # Notify subscriber(s) of an internal error event with the payload of the + # exception once done + # @param [Exception] exp the exception that caused the error + # @return [ActiveSupport::Notifications::Event] provides an object-oriented + # interface to the event + def instrument_internal_error(exception) + ActiveSupport::Notifications.instrument('internal_error.application', exception: exception) end end diff --git a/app/controllers/browse_controller.rb b/app/controllers/browse_controller.rb index 0511a785..8b7f2a3e 100644 --- a/app/controllers/browse_controller.rb +++ b/app/controllers/browse_controller.rb @@ -3,7 +3,7 @@ # Controller for the main user experience of browsing the UKHPI statistics. # Usually the primary interaction will be via JavaScript and XHR, but we also # support non-JS access by setting browse preferences in the `edit` action. -class BrowseController < ApplicationController # rubocop:disable Metrics/ClassLength +class BrowseController < ApplicationController layout 'webpack_application' def show @@ -128,7 +128,7 @@ def view_result(view_state) }.merge(new_params)) end - def render_request_error(user_selections, status) # rubocop:disable Metrics/MethodLength + def render_request_error(user_selections, status) respond_to do |format| @view_state = { user_selections: user_selections } request_status = status == 400 ? :bad_request : :internal_server_error diff --git a/app/controllers/compare_controller.rb b/app/controllers/compare_controller.rb index a66da0ca..4998baf9 100644 --- a/app/controllers/compare_controller.rb +++ b/app/controllers/compare_controller.rb @@ -31,7 +31,7 @@ def render_print render 'compare/print', layout: 'print' end - def perform_query(user_compare_selections) # rubocop:disable Metrics/MethodLength + def perform_query(user_compare_selections) query_results = {} base_selection = UserSelections.new( __safe_params: { diff --git a/app/controllers/exceptions_controller.rb b/app/controllers/exceptions_controller.rb index 8258309f..11c20945 100644 --- a/app/controllers/exceptions_controller.rb +++ b/app/controllers/exceptions_controller.rb @@ -10,6 +10,8 @@ def render_error status_code = ActionDispatch::ExceptionWrapper.new(env, exception).status_code sentry_code = maybe_report_to_sentry(exception, status_code) + # add the exception to the prometheus metrics + instrument_internal_error(exception) render :error_page, locals: { status: status_code, sentry_code: sentry_code }, diff --git a/app/javascript/components/compare-locations.vue b/app/javascript/components/compare-locations.vue index e3224edd..41d8a323 100644 --- a/app/javascript/components/compare-locations.vue +++ b/app/javascript/components/compare-locations.vue @@ -10,7 +10,8 @@ :key='item.slug' :label='item.label' :value='item.slug' - :disabled='isDisabledIndicator(item.slug)'> + :disabled='isDisabledIndicator(item.slug)' + :aria-disabled='isDisabledIndicator(item.slug)'> @@ -26,7 +27,8 @@ :key='item.slug' :label='item.label' :value='item.slug' - :disabled='isDisabledStatistic(item.slug)'> + :disabled='isDisabledStatistic(item.slug)' + :aria-disabled='isDisabledStatistic(item.slug)'> diff --git a/app/javascript/components/select-location.vue b/app/javascript/components/select-location.vue index 72694eda..36e3aa6e 100644 --- a/app/javascript/components/select-location.vue +++ b/app/javascript/components/select-location.vue @@ -70,12 +70,12 @@ {{ $t("js.location.show_on_map") }} @@ -87,6 +87,8 @@ type='primary' @click='onSaveChanges' :disabled='!allowConfirm' + :aria-disabled='!allowConfirm' + :aria-label='$t("js.action.confirm")' >{{ $t('js.action.confirm') }} diff --git a/app/models/concerns/cube_data_model/cube_measure.rb b/app/models/concerns/cube_data_model/cube_measure.rb index 99ed8a96..d6e7c827 100644 --- a/app/models/concerns/cube_data_model/cube_measure.rb +++ b/app/models/concerns/cube_data_model/cube_measure.rb @@ -33,7 +33,7 @@ def decimal_range? range.include?(RDF::XSD.decimal) end - def unit_type # rubocop:disable Metrics/MethodLength + def unit_type if scalar? :scalar elsif percentage? diff --git a/app/models/data_view.rb b/app/models/data_view.rb index 52e24037..f2844e46 100644 --- a/app/models/data_view.rb +++ b/app/models/data_view.rb @@ -7,7 +7,7 @@ # a view of the `averagePrice` indicator, together with the relevant dates, # location and other options, and access to the underlying data, to enable # the renderer to draw the display -class DataView # rubocop:disable Metrics/ClassLength +class DataView include Rails.application.routes.url_helpers attr_reader :user_selections, :query_result, :indicator, :theme diff --git a/app/models/latest_values_command.rb b/app/models/latest_values_command.rb index 965bdcc3..aaa43dad 100644 --- a/app/models/latest_values_command.rb +++ b/app/models/latest_values_command.rb @@ -14,7 +14,7 @@ def perform_query(service = nil) private - def service_api(service) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize + def service_api(service) # rubocop:disable Metrics/AbcSize service || dataset(:ukhpi) rescue Faraday::ConnectionFailed => e Rails.logger.error { 'Failed to connect to UK HPI ' } @@ -33,7 +33,7 @@ def service_api(service) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize nil end - def run_query(hpi) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize + def run_query(hpi) # rubocop:disable Metrics/AbcSize success = true query = add_date_range_constraint(base_query) query = add_location_constraint(query) diff --git a/app/models/user_compare_selections.rb b/app/models/user_compare_selections.rb index 8f1a693d..f2323149 100644 --- a/app/models/user_compare_selections.rb +++ b/app/models/user_compare_selections.rb @@ -78,7 +78,7 @@ def search? delegate :to_h, to: :params - def as_json # rubocop:disable Metrics/MethodLength, Metrics/AbcSize + def as_json # rubocop:disable Metrics/AbcSize { from: { date: from_date }.to_json, to: { date: to_date }.to_json, diff --git a/app/models/user_selections.rb b/app/models/user_selections.rb index 53300b5f..e8fc2af1 100644 --- a/app/models/user_selections.rb +++ b/app/models/user_selections.rb @@ -8,7 +8,7 @@ # standard set of statistics is presented if there is no information in the # user parameters yet. This functionality combines the previous # `models/UserPreferences` and `presenters/Aspects` -class UserSelections # rubocop:disable Metrics/ClassLength +class UserSelections include UserChoices include UserSelectionValidations include UserLanguage diff --git a/app/presenters/compare_locations_presenter.rb b/app/presenters/compare_locations_presenter.rb index 09038185..509869df 100644 --- a/app/presenters/compare_locations_presenter.rb +++ b/app/presenters/compare_locations_presenter.rb @@ -4,7 +4,7 @@ # Presenter class that encapsulates the behaviour of mapping the user-selections # to side-by-side comparisons for different areas -class CompareLocationsPresenter # rubocop:disable Metrics/ClassLength +class CompareLocationsPresenter include I18n include LocationsTable @@ -25,7 +25,7 @@ def initialize(user_compare_selections, query_results) delegate :as_json, to: :user_compare_selections delegate :selected_locations, to: :user_compare_selections - def headline_summary # rubocop:disable Metrics/AbcSize, Metrics/MethodLength + def headline_summary # rubocop:disable Metrics/AbcSize ind = I18n.t("indicator.#{indicator.slug}") stat = I18n.t("statistic.#{statistic.label_key}").downcase from = I18n.l(user_compare_selections.from_date, format: '%B %Y') diff --git a/app/presenters/download_presenter.rb b/app/presenters/download_presenter.rb index 511cc377..f69a57e8 100644 --- a/app/presenters/download_presenter.rb +++ b/app/presenters/download_presenter.rb @@ -116,7 +116,7 @@ def all_themes ukhpi.themes.values.map(&:slug) end - def sort_results_by_date_and_location # rubocop:disable Metrics/MethodLength + def sort_results_by_date_and_location @results.sort! do |result0, result1| date0 = result0['ukhpi:refMonth']['@value'] date1 = result1['ukhpi:refMonth']['@value'] diff --git a/app/presenters/landing_state.rb b/app/presenters/landing_state.rb index 04b5e02c..7cdf0155 100644 --- a/app/presenters/landing_state.rb +++ b/app/presenters/landing_state.rb @@ -72,7 +72,7 @@ def to_value(val) DataServicesApi::Value.new(val.symbolize_keys) end - def format_percentage(change) # rubocop:disable Metrics/MethodLength + def format_percentage(change) if change == 'unknown' change elsif change.zero? diff --git a/app/presenters/print_presenter.rb b/app/presenters/print_presenter.rb index 6e9d5e61..966b5acc 100644 --- a/app/presenters/print_presenter.rb +++ b/app/presenters/print_presenter.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # A presenter for the printable view, based on the download view presenter -class PrintPresenter < DownloadPresenter # rubocop:disable Metrics/ClassLength +class PrintPresenter < DownloadPresenter include ActionView::Helpers::NumberHelper PRINT_COLUMNS = [ @@ -120,7 +120,7 @@ def user_selection_columns # @return An array of the given statistic paired with the currently selected # indicators - def statistic_indicator_columns(stat) # rubocop:disable Metrics/MethodLength + def statistic_indicator_columns(stat) selected_indicators.map do |ind| DownloadColumn.new( ind: ind, diff --git a/app/subscribers/action_dispatch_prometheus_subscriber.rb b/app/subscribers/action_dispatch_prometheus_subscriber.rb index 5f02b5e0..8e0e428a 100644 --- a/app/subscribers/action_dispatch_prometheus_subscriber.rb +++ b/app/subscribers/action_dispatch_prometheus_subscriber.rb @@ -4,11 +4,57 @@ class ActionDispatchPrometheusSubscriber < ActiveSupport::Subscriber attach_to :action_dispatch - def request(_event) + # rubocop:disable Metrics/AbcSize + def process_action(_event) mem = GetProcessMem.new - Prometheus::Client.registry .get(:memory_used_mb) .set(mem.mb) + # description: 'Thread is aborting' + Prometheus::Client.registry + .get(:process_threads) + .set( + Thread.list.select { |thread| thread.status == 'aborting' }.count, + labels: { + status: 'aborting' + } + ) + # description: 'Thread is sleeping or waiting on I/O' + Prometheus::Client.registry + .get(:process_threads) + .set( + Thread.list.select { |thread| thread.status == 'sleep' }.count, + labels: { + status: 'sleep' + } + ) + # description: 'Thread is executing' + Prometheus::Client.registry + .get(:process_threads) + .set( + Thread.list.select { |thread| thread.status == 'run' }.count, + labels: { + status: 'run' + } + ) + # description: 'Thread is terminated normally' + Prometheus::Client.registry + .get(:process_threads) + .set( + Thread.list.select { |thread| thread.status == false }.count, + labels: { + status: 'false' + } + ) + # description: 'Thread is terminated with an exception' + Prometheus::Client.registry + .get(:process_threads) + .set( + Thread.list.select { |thread| thread.status.nil? }.count, + labels: { + status: 'nil' + } + ) end + # rubocop:enable Metrics/AbcSize end diff --git a/app/subscribers/api_prometheus_subscriber.rb b/app/subscribers/api_prometheus_subscriber.rb index 7b8b8678..f2a54a8d 100644 --- a/app/subscribers/api_prometheus_subscriber.rb +++ b/app/subscribers/api_prometheus_subscriber.rb @@ -4,7 +4,7 @@ class ApiPrometheusSubscriber < ActiveSupport::Subscriber attach_to :api - def response(event) # rubocop:disable Metrics/MethodLength + def response(event) response = event.payload[:response] duration = event.payload[:duration] diff --git a/app/views/changelog/_changelog_cy.html.haml b/app/views/changelog/_changelog_cy.html.haml index d3fdc994..c671b038 100644 --- a/app/views/changelog/_changelog_cy.html.haml +++ b/app/views/changelog/_changelog_cy.html.haml @@ -2,7 +2,7 @@ %section#main.c-changelog %h1.heading-large - = I18n.t('common.header.app_title') + " : " + yield(:title) + = "#{I18n.t('common.header.app_title')}: #{yield(:title)}" %h2.heading-medium Ebrill 2023 – Newidiadau i ddaearyddiaeth awdurdodau lleol yn Lloegr diff --git a/app/views/changelog/_changelog_en.html.haml b/app/views/changelog/_changelog_en.html.haml index 39a7f846..f34b9217 100644 --- a/app/views/changelog/_changelog_en.html.haml +++ b/app/views/changelog/_changelog_en.html.haml @@ -2,7 +2,7 @@ %section#main.c-changelog %h1.heading-large - = I18n.t('common.header.app_title') + " : " + yield(:title) + = "#{I18n.t('common.header.app_title')}: #{yield(:title)}" %h2.heading-medium April 2023 – Changes to local authority geography in England diff --git a/app/views/common/_footer.html.haml b/app/views/common/_footer.html.haml index 6dcae841..2edd6210 100644 --- a/app/views/common/_footer.html.haml +++ b/app/views/common/_footer.html.haml @@ -16,9 +16,9 @@ %a{:href => "https://www.gov.uk/land-registry-public-data"} = t('common.footer.public_data') %li.u-print-hidden - = link_to(t('common.footer.accessibility'), "#{Rails.application.config.accessibility_document_path}?lang=#{I18n.locale}") + = link_to(t('common.footer.accessibility'),"#{Rails.application.config.accessibility_document_path}#{"?lang=#{I18n.locale}" if params[:lang].present?}") %li.u-print-hidden - = link_to(t('common.footer.privacy'), "#{Rails.application.config.privacy_document_path}?lang=#{I18n.locale}") + = link_to(t('common.footer.privacy'),"#{Rails.application.config.privacy_document_path}#{"?lang=#{I18n.locale}" if params[:lang].present?}") .ogl.open-government-licence %p.logo.u-print-hidden %a{href: t('common.footer.ogl_url'), rel:"license"} @@ -29,3 +29,8 @@ %p.u-muted--footer = t('common.footer.application_release') = Version::VERSION + - if Rails.env.development? + %pre + [puma stats: + = JSON.pretty_generate(JSON.parse(Puma.stats, symbolize_names: true)) + , time: #{Time.now}] diff --git a/app/views/compare/show.html.haml b/app/views/compare/show.html.haml index 0cf1ebed..f4bcaeba 100644 --- a/app/views/compare/show.html.haml +++ b/app/views/compare/show.html.haml @@ -4,7 +4,7 @@ .column-full %article.c-compare %h1.o-heading--2 - = t('compare.show.heading') + = yield(:title) %p.u-muted = t('compare.show.prompt') diff --git a/app/views/doc/_about_ukhpi_cy.html.haml b/app/views/doc/_about_ukhpi_cy.html.haml index 64c028e7..33ad83ef 100644 --- a/app/views/doc/_about_ukhpi_cy.html.haml +++ b/app/views/doc/_about_ukhpi_cy.html.haml @@ -1,7 +1,7 @@ = content_for(:title, "Am") %h1.heading-large - = I18n.t('common.header.app_title') + " : " + yield(:title) + = "#{I18n.t('common.header.app_title')}: #{yield(:title)}" %h2.heading-medium Beth sydd wedi ei gynnwys yn Set Ddata’r Mynegai Prisiau Tai? diff --git a/app/views/doc/_about_ukhpi_en.html.haml b/app/views/doc/_about_ukhpi_en.html.haml index 3de4af77..9c841caa 100644 --- a/app/views/doc/_about_ukhpi_en.html.haml +++ b/app/views/doc/_about_ukhpi_en.html.haml @@ -1,7 +1,7 @@ = content_for(:title, "About") %h1.heading-large - = I18n.t('common.header.app_title') + " : " + yield(:title) + = "#{I18n.t('common.header.app_title')}: #{yield(:title)}" %h2.heading-medium What does the House Price Index Dataset consist of? diff --git a/config.ru b/config.ru index 841c9832..b88c1e24 100644 --- a/config.ru +++ b/config.ru @@ -6,11 +6,13 @@ require_relative 'config/environment' require ::File.expand_path('config/environment', __dir__) -require 'prometheus/middleware/collector' -require 'prometheus/middleware/exporter' +unless Rails.env.test? + require 'prometheus/middleware/collector' + require 'prometheus/middleware/exporter' -use Prometheus::Middleware::Collector -use Prometheus::Middleware::Exporter + use Prometheus::Middleware::Collector + use Prometheus::Middleware::Exporter +end if ENV['RAILS_ENV'] == 'production' map Rails.application.config.relative_url_root || '/' do diff --git a/config/initializers/prometheus.rb b/config/initializers/prometheus.rb index c802544b..c8c06056 100644 --- a/config/initializers/prometheus.rb +++ b/config/initializers/prometheus.rb @@ -35,6 +35,13 @@ docstring: 'Process memory usage in mb' ) +prometheus.gauge( + :process_threads, + docstring: 'The number of process threads, labelled by status', + labels: [:status], + preset_labels: { status: 'total' } +) + # Prometheus histograms prometheus.histogram( :api_response_times, diff --git a/test/services/query_command_test.rb b/test/services/query_command_test.rb index 90999250..b3c53a8c 100644 --- a/test/services/query_command_test.rb +++ b/test/services/query_command_test.rb @@ -10,7 +10,7 @@ def query(query) end end -def validate_json(json) # rubocop:disable Metrics/MethodLength +def validate_json(json) _(json).must_match_json_expression( '@and': [