diff --git a/module3/lessons/testing_tools_for_api_consumption.md b/module3/lessons/testing_tools_for_api_consumption.md index 19cc56e0..dddce394 100644 --- a/module3/lessons/testing_tools_for_api_consumption.md +++ b/module3/lessons/testing_tools_for_api_consumption.md @@ -27,7 +27,7 @@ Slides are available [here](https://github.com/turingschool/backend-curriculum-s [đź“ş Here is a walkthrough video to help you set up your Rails Application Credentials.](https://drive.google.com/file/d/1Cy598b1W1d7nZ-gv6ur_gPmAGOmaD3Gi/view?usp=sharing) -- [Request a Propublica API Key](https://www.propublica.org/datastore/api/propublica-congress-api) +- [Request a Congress.gov API Key](https://api.congress.gov/sign-up/) - Clone [the House Salad 7](https://github.com/turingschool-examples/house-salad-7/tree/testing-setup) - (forking is optional since we won't ask you to push up any changes) - In the `testing-setup` branch, run setup steps: @@ -39,10 +39,10 @@ rails db:{create, migrate} - If the following steps don't work, you'll need to follow [these 'Launching From the Command Line' steps](https://code.visualstudio.com/docs/setup/mac#:~:text=Keep%20in%20Dock.-,Launching%20from%20the%20command%20line,code) to configure the command - Generate what is called a 'master key' by running `EDITOR="code --wait" rails credentials:edit` in the command line - This will create a new key in `config/master.key` and a temporary YAML file which will open in your text editor. -- Add your Propublica API Key to the opened file +- Add your Congress API Key to the opened file ``` -propublica: +congress: key: asdsa3498serghjirteg978ertertwhter # Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies. @@ -75,7 +75,8 @@ Add in a new form to search for Senators: <%= form.submit 'Search' %> <% end %> <% if @member %> -
<%= image_tag @member[:depiction][:imageUrl] %>
<% end %> ``` @@ -85,27 +86,30 @@ And let’s add a search method for our search controller: ```ruby def search - conn = Faraday.new(url: "https://api.propublica.org") do |faraday| - faraday.headers["X-API-KEY"] = Rails.application.credentials.propublica[:key] - end - response = conn.get("/congress/v1/116/senate/members.json") + conn = Faraday.new(url: "https://api.congress.gov") do |faraday| + faraday.headers["X-API-Key"] = Rails.application.credentials.congress[:key] + end + + response = conn.get("/v3/member?limit=250") - data = JSON.parse(response.body, symbolize_names: true) + data = JSON.parse(response.body, symbolize_names: true) - members = data[:results][0][:members] + members = data[:members] - found_members = members.find_all {|m| m[:last_name] == params[:search]} - @member = found_members.first - render "welcome/index" + found_senators = members.find_all do |member| + senator = (member[:terms][:item][0][:chamber] == "Senate") + last_name = member[:name].split(' ')[0].gsub(',', '') + last_name == params[:search] && senator end + @member = found_senators.first + render "welcome/index" +end ``` For simplicity’s sake we aren’t going to use the refactored pattern, we are just going to leave all of the code in your controller. You can test this code is working correctly in the browser if you can find a Senator by last name. `@member` will be a hash of that Senator’s data. -Note: In order to future proof this lesson, this API is calling to get the results only for the 116th session of Congress, so you will likely not get good results searching for a Senator. For example, it will find a result if you search for say Sanders or Booker, but not Fetterman. - When it exists, we will grab some data from `@member` and display it on the welcome page We can test this functionality by adding a test called: `user_can_search_by_senator_last_name_spec.rb` This is what lives in that test file: @@ -124,8 +128,8 @@ RSpec.describe 'Senator Search' do click_button 'Search' expect(page.status_code).to eq 200 - expect(page).to have_content("Senator Bernard Sanders was found!") - expect(page).to have_content("SenSanders") + expect(page).to have_content('Sanders, Bernard was found!') + expect(page.find('.senator-image')['src']).to have_content('https://www.congress.gov/img/member/s000033_200.jpg') end end end @@ -135,7 +139,7 @@ end ## Mocking Network Requests -The [setup branch](https://github.com/turingschool-examples/house-salad-7/tree/testing-setup) for this class has implemented a test to ensure that we are able to hit our API and display some data from the response. However, our test is actually hitting the Propublica API every time it runs. There are many reasons we wouldn't want to do this: +The [setup branch](https://github.com/turingschool-examples/house-salad-7/tree/testing-setup) for this class has implemented a test to ensure that we are able to hit our API and display some data from the response. However, our test is actually hitting the Congress API every time it runs. There are many reasons we wouldn't want to do this: 1. We could hit API rate limits much faster. 2. Our test suite will be slower. @@ -163,23 +167,23 @@ $ bundle exec rspec spec/features/user_can_search_by_senator_last_name_spec.rb Now we will se a big ol’ error message: ```bash -Failure/Error: response = conn.get(url) - + Failure/Error: response = conn.get("/v3/member?limit=250") + WebMock::NetConnectNotAllowedError: - Real HTTP connections are disabled. Unregistered request: GET https://api.propublica.org/congress/v1/members/house/CO/current.json with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v2.7.4', 'X-Api-Key'=>'S9JON3ruNOI6XiyymcnZ7gtsjnToPxuXyT0bgeaX'} - + Real HTTP connections are disabled. Unregistered request: GET https://api.congress.gov/v3/member?limit=250 with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v2.9.0', 'X-Api-Key'=>'c8A5PNW7BC1ccEdzMVK0s5WZcJtZsFTUEaRVD3Up'} + You can stub this request with the following snippet: - - stub_request(:get, "https://api.propublica.org/congress/v1/members/house/CO/current.json"). + + stub_request(:get, "https://api.congress.gov/v3/member?limit=250"). with( headers: { 'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', - 'User-Agent'=>'Faraday v2.7.4', - 'X-Api-Key'=>'S9JON3ruNOI6XiyymcnZ7gtsjnToPxuXyT0bgeaX' + 'User-Agent'=>'Faraday v2.9.0', + 'X-Api-Key'=>'c8A5PNW7BC1ccEdzMVK0s5WZcJtZsFTUEaRVD3Up' }). to_return(status: 200, body: "", headers: {}) - + ============================================================ ``` @@ -196,18 +200,18 @@ require 'rails_helper' RSpec.describe 'Senator Search' do describe 'happy path' do - + it 'allows user to search for Senators by last name' do - stub_request(:get, "https://api.propublica.org/congress/v1/116/senate/members.json"). - to_return(status: 200, body: "") + stub_request(:get, "https://api.congress.gov/v3/member?limit=250").to_return(status: 200, body: '') + visit root_path fill_in :search, with: 'Sanders' click_button 'Search' expect(page.status_code).to eq 200 - expect(page).to have_content("Senator Bernard Sanders was found!") - expect(page).to have_content("SenSanders") + expect(page).to have_content('Sanders, Bernard was found!') + expect(page.find('.senator-image')['src']).to have_content('https://www.congress.gov/img/member/s000033_200.jpg') end end end @@ -223,8 +227,8 @@ Now, when we run the test, we get a new error. JSON::ParserError: unexpected token at '' - # ./app/controllers/search_controller.rb:12:in `search' - # ./spec/features/user_can_search_by_senator_last_name_spec.rb:12:in `block (3 levels) in