diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index 05462580e88..35d0df269c9 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -62,11 +62,13 @@ jobs: run: ./refresh-data.sh test.sql.gz - name: Run Cypress - uses: cypress-io/github-action@v5 + uses: cypress-io/github-action@v6.6.0 with: build: yarn build start: python cfgov/manage.py runserver 0.0.0.0:8000 wait-on: 'http://localhost:8000' + spec: test/cypress/integration/paying-for-college/disclosures/disclosures-basics.cy.js + env: MAPBOX_ACCESS_TOKEN: ${{ secrets.MAPBOX_ACCESS_TOKEN }} CYPRESS_ENVIRONMENT: github diff --git a/cfgov/paying_for_college/jinja2/paying-for-college/disclosure.html b/cfgov/paying_for_college/jinja2/paying-for-college/disclosure.html index 473527552b0..f36aaa2b8ac 100644 --- a/cfgov/paying_for_college/jinja2/paying-for-college/disclosure.html +++ b/cfgov/paying_for_college/jinja2/paying-for-college/disclosure.html @@ -10,6 +10,7 @@ {% endblock %} {% block content %} +{% set school_primary_alias = school.primary_alias if school else '' %}
@@ -83,7 +84,7 @@

- {{school.primary_alias}} + {{school_primary_alias}}
{% if school %}{{school.city}}, {{school.state}}{% endif %} @@ -258,7 +259,7 @@

Here is your financial aid offer from {{school.primary_alias}}. Please review the amounts provided by + id="intro__school-name">{{school_primary_alias}}. Please review the amounts provided by your school below and make any necessary changes or add any missing information. Please note any changes you make here will not change your @@ -886,7 +887,7 @@

This is an estimate of the remaining costs of studying your program at - {{school.primary_alias}} for one year. + {{school_primary_alias}} for one year.

@@ -1742,7 +1743,7 @@

This is an estimate of the remaining costs of studying your program at - {{school.primary_alias}} for one year based + {{school_primary_alias}} for one year based on your inputs above.

@@ -1873,7 +1874,7 @@

After all the grants, scholarships, loans, and personal contributions, this is how much you still need to pay to attend - {{school.primary_alias}} for one year. + {{school_primary_alias}} for one year.

For first-time students enrolled full-time in {{program.program_name}} at - {{school.primary_alias}}, + {{school_primary_alias}}, {{program.completers}} out of {{program.completion_cohort}} graduated. @@ -2942,7 +2943,7 @@

It's estimated you'll owe [XX] to complete this program in {{program.program_name}} at - {{school.primary_alias}}. Do you better + {{school_primary_alias}}. Do you better understand how this may impact your future finances?

diff --git a/cfgov/unprocessed/apps/paying-for-college/js/disclosures/dispatchers/get-api-values.js b/cfgov/unprocessed/apps/paying-for-college/js/disclosures/dispatchers/get-api-values.js index e3152d0593f..72718556a53 100755 --- a/cfgov/unprocessed/apps/paying-for-college/js/disclosures/dispatchers/get-api-values.js +++ b/cfgov/unprocessed/apps/paying-for-college/js/disclosures/dispatchers/get-api-values.js @@ -1,30 +1,12 @@ -import { promiseRequest } from '../utils/promise-request.js'; import financialView from '../views/financial-view.js'; -/** - * getApi - Make an API request to the endpoint specified with parameters specified - * @param {string} url - URL of API endpoint - * @returns {object} Promise - */ -function getApi(url) { - return new Promise(function (resolve, reject) { - promiseRequest('GET', url) - .then(function (resp) { - resolve(resp); - }) - .catch(function (error) { - reject(new Error(error)); - }); - }); -} - const getApiValues = { values: {}, constants: function () { const urlBase = document.querySelector('main').getAttribute('data-context'); const url = '/' + urlBase + '/understanding-your-financial-aid-offer/api/constants/'; - return getApi(url); + return fetch(url); }, expenses: function () { @@ -32,7 +14,7 @@ const getApiValues = { const url = '/' + urlBase + '/understanding-your-financial-aid-offer/api/expenses/'; - return getApi(url); + return fetch(url); }, fetchSchoolData: function (iped) { @@ -44,15 +26,9 @@ const getApiValues = { iped + '/'; - return new Promise(function (resolve ) { - promiseRequest('GET', url) - .then(function (resp) { - resolve(resp); - }) - .catch(function (error) { - financialView.missingData('school'); - new Error(error); - }); + return fetch(url).catch(function (error) { + financialView.missingData('noSchool'); + return new Error(error); }); }, @@ -77,26 +53,9 @@ const getApiValues = { pid + '/'; - // $.ajax({ - // url: url, - // dataType: 'json', - // success: function (resp) { - // return resp; - // }, - // error: function (/* req, status, err */) { - // financialView.missingData('program'); - // }, - // }); - - return new Promise(function (resolve ) { - promiseRequest('GET', url) - .then(function (resp) { - resolve(resp); - }) - .catch(function () { - financialView.missingData('school'); - // reject(new Error(error)); - }); + return fetch(url).catch(function (error) { + financialView.missingData('noProgram'); + return new Error(error); }); }, @@ -114,14 +73,14 @@ const getApiValues = { url += '_' + pid + '/'; } - return getApi(url); + return fetch(url); }, schoolData: function (iped, pid) { return Promise.all([ - this.fetchSchoolData(iped), - this.fetchProgramData(iped, pid), - this.fetchNationalData(iped, pid), + this.fetchSchoolData(iped).then((v) => v.json()), + this.fetchProgramData(iped, pid).then((v) => v.json()), + this.fetchNationalData(iped, pid).then((v) => v.json()), ]); }, @@ -130,16 +89,14 @@ const getApiValues = { const warning = document .querySelector('[data-warning]') .getAttribute('data-warning'); - if (warning !== '' && typeof warning !== 'undefined') { + if (warning && !window.Cypress) { financialView.missingData(warning); - const deferred = {}; - deferred.promise = new Promise((resolve, reject) => { - deferred.resolve = resolve; - deferred.reject = reject; - }); - return deferred; + return Promise.resolve(); } - return Promise.all([this.constants(), this.expenses()]); + return Promise.all([ + this.constants().then((v) => v.json()), + this.expenses().then((v) => v.json()), + ]); }, }; diff --git a/cfgov/unprocessed/apps/paying-for-college/js/disclosures/index.js b/cfgov/unprocessed/apps/paying-for-college/js/disclosures/index.js index 0309f25a7c5..1c8268f098e 100755 --- a/cfgov/unprocessed/apps/paying-for-college/js/disclosures/index.js +++ b/cfgov/unprocessed/apps/paying-for-college/js/disclosures/index.js @@ -1,5 +1,5 @@ import $ from './utils/dollar-sign.js'; -import fetch from './dispatchers/get-api-values.js'; +import getApiValues from './dispatchers/get-api-values.js'; import verifyOffer from './dispatchers/post-verify.js'; import financialModel from './models/financial-model.js'; import schoolModel from './models/school-model.js'; @@ -38,10 +38,9 @@ const ready = function (callback) { const app = { urlValues: {}, init: function () { - // jquery promise to delay full model creation until ajax resolves - fetch.initialData().then((resp) => { - const constants = JSON.parse(resp[0].responseText); - const expenses = JSON.parse(resp[1].responseText); + getApiValues.initialData().then((resp) => { + if (!resp) return; + const [constants, expenses] = resp; financialModel.init(constants[0]); financialView.init(); if (location.href.indexOf('about-this-tool') === -1) { @@ -51,12 +50,10 @@ const app = { if (getUrlOfferExists()) { // Check for URL offer data this.urlValues = getUrlValues(); - fetch + getApiValues .schoolData(this.urlValues.collegeID, this.urlValues.programID) .then((respArr) => { - const schoolData = JSON.parse(respArr[0].responseText); - const programData = JSON.parse(respArr[1].responseText); - const nationalData = JSON.parse(respArr[1].responseText); + const [schoolData, programData, nationalData] = respArr; const data = {}; Object.assign(data, schoolData, programData, nationalData); const schoolValues = schoolModel.init( diff --git a/cfgov/unprocessed/apps/paying-for-college/js/disclosures/utils/dollar-sign.js b/cfgov/unprocessed/apps/paying-for-college/js/disclosures/utils/dollar-sign.js index 0320945f684..92265298d3f 100644 --- a/cfgov/unprocessed/apps/paying-for-college/js/disclosures/utils/dollar-sign.js +++ b/cfgov/unprocessed/apps/paying-for-college/js/disclosures/utils/dollar-sign.js @@ -17,17 +17,11 @@ function Query(selector) { if (typeof selector === 'string' && selector !== '') { this.elements = document.querySelectorAll(selector); } - - // if ( this.elements.length > 1 ) { - // return this.elements; - // } else { - // return this.elements[0]; - // } } Query.prototype.attr = function (name, value) { if (typeof value === 'undefined') { - return this.elements[0].getAttribute(name); + return this.elements.length ? this.elements[0].getAttribute(name) : null; } else { this.elements.forEach((elem) => { elem.setAttribute(name, value); @@ -36,13 +30,13 @@ Query.prototype.attr = function (name, value) { }; Query.prototype.cloner = function () { - return this.elements[0].cloneNode(true); + return this.elements.length ? this.elements[0].cloneNode(true) : null; }; Query.prototype.text = function (value) { // getter if (typeof value === 'undefined') { - return this.elements[0].textContent; + return this.elements.length ? this.elements[0].textContent : null; } //setter else { @@ -55,7 +49,7 @@ Query.prototype.text = function (value) { Query.prototype.val = function (value) { // getter if (typeof value === 'undefined' && this.elements.length > 0) { - return this.elements[0].value; + return this.elements.length ? this.elements[0].value : null; } //setter else { @@ -146,19 +140,11 @@ Query.prototype.show = function (className) { }; Query.prototype.height = function () { - if (this.elements.length > 0) { - return this.elements[0].offsetHeight; - } else { - return null; - } + return this.elements.length ? this.elements[0].offsetHeight : null; }; Query.prototype.top = function () { - if (this.elements.length > 0) { - return this.elements[0].offsetTop; - } else { - return null; - } + return this.elements.length ? this.elements[0].offsetTop : null; }; Query.prototype.listen = function (eventType, callback) { @@ -168,7 +154,7 @@ Query.prototype.listen = function (eventType, callback) { }; Query.prototype.tagName = function () { - return this.elements[0].tagName; + return this.elements.length ? this.elements[0].tagName : null; }; Query.prototype.addClass = function (classNames) { diff --git a/cfgov/unprocessed/apps/paying-for-college/js/disclosures/utils/promise-request.js b/cfgov/unprocessed/apps/paying-for-college/js/disclosures/utils/promise-request.js deleted file mode 100644 index 5a9d4bcdd3d..00000000000 --- a/cfgov/unprocessed/apps/paying-for-college/js/disclosures/utils/promise-request.js +++ /dev/null @@ -1,30 +0,0 @@ -/* Promise requests are better. */ - -/** - * promiseRequest - A handy function for returning XHR Promises - * @param {string} method - The method, ex. POST or GET - * @param {string} url - The url to be requested - * @returns {object} Promise of the XHR request - */ -function promiseRequest(method, url) { - const xhr = new XMLHttpRequest(); - - return new Promise(function (resolve, reject) { - // Completed xhr - xhr.onreadystatechange = function () { - // Do not run unless xhr is complete - if (xhr.readyState !== 4) return; - if (xhr.status >= 200 && xhr.status < 300) { - resolve(xhr); - } else { - reject(new Error(xhr.status + ', ' + xhr.statusText)); - } - }; - - xhr.open(method, url, true); - - xhr.send(); - }); -} - -export { promiseRequest }; diff --git a/cfgov/unprocessed/apps/paying-for-college/js/disclosures/views/financial-view.js b/cfgov/unprocessed/apps/paying-for-college/js/disclosures/views/financial-view.js index 639f3e44fcd..6d50408e1cd 100755 --- a/cfgov/unprocessed/apps/paying-for-college/js/disclosures/views/financial-view.js +++ b/cfgov/unprocessed/apps/paying-for-college/js/disclosures/views/financial-view.js @@ -277,8 +277,11 @@ const financialView = { */ updateViewWithProgram: function (values, urlValues) { // Update program length - const lengthExists = Object.prototype.hasOwnProperty.call(urlValues, 'urlProgramLength'); - if ( lengthExists ) { + const lengthExists = Object.prototype.hasOwnProperty.call( + urlValues, + 'urlProgramLength', + ); + if (lengthExists) { this.$programLength.val(urlValues.urlProgramLength / 12).change(); } else { this.$programLength.val(values.programLength).change(); @@ -959,18 +962,14 @@ const financialView = { */ missingData: function (dataType) { $('.verify_wrapper').hide(); - if ( - $('[data-missing-data-error]:not([style*="display: none"]').length === 0 - ) { - $('[data-missing-data-error="' + dataType + '"]').show(); - } + $('[data-missing-data-error="' + dataType + '"]').show(); }, /** * Listener function for change events on financial INPUT fields */ financialInputChangeListener: function () { - $('[nancial]').each((elmo) => { + $('[data-financial]').each((elmo) => { elmo.addEventListener('change', (event) => { const dataFinancial = event.target.dataset.financial; if (dataFinancial) {