-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into dst1957-replace-deprecated-color
- Loading branch information
Showing
12 changed files
with
1,464 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# AVS application | ||
|
||
## Quick start to get running locally | ||
Before you get started check [this page](https://depo-platform-documentation.scrollhelp.site/developer-docs/setting-up-your-local-frontend-environment) first to make sure you are setup to use the correct version of Node and Yarn. | ||
- clone vets-website repo `git clone [email protected]:department-of-veterans-affairs/vets-website.git` | ||
- navigate to the check-in application `cd src/applications/avs` | ||
- run `yarn install` | ||
- turn on local mocks `yarn --cwd $( git rev-parse --show-toplevel ) mock-api --responses src/applications/avs/api/mocks/index.js` | ||
- start app `yarn --cwd $( git rev-parse --show-toplevel ) watch --env entry=avs` | ||
- visit the app: `http://localhost:3001/my-health/care-notes/avs/64aee349ceec8352f2403cb0` | ||
|
||
## Running tests | ||
Unit tests for can be run using this command: `yarn test:unit --app-folder avs`. To get detailed errors, run this command with `--log-level=error`. To get coverage reports run this command `yarn test:unit --app-folder avs --coverage --coverage-html`. View the report at `/coverage/index.html` | ||
|
||
Cypress tests can be run with the GUI using this command: `yarn cy:open`. From there you can filter by `avs` to run just AVS end to end tests. | ||
|
||
Run Cypress from command line: | ||
- Run all `yarn cy:run --spec "src/applications/avs/**/**/*"` | ||
- Specify browser `-b electron` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
const data = id => { | ||
let avs = {}; | ||
const filename = `../../../tests/fixtures/${id}.json`; | ||
|
||
try { | ||
// eslint-disable-next-line import/no-dynamic-require | ||
avs = require(filename); | ||
} catch (e) { | ||
// eslint-disable-next-line no-console | ||
console.error(`Could not load file for AVS id ${id}.`); | ||
} | ||
|
||
return { | ||
data: avs, | ||
}; | ||
}; | ||
|
||
module.exports = { | ||
data, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
const generateFeatureToggles = (toggles = {}) => { | ||
const { avsEnabled = true } = toggles; | ||
|
||
return { | ||
data: { | ||
type: 'feature_toggles', | ||
features: [ | ||
{ | ||
name: 'avs_enabled', | ||
value: avsEnabled, | ||
}, | ||
], | ||
}, | ||
}; | ||
}; | ||
|
||
module.exports = { generateFeatureToggles }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* eslint-disable camelcase */ | ||
const delay = require('mocker-api/lib/delay'); | ||
|
||
const commonResponses = require('../../../../platform/testing/local-dev-mock-api/common'); | ||
|
||
const featureToggles = require('./feature-toggles'); | ||
const avs = require('./avs'); | ||
|
||
const responses = { | ||
...commonResponses, | ||
'GET /v0/feature_toggles': featureToggles.generateFeatureToggles({}), | ||
'GET /avs/v0/avs/:id': (req, res) => { | ||
const { data } = avs.data(req.params.id); | ||
if (!data.data) { | ||
return res.status(404).json(data); | ||
} | ||
return res.json(data); | ||
}, | ||
}; | ||
|
||
module.exports = delay(responses, 1000); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { apiRequest } from '@department-of-veterans-affairs/platform-utilities/exports'; | ||
import environment from '@department-of-veterans-affairs/platform-utilities/environment'; | ||
|
||
const apiBasePath = `${environment.API_URL}/avs/v0`; | ||
|
||
/** | ||
* Get an AVS by ID | ||
* @param {String} id | ||
* | ||
* @returns {Object} AVS | ||
*/ | ||
export const getAvs = async id => { | ||
return apiRequest(`${apiBasePath}/avs/${id}`, { | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
}); | ||
}; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import { connect, useSelector } from 'react-redux'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import FEATURE_FLAG_NAMES from '@department-of-veterans-affairs/platform-utilities/featureFlagNames'; | ||
import { selectUser } from '@department-of-veterans-affairs/platform-user/selectors'; | ||
import backendServices from '@department-of-veterans-affairs/platform-user/profile/backendServices'; | ||
import { RequiredLoginView } from '@department-of-veterans-affairs/platform-user/RequiredLoginView'; | ||
|
||
import { getAvs } from '../api/v0'; | ||
|
||
const Avs = props => { | ||
const user = useSelector(selectUser); | ||
const { avsEnabled, featureTogglesLoading } = useSelector( | ||
state => { | ||
return { | ||
featureTogglesLoading: state.featureToggles.loading, | ||
avsEnabled: state.featureToggles[FEATURE_FLAG_NAMES.avsEnabled], | ||
}; | ||
}, | ||
state => state.featureToggles, | ||
); | ||
const { isLoggedIn } = props; | ||
const { id } = props.params; | ||
|
||
const [avs, setAvs] = useState({}); | ||
const [avsLoading, setAvsLoading] = useState(true); | ||
|
||
useEffect( | ||
() => { | ||
const fetchAvs = async () => { | ||
const response = await getAvs(id); | ||
// cf. https://github.com/department-of-veterans-affairs/avs/blob/master/ll-avs-web/src/main/java/gov/va/med/lom/avs/client/model/AvsDataModel.java | ||
setAvs(response.data.attributes); | ||
setAvsLoading(false); | ||
}; | ||
|
||
if (isLoggedIn && avsLoading) { | ||
fetchAvs(); | ||
} | ||
}, | ||
[avs, avsLoading, id, isLoggedIn], | ||
); | ||
|
||
if (avsEnabled === false) { | ||
window.location.replace('/'); | ||
} | ||
|
||
if (isLoggedIn && (avsLoading || featureTogglesLoading)) { | ||
return ( | ||
<va-loading-indicator | ||
data-testid="avs-loading-indicator" | ||
message="Loading your After-visit Summary" | ||
/> | ||
); | ||
} | ||
|
||
return ( | ||
<div className="vads-l-grid-container main-content"> | ||
<RequiredLoginView | ||
user={user} | ||
serviceRequired={[backendServices.USER_PROFILE]} | ||
> | ||
<h1>After-visit Summary</h1> | ||
</RequiredLoginView> | ||
</div> | ||
); | ||
}; | ||
|
||
const mapStateToProps = state => ({ | ||
isLoggedIn: state.user.login.currentlyLoggedIn, | ||
}); | ||
|
||
Avs.propTypes = { | ||
isLoggedIn: PropTypes.bool, | ||
params: PropTypes.object, | ||
}; | ||
|
||
export default connect(mapStateToProps)(Avs); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
import React from 'react'; | ||
import { Route } from 'react-router'; | ||
import App from './containers/App'; | ||
import { Route } from 'react-router-dom'; | ||
|
||
const routes = <Route path="/" component={App} />; | ||
import Avs from './containers/Avs'; | ||
|
||
const routes = [<Route path="/:id" key="/:id" component={Avs} />]; | ||
|
||
export default routes; |
101 changes: 101 additions & 0 deletions
101
src/applications/avs/tests/containers/Avs.unit.spec.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import React from 'react'; | ||
import { expect } from 'chai'; | ||
import { mockApiRequest } from '@department-of-veterans-affairs/platform-testing/helpers'; | ||
import { renderWithStoreAndRouter } from '@department-of-veterans-affairs/platform-testing/react-testing-library-helpers'; | ||
import { waitFor } from '@testing-library/react'; | ||
import backendServices from '@department-of-veterans-affairs/platform-user/profile/backendServices'; | ||
import sinon from 'sinon'; | ||
import Avs from '../../containers/Avs'; | ||
|
||
import mockAvs from '../fixtures/9A7AF40B2BC2471EA116891839113252.json'; | ||
|
||
describe('Avs container', () => { | ||
let oldLocation; | ||
|
||
beforeEach(() => { | ||
oldLocation = global.window.location; | ||
delete global.window.location; | ||
global.window.location = { | ||
replace: sinon.spy(), | ||
}; | ||
}); | ||
|
||
afterEach(() => { | ||
global.window.location = oldLocation; | ||
}); | ||
const initialState = { | ||
featureToggles: { | ||
// eslint-disable-next-line camelcase | ||
avs_enabled: false, | ||
loading: false, | ||
}, | ||
user: { | ||
login: { | ||
currentlyLoggedIn: false, | ||
}, | ||
}, | ||
}; | ||
const props = { | ||
params: { | ||
id: 'foo', | ||
}, | ||
}; | ||
|
||
it('user is not logged in', () => { | ||
// expected behavior is be redirected to the home page with next in the url | ||
renderWithStoreAndRouter(<Avs {...props} />, { | ||
initialState, | ||
}); | ||
|
||
expect(window.location.replace.called).to.be.true; | ||
expect(window.location.replace.firstCall.args[0]).to.eq('/'); | ||
}); | ||
|
||
it('feature flags are still loading', () => { | ||
const screen = renderWithStoreAndRouter(<Avs {...props} />, { | ||
initialState: { | ||
...initialState, | ||
featureToggles: { | ||
loading: true, | ||
}, | ||
user: { | ||
login: { | ||
currentlyLoggedIn: true, | ||
}, | ||
}, | ||
}, | ||
}); | ||
expect(screen.getByTestId('avs-loading-indicator')); | ||
}); | ||
|
||
it('feature flag set to false', () => { | ||
renderWithStoreAndRouter(<Avs {...props} />, { initialState }); | ||
expect(window.location.replace.called).to.be.true; | ||
expect(window.location.replace.firstCall.args[0]).to.eq('/'); | ||
}); | ||
|
||
it('feature flag set to true', async () => { | ||
mockApiRequest(mockAvs); | ||
const screen = renderWithStoreAndRouter(<Avs {...props} />, { | ||
initialState: { | ||
...initialState, | ||
featureToggles: { | ||
// eslint-disable-next-line camelcase | ||
avs_enabled: true, | ||
loading: false, | ||
}, | ||
user: { | ||
login: { | ||
currentlyLoggedIn: true, | ||
}, | ||
profile: { | ||
services: [backendServices.USER_PROFILE], | ||
}, | ||
}, | ||
}, | ||
}); | ||
await waitFor(() => { | ||
expect(screen.getByText('After-visit Summary')); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.