Debugging Tips - TISTATechnologies/caseflow GitHub Wiki
Debugging Tips
This page provides an introduction to debugging in Caseflow. Post your questions and ask someone to answer it on this page.
Also see these:
ActiveRecord vs ActiveModel
- ActiveRecord - e.g., Appeal or Tasks in Caseflow's DB
- ActiveModel - e.g., LegacyAppeals in VACOLS
Related: where vs. find
> Task.where(id: [1, 2]).class
=> Task::ActiveRecord_Relation
> Task.find([1, 2]).class
=> Array
URLs handled by a Rails Controller
Given a controller, look for the controller name on the right-hand side of bundle exec rake routes output
(or http://localhost:3000/rails/info/routes if Caseflow is running).
The left-side shows the URL (aka, API call).
Grep for that URL in js and jsx code to find pages and components that use the given controller.
For more, see https://reinteractive.com/posts/188-rails-discovery-magical-routes-part-1-major-usages
Which React component is this web element?
- Install React Developer Tools browser extension.
- Load the relevant web page.
- Open Developer Tools in the browser; open the "Components" tab. A hierarchy of React components should be shown.
- Click on the square-with-arrow icon on the upper left (but within the tab), then select the web element on the web page.
- On the right side of the tab, scroll down to the "rendered by" section to see relevant React components.
Given a SomeComponentView.jsx, how do I navigate to it?
- Trial and error
- More experience with the Caseflow UI and how it is used by users. See training material.
- Find RSpecs that use the view to get an idea when it is used.
How is a web element populated?
- Install Redux DevTools browser extension
- Load the relevant web page.
- Open Developer Tools in the browser
- Open the "Redux" tab. A hierarchy of React components should be shown.
- Open the "Network" tab. You may have to reload the web page or reopen Developer Tools.
- Click on rows to see the "Request URL" on the right side of the tab. These requests are handled by Rails controllers (see other section).
 
 
- Open the "Network" tab. You may have to reload the web page or reopen Developer Tools.
 
- Open the "Redux" tab. A hierarchy of React components should be shown.
- Redux explanation with example from Queue:
- React components dispatch Redux actions, which get processed by Redux reducers based on the action type. All reducers are contained in a single agglomerate reducer, which returns a JavaScript object used to update the Redux store.
- client/app/queue/reducers.js: defines reducers associated with names that will be seen in the "Redux" developer tool tab. The result of these reducers are used to modify the state of the store.
- client/app/queue/QueueActions.jsdefines functions that use- ApiUtilto submit a request to the backend and maps the response to an- actionobject, which has a- typethat is used to select a reducer and by convention corresponds to names in the "Redux" developer tool tab. The- actionobject also has a- payloadthat holds response data received from the backend.
 
- React components dispatch Redux actions, which get processed by Redux reducers based on the action 
- Given an updated Redux store, any React component can retrieve store data. To do this, update the jsxfile as follows:- Update the mapStateToPropsfunction to extract specific data from the Redux state and return an object that is used as thepropsfor React components.
- TODO: describe mapDispatchToProps
- Update propTypesto define the shape of the data.
- Use the propswithin the React component.
 
- Update the 
How do you find a hearing?
- Hearing for AMA appeals
- Find using the appeal_id:Hearing.find_by(appeal_id: 864)
- Find using the uuid:- Hearing.find_by(uuid: "25184d31-36c8-4bb0-864f-af3541de46fe")
- or Hearing.find_hearing_by_uuid_or_vacols_id("25184d31-36c8-4bb0-864f-af3541de46fe")
 
 
- Find using the 
- LegacyHearing for Legacy appeals
- Find using the vacols_id:- LegacyHearing.find_by(vacols_id: "707133")
- or Hearing.find_hearing_by_uuid_or_vacols_id("707133")
 
 
- Find using the 
How do you look up an appeal using the decision document id?
- AttorneyCaseReview.find_by(document_id: "12345-12345678").appeal
Create Colocated Tasks in Dev/Demo
https://dsva.slack.com/archives/CJL810329/p1581700299284200
Log in as “VLJ_SUPPORT_ADMIN”
Create a bunch of colocated tasks to play with:
ColocatedTask.actions_assigned_to_colocated.map(&:to_sym).each { |action|
  FactoryBot.create(:ama_colocated_task, action, 
    assigned_by: User.first,
    assigned_to: Colocated.singleton, 
    appeal: FactoryBot.create(:appeal), 
    parent: FactoryBot.create(:task, assigned_to: User.first, assigned_by: User.first) ) }
Application Startup
- Different environments are specified in config/environments/: demo, development, prod, staging, test
- Base settings are in config/application.rb, including Rails console and pry, and are overridden by environment settings
- Database settings are in config/database.yml
- Application configurations are in config/initializers/; all .rb files in this directory are automatically loaded- fake_dependencies.rbcalls- Fakes::Initializer.app_init!(Rails.env), which for certain configurations:- sets User.authentication_service = Fakes::AuthenticationService
- and User.authentication_service.user_session = { ... "FAKEUSER" }
- This mimics ApplicationController.current_user.
 
- sets 
 
User Sessions
About sessions and ActionController Session details.
- User.authenticate!authenticates as a specific user or a default user with specified- css_idand/or- roles(see method definition in- StubbableUser)- Feature RSpecs (those within ./spec/feature) and other RSpecs useUser.authenticate!
- It sets RequestStore.store[:current_user] = userandUser.stub = user
- unauthenticate!resets these
 
- Feature RSpecs (those within 
- RequestStore.store[:current_user] = usersets the current user as- user.- Many non-feature RSpecs use RequestStore.store[:current_user]directly
- It gets overridden in ApplicationController.current_userwith every HTTP request based on info in the request.
 
- Many non-feature RSpecs use 
- Some early code uses User.stubto set the current user.
User.authenticate! and User.stub are provided by StubbableUser, which is only available for RSpec tests.
- In StubbableUser, ifstubis set, it is returned forUser.from_session(session), which is used for authentication inApplicationController
Authenticating in the Rails console
Below are two methods to authenticate as any user in the Rails console (of the development environment).
- Method 1 makes use of Fakes::AuthenticationServiceproviding.default_user_session, which is used when no one is authenticated. SeeUser.from_session(session), which is used byStubbableUser.authenticate!(akaUser.authenticate!).
- Method 2 uses the '/test/set_user' route.
User.authentication_service
=> Fakes::AuthenticationService
# Who I want to authenticate as
me=User.find(3)
# Method 1: Set me the default user
# Only works if you haven't authenticated yet (e.g., just started a new Rails console).
# But you don't need a CSRF token
User.authentication_service.user_session = User.authentication_service.get_user_session(me.id)
# To debug, add `binding.pry` in app/models/user.from_session(session)
app.get '/';  app.response.body[/userDisplayName.*/]
# Method 2: Get CSRF token and authenticate
app.get '/';
parameters = { authenticity_token: app.session.to_hash["_csrf_token"] }
# Repeat this for different user_ids as many times as you want
app.post "/test/set_user/#{me.id}", params: parameters
app.get '/';  app.response.body[/userDisplayName.*/]
# To log out
app.get '/logout'
(Going to http://localhost:3000/test/users/me will show the _csrf_token in the browser.)
Get tasks for a Legacy Appeal
Certain tasks for legacy appeals are not saved to Caseflow's database. They are transient tasks and are created in memory based on VACOLS data using LegacyWorkQueue.tasks_by_appeal_id(vacols_id). The transient tasks are defined in app/models/legacy_tasks/.
To get the appeal's assignment history, pp appeal.location_history.map(&:summary).