Skip to content

Commit

Permalink
Add JavaScript validation documentation to TESTING.md
Browse files Browse the repository at this point in the history
  • Loading branch information
Laura10101 committed Feb 8, 2024
1 parent 56f7d05 commit 50f519b
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 31 deletions.
44 changes: 44 additions & 0 deletions TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,50 @@ All custom CSS is contained within my base.css file as part of the base template
![CSS validation for base.css](https://laura10101.github.io/contractor-tax-calculator/documentation/validation/css/css-validation.png)

### JavaScript Validation
For this project, I developed custom JavaScript to provide enhanced user experiences in three areas:

- To validate user input on the financial information form when creating a tax calculation.
- To provide Stripe integration through the card and address elements on the checkout page.
- To provide a single-page configuration experience for managing tax questions and rates in the config app. This JavaScript is separated into five files as follows:
- **views.js** provides the event handlers and action methods that provide the functionality for each component of the user interface.
- **view_utils.js** provides a set of utility functions for DOM manipulation and data validation. These cover controlling Bootstrap modals, validating user input, and displaying models returned by the API to the user.
- **view_models.js** provide a set of functions used for managing application state. This includes storing and refreshing referential data (Jurisdictions and Tax Categories), query methods to retrieve objects from the app state by ID or other attributes, and commands for managing entity ordinals.
- **view_consts.js** define constants used by the other layers of JavaScript. These constants include API endpoints for different actions and IDs of important DOM elements.
- **service_clients.js** define a set of functions that provide easier access to the APIs via a set of JQuery AJAX requests.

Additionally, custom JavaScript is used to implement the Jest testing for the config app.

All custom JavaScript passes validation without errors as shown below.

There are a number of undefined and unused variables in each of the files. These relate to variables which are either imported to, or exported from, JavaScript modules.

**Validating user input - validation.js**

![JSHint validation for validation.js](https://laura10101.github.io/contractor-tax-calculator/documentation/validation/js/validation-js-validation.png)

**Stripe integration - stripe_elements.js**

![JSHint validation for stripe_elements.js](https://laura10101.github.io/contractor-tax-calculator/documentation/validation/js/stripe-elements-js-validation.png)

**Config app - views.js**

![JSHint validation for views.js](https://laura10101.github.io/contractor-tax-calculator/documentation/validation/js/views-validation.png)

**Config app - view_utils.js**

![JSHint validation for view_utils.js](https://laura10101.github.io/contractor-tax-calculator/documentation/validation/js/view-utils-js-validation.png)

**Config app - view_models.js**

![JSHint validation for view_models.js](https://laura10101.github.io/contractor-tax-calculator/documentation/validation/js/view-models-js-validation.png)

**Config app - view_consts.js**

![JSHint validation for view_consts.js](https://laura10101.github.io/contractor-tax-calculator/documentation/validation/js/view-utils-js-validation.png)

**Config app - service_clients.js**

![JSHint validation for service_clients.js](https://laura10101.github.io/contractor-tax-calculator/documentation/validation/js/service-clients-js-validation.png)

## Responsiveness

Expand Down
2 changes: 1 addition & 1 deletion checkout/static/checkout/js/stripe_elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ form.addEventListener('submit', function(ev) {
.createPaymentMethod(data)
.then(function(result) {
// Handle result.error or result.paymentMethod
paymentMethodId = result.paymentMethod.id;
let paymentMethodId = result.paymentMethod.id;
$("#payment_method_id").val(paymentMethodId);

// Submit the form
Expand Down
58 changes: 29 additions & 29 deletions config/static/js/service_clients.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function getCSRFCookie() {

// Generate a querystring from a JSON object
function queryToString(query) {
queryString = "";
let queryString = "";
for (const key in query) {
if (query.hasOwnProperty(key)) {
if (queryString == "") {
Expand Down Expand Up @@ -73,7 +73,7 @@ function processBatch(requestQueue, updater, onQueueEmpty) {
// Retrieve data from an API by invoking an HTTP GET request
// on an API endpoint with a query string added
function query(endpoint, query, success, error) {
url = toUrl(endpoint);
let url = toUrl(endpoint);
return $.ajax({
type: "GET",
url: query == null ? url: url + "?" + queryToString(query),
Expand All @@ -87,7 +87,7 @@ function query(endpoint, query, success, error) {
// Retrieve data from an API by invoking an HTTP GET request
// on an API endpoint without a query string added
function get(endpoint, id, success, error) {
url = toUrl(endpoint);
let url = toUrl(endpoint);
return $.ajax({
type: "GET",
url: url + id + "/",
Expand All @@ -101,7 +101,7 @@ function get(endpoint, id, success, error) {
// Create a new entity via an API by triggering an
// HTTP POST request
function post(endpoint, data, success, error) {
url = toUrl(endpoint);
let url = toUrl(endpoint);
return $.ajax({
type: "POST",
url: url,
Expand All @@ -117,7 +117,7 @@ function post(endpoint, data, success, error) {
// Update an entity via an API by triggering an HTTP PUT
// request
function put(endpoint, id, data, success, error) {
url = toUrl(endpoint);
let url = toUrl(endpoint);
return $.ajax({
type: "PUT",
url: url + id + "/",
Expand All @@ -133,7 +133,7 @@ function put(endpoint, id, data, success, error) {
// Update an entity via an API by triggering an HTTP PATCH
// request
function patch(endpoint, id, data, success, error) {
url = toUrl(endpoint);
let url = toUrl(endpoint);
return $.ajax({
type: "PATCH",
url: url + id + "/",
Expand All @@ -149,7 +149,7 @@ function patch(endpoint, id, data, success, error) {
// Delete an entity via an API by triggering an HTTP DELETE
// request
function remove(endpoint, id, success, error) {
url = toUrl(endpoint);
let url = toUrl(endpoint);
return $.ajax({
type: "DELETE",
url: url + id + "/",
Expand Down Expand Up @@ -185,7 +185,7 @@ function getTaxCategories(onSuccess, onFailure) {

// Get all form and question data for a given jurisdiction via the forms API
function getFormForJurisdiction(jurisdictionId, onSuccess, onFailure) {
queryParameters = {
let queryParameters = {
jurisdiction_ids: jurisdictionId
};
return query(endpoints.forms.base, queryParameters, onSuccess, onFailure);
Expand All @@ -197,7 +197,7 @@ function getFormForJurisdiction(jurisdictionId, onSuccess, onFailure) {

// Create a new boolean question entity via the forms API based on the given data
function createBooleanQuestion(formId, text, ordinal, explainer, variableName, isMandatory, onSuccess, onFailure) {
data = {
let data = {
text: text,
ordinal: ordinal,
explainer: explainer,
Expand All @@ -210,7 +210,7 @@ function createBooleanQuestion(formId, text, ordinal, explainer, variableName, i

// Update an existing boolean question entity via the forms API based on the given data
function updateBooleanQuestion(formId, questionId, text, ordinal, explainer, isMandatory, onSuccess, onFailure) {
data = {
let data = {
text: text,
ordinal: ordinal,
explainer: explainer,
Expand All @@ -222,7 +222,7 @@ function updateBooleanQuestion(formId, questionId, text, ordinal, explainer, isM

// Create a new numeric question entity via the forms API based on the given data
function createNumericQuestion(formId, text, ordinal, explainer, variableName, isMandatory, isInteger, minValue, maxValue, onSuccess, onFailure) {
data = {
let data = {
text: text,
ordinal: ordinal,
explainer: explainer,
Expand All @@ -238,7 +238,7 @@ function createNumericQuestion(formId, text, ordinal, explainer, variableName, i

// Update an existing numeric question entity via the forms API based on the given data
function updateNumericQuestion(formId, questionId, text, ordinal, explainer, isMandatory, isInteger, minValue, maxValue, onSuccess, onFailure) {
data = {
let data = {
text: text,
ordinal: ordinal,
explainer: explainer,
Expand All @@ -253,7 +253,7 @@ function updateNumericQuestion(formId, questionId, text, ordinal, explainer, isM

// Create a new multiple choice question entity via the forms API based on the given data
function createMultipleChoiceQuestion(formId, text, ordinal, explainer, variableName, isMandatory, onSuccess, onFailure) {
data = {
let data = {
text: text,
ordinal: ordinal,
explainer: explainer,
Expand All @@ -266,7 +266,7 @@ function createMultipleChoiceQuestion(formId, text, ordinal, explainer, variable

// Update an existing multiple choice question entity via the forms API based on the given data
function updateMultipleChoiceQuestion(formId, questionId, text, ordinal, explainer, isMandatory, onSuccess, onFailure) {
data = {
let data = {
text: text,
ordinal: ordinal,
explainer: explainer,
Expand All @@ -280,7 +280,7 @@ function updateMultipleChoiceQuestion(formId, questionId, text, ordinal, explain
// based on the provided question object
// Invoke the appropriate API call based on the type of the given question object
function updateQuestion(question, onSuccess, onFailure) {
formId = getFormId();
let formId = getFormId();
switch (question.type) {
case "boolean":
return updateBooleanQuestion(formId, question.id, question.text, question.ordinal, question.explainer, question.is_mandatory, onSuccess, onFailure);
Expand Down Expand Up @@ -313,7 +313,7 @@ function removeQuestion(formId, questionId, onSuccess, onFailure) {

// Create a new multiple choice option entity via the forms API based on the given data
function postMultipleChoiceOption(formId, questionId, text, explainer, onSuccess, onFailure) {
data = {
let data = {
text: text,
explainer: explainer
};
Expand All @@ -331,15 +331,15 @@ function removeMultipleChoiceOption(formId, questionId, optionId, onSuccess, onF

// Retrieve all rulesets and rules for a given jurisdiction
function getRulesetsForJurisdiction(jurisdictionId, onSuccess, onFailure) {
queryParameters = {
let queryParameters = {
jurisdiction_id: jurisdictionId
};
return query(endpoints.rules.rulesets, queryParameters, onSuccess, onFailure);
}

// Create a new ruleset entity via the rules API based on the given data
function postRuleset(jurisdictionId, taxCategoryId, ordinal, onSuccess, onFailure) {
data = {
let data = {
jurisdiction_id: parseInt(jurisdictionId),
tax_category_id: parseInt(taxCategoryId),
ordinal: ordinal
Expand All @@ -349,7 +349,7 @@ function postRuleset(jurisdictionId, taxCategoryId, ordinal, onSuccess, onFailur

// Update an existing ruleset entity via the rules API based on the given data
function patchRuleset(rulesetId, ordinal, onSuccess, onFailure) {
data = {
let data = {
ordinal: ordinal
};
return patch(endpoints.rules.rulesets, rulesetId, data, onSuccess, onFailure);
Expand All @@ -366,7 +366,7 @@ function removeRuleset(rulesetId, onSuccess, onFailure) {

// Create a new flat rate rule entity via the rules API based on the given data
function createFlatRateRule(rulesetId, name, explainer, variableName, ordinal, taxRate, onSuccess, onFailure) {
data = {
let data = {
name: name,
explainer: explainer,
variable_name: variableName,
Expand All @@ -379,7 +379,7 @@ function createFlatRateRule(rulesetId, name, explainer, variableName, ordinal, t

// Update an existing flat rate rule entity via the rules API based on the given data
function updateFlatRateRule(rulesetId, ruleId, name, explainer, variableName, ordinal, taxRate, onSuccess, onFailure) {
data = {
let data = {
name: name,
explainer: explainer,
variable_name: variableName,
Expand All @@ -392,7 +392,7 @@ function updateFlatRateRule(rulesetId, ruleId, name, explainer, variableName, or

// Create a new tiered rate rule entity via the rules API based on the given data
function createTieredRateRule(rulesetId, name, explainer, variableName, ordinal, onSuccess, onFailure) {
data = {
let data = {
name: name,
explainer: explainer,
variable_name: variableName,
Expand All @@ -404,7 +404,7 @@ function createTieredRateRule(rulesetId, name, explainer, variableName, ordinal,

// Update an existing tiered rate rule entity via the rules API based on the given data
function updateTieredRateRule(rulesetId, ruleId, name, explainer, variableName, ordinal, onSuccess, onFailure) {
data = {
let data = {
name: name,
explainer: explainer,
variable_name: variableName,
Expand All @@ -416,7 +416,7 @@ function updateTieredRateRule(rulesetId, ruleId, name, explainer, variableName,

// Create a new secondary tiered rate rule entity via the rules API based on the given data
function createSecondaryTieredRateRule(rulesetId, name, explainer, variableName, ordinal, primaryRuleId, onSuccess, onFailure) {
data = {
let data = {
name: name,
explainer: explainer,
variable_name: variableName,
Expand All @@ -429,7 +429,7 @@ function createSecondaryTieredRateRule(rulesetId, name, explainer, variableName,

// Update an existing secondary tiered rate rule entity via the rules API based on the given data
function updateSecondaryTieredRateRule(rulesetId, ruleId, name, explainer, variableName, ordinal, primaryRuleId, onSuccess, onFailure) {
data = {
let data = {
name: name,
explainer: explainer,
variable_name: variableName,
Expand Down Expand Up @@ -496,7 +496,7 @@ function removeRule(rulesetId, ruleId, onSuccess, onFailure) {

// Create a new rule tier entity via the rules API based on the given data
function postRuleTier(rulesetId, ruleId, minValue, maxValue, ordinal, taxRate, onSuccess, onFailure) {
data = {
let data = {
min_value: !isNaN(parseInt(minValue)) ? parseInt(minValue) : null,
max_value: !isNaN(parseInt(maxValue)) ? parseInt(maxValue) : null,
ordinal: ordinal,
Expand All @@ -507,7 +507,7 @@ function postRuleTier(rulesetId, ruleId, minValue, maxValue, ordinal, taxRate, o

// Update an existing rule tier entity via the rules API based on the given data
function updateRuleTier(rulesetId, ruleId, tierId, minValue, maxValue, ordinal, taxRate, onSuccess, onFailure) {
data = {
let data = {
min_value: !isNaN(parseInt(minValue)) ? parseInt(minValue) : null,
max_value: !isNaN(parseInt(maxValue)) ? parseInt(maxValue) : null,
ordinal: ordinal,
Expand All @@ -527,7 +527,7 @@ function removeRuleTier(rulesetId, ruleId, tierId, onSuccess, onFailure) {

// Create a new secondary rule tier entity via the rules API based on the given data
function postSecondaryRuleTier(rulesetId, ruleId, primaryTierId, ordinal, taxRate, onSuccess, onFailure) {
data = {
let data = {
primary_tier_id: parseInt(primaryTierId),
ordinal: ordinal,
tax_rate: !isNaN(parseFloat(taxRate)) ? parseFloat(taxRate) : null
Expand All @@ -537,7 +537,7 @@ function postSecondaryRuleTier(rulesetId, ruleId, primaryTierId, ordinal, taxRat

// Update an existing secondary rule tier entity via the rules API based on the given data
function updateSecondaryRuleTier(rulesetId, ruleId, tierId, primaryTierId, ordinal, taxRate, onSuccess, onFailure) {
data = {
let data = {
primary_tier_id: primaryTierId,
ordinal: ordinal,
tax_rate: !isNaN(parseFloat(taxRate)) ? parseFloat(taxRate) : null
Expand Down
2 changes: 1 addition & 1 deletion config/static/js/view_models.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ function getTieredRateRulesForJurisdiction() {

// Get all of the currently loaded rules for the specified type
function getRulesByTypeForJurisdiction(type) {
rules = [];
let rules = [];
app.jurisdictionRules.forEach(ruleset => {
ruleset.rules.forEach(rule => {
if (rule.type == type) {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added documentation/validation/js/views-validation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 50f519b

Please sign in to comment.