oesmith / puffing-billy

A rewriting web proxy for testing interactions between your browser and external sites. Works with ruby + rspec.
MIT License
656 stars 170 forks source link

New requests being recorded on each run #297

Closed codemang closed 4 years ago

codemang commented 4 years ago

I'm testing a Rails backend and React frontend app. We're using the Stripe React library and trying to use PuffingBilly to record the requests between our frontend and the stripe backend.

I'm noticing that each time we run the specs, we have new requests being recorded. I believe this is because our spec is not ignoring parameters in the requests correctly, even though I configured PuffingBilly to do so.

As an example, here is a request that gets recorded on the first spec run:

---
:scope: 
:url: https://m.stripe.com/4
:body: JTdCJTIydjIlMjIlM0EyJTJDJTIyaWQlMjIlM0ElMjJjMDM1Y2NlZjYyM2M4YWIyNjYyMzcwZDVhZGQ2Yzg3ZiUyMiUyQyUyMnQlMjIlM0EzNy43NDUlMkMlMjJ0YWclMjIlM0ElMjI0LjUuMjclMjIlMkMlMjJzcmMlMjIlM0ElMjJqcyUyMiUyQyUyMmElMjIlM0ElN0IlMjJhJTIyJTNBJTdCJTIydiUyMiUzQSUyMnRydWUlMjIlMkMlMjJ0JTIyJTNBMC44NjUlN0QlMkMlMjJiJTIyJTNBJTdCJTIydiUyMiUzQSUyMmZhbHNlJTIyJTJDJTIydCUyMiUzQTAuMDQlN0QlMkMlMjJjJTIyJTNBJTdCJTIydiUyMiUzQSUyMmVuLVVTJTIyJTJDJTIydCUyMiUzQTAuMDQ1JTdEJTJDJTIyZCUyMiUzQSU3QiUyMnYlMjIlM0ElMjJMaW51eCUyMHg4Nl82NCUyMiUyQyUyMnQlMjIlM0EwLjAzJTdEJTJDJTIyZSUyMiUzQSU3QiUyMnYlMjIlM0ElMjIlMjIlMkMlMjJ0JTIyJTNBMC4wNCU3RCUyQyUyMmYlMjIlM0ElN0IlMjJ2JTIyJTNBJTIyMTI4MHdfNzIwaF8yNGRfMXIlMjIlMkMlMjJ0JTIyJTNBMC4wMzUlN0QlMkMlMjJnJTIyJTNBJTdCJTIydiUyMiUzQSUyMjAlMjIlMkMlMjJ0JTIyJTNBMC4wMzUlN0QlMkMlMjJoJTIyJTNBJTdCJTIydiUyMiUzQSUyMmZhbHNlJTIyJTJDJTIydCUyMiUzQTAuMDM1JTdEJTJDJTIyaSUyMiUzQSU3QiUyMnYlMjIlM0ElMjJzZXNzaW9uU3RvcmFnZS1lbmFibGVkJTJDJTIwbG9jYWxTdG9yYWdlLWVuYWJsZWQlMjIlMkMlMjJ0JTIyJTNBMC4yNSU3RCUyQyUyMmolMjIlM0ElN0IlMjJ2JTIyJTNBJTIyMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDExMDAwMCUyMiUyQyUyMnQlMjIlM0EzNS4xMSUyQyUyMmF0JTIyJTNBMC4zNTUlN0QlMkMlMjJrJTIyJTNBJTdCJTIydiUyMiUzQSUyMiUyMiUyQyUyMnQlMjIlM0EwLjAyNSU3RCUyQyUyMmwlMjIlM0ElN0IlMjJ2JTIyJTNBJTIyTW96aWxsYSUyRjUuMCUyMChYMTElM0IlMjBMaW51eCUyMHg4Nl82NCklMjBBcHBsZVdlYktpdCUyRjUzNy4zNiUyMChLSFRNTCUyQyUyMGxpa2UlMjBHZWNrbyklMjBIZWFkbGVzc0Nocm9tZSUyRjc4LjAuMzkwNC43MCUyMFNhZmFyaSUyRjUzNy4zNiUyMiUyQyUyMnQlMjIlM0EwLjA1NSU3RCUyQyUyMm0lMjIlM0ElN0IlMjJ2JTIyJTNBJTIyJTIyJTJDJTIydCUyMiUzQTAuMDQ1JTdEJTJDJTIybiUyMiUzQSU3QiUyMnYlMjIlM0ElMjJmYWxzZSUyMiUyQyUyMnQlMjIlM0EzNC41NCUyQyUyMmF0JTIyJTNBMC4wMjUlN0QlMkMlMjJvJTIyJTNBJTdCJTIydiUyMiUzQSUyMjk5MWQ3Yjk5YzkwMWI2Nzk0NzY2M2NhZjcwNzhiYWI0JTIyJTJDJTIydCUyMiUzQTMzLjY4JTdEJTdEJTJDJTIyYiUyMiUzQSU3QiUyMmElMjIlM0ElMjIlMjIlMkMlMjJiJTIyJTNBJTIyaHR0cCUzQSUyRiUyRjEyNy4wLjAuMSUzQTQxNDk1JTJGY3JlZGl0LWNhcmQtZm9ybS1kZW1vJTIyJTJDJTIyYyUyMiUzQSUyMk5ldyUyMFdhdmUlMjBCb3N0b24lMjBSZWFsJTIwRXN0YXRlJTIyJTJDJTIyZCUyMiUzQSUyMjhjOTM3Y2M5LWE3NDMtNGEwNS04NGEzLTMwODIxYWI5YTUwZiUyMiUyQyUyMmUlMjIlM0ElMjIzMDVkMmQyMi1iYjJkLTQ1NTgtOGI2Zi1jZmJiZjlkNGU4ZWMlMjIlMkMlMjJmJTIyJTNBZmFsc2UlMkMlMjJnJTIyJTNBdHJ1ZSUyQyUyMmglMjIlM0F0cnVlJTJDJTIyaSUyMiUzQSU1QiUyMmxvY2F0aW9uJTIyJTVEJTJDJTIyaiUyMiUzQSU1QiU1RCUyQyUyMm4lMjIlM0E2MDIuNzk5OTk5OTkzMjk0NSU3RCU3RA==
:status: 200
:method: post
:headers:
  Server: nginx
  Date: Tue, 14 Jul 2020 01:21:10 GMT
  Content-Type: text/plain;charset=utf-8
  Content-Length: '36'
  Connection: close
  Vary: Accept-Encoding
  Set-Cookie: m=1bd5c200-e5d9-4f60-b027-99280743aa4b;Expires=Thu, 14-Jul-2022 01:21:10
    GMT;Secure;HttpOnly; SameSite=None
  X-Content-Type-Options: nosniff
  Access-Control-Allow-Origin: https://m.stripe.network
  Access-Control-Allow-Credentials: 'true'
  Access-Control-Allow-Headers: Content-Type
  Strict-Transport-Security: max-age=31556926; includeSubDomains; preload
:content: 1bd5c200-e5d9-4f60-b027-99280743aa4b

When I run it a second time, it records a new request that looks like this:

:scope: 
:url: https://m.stripe.com/4
:body: JTdCJTIybXVpZCUyMiUzQSUyMjkzNzBkOTNjLWE4YzMtNDkzZi04NzY5LWU3NmJkM2Q3NTNlNiUyMiUyQyUyMnNpZCUyMiUzQSUyMmI2NGZkNWFkLTJmMGUtNDY1MS1iNGZjLTM2NTNiYjhmZDIxNiUyMiUyQyUyMnVybCUyMiUzQSUyMmh0dHAlM0ElMkYlMkYxMjcuMC4wLjElM0EzNTc2NSUyRmNyZWRpdC1jYXJkLWZvcm0tZGVtbyUyMiUyQyUyMnNvdXJjZSUyMiUzQSUyMm1vdXNlLXRpbWluZ3MtMTAtdjIlMjIlMkMlMjJkYXRhJTIyJTNBJTVCJTVEJTdE
:status: 200
:method: post
:headers:
  Server: nginx
  Date: Tue, 14 Jul 2020 01:21:10 GMT
  Content-Type: text/plain;charset=utf-8
  Content-Length: '36'
  Connection: close
  Vary: Accept-Encoding
  Set-Cookie: m=1bd5c200-e5d9-4f60-b027-99280743aa4b;Expires=Thu, 14-Jul-2022 01:21:10
    GMT;Secure;HttpOnly; SameSite=None
  X-Content-Type-Options: nosniff
  Access-Control-Allow-Origin: https://m.stripe.network
  Access-Control-Allow-Credentials: 'true'
  Access-Control-Allow-Headers: Content-Type
  Strict-Transport-Security: max-age=31556926; includeSubDomains; preload
:content: 1bd5c200-e5d9-4f60-b027-99280743aa4b

It looks as if the only thing that's different is the body field. Is there any way to ignore that?

Here is my config:

Billy.configure do |c|
  c.cache = true
  c.persist_cache = true
  c.cache_request_headers = false
  c.use_ignore_params = true

  c.ignore_params = ["http://www.google-analytics.com/", "http://192.168.8.141/sockjs-node", "https://m.stripe.com"]
  c.path_blacklist = ["http://www.google-analytics.com/", "http://192.168.8.141/sockjs-node", "https://m.stripe.com"]
  c.cache_path = 'spec/fixtures/billy/req_cache'
  c.certs_path = 'spec/fixtures/billy/req_certs'
end
codemang commented 4 years ago

Actually looking through the docs more, I see there is a c.before_handle_request option, where you can mutate the body before it's saved to the cache. Is the pattern then to look through each request and identify attributes that can change slightly over time, and overwrite them with hardcoded, mock data?

ronwsmith commented 4 years ago

use_ignore_params is default true so you shouldn't need to define that.

Looks like you just need to add the path /4 to your ignore_params array. Give that a shot and report back.

codemang commented 4 years ago

My understanding of things have changed, I'm going to open a new question with more information.