Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vamc 15446 spike vamc police data page #1753

Merged
merged 21 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"cy-mobile-commands": "^0.3.0",
"cypress": "^10.8.0",
"cypress-axe": "^1.0.0",
"cypress-downloadfile": "^1.2.3",
"cypress-multi-reporters": "^1.5.0",
"cypress-plugin-tab": "^1.0.5",
"cypress-real-events": "^1.7.1",
Expand Down Expand Up @@ -210,6 +211,7 @@
"aws-sdk": "^2.1441.0",
"blob-polyfill": "^4.0.20200601",
"core-js": "^3.17.3",
"csvtojson": "^2.0.10",
"diff2html": "^3.4.11",
"dotenv": "^10.0.0",
"express": "^4.17.1",
Expand All @@ -229,6 +231,7 @@
"metalsmith-sitemap": "^1.0.0",
"moment": "^2.29.2",
"moment-timezone": "^0.5.33",
"node-libcurl": "^3.0.0",
"number-to-words": "^1.2.4",
"raven": "^2.6.4",
"react": "^16.13.1",
Expand Down
15 changes: 14 additions & 1 deletion src/platform/testing/e2e/cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const fs = require('fs-extra');
const path = require('path');
const table = require('table').table;
const { table } = require('table');
const { downloadFile } = require('cypress-downloadfile/lib/addPlugin');

const tableConfig = {
columns: {
Expand Down Expand Up @@ -76,5 +77,17 @@ module.exports = on => {

return dir;
},
downloadFile,
deleteFileOrDir(fileOrDirName) {
if (fs.existsSync(fileOrDirName)) {
fs.rmSync(fileOrDirName, {
recursive: true,
});
}
return null;
},
fileOrDirExists(fileOrDirName) {
return fs.existsSync(fileOrDirName);
},
});
};
9 changes: 9 additions & 0 deletions src/platform/testing/e2e/cypress/support/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,12 @@ import './hasCount';
import './keyboard';
import 'cy-mobile-commands';
import 'cypress-wait-until';
import 'cypress-downloadfile/lib/downloadFileCommand';

Cypress.Commands.add('deleteFileOrDir', fileOrDirName => {
return cy.task('deleteFileOrDir', fileOrDirName);
});

Cypress.Commands.add('fileOrDirExists', fileOrDirName => {
return cy.task('fileOrDirExists', fileOrDirName);
});
39 changes: 38 additions & 1 deletion src/site/stages/build/drupal/metalsmith-drupal.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ function pipeDrupalPagesIntoMetalsmith(contentData, files) {
const pages = contentData.data.nodeQuery.entities.filter(
e => e && Object.keys(e).length,
);

for (const page of pages) {
const {
entityUrl: { path: drupalUrl },
Expand Down Expand Up @@ -355,6 +354,44 @@ function getDrupalContent(buildOptions) {
let drupalData = null;
try {
drupalData = await loadDrupal(buildOptions);

// Add to drupal Sidebars at the bottom of the ABOUT VA/ABOUT LOVELL section the va-police link
// TODO: Remove if CMS goes forward with creating VA Police Pages
// const facilitySidebarQueries = Object.keys(drupalData.data).filter(k =>
// k.includes('FacilitySidebarQuery'),
// );
// FOR EACH FACILITY SIDEBAR QUERY, UNDER THE ABOUT XYZ SECTION ADD "VA Police" link
// for (const query of facilitySidebarQueries) {
// for (let i = 0; i < drupalData.data[query].links.length; i += 1) {
// const j = drupalData.data[query].links[i].links.findIndex(l => {
// return (
// l.label.toUpperCase().startsWith('ABOUT VA') ||
// l.label.toUpperCase().startsWith('ABOUT LOVELL')
// );
// });
// if (j !== -1) {
// console.log(
// `Adding VA Police to: ${drupalData.data[query].links[0].url.path}/va-police`,
// );
// drupalData.data[query].links[i].links[j].links.push({
// expanded: false,
// description: 'Police data',
// label: 'VA Police',
// links: [],
// url: {
// path: `${drupalData.data[query].links[0].url.path}/va-police`,
// },
// entity: {
// linkedEntity: {
// entityPublished: true,
// moderationState: 'published',
// },
// },
// });
// }
// }
// }

drupalData = convertDrupalFilesToLocal(drupalData, files);

await loadCachedDrupalFiles(buildOptions, files);
Expand Down
5 changes: 3 additions & 2 deletions src/site/stages/build/drupal/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function paginatePages(page, files, field, layout, ariaLabel, perPage) {
if (page[pageField]) {
const pagedEntities = _.chunk(page[pageField].entities, perPage);

for (let pageNum = 0; pageNum < pagedEntities.length; pageNum++) {
for (let pageNum = 0; pageNum < pagedEntities.length; pageNum += 1) {
eselkin marked this conversation as resolved.
Show resolved Hide resolved
let pagedPage = { ...page };

if (pageNum > 0) {
Expand Down Expand Up @@ -98,7 +98,7 @@ function paginatePages(page, files, field, layout, ariaLabel, perPage) {
start = pageNum;
}
}
for (let num = start; num < start + length; num++) {
for (let num = start; num < start + length; num += 1) {
innerPages.push({
href:
num === pageNum
Expand Down Expand Up @@ -356,6 +356,7 @@ function compilePage(page, contentData) {
const facilitySidebarNavItems = {
facilitySidebar: getFacilitySidebar(page, contentData),
};

const outreachSidebarNavItems = { outreachSidebar: outreachSidebarNav };
const alertItems = { alert: alertsItem };

Expand Down
17 changes: 16 additions & 1 deletion src/site/stages/build/drupal/static-data-files/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ const {
postProcess: postProcessVamcFacilitySupplementalStatus,
} = require('./vamcFacilitySupplementalStatus');

const {
query: queryVAPoliceData,
postProcess: postProcessVAPoliceData,
} = require('./vaPoliceData');

const DATA_FILE_PATH = 'data/cms';

/**
* {
* description: String used in build log,
* filename: File will be generated at `${DATA_FILE_PATH}/${filename}`,
* queryType: 'graphql' (default); aim to eventually support jsonapi
* query: String defining the query to be run,
* query: String|Object defining the query to be run,
* postProcess: Callback function to apply post-query processing on query result,
* }
*/
Expand All @@ -24,14 +29,24 @@ const DATA_FILES = [
description: 'VAMC EHR System',
filename: 'vamc-ehr.json',
query: queryVamcEhrSystem,
queryType: 'graphql',
eselkin marked this conversation as resolved.
Show resolved Hide resolved
postProcess: postProcessVamcEhrSystem,
},
{
description: 'VAMC Facility Supplemental Status',
filename: 'vamc-facility-supplemental-status.json',
query: queryVamcFacilitySupplementalStatus,
queryType: 'graphql',
postProcess: postProcessVamcFacilitySupplementalStatus,
},
{
description: 'VAMC Police Data',
filename: 'vamc-police.json',
queryType: 'curl',
// This looks like a highly complicated route to get the file data, but it is generalizeable to all CURL requests, not just file URLs
query: queryVAPoliceData,
postProcess: postProcessVAPoliceData,
},
];

module.exports = {
Expand Down
73 changes: 73 additions & 0 deletions src/site/stages/build/drupal/static-data-files/fetchApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
const fetch = require('node-fetch');
const SocksProxyAgent = require('socks-proxy-agent');
const syswidecas = require('syswide-cas');
const { curly } = require('node-libcurl');

const { Response } = fetch;

// Uses fetch to make a request to a non-file URL or uses node-libcurl to make a request to a file URL
// Returns a node-fetch response in all cases
async function fetchWrapper(url, options) {
if (url.startsWith('file:')) {
const { data } = await curly.get(url);
return new Response(data, { status: 200, statusText: 'OK', url });
}
return fetch(url, options);
}

function encodeCredentials({ user, password }) {
const credentials = `${user}:${password}`;
return Buffer.from(credentials).toString('base64');
}

function getCurlClient(buildOptions, _clientOptionsArg = { verbose: true }) {
const buildArgs = {
user: buildOptions['drupal-user'],
password: buildOptions['drupal-password'],
maxParallelRequests: buildOptions['drupal-max-parallel-requests'],
};

Object.keys(buildArgs).forEach(key => {
if (!buildArgs[key]) delete buildArgs[key];
});

const { user, password } = buildArgs;

const encodedCredentials = encodeCredentials({ user, password });
const headers = {
Authorization: `Basic ${encodedCredentials}`,
'Content-Type': 'application/json',
};
const agent = new SocksProxyAgent('socks://127.0.0.1:2001');
return {
// We have to point to aws urls on Jenkins, so the only
// time we'll be using cms.va.gov addresses is locally,
// when we need a proxy

async proxyFetch(url, options = { headers }) {
const usingProxy =
/^https?:\/\/.*\.cms\.va\.gov\//.test(url) &&
Dismissed Show dismissed Hide dismissed
!buildOptions['no-drupal-proxy'];

if (usingProxy) {
// addCAs() is here because VA uses self-signed certificates with a
// non-globally trusted Root Certificate Authority and we need to
// tell our code to trust it, otherwise we get self-signed certificate errors.
syswidecas.addCAs([
'certs/VA-Internal-S2-RCA1-v1.pem',
'certs/VA-Internal-S2-RCA2.pem',
]);
}

return fetchWrapper(
url,
// eslint-disable-next-line prefer-object-spread
eselkin marked this conversation as resolved.
Show resolved Hide resolved
Object.assign({}, options, {
agent: usingProxy ? agent : undefined,
}),
);
},
};
}

module.exports = getCurlClient;
Loading
Loading