diff --git a/.gitignore b/.gitignore index 2b30b02..bd00448 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,71 @@ -*.gem +# Created by https://www.toptal.com/developers/gitignore/api/rails,ruby +# Edit at https://www.toptal.com/developers/gitignore?templates=rails,ruby + +### Rails ### *.rbc -.bundle -.config -.yardoc -Gemfile.lock -InstalledFiles -_yardoc -coverage -doc/ -lib/bundler/man -pkg -rdoc -spec/reports -test/tmp -test/version_tmp -tmp +capybara-*.html +.rspec +/db/*.sqlite3 +/db/*.sqlite3-journal +/db/*.sqlite3-[0-9]* +/public/system +/coverage/ +/spec/tmp +*.orig +rerun.txt +pickle-email-*.html + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# dotenv, dotenv-rails +.env +.env*.local + +## Environment normalization: +/.bundle +/vendor/bundle + +# Ignore Byebug command history file. .byebug_history + +# Ignore node_modules +node_modules/ + +# Ignore precompiled javascript packs +/public/packs +/public/packs-test +/public/assets + +# Ignore yarn files +/yarn-error.log +yarn-debug.log* +.yarn-integrity + +# Ignore uploaded files in development +/storage/* +!/storage/.keep +/public/uploads + +### Ruby ### +*.gem +/.config +/InstalledFiles +/pkg/ +/spec/reports/ +/spec/examples.txt +/test/tmp/ +/test/version_tmp/ +/tmp/ + +## Documentation cache and generated files: +/doc/ +/rdoc/ + +/.bundle/ +/lib/bundler/man/ + +# End of https://www.toptal.com/developers/gitignore/api/rails,ruby diff --git a/.rubocop.yml b/.rubocop.yml index 5930519..457e599 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,5 @@ AllCops: - TargetRubyVersion: 2.6 + TargetRubyVersion: 3.4 Exclude: - config/unicorn.rb - db/** @@ -7,7 +7,7 @@ AllCops: Layout/LineLength: Max: 100 - IgnoredPatterns: ['^(\s*#)'] + AllowedPatterns: ['^(\s*#)'] Exclude: - test/**/* diff --git a/.ruby-version b/.ruby-version index 6a81b4c..f989260 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.8 +3.4.4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c57458..fa1f164 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog for DS API rubygem +## 1.6.0 - 2025-07 + +- Update TargetRubyVersion to 3.4 for compatibility +- Refresh dependencies for better stability +- Refactor logging and error handling for clarity +- Enhance JSON parsing reliability +- Revise VCR setups with new HTTP client +- Expand .gitignore to cover more files +- Include Gemfile.lock for consistent dependencies + ## 1.5.4 - 2025-04 - (Jon) Adds returned row count to logs when the count is a positive integer. diff --git a/Gemfile b/Gemfile index 9a211c2..62884e6 100644 --- a/Gemfile +++ b/Gemfile @@ -5,18 +5,21 @@ source 'https://rubygems.org' # Specify your gem's dependencies in data-api.gemspec gemspec +gem 'byebug', group: %i[development test], require: false + # Add development dependencies here though as they are not required to run the gem group :development, :test do - gem 'bundler', '~> 2.4' - gem 'byebug', '~> 11.1.3' - gem 'excon', '~> 0.90.0' - gem 'json_expressions', '~> 0.9.0' - gem 'minitest', '~> 5.15.0' - gem 'minitest-rg', '~> 5.2.0' - gem 'minitest-vcr', '~> 1.4.0' - gem 'mocha', '~> 1.13.0' - gem 'rake', '~> 13.0.6' - gem 'rubocop', '~> 1.25.0' - gem 'simplecov', '~> 0.21.2', require: false - gem 'webmock', '~> 3.14.0' + gem 'bundler' + gem 'excon' + gem 'json_expressions' + gem 'minitest' + gem 'minitest-rg' + gem 'minitest-vcr' + gem 'mocha' + gem 'mutex_m' + gem 'ostruct' + gem 'rake' + gem 'rubocop' + gem 'simplecov', require: false + gem 'webmock' end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..16abc1c --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,129 @@ +PATH + remote: . + specs: + data_services_api (1.6.0) + faraday (~> 2.13) + faraday-encoding (~> 0.0.6) + faraday-follow_redirects (~> 0.3.0) + faraday-retry (~> 2.0) + json (~> 2.0) + yajl-ruby (~> 1.4) + +GEM + remote: https://rubygems.org/ + specs: + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + ast (2.4.3) + base64 (0.3.0) + bigdecimal (3.2.2) + byebug (12.0.0) + crack (1.0.0) + bigdecimal + rexml + docile (1.4.1) + excon (1.2.8) + logger + faraday (2.13.4) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-encoding (0.0.6) + faraday + faraday-follow_redirects (0.3.0) + faraday (>= 1, < 3) + faraday-net_http (3.4.1) + net-http (>= 0.5.0) + faraday-retry (2.3.2) + faraday (~> 2.0) + hashdiff (1.2.0) + json (2.13.2) + json_expressions (0.9.0) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + logger (1.7.0) + minispec-metadata (2.0.0) + minitest + minitest (5.25.5) + minitest-rg (5.3.0) + minitest (~> 5.0) + minitest-vcr (1.4.0) + minispec-metadata (~> 2.0) + minitest (>= 4.7.5) + vcr (>= 2.9) + mocha (2.7.1) + ruby2_keywords (>= 0.0.5) + mutex_m (0.3.0) + net-http (0.6.0) + uri + ostruct (0.6.3) + parallel (1.27.0) + parser (3.3.9.0) + ast (~> 2.4.1) + racc + prism (1.4.0) + public_suffix (6.0.2) + racc (1.8.1) + rainbow (3.1.1) + rake (13.3.0) + regexp_parser (2.10.0) + rexml (3.4.1) + rubocop (1.79.0) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.46.0, < 2.0) + ruby-progressbar (~> 1.7) + tsort (>= 0.2.0) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.46.0) + parser (>= 3.3.7.2) + prism (~> 1.4) + ruby-progressbar (1.13.0) + ruby2_keywords (0.0.5) + simplecov (0.22.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-html (0.13.2) + simplecov_json_formatter (0.1.4) + tsort (0.2.0) + unicode-display_width (3.1.4) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) + uri (1.0.3) + vcr (6.3.1) + base64 + webmock (3.25.1) + addressable (>= 2.8.0) + crack (>= 0.3.2) + hashdiff (>= 0.4.0, < 2.0.0) + yajl-ruby (1.4.3) + +PLATFORMS + ruby + x86_64-darwin-24 + +DEPENDENCIES + bundler + byebug + data_services_api! + excon + json_expressions + minitest + minitest-rg + minitest-vcr + mocha + mutex_m + ostruct + rake + rubocop + simplecov + webmock + +BUNDLED WITH + 2.7.0 diff --git a/data_services_api.gemspec b/data_services_api.gemspec index 1f4b8f7..87c74de 100644 --- a/data_services_api.gemspec +++ b/data_services_api.gemspec @@ -14,16 +14,18 @@ Gem::Specification.new do |spec| spec.description = 'Ruby wrapper for Epimorphics Data Services API' spec.homepage = 'https://github.com/epimorphics/data-API-ruby' spec.license = 'MIT' - spec.required_ruby_version = '>= 2.6' + spec.required_ruby_version = '>= 3.4' spec.files = `git ls-files -z`.split("\x0") spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } - spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ['lib'] spec.metadata['rubygems_mfa_required'] = 'true' - spec.add_dependency 'faraday_middleware', '~> 1.2.0' - spec.add_dependency 'json', '~> 2.6.1' - spec.add_dependency 'yajl-ruby', '~> 1.4.1' + spec.add_dependency 'faraday', '~> 2.13' + spec.add_dependency 'faraday-encoding', '~> 0.0.6' + spec.add_dependency 'faraday-follow_redirects', '~> 0.3.0' + spec.add_dependency 'faraday-retry', '~> 2.0' + spec.add_dependency 'json', '~> 2.0' + spec.add_dependency 'yajl-ruby', '~> 1.4' end diff --git a/fixtures/vcr_cassettes/test_0002_should_accept_a_query_and_return_the_result.yml b/fixtures/vcr_cassettes/test_0002_should_accept_a_query_and_return_the_result.yml index cabc29e..4ac3789 100644 --- a/fixtures/vcr_cassettes/test_0002_should_accept_a_query_and_return_the_result.yml +++ b/fixtures/vcr_cassettes/test_0002_should_accept_a_query_and_return_the_result.yml @@ -108,4 +108,56 @@ http_interactions: encoding: UTF-8 string: '{"meta":{"@id":"http://localhost//landregistry/id/ukhpi?_limit=1&_sort=-refMonth&mineq-refMonth=2019-01&refRegion=http%3A%2F%2Flandregistry.data.gov.uk%2Fid%2Fregion%2Funited-kingdom","publisher":"","license":"","licenseName":"","comment":"","version":"0.1","hasFormat":["http://localhost//landregistry/id/ukhpi.rdf?_limit=1&_sort=-refMonth&mineq-refMonth=2019-01&refRegion=http%3A%2F%2Flandregistry.data.gov.uk%2Fid%2Fregion%2Funited-kingdom","http://localhost//landregistry/id/ukhpi.html?_limit=1&_sort=-refMonth&mineq-refMonth=2019-01&refRegion=http%3A%2F%2Flandregistry.data.gov.uk%2Fid%2Fregion%2Funited-kingdom","http://localhost//landregistry/id/ukhpi.geojson?_limit=1&_sort=-refMonth&mineq-refMonth=2019-01&refRegion=http%3A%2F%2Flandregistry.data.gov.uk%2Fid%2Fregion%2Funited-kingdom","http://localhost//landregistry/id/ukhpi.csv?_limit=1&_sort=-refMonth&mineq-refMonth=2019-01&refRegion=http%3A%2F%2Flandregistry.data.gov.uk%2Fid%2Fregion%2Funited-kingdom","http://localhost//landregistry/id/ukhpi.ttl?_limit=1&_sort=-refMonth&mineq-refMonth=2019-01&refRegion=http%3A%2F%2Flandregistry.data.gov.uk%2Fid%2Fregion%2Funited-kingdom","http://localhost//landregistry/id/ukhpi.json?_limit=1&_sort=-refMonth&mineq-refMonth=2019-01&refRegion=http%3A%2F%2Flandregistry.data.gov.uk%2Fid%2Fregion%2Funited-kingdom"],"limit":1},"items":[{"@id":"http://landregistry.data.gov.uk/data/ukhpi/region/united-kingdom/month/2021-10","refRegion":{"@id":"http://landregistry.data.gov.uk/id/region/united-kingdom"},"refMonth":"2021-10","averagePrice":268349,"averagePriceSA":264786,"housePriceIndex":140.74,"housePriceIndexSA":138.87,"percentageAnnualChange":10.17,"percentageChange":-1.11,"averagePriceDetached":425121,"housePriceIndexDetached":147.75,"percentageChangeDetached":0.75,"percentageAnnualChangeDetached":13.99,"averagePriceSemiDetached":256537,"housePriceIndexSemiDetached":143.49,"percentageChangeSemiDetached":-1.64,"percentageAnnualChangeSemiDetached":10.39,"averagePriceTerraced":216481,"housePriceIndexTerraced":140.62,"percentageChangeTerraced":-2.88,"percentageAnnualChangeTerraced":8.79,"averagePriceFlatMaisonette":222381,"housePriceIndexFlatMaisonette":128.40,"percentageChangeFlatMaisonette":-0.17,"percentageAnnualChangeFlatMaisonette":6.63,"refPeriodStart":"2021-10-01","refPeriodDuration":1}]}' recorded_at: Tue, 25 Jan 2022 17:56:23 GMT -recorded_with: VCR 6.0.0 +- request: + method: get + uri: https://hmlr-dev-pres.epimorphics.net/landregistry/id/ukhpi?_limit=1&_sort=-refMonth&mineq-refMonth=2019-01&refRegion=http://landregistry.data.gov.uk/id/region/united-kingdom + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.13.4 + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-cache + Content-Type: + - text/html; charset=utf-8 + Date: + - Mon, 28 Jul 2025 11:54:20 GMT + Referrer-Policy: + - strict-origin-when-cross-origin + Server: + - nginx/1.27.5 + X-Cache-Status: + - MISS + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - 59aa874f2328dbf87c3c7ddb6bd79140 + X-Runtime: + - '0.003676' + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '0' + Connection: + - keep-alive + body: + encoding: UTF-8 + string: '' + recorded_at: Mon, 28 Jul 2025 11:54:20 GMT +recorded_with: VCR 6.3.1 diff --git a/fixtures/vcr_cassettes/test_0004_should_retrieve_JSON_with_HTTP_GET.yml b/fixtures/vcr_cassettes/test_0004_should_retrieve_JSON_with_HTTP_GET.yml index c2eec70..dfacadc 100644 --- a/fixtures/vcr_cassettes/test_0004_should_retrieve_JSON_with_HTTP_GET.yml +++ b/fixtures/vcr_cassettes/test_0004_should_retrieve_JSON_with_HTTP_GET.yml @@ -72,4 +72,56 @@ http_interactions: encoding: UTF-8 string: '{"meta":{"@id":"http://localhost//landregistry/id/ukhpi?_limit=1","publisher":"","license":"","licenseName":"","comment":"","version":"0.1","hasFormat":["http://localhost//landregistry/id/ukhpi.html?_limit=1","http://localhost//landregistry/id/ukhpi.geojson?_limit=1","http://localhost//landregistry/id/ukhpi.rdf?_limit=1","http://localhost//landregistry/id/ukhpi.json?_limit=1","http://localhost//landregistry/id/ukhpi.csv?_limit=1","http://localhost//landregistry/id/ukhpi.ttl?_limit=1"],"limit":1},"items":[{"@id":"http://landregistry.data.gov.uk/data/ukhpi/region/rutland/month/1999-05","refRegion":{"@id":"http://landregistry.data.gov.uk/id/region/rutland"},"refMonth":"1999-05","averagePrice":86936,"housePriceIndex":34.68,"percentageAnnualChange":7.75,"percentageChange":3.35,"salesVolume":77,"averagePriceDetached":118808,"housePriceIndexDetached":35.49,"percentageChangeDetached":3.21,"percentageAnnualChangeDetached":7.56,"averagePriceSemiDetached":71348,"housePriceIndexSemiDetached":34.29,"percentageChangeSemiDetached":3.42,"percentageAnnualChangeSemiDetached":7.91,"averagePriceTerraced":61817,"housePriceIndexTerraced":33.79,"percentageChangeTerraced":3.60,"percentageAnnualChangeTerraced":7.55,"averagePriceFlatMaisonette":42370,"housePriceIndexFlatMaisonette":34.70,"percentageChangeFlatMaisonette":3.61,"percentageAnnualChangeFlatMaisonette":9.47,"averagePriceNewBuild":99439,"housePriceIndexNewBuild":33.50,"percentageChangeNewBuild":3.17,"percentageAnnualChangeNewBuild":8.12,"salesVolumeNewBuild":21,"averagePriceExistingProperty":85036,"housePriceIndexExistingProperty":34.89,"percentageChangeExistingProperty":3.38,"percentageAnnualChangeExistingProperty":7.88,"salesVolumeExistingProperty":56,"refPeriodStart":"1999-05-01","refPeriodDuration":1}]}' recorded_at: Fri, 01 Apr 2022 15:48:30 GMT -recorded_with: VCR 6.1.0 +- request: + method: get + uri: https://hmlr-dev-pres.epimorphics.net/landregistry/id/ukhpi?_limit=1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.13.4 + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-cache + Content-Type: + - text/html; charset=utf-8 + Date: + - Mon, 28 Jul 2025 11:54:21 GMT + Referrer-Policy: + - strict-origin-when-cross-origin + Server: + - nginx/1.27.5 + X-Cache-Status: + - MISS + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - b99a398bf9572b6487933080ce17c642 + X-Runtime: + - '0.002625' + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '0' + Connection: + - keep-alive + body: + encoding: UTF-8 + string: '' + recorded_at: Mon, 28 Jul 2025 11:54:21 GMT +recorded_with: VCR 6.3.1 diff --git a/fixtures/vcr_cassettes/test_0005_should_instrument_an_API_call.yml b/fixtures/vcr_cassettes/test_0005_should_instrument_an_API_call.yml index 83f29c0..1a6b5e5 100644 --- a/fixtures/vcr_cassettes/test_0005_should_instrument_an_API_call.yml +++ b/fixtures/vcr_cassettes/test_0005_should_instrument_an_API_call.yml @@ -72,4 +72,56 @@ http_interactions: encoding: UTF-8 string: '{"meta":{"@id":"http://localhost//landregistry/id/ukhpi?_limit=1","publisher":"","license":"","licenseName":"","comment":"","version":"0.1","hasFormat":["http://localhost//landregistry/id/ukhpi.html?_limit=1","http://localhost//landregistry/id/ukhpi.geojson?_limit=1","http://localhost//landregistry/id/ukhpi.rdf?_limit=1","http://localhost//landregistry/id/ukhpi.json?_limit=1","http://localhost//landregistry/id/ukhpi.csv?_limit=1","http://localhost//landregistry/id/ukhpi.ttl?_limit=1"],"limit":1},"items":[{"@id":"http://landregistry.data.gov.uk/data/ukhpi/region/rutland/month/1999-05","refRegion":{"@id":"http://landregistry.data.gov.uk/id/region/rutland"},"refMonth":"1999-05","averagePrice":86936,"housePriceIndex":34.68,"percentageAnnualChange":7.75,"percentageChange":3.35,"salesVolume":77,"averagePriceDetached":118808,"housePriceIndexDetached":35.49,"percentageChangeDetached":3.21,"percentageAnnualChangeDetached":7.56,"averagePriceSemiDetached":71348,"housePriceIndexSemiDetached":34.29,"percentageChangeSemiDetached":3.42,"percentageAnnualChangeSemiDetached":7.91,"averagePriceTerraced":61817,"housePriceIndexTerraced":33.79,"percentageChangeTerraced":3.60,"percentageAnnualChangeTerraced":7.55,"averagePriceFlatMaisonette":42370,"housePriceIndexFlatMaisonette":34.70,"percentageChangeFlatMaisonette":3.61,"percentageAnnualChangeFlatMaisonette":9.47,"averagePriceNewBuild":99439,"housePriceIndexNewBuild":33.50,"percentageChangeNewBuild":3.17,"percentageAnnualChangeNewBuild":8.12,"salesVolumeNewBuild":21,"averagePriceExistingProperty":85036,"housePriceIndexExistingProperty":34.89,"percentageChangeExistingProperty":3.38,"percentageAnnualChangeExistingProperty":7.88,"salesVolumeExistingProperty":56,"refPeriodStart":"1999-05-01","refPeriodDuration":1}]}' recorded_at: Fri, 01 Apr 2022 15:48:31 GMT -recorded_with: VCR 6.1.0 +- request: + method: get + uri: https://hmlr-dev-pres.epimorphics.net/landregistry/id/ukhpi?_limit=1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.13.4 + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-cache + Content-Type: + - text/html; charset=utf-8 + Date: + - Mon, 28 Jul 2025 11:54:21 GMT + Referrer-Policy: + - strict-origin-when-cross-origin + Server: + - nginx/1.27.5 + X-Cache-Status: + - MISS + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - a64997a5c3e2af97842ce169e1d6b4af + X-Runtime: + - '0.002155' + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '0' + Connection: + - keep-alive + body: + encoding: UTF-8 + string: '' + recorded_at: Mon, 28 Jul 2025 11:54:21 GMT +recorded_with: VCR 6.3.1 diff --git a/fixtures/vcr_cassettes/test_0007_should_also_instrument_an_API_Service_Exception.yml b/fixtures/vcr_cassettes/test_0007_should_also_instrument_an_API_Service_Exception.yml index cee7d55..0000e7d 100644 --- a/fixtures/vcr_cassettes/test_0007_should_also_instrument_an_API_Service_Exception.yml +++ b/fixtures/vcr_cassettes/test_0007_should_also_instrument_an_API_Service_Exception.yml @@ -46,4 +46,148 @@ http_interactions: "path" : "/ceci/nest/pas/une/page" } recorded_at: Wed, 21 Jun 2023 13:00:41 GMT -recorded_with: VCR 6.1.0 +- request: + method: get + uri: https://hmlr-dev-pres.epimorphics.net/ceci/nest/pas/une/page?_limit=1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.13.4 + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-cache + Content-Type: + - text/html; charset=utf-8 + Date: + - Mon, 28 Jul 2025 11:54:21 GMT + Referrer-Policy: + - strict-origin-when-cross-origin + Server: + - nginx/1.27.5 + X-Cache-Status: + - MISS + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - 8847c72c154a577c6f096245507ec603 + X-Runtime: + - '0.002501' + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '0' + Connection: + - keep-alive + body: + encoding: UTF-8 + string: '' + recorded_at: Mon, 28 Jul 2025 11:54:21 GMT +- request: + method: get + uri: http://localhost:8888/ceci/nest/pas/une/page?_limit=1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.13.4 + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 404 + message: '' + headers: + Sleuth-Trace-Id: + - '' + Sleuth-Span-Id: + - '' + Vary: + - Accept + - Access-Control-Request-Headers + - Access-Control-Request-Method + - Origin + Cache-Control: + - max-age=0 + Content-Type: + - application/json + Content-Length: + - '183' + Date: + - Mon, 28 Jul 2025 17:05:12 GMT + body: + encoding: UTF-8 + string: |- + { + "timestamp" : "Mon Jul 28 17:05:12 GMT 2025", + "status" : "404", + "error" : "Not Found", + "message" : "Requested endpoint doesn't exist", + "path" : "/ceci/nest/pas/une/page" + } + recorded_at: Mon, 28 Jul 2025 17:05:12 GMT +- request: + method: get + uri: http://localhost:8888/ceci/nest/pas/une/page?_limit=1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.13.4 + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 404 + message: '' + headers: + Sleuth-Trace-Id: + - '' + Sleuth-Span-Id: + - '' + Vary: + - Accept + - Access-Control-Request-Headers + - Access-Control-Request-Method + - Origin + Cache-Control: + - max-age=0 + Content-Type: + - application/json + Content-Length: + - '183' + Date: + - Mon, 28 Jul 2025 17:05:12 GMT + body: + encoding: UTF-8 + string: |- + { + "timestamp" : "Mon Jul 28 17:05:12 GMT 2025", + "status" : "404", + "error" : "Not Found", + "message" : "Requested endpoint doesn't exist", + "path" : "/ceci/nest/pas/une/page" + } + recorded_at: Mon, 28 Jul 2025 17:05:12 GMT +recorded_with: VCR 6.3.1 diff --git a/fixtures/vcr_cassettes/test_0008_should_log_the_call_to_the_data_API.yml b/fixtures/vcr_cassettes/test_0008_should_log_the_call_to_the_data_API.yml index e8742c9..dc9253a 100644 --- a/fixtures/vcr_cassettes/test_0008_should_log_the_call_to_the_data_API.yml +++ b/fixtures/vcr_cassettes/test_0008_should_log_the_call_to_the_data_API.yml @@ -72,4 +72,56 @@ http_interactions: encoding: UTF-8 string: '{"meta":{"@id":"http://localhost//landregistry/id/ukhpi?_limit=1","publisher":"","license":"","licenseName":"","comment":"","version":"0.1","hasFormat":["http://localhost//landregistry/id/ukhpi.html?_limit=1","http://localhost//landregistry/id/ukhpi.geojson?_limit=1","http://localhost//landregistry/id/ukhpi.rdf?_limit=1","http://localhost//landregistry/id/ukhpi.json?_limit=1","http://localhost//landregistry/id/ukhpi.csv?_limit=1","http://localhost//landregistry/id/ukhpi.ttl?_limit=1"],"limit":1},"items":[{"@id":"http://landregistry.data.gov.uk/data/ukhpi/region/rutland/month/1999-05","refRegion":{"@id":"http://landregistry.data.gov.uk/id/region/rutland"},"refMonth":"1999-05","averagePrice":86936,"housePriceIndex":34.68,"percentageAnnualChange":7.75,"percentageChange":3.35,"salesVolume":77,"averagePriceDetached":118808,"housePriceIndexDetached":35.49,"percentageChangeDetached":3.21,"percentageAnnualChangeDetached":7.56,"averagePriceSemiDetached":71348,"housePriceIndexSemiDetached":34.29,"percentageChangeSemiDetached":3.42,"percentageAnnualChangeSemiDetached":7.91,"averagePriceTerraced":61817,"housePriceIndexTerraced":33.79,"percentageChangeTerraced":3.60,"percentageAnnualChangeTerraced":7.55,"averagePriceFlatMaisonette":42370,"housePriceIndexFlatMaisonette":34.70,"percentageChangeFlatMaisonette":3.61,"percentageAnnualChangeFlatMaisonette":9.47,"averagePriceNewBuild":99439,"housePriceIndexNewBuild":33.50,"percentageChangeNewBuild":3.17,"percentageAnnualChangeNewBuild":8.12,"salesVolumeNewBuild":21,"averagePriceExistingProperty":85036,"housePriceIndexExistingProperty":34.89,"percentageChangeExistingProperty":3.38,"percentageAnnualChangeExistingProperty":7.88,"salesVolumeExistingProperty":56,"refPeriodStart":"1999-05-01","refPeriodDuration":1}]}' recorded_at: Fri, 01 Apr 2022 15:48:30 GMT -recorded_with: VCR 6.1.0 +- request: + method: get + uri: https://hmlr-dev-pres.epimorphics.net/landregistry/id/ukhpi?_limit=1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.13.4 + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-cache + Content-Type: + - text/html; charset=utf-8 + Date: + - Mon, 28 Jul 2025 11:54:20 GMT + Referrer-Policy: + - strict-origin-when-cross-origin + Server: + - nginx/1.27.5 + X-Cache-Status: + - MISS + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - 7cd480d304f1c0f154a6e2541be71c0d + X-Runtime: + - '0.002982' + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '0' + Connection: + - keep-alive + body: + encoding: UTF-8 + string: '' + recorded_at: Mon, 28 Jul 2025 11:54:20 GMT +recorded_with: VCR 6.3.1 diff --git a/fixtures/vcr_cassettes/test_0009_should_correctly_receive_a_duration_in_microseconds.yml b/fixtures/vcr_cassettes/test_0009_should_correctly_receive_a_duration_in_microseconds.yml index bd170ec..4a9ee21 100644 --- a/fixtures/vcr_cassettes/test_0009_should_correctly_receive_a_duration_in_microseconds.yml +++ b/fixtures/vcr_cassettes/test_0009_should_correctly_receive_a_duration_in_microseconds.yml @@ -72,4 +72,128 @@ http_interactions: encoding: UTF-8 string: '{"meta":{"@id":"http://localhost//landregistry/id/ukhpi?_limit=1","publisher":"","license":"","licenseName":"","comment":"","version":"0.1","hasFormat":["http://localhost//landregistry/id/ukhpi.html?_limit=1","http://localhost//landregistry/id/ukhpi.geojson?_limit=1","http://localhost//landregistry/id/ukhpi.rdf?_limit=1","http://localhost//landregistry/id/ukhpi.json?_limit=1","http://localhost//landregistry/id/ukhpi.csv?_limit=1","http://localhost//landregistry/id/ukhpi.ttl?_limit=1"],"limit":1},"items":[{"@id":"http://landregistry.data.gov.uk/data/ukhpi/region/rutland/month/1999-05","refRegion":{"@id":"http://landregistry.data.gov.uk/id/region/rutland"},"refMonth":"1999-05","averagePrice":86936,"housePriceIndex":34.68,"percentageAnnualChange":7.75,"percentageChange":3.35,"salesVolume":77,"averagePriceDetached":118808,"housePriceIndexDetached":35.49,"percentageChangeDetached":3.21,"percentageAnnualChangeDetached":7.56,"averagePriceSemiDetached":71348,"housePriceIndexSemiDetached":34.29,"percentageChangeSemiDetached":3.42,"percentageAnnualChangeSemiDetached":7.91,"averagePriceTerraced":61817,"housePriceIndexTerraced":33.79,"percentageChangeTerraced":3.60,"percentageAnnualChangeTerraced":7.55,"averagePriceFlatMaisonette":42370,"housePriceIndexFlatMaisonette":34.70,"percentageChangeFlatMaisonette":3.61,"percentageAnnualChangeFlatMaisonette":9.47,"averagePriceNewBuild":99439,"housePriceIndexNewBuild":33.50,"percentageChangeNewBuild":3.17,"percentageAnnualChangeNewBuild":8.12,"salesVolumeNewBuild":21,"averagePriceExistingProperty":85036,"housePriceIndexExistingProperty":34.89,"percentageChangeExistingProperty":3.38,"percentageAnnualChangeExistingProperty":7.88,"salesVolumeExistingProperty":56,"refPeriodStart":"1999-05-01","refPeriodDuration":1}]}' recorded_at: Wed, 25 Jan 2023 16:37:39 GMT -recorded_with: VCR 6.1.0 +- request: + method: get + uri: https://hmlr-dev-pres.epimorphics.net/landregistry/id/ukhpi?_limit=1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.13.4 + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-cache + Content-Type: + - text/html; charset=utf-8 + Date: + - Mon, 28 Jul 2025 11:54:20 GMT + Referrer-Policy: + - strict-origin-when-cross-origin + Server: + - nginx/1.27.5 + X-Cache-Status: + - MISS + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - e48aa0dfb017c0aceeb8e95fb4d16d7a + X-Runtime: + - '0.002343' + X-Xss-Protection: + - 1; mode=block + Content-Length: + - '0' + Connection: + - keep-alive + body: + encoding: UTF-8 + string: '' + recorded_at: Mon, 28 Jul 2025 11:54:20 GMT +- request: + method: get + uri: http://localhost:8888/landregistry/id/ukhpi?_limit=1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.13.4 + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Sleuth-Trace-Id: + - '' + Sleuth-Span-Id: + - '' + Vary: + - Accept + Cache-Control: + - max-age=0 + Content-Type: + - application/json + Content-Length: + - '1771' + Date: + - Mon, 28 Jul 2025 15:16:52 GMT + body: + encoding: UTF-8 + string: '{"meta":{"@id":"http://localhost//landregistry/id/ukhpi?_limit=1","publisher":"","license":"","licenseName":"","comment":"","version":"0.1","hasFormat":["http://localhost//landregistry/id/ukhpi.html?_limit=1","http://localhost//landregistry/id/ukhpi.geojson?_limit=1","http://localhost//landregistry/id/ukhpi.rdf?_limit=1","http://localhost//landregistry/id/ukhpi.json?_limit=1","http://localhost//landregistry/id/ukhpi.csv?_limit=1","http://localhost//landregistry/id/ukhpi.ttl?_limit=1"],"limit":1},"items":[{"@id":"http://landregistry.data.gov.uk/data/ukhpi/region/rutland/month/1999-05","refRegion":{"@id":"http://landregistry.data.gov.uk/id/region/rutland"},"refMonth":"1999-05","averagePrice":76646,"housePriceIndex":23.10,"percentageAnnualChange":7.70,"percentageChange":3.30,"salesVolume":77,"averagePriceDetached":112560,"housePriceIndexDetached":23.40,"percentageChangeDetached":3.20,"percentageAnnualChangeDetached":7.60,"averagePriceSemiDetached":68829,"housePriceIndexSemiDetached":22.60,"percentageChangeSemiDetached":3.40,"percentageAnnualChangeSemiDetached":7.90,"averagePriceTerraced":56145,"housePriceIndexTerraced":22.40,"percentageChangeTerraced":3.60,"percentageAnnualChangeTerraced":7.60,"averagePriceFlatMaisonette":39717,"housePriceIndexFlatMaisonette":26.10,"percentageChangeFlatMaisonette":3.60,"percentageAnnualChangeFlatMaisonette":9.50,"averagePriceNewBuild":63757,"housePriceIndexNewBuild":22.60,"percentageChangeNewBuild":3.20,"percentageAnnualChangeNewBuild":8.10,"salesVolumeNewBuild":21,"averagePriceExistingProperty":76196,"housePriceIndexExistingProperty":23.00,"percentageChangeExistingProperty":3.40,"percentageAnnualChangeExistingProperty":7.90,"salesVolumeExistingProperty":56,"refPeriodStart":"1999-05-01","refPeriodDuration":1}]}' + recorded_at: Mon, 28 Jul 2025 15:16:52 GMT +- request: + method: get + uri: http://localhost:8888/landregistry/id/ukhpi?_limit=1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v2.13.4 + Accept: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: '' + headers: + Sleuth-Trace-Id: + - '' + Sleuth-Span-Id: + - '' + Vary: + - Accept + Cache-Control: + - max-age=0 + Content-Type: + - application/json + Content-Length: + - '1771' + Date: + - Mon, 28 Jul 2025 15:16:56 GMT + body: + encoding: UTF-8 + string: '{"meta":{"@id":"http://localhost//landregistry/id/ukhpi?_limit=1","publisher":"","license":"","licenseName":"","comment":"","version":"0.1","hasFormat":["http://localhost//landregistry/id/ukhpi.html?_limit=1","http://localhost//landregistry/id/ukhpi.geojson?_limit=1","http://localhost//landregistry/id/ukhpi.rdf?_limit=1","http://localhost//landregistry/id/ukhpi.json?_limit=1","http://localhost//landregistry/id/ukhpi.csv?_limit=1","http://localhost//landregistry/id/ukhpi.ttl?_limit=1"],"limit":1},"items":[{"@id":"http://landregistry.data.gov.uk/data/ukhpi/region/rutland/month/1999-05","refRegion":{"@id":"http://landregistry.data.gov.uk/id/region/rutland"},"refMonth":"1999-05","averagePrice":76646,"housePriceIndex":23.10,"percentageAnnualChange":7.70,"percentageChange":3.30,"salesVolume":77,"averagePriceDetached":112560,"housePriceIndexDetached":23.40,"percentageChangeDetached":3.20,"percentageAnnualChangeDetached":7.60,"averagePriceSemiDetached":68829,"housePriceIndexSemiDetached":22.60,"percentageChangeSemiDetached":3.40,"percentageAnnualChangeSemiDetached":7.90,"averagePriceTerraced":56145,"housePriceIndexTerraced":22.40,"percentageChangeTerraced":3.60,"percentageAnnualChangeTerraced":7.60,"averagePriceFlatMaisonette":39717,"housePriceIndexFlatMaisonette":26.10,"percentageChangeFlatMaisonette":3.60,"percentageAnnualChangeFlatMaisonette":9.50,"averagePriceNewBuild":63757,"housePriceIndexNewBuild":22.60,"percentageChangeNewBuild":3.20,"percentageAnnualChangeNewBuild":8.10,"salesVolumeNewBuild":21,"averagePriceExistingProperty":76196,"housePriceIndexExistingProperty":23.00,"percentageChangeExistingProperty":3.40,"percentageAnnualChangeExistingProperty":7.90,"salesVolumeExistingProperty":56,"refPeriodStart":"1999-05-01","refPeriodDuration":1}]}' + recorded_at: Mon, 28 Jul 2025 15:16:56 GMT +recorded_with: VCR 6.3.1 diff --git a/lib/data_services_api/dsapi_response_converter.rb b/lib/data_services_api/dsapi_response_converter.rb index 8be19ea..cac35b4 100644 --- a/lib/data_services_api/dsapi_response_converter.rb +++ b/lib/data_services_api/dsapi_response_converter.rb @@ -38,7 +38,7 @@ def json_mode_compact(sapint_key, sapint_value) return { "#{@dataset_name}:#{sapint_key}" => sapint_value } unless sapint_value.is_a?(Hash) sapint_value.transform_keys do |key| - "#{@dataset_name}:#{sapint_key}#{key == '@id' ? '' : key.capitalize}" + "#{@dataset_name}:#{sapint_key}#{key.capitalize unless key == '@id'}" end end diff --git a/lib/data_services_api/query_generator.rb b/lib/data_services_api/query_generator.rb index 1c1994c..73d470a 100644 --- a/lib/data_services_api/query_generator.rb +++ b/lib/data_services_api/query_generator.rb @@ -48,7 +48,7 @@ def lt(attribute, value) end def op(oper, attribute, value) - oper = oper.is_a?(Symbol) ? "@#{oper}" : oper + oper = "@#{oper}" if oper.is_a?(Symbol) raise NameError, "Unrecognised operation #{oper}" unless OPERATIONS.include?(oper) relational(oper, attribute, value) diff --git a/lib/data_services_api/service.rb b/lib/data_services_api/service.rb index f5842de..96226db 100644 --- a/lib/data_services_api/service.rb +++ b/lib/data_services_api/service.rb @@ -49,7 +49,7 @@ def get_json(http_url, params, options) # rubocop:disable Metrics/MethodLength, timer: nil }), path: URI.parse(http_url).path, - query_string: query_string, + query_string:, request_status: 'processing' } @@ -71,7 +71,7 @@ def get_json(http_url, params, options) # rubocop:disable Metrics/MethodLength, # log the response and status code logged_fields[:message] = generate_service_message( { - msg: "API returned #{returned_rows} row#{returned_rows == 1 ? '' : 's'}", + msg: "API returned #{returned_rows} #{returned_rows == 1 ? 'row' : 'rows'}", timer: elapsed_time } ) @@ -102,20 +102,20 @@ def get_from_api(http_url, accept_headers, params, options) # rubocop:disable Me instrument_response(response, start_time, 'received') ok?(response, http_url) && response - rescue ServiceException => e - instrument_service_exception(http_url, e, start_time) - raise e - rescue Faraday::ConnectionFailed => e + rescue Faraday::TimeoutError, Faraday::ConnectionFailed => e instrument_connection_failure(http_url, e, start_time) raise e + rescue Faraday::ResourceNotFound, ServiceException => e + instrument_service_exception(http_url, e, start_time) + raise e end # Parse the given JSON string into a data structure. Throws an exception if # parsing fails def parse_json(json) # rubocop:disable Metrics/MethodLength result = nil - - json_hash = parser.parse(StringIO.new(json)) do |json_chunk| + jsonified = json.is_a?(String) ? json : json.to_json + json_hash = parser.parse(jsonified) do |json_chunk| if result result = [result] unless result.is_a?(Array) result << json_chunk @@ -125,6 +125,7 @@ def parse_json(json) # rubocop:disable Metrics/MethodLength end report_json_failure(json) unless result || json_hash + result || json_hash end @@ -151,20 +152,27 @@ def post_to_api(http_url, json) # rubocop:disable Metrics/AbcSize ok?(response, http_url) && response end - def create_http_connection(http_url, auth = false) - Faraday.new(url: http_url) do |faraday| - faraday.use Faraday::Request::UrlEncoded - faraday.use Faraday::Request::Retry - faraday.use FaradayMiddleware::FollowRedirects + def create_http_connection(http_url, auth = false) # rubocop:disable Metrics/MethodLength + retry_options = { + max: 2, + interval: 0.05, + interval_randomness: 0.5, + backoff_factor: 2, + exceptions: [Faraday::TimeoutError, Faraday::ConnectionFailed, Faraday::ResourceNotFound] + } - # instrument the request to log the time it takes to complete but only if we're in a Rails environment - faraday.request :instrumentation, name: 'requests.api' if in_rails? + Faraday.new(url: http_url) do |config| + config.use Faraday::Request::UrlEncoded + config.use Faraday::FollowRedirects::Middleware - # set the basic auth if required - faraday.basic_auth(api_user, api_pw) if auth + config.request :authorization, :basic, api_user, api_pw if auth + # instrument the request to log the time it takes to complete but only if we're in a Rails environment + config.request :instrumentation, name: 'requests.api' if in_rails? + config.request :retry, retry_options + with_logger_in_rails(config) - # setting the adapter must be the final step, otherwise get a warning from Faraday - faraday.adapter(:net_http) + config.response :json + config.response :raise_error end end @@ -187,18 +195,21 @@ def ok?(response, http_url) end def as_http_api(api) - api.start_with?('http') ? api : "#{url}#{api}" + return api if api.start_with?('http://', 'https://') + + # if the API is a relative path, append to the base URL + URI::HTTP.build(host: @url, path: api).to_s end def report_json_failure(json) - msg = "JSON result was not parsed correctly: #{json.slice(0, 1000)}" + msg = "JSON result was not parsed correctly: #{json.to_s.slice(0, 1000)}" if in_rails? # msg = 'JSON result was not parsed correctly (no temp file saved)' logger.error(msg) end - throw msg + raise ServiceException.new(msg, 500, nil, json) end def instrument_response(response, start_time, _request_status) @@ -208,7 +219,7 @@ def instrument_response(response, start_time, _request_status) elapsed_time = (end_time - start_time) / 1000 instrumenter&.instrument( 'response.api', - response: response, + response:, duration: elapsed_time ) end @@ -233,7 +244,7 @@ def instrument_connection_failure(http_url, exception, start_time) # rubocop:dis 'error' ) - instrumenter&.instrument('connection_failure.api', exception: exception) + instrumenter&.instrument('connection_failure.api', exception:) end def instrument_service_exception(http_url, exception, start_time) # rubocop:disable Metrics/MethodLength @@ -256,7 +267,7 @@ def instrument_service_exception(http_url, exception, start_time) # rubocop:disa 'error' ) - instrumenter&.instrument('service_exception.api', exception: exception) + instrumenter&.instrument('service_exception.api', exception:) end # Return true if we're currently running in a Rails environment @@ -264,6 +275,19 @@ def in_rails? defined?(Rails) end + def with_logger_in_rails(config) + return config.response :logger unless in_rails? + + level = Rails.env.production? ? :info : :debug + + config.response :logger, Rails.logger, { + headers: true, + bodies: false, + errors: true, + log_level: level.to_sym + } + end + # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize # Log the provided properties with the appropriate log level # @param [Hash] log_fields - The fields to log diff --git a/lib/data_services_api/version.rb b/lib/data_services_api/version.rb index 931f421..35ddafa 100644 --- a/lib/data_services_api/version.rb +++ b/lib/data_services_api/version.rb @@ -3,8 +3,8 @@ # :nodoc: module DataServicesApi MAJOR = 1 - MINOR = 5 - PATCH = 4 + MINOR = 6 + PATCH = 0 SUFFIX = nil - VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}#{SUFFIX && ".#{SUFFIX}"}" + VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}#{SUFFIX && ".#{SUFFIX}"}".freeze end diff --git a/test/data_services_api/data_services_api_test.rb b/test/data_services_api/data_services_api_test.rb index ac6fe6f..9b19c1c 100644 --- a/test/data_services_api/data_services_api_test.rb +++ b/test/data_services_api/data_services_api_test.rb @@ -8,11 +8,11 @@ end it 'should be constructable with a given URL' do - instrumenter = MockNotifications.new + mock_notifier = MockNotifications.new mock_logger = mock('logger') mock_logger.expects(:info).at_least(0) - dsapi = DataServicesApi::Service.new(url: 'foo/bar', instrumenter: instrumenter, logger: mock_logger) + dsapi = DataServicesApi::Service.new(url: 'foo/bar', instrumenter: mock_notifier, logger: mock_logger) _(dsapi.url).must_match(%r{foo/bar}) end diff --git a/test/data_services_api/dataset_test.rb b/test/data_services_api/dataset_test.rb index 22a7036..6e98697 100644 --- a/test/data_services_api/dataset_test.rb +++ b/test/data_services_api/dataset_test.rb @@ -36,12 +36,12 @@ def info(message, &block) end before do - instrumenter = MockNotifications.new + mock_notifier = MockNotifications.new VCR.insert_cassette(name, record: :new_episodes) mock_logger.expects(:info).at_least(0) - @dataset = DataServicesApi::Service.new(url: api_url, instrumenter: instrumenter, logger: mock_logger).dataset('ukhpi') + @dataset = DataServicesApi::Service.new(url: api_url, instrumenter: mock_notifier, logger: mock_logger).dataset('ukhpi') end after do @@ -69,7 +69,15 @@ def to_json(*_args) end end.new + # Ensure the query responds to the expected methods + _(query).must_respond_to :terms + _(query).must_respond_to :to_json + # Ensure the query terms are a Hash + _(query.terms).must_be_kind_of Hash + + # Perform the query json = @dataset.query(query) + # Check the response _(json).wont_be_nil _(json.size).must_be :>, 0 end diff --git a/test/data_services_api/service_test.rb b/test/data_services_api/service_test.rb index d8c7b0f..d7e8b5c 100644 --- a/test/data_services_api/service_test.rb +++ b/test/data_services_api/service_test.rb @@ -84,8 +84,9 @@ def info(message, &block) end it 'should instrument a failed API call' do - mock_notifier = MockNotifications.new mock_api_url = 'http://localhost:8765' + mock_notifier = MockNotifications.new + mock_logger = MockLogger.new _ do DataServicesApi::Service @@ -100,6 +101,7 @@ def info(message, &block) it 'should also instrument an API Service Exception' do mock_notifier = MockNotifications.new + mock_logger = MockLogger.new _ do DataServicesApi::Service @@ -108,13 +110,13 @@ def info(message, &block) end.must_raise instrumentations = mock_notifier.instrumentations - _(instrumentations.size).must_equal 2 - _(instrumentations[0].first).must_equal 'response.api' - _(instrumentations[1].first).must_equal 'service_exception.api' + _(instrumentations.size).must_equal 1 + _(instrumentations.first.first).must_equal 'service_exception.api' end it 'should log the call to the data API' do mock_notifier = MockNotifications.new + mock_logger = MockLogger.new DataServicesApi::Service .new(url: api_url, instrumenter: mock_notifier, logger: mock_logger) @@ -134,8 +136,8 @@ def info(message, &block) _(mock_logger).wont_be_nil - mock_log = mock_logger.messages[:info].first - + # Check the last logged message for duration + mock_log = mock_logger.messages[:info].last _(mock_log).wont_be_nil _(mock_log.size).must_equal 2 @@ -143,10 +145,7 @@ def info(message, &block) duration = JSON.parse(json)['request_time'] if duration - seconds, milliseconds = duration.divmod(1000) - duration = format('%.0f.%04d', seconds, milliseconds) # rubocop:disable Style/FormatStringToken - _(duration).wont_be_nil - _(duration).must_be :>, 0 + _(duration.to_f).must_be :>, 0 assert_kind_of(String, duration) end end diff --git a/test/minitest_helper.rb b/test/minitest_helper.rb index 5aaf605..6bbdd6a 100644 --- a/test/minitest_helper.rb +++ b/test/minitest_helper.rb @@ -17,7 +17,10 @@ Bundler.require(:default, :development, :test) require 'faraday' -require 'faraday_middleware' +require 'faraday/encoding' +require 'faraday/follow_redirects' +require 'faraday/retry' + require 'byebug' require 'mocha/minitest'