lhs 19.8.2 → 20.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e57e3afbbffbdd6fdbcc8b64a947daae97b5faa5975ae8fe29b6b77d87b0d47
4
- data.tar.gz: 5d8363f9dcbd226f60428e6344967ef2369639fd36544b7a6d9112d5058b8d31
3
+ metadata.gz: 6222738010dc108833f001419f0fe23f97c1fbe6bb3211347724455bd6d1fab6
4
+ data.tar.gz: ec1856d1a8ce39396dedf8251058f59604f3e84111a2dffea05a7b0d97b07cab
5
5
  SHA512:
6
- metadata.gz: 4f7ae19794cade9f046731c0c6cc948a87b8a04bada44e14c52853600b78c47f6ecfb53bc2bedbb16918cb0cf2788e3ac780873ebbeebbad544eb504494464aa
7
- data.tar.gz: b8092ac44ed946248fa686e95873ce841cd1b38dbebbc41f7547037840b56e8c8c5d168c1866382e9f6e6eb51c181e43f407febe9d5ff1b476b1df3a063f326e
6
+ metadata.gz: 22dde92abf63322ceab6d51962462c5dac3a34c12c46438a761fdce584066e50c1202babbc31762326cd96d073edd7d83aa8b8a231948a3d404adb93ea8a8ea2
7
+ data.tar.gz: eaafb72d93e036a0e8af226877fea17d5489e722bbd0d403946bc4828e3429f2a37cf85dc46818116fe751fb937dc3c1851e4cc9ac55f0d7fbbb0482611abe38
data/README.md CHANGED
@@ -119,6 +119,7 @@ record.review # "Lunch was great
119
119
  * [Record setters](#record-setters)
120
120
  * [Record getters](#record-getters)
121
121
  * [Include linked resources (hyperlinks and hypermedia)](#include-linked-resources-hyperlinks-and-hypermedia)
122
+ * [Generate links from parameters](#generate-links-from-parameters)
122
123
  * [Ensure the whole linked collection is included: includes_all](#ensure-the-whole-linked-collection-is-included-includes_all)
123
124
  * [Include the first linked page or single item is included: include](#include-the-first-linked-page-or-single-item-is-included-include)
124
125
  * [Include various levels of linked data](#include-various-levels-of-linked-data)
@@ -136,8 +137,11 @@ record.review # "Lunch was great
136
137
  * [Disable request cycle cache](#disable-request-cycle-cache)
137
138
  * [Option Blocks](#option-blocks)
138
139
  * [Request tracing](#request-tracing)
140
+ * [Extended Rollbar Logging](#extended-rollbar-logging)
139
141
  * [Testing with LHS](#testing-with-lhs)
140
- * [Test helper for request cycle cache](#test-helper-for-request-cycle-cache)
142
+ * [Test helper](#test-helper)
143
+ * [Stub](#stub)
144
+ * [Stub All](#stub-all)
141
145
  * [Test query chains](#test-query-chains)
142
146
  * [By explicitly resolving the chain: fetch](#by-explicitly-resolving-the-chain-fetch)
143
147
  * [Without resolving the chain: where_values_hash](#without-resolving-the-chain-where_values_hash)
@@ -1627,6 +1631,15 @@ POST https://service.example.com/records/1z-5r1fkaj { body: "{ 'name': 'Starbuck
1627
1631
 
1628
1632
  -> See [record validation](#record-validation) for how to handle validation errors when updating records.
1629
1633
 
1634
+ You can also pass explicit request options to `update`, by passing two explicit hashes:
1635
+
1636
+ ```ruby
1637
+ # app/controllers/some_controller.rb
1638
+
1639
+ record.update({ recommended: true }, { method: 'put' })
1640
+
1641
+ ```
1642
+
1630
1643
  ##### partial_update
1631
1644
 
1632
1645
  `partial_update` updates just the provided parameters.
@@ -1658,6 +1671,15 @@ POST https://service.example.com/records/1z-5r1fkaj { body: "{ 'name': 'Starbuck
1658
1671
 
1659
1672
  -> See [record validation](#record-validation) for how to handle validation errors when updating records.
1660
1673
 
1674
+ You can also pass explicit request options to `partial_update`, by passing two explicit hashes:
1675
+
1676
+ ```ruby
1677
+ # app/controllers/some_controller.rb
1678
+
1679
+ record.partial_update({ recommended: true }, { method: 'put' })
1680
+
1681
+ ```
1682
+
1661
1683
  #### Endpoint url parameter injection during record creation/change
1662
1684
 
1663
1685
  LHS injects parameters provided to `create`, `update`, `partial_update`, `save` etc. into an endpoint's URL when matching:
@@ -2020,6 +2042,21 @@ With `includes` or `includes_all` (to enforce fetching all remote objects for pa
2020
2042
 
2021
2043
  Including linked resources/records is heavily influenced by [https://guides.rubyonrails.org/active_record_querying.html](https://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations) and you should read it to understand this feature in all it's glory.
2022
2044
 
2045
+ #### Generate links from parameters
2046
+
2047
+ Sometimes you need to generate full hrefs/urls for records but you just have parameters that describe that record, like the ID.
2048
+
2049
+ For those usecases you can use `href_for(params)`:
2050
+
2051
+ ```ruby
2052
+ # app/controllers/some_controller.rb
2053
+
2054
+ Presence.create(place: { href: Place.href_for(123) })
2055
+ ```
2056
+ ```
2057
+ POST '/presences' { place: { href: "http://datastore/places/123" } }
2058
+ ```
2059
+
2023
2060
  #### Ensure the whole linked collection is included: includes_all
2024
2061
 
2025
2062
  In case endpoints are paginated and you are certain that you'll need all objects of a set and not only the first page/batch, use `includes_all`.
@@ -2428,6 +2465,26 @@ code.places
2428
2465
  }
2429
2466
  ```
2430
2467
 
2468
+ ## Extended Rollbar Logging
2469
+
2470
+ In order to log all requests/responses prior to an exception reported by Rollbar in addition to the exception itself, use the `LHS::ExtendedRollbar` interceptor in combination with the rollbar processor/handler:
2471
+
2472
+ ```ruby
2473
+ # config/initializers/lhc.rb
2474
+
2475
+ LHC.configure do |config|
2476
+ config.interceptors = [LHS::ExtendedRollbar]
2477
+ end
2478
+ ```
2479
+
2480
+ ```ruby
2481
+ # config/initializers/rollbar.rb
2482
+
2483
+ Rollbar.configure do |config|
2484
+ config.before_process << LHS::Interceptors::ExtendedRollbar::Handler.init
2485
+ end
2486
+ ```
2487
+
2431
2488
  ## Testing with LHS
2432
2489
 
2433
2490
  **Best practice in regards of testing applications using LHS, is to let LHS fetch your records, actually perform HTTP requests and [WebMock](https://github.com/bblimke/webmock) to stub/mock those http requests/responses.**
@@ -2465,17 +2522,44 @@ it 'displays contracts' do
2465
2522
  end
2466
2523
  ```
2467
2524
 
2468
- ### Test helper for request cycle cache
2525
+ ### Test helper
2469
2526
 
2470
- In order to not run into caching issues during your tests, when (request cycle cache)[#request-cycle-cache] is enabled, simply require the following helper in your tests:
2527
+ In order to load LHS test helpers into your tests, add the following to your spec helper:
2471
2528
 
2472
2529
  ```ruby
2473
2530
  # spec/spec_helper.rb
2474
2531
 
2475
- require 'lhs/test/request_cycle_cache_helper'
2532
+ require 'lhs/rspec'
2476
2533
  ```
2477
2534
 
2478
- This will initialize a MemoryStore cache for LHC::Caching interceptor and resets the cache before every test.
2535
+ This e.g. will prevent running into caching issues during your tests, when (request cycle cache)[#request-cycle-cache] is enabled.
2536
+ It will initialize a MemoryStore cache for LHC::Caching interceptor and resets the cache before every test.
2537
+
2538
+ #### Stub
2539
+
2540
+ LHS offers stub helpers that simplify stubbing https request to your apis.
2541
+
2542
+ ##### Stub All
2543
+
2544
+ `LHS.stub.all(url, items, additional_options)`
2545
+
2546
+ ```ruby
2547
+ # your_spec.rb
2548
+
2549
+ before do
2550
+ LHS.stub.all(
2551
+ 'https://records',
2552
+ 200.times.map{ |index| { name: "Item #{index}" } },
2553
+ headers: {
2554
+ 'Authorization' => 'Bearer 123'
2555
+ }
2556
+ )
2557
+ end
2558
+ ```
2559
+ ```
2560
+ GET https://records?limit=100
2561
+ GET https://records?limit=100&offset=100
2562
+ ```
2479
2563
 
2480
2564
  ### Test query chains
2481
2565
 
data/lhs.gemspec CHANGED
@@ -28,9 +28,11 @@ Gem::Specification.new do |s|
28
28
 
29
29
  s.add_development_dependency 'capybara'
30
30
  s.add_development_dependency 'json', '>= 1.8.2'
31
+ s.add_development_dependency 'local_uri'
31
32
  s.add_development_dependency 'pry'
32
33
  s.add_development_dependency 'pry-byebug'
33
34
  s.add_development_dependency 'rails', '>= 4.2.11'
35
+ s.add_development_dependency 'rollbar'
34
36
  s.add_development_dependency 'rspec-rails', '>= 3.7.0'
35
37
  s.add_development_dependency 'rubocop', '~> 0.57.1'
36
38
  s.add_development_dependency 'rubocop-rspec', '~> 1.26.0'
data/lib/lhs.rb CHANGED
@@ -15,10 +15,28 @@ module LHS
15
15
  'lhs/config'
16
16
  autoload :Data,
17
17
  'lhs/data'
18
+ autoload :ExtendedRollbar,
19
+ 'lhs/interceptors/extended_rollbar/interceptor'
18
20
  autoload :Endpoint,
19
21
  'lhs/endpoint'
20
22
  autoload :Inspect,
21
23
  'lhs/concerns/inspect'
24
+ module Interceptors
25
+ module RequestCycleCache
26
+ autoload :ThreadRegistry,
27
+ 'lhs/interceptors/request_cycle_cache/thread_registry'
28
+ autoload :Interceptor,
29
+ 'lhs/interceptors/request_cycle_cache/interceptor'
30
+ end
31
+ module ExtendedRollbar
32
+ autoload :ThreadRegistry,
33
+ 'lhs/interceptors/extended_rollbar/thread_registry'
34
+ autoload :Interceptor,
35
+ 'lhs/interceptors/extended_rollbar/interceptor'
36
+ autoload :Handler,
37
+ 'lhs/interceptors/extended_rollbar/handler'
38
+ end
39
+ end
22
40
  autoload :IsHref,
23
41
  'lhs/concerns/is_href'
24
42
  autoload :Item,
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support'
4
+ require 'active_support/per_thread_registry'
4
5
 
5
6
  module LHS
6
7
  module OptionBlocks
@@ -8,7 +9,7 @@ module LHS
8
9
 
9
10
  class CurrentOptionBlock
10
11
  # Using ActiveSupports PerThreadRegistry to be able to support Active Support v4.
11
- # Will switch to thread_mattr_accessor (which comes with Activesupport) when we dropping support for Active Support v5.
12
+ # Will switch to thread_mattr_accessor (which comes with Activesupport) when we dropping support for Active Support v4.
12
13
  extend ActiveSupport::PerThreadRegistry
13
14
  attr_accessor :options
14
15
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+
5
+ class LHS::Record
6
+
7
+ module HrefFor
8
+ extend ActiveSupport::Concern
9
+
10
+ module ClassMethods
11
+ def href_for(args = nil)
12
+ return unless [Integer, String].include?(args.class)
13
+ params = { id: args }
14
+ find_endpoint(params).compile(params)
15
+ end
16
+ alias url_for href_for
17
+ end
18
+ end
19
+ end
@@ -509,16 +509,16 @@ class LHS::Record
509
509
  options
510
510
  end
511
511
 
512
- # Injects options into request, that enable the LHS::Record::RequestCycleCache::Interceptor
512
+ # Injects options into request, that enable the request cycle cache interceptor
513
513
  def inject_request_cycle_cache!(options)
514
514
  return unless LHS.config.request_cycle_cache_enabled
515
515
  interceptors = options[:interceptors] || LHC.config.interceptors
516
516
  if interceptors.include?(LHC::Caching)
517
- # Ensure LHS::RequestCycleCache interceptor is prepend
518
- interceptors = interceptors.unshift(LHS::Record::RequestCycleCache::Interceptor)
517
+ # Ensure interceptor is prepend
518
+ interceptors = interceptors.unshift(LHS::Interceptors::RequestCycleCache::Interceptor)
519
519
  options[:interceptors] = interceptors
520
520
  else
521
- warn("[WARNING] Can't enable LHS::RequestCycleCache as LHC::Caching interceptor is not enabled/configured (see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor)!")
521
+ warn("[WARNING] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured (see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor)!")
522
522
  end
523
523
  end
524
524
 
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LHS
4
+ module Interceptors
5
+ module ExtendedRollbar
6
+ class Handler
7
+
8
+ def self.init
9
+ proc do |options|
10
+ # as handlers cant influence what actually is reported to rollbar
11
+ # this just makes sure that Rollbar is already loaded when this class is loaded,
12
+ # so that we can extend rollbar loging
13
+ end
14
+ end
15
+
16
+ module ExtendedLogging
17
+ def log(level, *args)
18
+ args[2] = {} if args[2].nil?
19
+ args[2][:lhs] = LHS::Interceptors::ExtendedRollbar::ThreadRegistry.log.map do |entry|
20
+ {
21
+ request: entry[:request].options,
22
+ response: {
23
+ code: entry[:response].code,
24
+ body: entry[:response].body
25
+ }
26
+ }
27
+ end.to_json
28
+ super
29
+ end
30
+ end
31
+
32
+ module ::Rollbar
33
+ class Notifier
34
+ prepend LHS::Interceptors::ExtendedRollbar::Handler::ExtendedLogging
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+
5
+ module LHS
6
+ module Interceptors
7
+ module ExtendedRollbar
8
+ extend ActiveSupport::Concern
9
+
10
+ class Interceptor < LHC::Interceptor
11
+ def after_response
12
+ return unless LHS::Interceptors::ExtendedRollbar::ThreadRegistry.log
13
+ LHS::Interceptors::ExtendedRollbar::ThreadRegistry.log.push(request: request, response: response)
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ const_set('ExtendedRollbar', LHS::Interceptors::ExtendedRollbar::Interceptor)
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/per_thread_registry'
5
+
6
+ module LHS
7
+ module Interceptors
8
+ module ExtendedRollbar
9
+ extend ActiveSupport::Concern
10
+
11
+ class ThreadRegistry
12
+ # Using ActiveSupports PerThreadRegistry to be able to support Active Support v4.
13
+ # Will switch to thread_mattr_accessor (which comes with Activesupport) when we dropping support for Active Support v4.
14
+ extend ActiveSupport::PerThreadRegistry
15
+ attr_accessor :log
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+
5
+ module LHS
6
+ module Interceptors
7
+ module RequestCycleCache
8
+ extend ActiveSupport::Concern
9
+
10
+ class Interceptor < LHC::Interceptor
11
+
12
+ VERSION = 1
13
+ CACHED_METHODS = [:get].freeze
14
+
15
+ def before_request
16
+ request.options = {
17
+ cache: {
18
+ expires_in: 5.minutes,
19
+ race_condition_ttl: 5.seconds,
20
+ key: cache_key_for(request),
21
+ methods: CACHED_METHODS,
22
+ use: LHS.config.request_cycle_cache
23
+ }
24
+ }.merge(request.options)
25
+ end
26
+
27
+ private
28
+
29
+ def cache_key_for(request)
30
+ [
31
+ "LHS_REQUEST_CYCLE_CACHE(v#{VERSION})",
32
+ request.method.upcase,
33
+ [request.url, request.params.presence].compact.join('?'),
34
+ "REQUEST=#{LHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id}",
35
+ "HEADERS=#{request.headers.hash}"
36
+ ].join(' ')
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/per_thread_registry'
5
+
6
+ module LHS
7
+ module Interceptors
8
+ module RequestCycleCache
9
+ extend ActiveSupport::Concern
10
+ class ThreadRegistry
11
+ # Using ActiveSupports PerThreadRegistry to be able to support Active Support v4.
12
+ # Will switch to thread_mattr_accessor (which comes with Activesupport) when we dropping support for Active Support v4.
13
+ extend ActiveSupport::PerThreadRegistry
14
+ attr_accessor :request_id
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/lhs/railtie.rb CHANGED
@@ -8,6 +8,7 @@ module LHS
8
8
  def initialize
9
9
  prepare_lhs_request_cycle_cache
10
10
  reset_option_blocks
11
+ reset_extended_rollbar_request_logs
11
12
  super
12
13
  end
13
14
 
@@ -15,12 +16,18 @@ module LHS
15
16
 
16
17
  def prepare_lhs_request_cycle_cache
17
18
  return unless LHS.config.request_cycle_cache_enabled
18
- LHS::Record::RequestCycleCache::RequestCycleThreadRegistry.request_id = [Time.now.to_f, request.object_id].join('#')
19
+ LHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id = [Time.now.to_f, request.object_id].join('#')
19
20
  end
20
21
 
21
22
  def reset_option_blocks
22
23
  LHS::OptionBlocks::CurrentOptionBlock.options = nil
23
24
  end
25
+
26
+ def reset_extended_rollbar_request_logs
27
+ return unless defined?(::Rollbar)
28
+ return unless LHC.config.interceptors.include?(LHS::Interceptors::ExtendedRollbar::Interceptor)
29
+ LHS::Interceptors::ExtendedRollbar::ThreadRegistry.log = []
30
+ end
24
31
  end
25
32
  end
26
33
  end
data/lib/lhs/record.rb CHANGED
@@ -23,6 +23,8 @@ class LHS::Record
23
23
  'lhs/concerns/record/find_by'
24
24
  autoload :First,
25
25
  'lhs/concerns/record/first'
26
+ autoload :HrefFor,
27
+ 'lhs/concerns/record/href_for'
26
28
  autoload :Last,
27
29
  'lhs/concerns/record/last'
28
30
  autoload :Mapping,
@@ -46,13 +48,6 @@ class LHS::Record
46
48
  autoload :AttributeAssignment,
47
49
  'lhs/concerns/record/attribute_assignment'
48
50
 
49
- module RequestCycleCache
50
- autoload :RequestCycleThreadRegistry,
51
- 'lhs/concerns/record/request_cycle_cache/request_cycle_thread_registry'
52
- autoload :Interceptor,
53
- 'lhs/concerns/record/request_cycle_cache/interceptor'
54
- end
55
-
56
51
  include Batch
57
52
  include Chainable
58
53
  include Configuration
@@ -64,6 +59,7 @@ class LHS::Record
64
59
  include Find
65
60
  include FindBy
66
61
  include First
62
+ include HrefFor
67
63
  include LHS::IsHref
68
64
  include Last
69
65
  include LHS::Inspect
@@ -74,7 +70,6 @@ class LHS::Record
74
70
  include Provider
75
71
  include Request
76
72
  include Relations
77
- include RequestCycleCache
78
73
  include Scope
79
74
  include Tracing
80
75
  include AttributeAssignment
data/lib/lhs/rspec.rb ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lhs'
4
+ require 'lhs/test/stub'
5
+
6
+ RSpec.configure do |config|
7
+ config.before(:each) do
8
+ LHS.config.request_cycle_cache.clear
9
+ end
10
+
11
+ config.before(:all) do
12
+
13
+ module LHS
14
+ def self.stub
15
+ LHS::Test::Stub
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'local_uri'
4
+ require 'webmock'
5
+ module LHS
6
+ module Test
7
+ class Stub
8
+ extend WebMock::API
9
+ DEFAULT_LIMIT = LHS::Pagination::Base::DEFAULT_LIMIT
10
+
11
+ def self.all(url, items, options = {})
12
+ items.each_slice(DEFAULT_LIMIT).with_index do |(*batch), index|
13
+ uri = LocalUri::URI.new(url)
14
+ uri.query.merge!(limit: DEFAULT_LIMIT)
15
+ uri.query.merge!(offset: DEFAULT_LIMIT * index) unless index.zero?
16
+ stub_request(:get, uri.to_s)
17
+ .with(options)
18
+ .to_return(
19
+ body: {
20
+ items: batch,
21
+ offset: index * DEFAULT_LIMIT,
22
+ total: items.length
23
+ }.to_json
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
data/lib/lhs/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LHS
4
- VERSION = '19.8.2'
4
+ VERSION = '20.1.2'
5
5
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ExtendedRollbarController < ApplicationController
4
+
5
+ def extended_rollbar
6
+ Record.where(color: 'blue').fetch
7
+ Record.where(color: 'red').fetch
8
+ raise "Let's see if rollbar logs information about what kind of requests where made around here!"
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ if defined?(Rollbar)
4
+ Rollbar.configure do |config|
5
+ config.access_token = '12345'
6
+ config.enabled = true
7
+ config.before_process << LHS::Interceptors::ExtendedRollbar::Handler.init
8
+ end
9
+ end
@@ -16,4 +16,7 @@ Rails.application.routes.draw do
16
16
  # Option Blocks
17
17
  get 'option_blocks/first' => 'option_blocks#first'
18
18
  get 'option_blocks/second' => 'option_blocks#second'
19
+
20
+ # Extended Rollbar
21
+ get 'extended_rollbar' => 'extended_rollbar#extended_rollbar'
19
22
  end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe 'Extended Rollbar', type: :request do
6
+ let!(:records_request_1) do
7
+ stub_request(:get, "http://datastore/v2/records?color=blue").to_return(body: ['blue'].to_json)
8
+ end
9
+
10
+ let!(:records_request_2) do
11
+ stub_request(:get, "http://datastore/v2/records?color=red").to_return(body: ['red'].to_json)
12
+ end
13
+
14
+ let!(:rollbar_request) do
15
+ stub_request(:post, "https://api.rollbar.com/api/1/item/")
16
+ .with do |request|
17
+ json = JSON.parse request.body
18
+ message = "Let's see if rollbar logs information about what kind of requests where made around here!"
19
+ extra = {
20
+ lhs: [
21
+ {
22
+ request: {
23
+ params: { color: 'blue' },
24
+ url: 'http://datastore/v2/records',
25
+ headers: {
26
+ 'Content-Type' => 'application/json; charset=utf-8',
27
+ 'Accept' => 'application/json,application/vnd.api+json',
28
+ 'Accept-Charset' => 'utf-8'
29
+ }
30
+ },
31
+ response: { code: 200, body: '["blue"]' }
32
+ }, {
33
+ request: {
34
+ params: { color: 'red' },
35
+ url: 'http://datastore/v2/records',
36
+ headers: {
37
+ 'Content-Type' => 'application/json; charset=utf-8',
38
+ 'Accept' => 'application/json,application/vnd.api+json',
39
+ 'Accept-Charset' => 'utf-8'
40
+ }
41
+ },
42
+ response: { code: 200, body: '["red"]' }
43
+ }
44
+ ].to_json
45
+ }
46
+ json['access_token'] == '12345' &&
47
+ json['data']['level'] == 'error' &&
48
+ json['data']['body']['trace']['exception']['message'] == message &&
49
+ json['data']['body']['trace']['extra'].to_json == extra.to_json
50
+ end
51
+ .to_return(status: 200)
52
+ end
53
+
54
+ before do
55
+ LHC.configure do |config|
56
+ config.interceptors = [LHS::ExtendedRollbar]
57
+ end
58
+ end
59
+
60
+ it 'extends default rollbar logging by adding information about the requests made during a request/response cycle',
61
+ dummy_models: true, extended_rollbar: true do
62
+ get '/extended_rollbar'
63
+ expect(records_request_1).to have_been_requested
64
+ expect(records_request_2).to have_been_requested
65
+ expect(rollbar_request).to have_been_requested
66
+ end
67
+ end
data/spec/rails_helper.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  ENV["RAILS_ENV"] ||= 'test'
4
+ ENV['DUMMYAPP_PATH'] = "spec/dummy"
4
5
 
6
+ require 'rails/rollbar_runner'
5
7
  require 'spec_helper'
6
8
  require File.expand_path("../dummy/config/environment", __FILE__)
7
9
  require 'rspec/rails'
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ before do
7
+ class Record < LHS::Record
8
+ endpoint 'http://datastore/records/'
9
+ endpoint 'http://datastore/records/{id}'
10
+ end
11
+ end
12
+
13
+ context 'href_for' do
14
+
15
+ it 'injects variables and returns href' do
16
+ expect(Record.href_for(1)).to eq 'http://datastore/records/1'
17
+ expect(Record.href_for('vmasd241')).to eq 'http://datastore/records/vmasd241'
18
+ end
19
+
20
+ it 'also works with url_for (alias)' do
21
+ expect(Record.url_for(1)).to eq 'http://datastore/records/1'
22
+ expect(Record.url_for('vmasd241')).to eq 'http://datastore/records/vmasd241'
23
+ end
24
+ end
25
+ end
@@ -37,7 +37,7 @@ describe 'Request Cycle Cache', type: :request do
37
37
  expect(lambda do
38
38
  get '/request_cycle_cache/no_caching_interceptor'
39
39
  end).to output(
40
- %r{\[WARNING\] Can't enable LHS::RequestCycleCache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor\)!}
40
+ %r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor\)!}
41
41
  ).to_stderr
42
42
  expect(request).to have_been_made.times(2)
43
43
  end
@@ -52,11 +52,11 @@ describe 'Request Cycle Cache', type: :request do
52
52
  it 'sets different uniq request ids as base for request cycle caching for different requests',
53
53
  dummy_models: true, request_cycle_cache: true do
54
54
  get '/request_cycle_cache/simple'
55
- first_request_id = LHS::Record::RequestCycleCache::RequestCycleThreadRegistry.request_id
55
+ first_request_id = LHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id
56
56
  second_request_id = nil
57
57
  thread = Thread.new do
58
58
  get '/request_cycle_cache/simple'
59
- second_request_id = LHS::Record::RequestCycleCache::RequestCycleThreadRegistry.request_id
59
+ second_request_id = LHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id
60
60
  end
61
61
  thread.join
62
62
  expect(first_request_id).not_to be_nil
@@ -70,7 +70,7 @@ describe 'Request Cycle Cache', type: :request do
70
70
  expect(lambda do
71
71
  get '/request_cycle_cache/no_caching_interceptor'
72
72
  end).not_to output(
73
- %r{\[WARNING\] Can't enable LHS::RequestCycleCache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor\)!}
73
+ %r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor\)!}
74
74
  ).to_stderr
75
75
  expect(request).to have_been_made.times(2)
76
76
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+ require 'lhs/rspec'
5
+
6
+ describe LHS do
7
+
8
+ before do
9
+ class Record < LHS::Record
10
+ endpoint 'https://records'
11
+ end
12
+
13
+ LHS.stub.all(
14
+ 'https://records',
15
+ 200.times.map { |index| { name: "Item #{index}" } },
16
+ headers: {
17
+ 'Authorization' => 'Bearer 123'
18
+ }
19
+ )
20
+ end
21
+
22
+ it 'stubs all requests' do
23
+ records = Record.options(headers: { 'Authorization' => 'Bearer 123' }).all.fetch
24
+ expect(records.count).to eq 200
25
+ expect(records.length).to eq 200
26
+ expect(records.first.name).to eq 'Item 0'
27
+ end
28
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lhs
3
3
  version: !ruby/object:Gem::Version
4
- version: 19.8.2
4
+ version: 20.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - https://github.com/local-ch/lhs/graphs/contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-25 00:00:00.000000000 Z
11
+ date: 2019-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 1.8.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: local_uri
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: pry
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +136,20 @@ dependencies:
122
136
  - - ">="
123
137
  - !ruby/object:Gem::Version
124
138
  version: 4.2.11
139
+ - !ruby/object:Gem::Dependency
140
+ name: rollbar
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
125
153
  - !ruby/object:Gem::Dependency
126
154
  name: rspec-rails
127
155
  requirement: !ruby/object:Gem::Requirement
@@ -252,6 +280,7 @@ files:
252
280
  - lib/lhs/concerns/record/find.rb
253
281
  - lib/lhs/concerns/record/find_by.rb
254
282
  - lib/lhs/concerns/record/first.rb
283
+ - lib/lhs/concerns/record/href_for.rb
255
284
  - lib/lhs/concerns/record/last.rb
256
285
  - lib/lhs/concerns/record/mapping.rb
257
286
  - lib/lhs/concerns/record/merge.rb
@@ -260,13 +289,16 @@ files:
260
289
  - lib/lhs/concerns/record/provider.rb
261
290
  - lib/lhs/concerns/record/relations.rb
262
291
  - lib/lhs/concerns/record/request.rb
263
- - lib/lhs/concerns/record/request_cycle_cache/interceptor.rb
264
- - lib/lhs/concerns/record/request_cycle_cache/request_cycle_thread_registry.rb
265
292
  - lib/lhs/concerns/record/scope.rb
266
293
  - lib/lhs/concerns/record/tracing.rb
267
294
  - lib/lhs/config.rb
268
295
  - lib/lhs/data.rb
269
296
  - lib/lhs/endpoint.rb
297
+ - lib/lhs/interceptors/extended_rollbar/handler.rb
298
+ - lib/lhs/interceptors/extended_rollbar/interceptor.rb
299
+ - lib/lhs/interceptors/extended_rollbar/thread_registry.rb
300
+ - lib/lhs/interceptors/request_cycle_cache/interceptor.rb
301
+ - lib/lhs/interceptors/request_cycle_cache/thread_registry.rb
270
302
  - lib/lhs/item.rb
271
303
  - lib/lhs/pagination/base.rb
272
304
  - lib/lhs/pagination/link.rb
@@ -282,7 +314,8 @@ files:
282
314
  - lib/lhs/proxy.rb
283
315
  - lib/lhs/railtie.rb
284
316
  - lib/lhs/record.rb
285
- - lib/lhs/test/request_cycle_cache_helper.rb
317
+ - lib/lhs/rspec.rb
318
+ - lib/lhs/test/stub.rb
286
319
  - lib/lhs/unprocessable.rb
287
320
  - lib/lhs/version.rb
288
321
  - script/ci/build.sh
@@ -321,6 +354,7 @@ files:
321
354
  - spec/dummy/app/controllers/application_controller.rb
322
355
  - spec/dummy/app/controllers/concerns/.keep
323
356
  - spec/dummy/app/controllers/error_handling_with_chains_controller.rb
357
+ - spec/dummy/app/controllers/extended_rollbar_controller.rb
324
358
  - spec/dummy/app/controllers/option_blocks_controller.rb
325
359
  - spec/dummy/app/controllers/request_cycle_cache_controller.rb
326
360
  - spec/dummy/app/helpers/application_helper.rb
@@ -349,6 +383,7 @@ files:
349
383
  - spec/dummy/config/initializers/filter_parameter_logging.rb
350
384
  - spec/dummy/config/initializers/inflections.rb
351
385
  - spec/dummy/config/initializers/mime_types.rb
386
+ - spec/dummy/config/initializers/rollbar.rb
352
387
  - spec/dummy/config/initializers/session_store.rb
353
388
  - spec/dummy/config/initializers/wrap_parameters.rb
354
389
  - spec/dummy/config/locales/en.yml
@@ -361,6 +396,7 @@ files:
361
396
  - spec/dummy/public/500.html
362
397
  - spec/dummy/public/favicon.ico
363
398
  - spec/endpoint/for_url_spec.rb
399
+ - spec/extended_rollbar_spec.rb
364
400
  - spec/item/access_errors_spec.rb
365
401
  - spec/item/accessors_spec.rb
366
402
  - spec/item/add_error_spec.rb
@@ -427,6 +463,7 @@ files:
427
463
  - spec/record/handle_includes_errors_spec.rb
428
464
  - spec/record/has_many_spec.rb
429
465
  - spec/record/has_one_spec.rb
466
+ - spec/record/href_for_spec.rb
430
467
  - spec/record/ignore_errors_spec.rb
431
468
  - spec/record/immutable_chains_spec.rb
432
469
  - spec/record/includes_all_spec.rb
@@ -465,6 +502,7 @@ files:
465
502
  - spec/request_cycle_cache_spec.rb
466
503
  - spec/require_lhs_spec.rb
467
504
  - spec/spec_helper.rb
505
+ - spec/stubs/all_spec.rb
468
506
  - spec/support/fixtures/json/feedback.json
469
507
  - spec/support/fixtures/json/feedbacks.json
470
508
  - spec/support/fixtures/json/localina_content_ad.json
@@ -492,8 +530,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
492
530
  version: '0'
493
531
  requirements:
494
532
  - Ruby >= 2.3.0
495
- rubyforge_project:
496
- rubygems_version: 2.7.8
533
+ rubygems_version: 3.0.3
497
534
  signing_key:
498
535
  specification_version: 4
499
536
  summary: 'REST services accelerator: Rails gem providing an easy, active-record-like
@@ -533,6 +570,7 @@ test_files:
533
570
  - spec/dummy/app/controllers/application_controller.rb
534
571
  - spec/dummy/app/controllers/concerns/.keep
535
572
  - spec/dummy/app/controllers/error_handling_with_chains_controller.rb
573
+ - spec/dummy/app/controllers/extended_rollbar_controller.rb
536
574
  - spec/dummy/app/controllers/option_blocks_controller.rb
537
575
  - spec/dummy/app/controllers/request_cycle_cache_controller.rb
538
576
  - spec/dummy/app/helpers/application_helper.rb
@@ -561,6 +599,7 @@ test_files:
561
599
  - spec/dummy/config/initializers/filter_parameter_logging.rb
562
600
  - spec/dummy/config/initializers/inflections.rb
563
601
  - spec/dummy/config/initializers/mime_types.rb
602
+ - spec/dummy/config/initializers/rollbar.rb
564
603
  - spec/dummy/config/initializers/session_store.rb
565
604
  - spec/dummy/config/initializers/wrap_parameters.rb
566
605
  - spec/dummy/config/locales/en.yml
@@ -573,6 +612,7 @@ test_files:
573
612
  - spec/dummy/public/500.html
574
613
  - spec/dummy/public/favicon.ico
575
614
  - spec/endpoint/for_url_spec.rb
615
+ - spec/extended_rollbar_spec.rb
576
616
  - spec/item/access_errors_spec.rb
577
617
  - spec/item/accessors_spec.rb
578
618
  - spec/item/add_error_spec.rb
@@ -639,6 +679,7 @@ test_files:
639
679
  - spec/record/handle_includes_errors_spec.rb
640
680
  - spec/record/has_many_spec.rb
641
681
  - spec/record/has_one_spec.rb
682
+ - spec/record/href_for_spec.rb
642
683
  - spec/record/ignore_errors_spec.rb
643
684
  - spec/record/immutable_chains_spec.rb
644
685
  - spec/record/includes_all_spec.rb
@@ -677,6 +718,7 @@ test_files:
677
718
  - spec/request_cycle_cache_spec.rb
678
719
  - spec/require_lhs_spec.rb
679
720
  - spec/spec_helper.rb
721
+ - spec/stubs/all_spec.rb
680
722
  - spec/support/fixtures/json/feedback.json
681
723
  - spec/support/fixtures/json/feedbacks.json
682
724
  - spec/support/fixtures/json/localina_content_ad.json
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support'
4
-
5
- class LHS::Record
6
-
7
- module RequestCycleCache
8
- extend ActiveSupport::Concern
9
-
10
- class Interceptor < LHC::Interceptor
11
-
12
- VERSION = 1
13
- CACHED_METHODS = [:get].freeze
14
-
15
- def before_request
16
- request.options = request.options.merge({
17
- cache: {
18
- expires_in: 5.minutes,
19
- race_condition_ttl: 5.seconds,
20
- key: cache_key_for(request),
21
- methods: CACHED_METHODS,
22
- use: LHS.config.request_cycle_cache
23
- }
24
- }.merge(request.options))
25
- end
26
-
27
- private
28
-
29
- def cache_key_for(request)
30
- [
31
- "LHS_REQUEST_CYCLE_CACHE(v#{VERSION})",
32
- request.method.upcase,
33
- [request.url, request.params.presence].compact.join('?'),
34
- "REQUEST=#{LHS::Record::RequestCycleCache::RequestCycleThreadRegistry.request_id}",
35
- "HEADERS=#{request.headers.hash}"
36
- ].join(' ')
37
- end
38
- end
39
- end
40
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support'
4
-
5
- class LHS::Record
6
-
7
- module RequestCycleCache
8
- class RequestCycleThreadRegistry
9
- # Using ActiveSupports PerThreadRegistry to be able to support Active Support v4.
10
- # Will switch to thread_mattr_accessor (which comes with Activesupport) when we dropping support for Active Support v5.
11
- extend ActiveSupport::PerThreadRegistry
12
- attr_accessor :request_id
13
- end
14
- end
15
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.configure do |config|
4
- config.before(:each) do
5
- LHS.config.request_cycle_cache.clear
6
- end
7
- end