-
Notifications
You must be signed in to change notification settings - Fork 19
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 - 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
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
- 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.
- 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.
- 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.js
defines functions that useApiUtil
to submit a request to the backend and maps the response to anaction
object, which has atype
that is used to select a reducer and by convention corresponds to names in the "Redux" developer tool tab. Theaction
object also has apayload
that 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
jsx
file as follows:- Update the
mapStateToProps
function to extract specific data from the Redux state and return an object that is used as theprops
for React components. - TODO: describe
mapDispatchToProps
- Update
propTypes
to define the shape of the data. - Use the
props
within the React component.
- Update the
-
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
AttorneyCaseReview.find_by(document_id: "12345-12345678").appeal
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) ) }
- 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.rb
callsFakes::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
-
About sessions and ActionController Session details.
-
User.authenticate!
authenticates as a specific user or a default user with specifiedcss_id
and/orroles
(see method definition inStubbableUser
)- Feature RSpecs (those within
./spec/feature
) and other RSpecs useUser.authenticate!
- It sets
RequestStore.store[:current_user] = user
andUser.stub = user
-
unauthenticate!
resets these
- Feature RSpecs (those within
-
RequestStore.store[:current_user] = user
sets the current user asuser
.- Many non-feature RSpecs use
RequestStore.store[:current_user]
directly - It gets overridden in
ApplicationController.current_user
with every HTTP request based on info in the request.
- Many non-feature RSpecs use
- Some early code uses
User.stub
to set the current user.
User.authenticate!
and User.stub
are provided by StubbableUser
, which is only available for RSpec tests.
- In
StubbableUser
, ifstub
is set, it is returned forUser.from_session(session)
, which is used for authentication inApplicationController
Below are two methods to authenticate as any user in the Rails console (of the development environment).
- Method 1 makes use of
Fakes::AuthenticationService
providing.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.)
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)
.
- Home
- Acronyms and Glossary
- Caseflow products
- Caseflow Intake
- Caseflow Queue
- Appeals Consumer
- Caseflow Reader
- Caseflow eFolder
- Caseflow Hearings
- Caseflow Certification
- Caseflow APIs
- Appeal Status API
- Caseflow Dispatch
-
CSUM Roles
- System Admin
- VHA Team Management
- Active Record Queries Resource
- External Integrations
- Caseflow Demo
- Caseflow ProdTest
- Background
- Stuck Jobs
- VA Notify
- Caseflow-Team
- Frontend Best Practices
- Accessibility
- How-To
- Debugging Tips
- Adding a Feature Flag with FeatureToggle
- Editing AMA issues
- Editing a decision review
- Fixing task trees
- Investigating and diagnosing issues
- Data and Metric Request Workflow
- Exporting and Importing Appeals
- Explain page for Appeals
- Record associations and Foreign Keys
- Upgrading Ruby
- Stuck Appeals
- Testing Action Mailer Messages Locally
- Re-running Seed Files
- Rake Generator for Legacy Appeals
- Manually running Scheduled Jobs
- System Admin UI
- Caseflow Makefile
- Upgrading Postgresql from v11.7 to v14.8 Locally
- VACOLS VM Trigger Fix M1
- Using SlackService to Send a Job Alert
- Technical Talks