From 7a68ec8bac23d1642fad71d7f15fcc90c40f1049 Mon Sep 17 00:00:00 2001 From: Preston Doman <pdoman@pdx.edu> Date: Mon, 4 Mar 2019 00:36:36 -0800 Subject: [PATCH 1/6] Add createCollapsibleCard and createCollapsibleCardBody tests --- front/static/js/viewHistory.js | 10 +-- front/static/tests/qunit_tests.html | 107 +++++++++++++++++++++++----- 2 files changed, 95 insertions(+), 22 deletions(-) diff --git a/front/static/js/viewHistory.js b/front/static/js/viewHistory.js index 97b4884..3e5b7f7 100644 --- a/front/static/js/viewHistory.js +++ b/front/static/js/viewHistory.js @@ -86,7 +86,7 @@ function updateSection(parsedData, saveButton) { saveButton.innerHTML = "Save"; saveButton.disabled = false; - + } // Wraps a Bootstrap form group around a field @@ -214,7 +214,7 @@ function createCollapsibleCard(sectionIdStr, sectionTitle, sectionCompleted, rul sectionState.classList.add("fas", "fa-exclamation-triangle"); } } - + // Create h2, button. Append button to h2, h2 to header, and header to card const h2 = document.createElement("h2"); h2.classList.add("mb-0"); @@ -232,7 +232,7 @@ function createCollapsibleCard(sectionIdStr, sectionTitle, sectionCompleted, rul return card; } -function createCollapsibleCardBody(form, type, sectionIdStr, sectionDescription, sectionCompleted, ruleViolations) { +function createCollapsibleCardBody(form, sectionIdStr, sectionDescription, sectionCompleted, ruleViolations) { // Create wrapper div const collapseDiv = document.createElement("div"); collapseDiv.id = sectionIdStr + "collapse"; @@ -284,7 +284,7 @@ function createCardFooter(ruleViolations) { violation.appendChild(ruleBreakText); violationMessage.appendChild(violation); } - + cardFooter.appendChild(violationMessage); return cardFooter; } @@ -358,7 +358,7 @@ function createReportForm(parsedData, type) { form.appendChild(saveButton); // Create collapsible card body, append form to it, append card to accordion - let cardBody = createCollapsibleCardBody(form, type, sectionIdStr, + let cardBody = createCollapsibleCardBody(form, sectionIdStr, sections[i].html_description, sections[i].completed, sections[i].rule_violations); let cardFooter = createCardFooter(sections[i].rule_violations); if (cardFooter) { diff --git a/front/static/tests/qunit_tests.html b/front/static/tests/qunit_tests.html index b751c4a..a1635d4 100644 --- a/front/static/tests/qunit_tests.html +++ b/front/static/tests/qunit_tests.html @@ -27,8 +27,8 @@ let formGroup = createFormGroup(sectionIdStr, field); let expectedHTML = `<div class="form-group row"><label class="col-sm-4 col-form" for="section-1-after_trip">Have you taken this trip already?: </label><div class="col-sm-6"><select name="after_trip" id="section-1-after_trip" class="form-control"><option value="true">Yes</option><option value="false" selected="selected">No</option></select></div></div>` - assert.deepEqual(formGroup.outerHTML, expectedHTML, "boolean false renders as no option selected"); - + assert.deepEqual(formGroup.outerHTML, expectedHTML, "boolean false renders as no option selected"); + }); QUnit.test("boolean input group true renders", function(assert) { @@ -42,12 +42,12 @@ let formGroup = createFormGroup(sectionIdStr, field); let expectedHTML = `<div class="form-group row"><label class="col-sm-4 col-form" for="section-1-after_trip">Have you taken this trip already?: </label><div class="col-sm-6"><select name="after_trip" id="section-1-after_trip" class="form-control"><option value="true" selected="selected">Yes</option><option value="false">No</option></select></div></div>` - assert.deepEqual(formGroup.outerHTML, expectedHTML, "boolean true renders as yes option selected"); + assert.deepEqual(formGroup.outerHTML, expectedHTML, "boolean true renders as yes option selected"); }); // END: Test rendering of fields with type boolean - + // BEGIN: Test rendering of fields with type date QUnit.test("date input group renders", function(assert) { let sectionIdStr = "section-1-"; @@ -59,7 +59,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let expectedHTML = `<div class="form-group row"><label class="col-sm-4 col-form" for="section-1-departure_date">Departure date: </label><div class="col-sm-6"><input name="departure_date" id="section-1-departure_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div>` - assert.deepEqual(formGroup.outerHTML, expectedHTML, "formGroup string matches expectedHTML string"); + assert.deepEqual(formGroup.outerHTML, expectedHTML, "formGroup string matches expectedHTML string"); }); QUnit.test("date value None", function(assert) { @@ -72,7 +72,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let value = formGroup.querySelector("#section-1-departure_date").value; - assert.deepEqual(value, "", "date initialized to None has null value"); + assert.deepEqual(value, "", "date initialized to None has null value"); }); QUnit.test("date value assignment", function(assert) { @@ -85,7 +85,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let value = formGroup.querySelector("#section-1-departure_date").value; - assert.deepEqual(value, field.value, "date input initialized to a value is rendered with that value"); + assert.deepEqual(value, field.value, "date input initialized to a value is rendered with that value"); }); // END: Test rendering of fields with type date @@ -100,7 +100,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let expectedHTML = `<div class="form-group row"><label class="col-sm-4 col-form" for="section-1-city">City: </label><div class="col-sm-6"><input name="city" id="section-1-city" type="text" class="form-control"></div></div>` - assert.deepEqual(formGroup.outerHTML, expectedHTML, "formGroup string matches expectedHTML string"); + assert.deepEqual(formGroup.outerHTML, expectedHTML, "formGroup string matches expectedHTML string"); }); QUnit.test("string value assignment", function(assert) { @@ -113,7 +113,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let value = formGroup.querySelector("#section-1-city").value; - assert.deepEqual(value, field.value, "text input initialized to a value is rendered with that value"); + assert.deepEqual(value, field.value, "text input initialized to a value is rendered with that value"); }); // END: Test rendering of fields with type date @@ -128,7 +128,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let expectedHTML = `<div class="form-group row"><label class="col-sm-4 col-form" for="section-1-lowest_fare">Lowest fare: </label><div class="col-sm-6"><input name="lowest_fare" id="section-1-lowest_fare" type="number" class="form-control" step="0.01" min="0"></div></div>` - assert.deepEqual(formGroup.outerHTML, expectedHTML, "formGroup string matches expectedHTML string"); + assert.deepEqual(formGroup.outerHTML, expectedHTML, "formGroup string matches expectedHTML string"); }); QUnit.test("decimal input group initialized to default", function(assert) { @@ -141,7 +141,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let value = formGroup.querySelector("#section-1-lowest_fare").value; - assert.deepEqual(value, "", "decimal input initialized to 0.00 has null value"); + assert.deepEqual(value, "", "decimal input initialized to 0.00 has null value"); }); QUnit.test("decimal input group initialized to value", function(assert) { @@ -154,7 +154,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let value = formGroup.querySelector("#section-1-lowest_fare").value; - assert.deepEqual(value, field.value, "decimal input initialized to 1337 has value 1337"); + assert.deepEqual(value, field.value, "decimal input initialized to 1337 has value 1337"); }); // END: Test rendering of fields with type decimal @@ -169,7 +169,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let expectedHTML = `<div class="form-group row"><label class="col-sm-4 col-form" for="section-1-full_days">Number of full days of travel: </label><div class="col-sm-6"><input name="full_days" id="section-1-full_days" type="number" class="form-control" step="1" min="0"></div></div>` - assert.deepEqual(formGroup.outerHTML, expectedHTML, "formGroup string matches expectedHTML string"); + assert.deepEqual(formGroup.outerHTML, expectedHTML, "formGroup string matches expectedHTML string"); }); QUnit.test("integer input group initialized to default", function(assert) { @@ -182,7 +182,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let value = formGroup.querySelector("#section-1-full_days").value; - assert.deepEqual(value, "", "integer input initialized to 0 has null value"); + assert.deepEqual(value, "", "integer input initialized to 0 has null value"); }); QUnit.test("integer input group initialized to value", function(assert) { @@ -195,7 +195,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let value = formGroup.querySelector("#section-1-full_days").value; - assert.deepEqual(value, field.value.toString(), "integer input initialized to 1234 has string value 1234"); + assert.deepEqual(value, field.value.toString(), "integer input initialized to 1234 has string value 1234"); }); // END: Test rendering of fields with type integer @@ -211,7 +211,7 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let expectedHTML = `<div class="form-group row"><label class="col-sm-4 col-form" for="section-1-invoice_screenshot">Screenshot of invoice: </label><div class="col-sm-6"><input name="invoice_screenshot" id="section-1-invoice_screenshot" type="file" class="form-control-file"><p class="form-text"></p></div></div>` - assert.deepEqual(formGroup.outerHTML, expectedHTML, "formGroup string matches expectedHTML string"); + assert.deepEqual(formGroup.outerHTML, expectedHTML, "formGroup string matches expectedHTML string"); }); QUnit.test("file input group form text assignment", function(assert) { @@ -224,10 +224,83 @@ }; let formGroup = createFormGroup(sectionIdStr, field); let value = formGroup.querySelector(".form-text").innerHTML; - assert.deepEqual(value, field.value, "file input initialized to screenshot.jpg has string value screenshot.jpg"); + assert.deepEqual(value, field.value, "file input initialized to screenshot.jpg has string value screenshot.jpg"); }); // END: Test rendering of fields with type file + // BEGIN createCollapsibleCard unit tests + QUnit.module("createCollapsibleCard"); + + QUnit.test("incomplete section renders", function(assert) { + let sectionIdStr = "section-1-"; + let sectionTitle = "General Info"; + let sectionCompleted = false; + let ruleViolations = []; + + let card = createCollapsibleCard(sectionIdStr, sectionTitle, sectionCompleted, ruleViolations); + let expectedHTML = `<div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-1-collapse">General Info</button><i id="section-1-state"></i></h2></div></div>`; + assert.deepEqual(card.outerHTML, expectedHTML, "card html and expectedHTML are identical"); + }); + + QUnit.test("complete section with no rule violations renders", function(assert) { + let sectionIdStr = "section-1-"; + let sectionTitle = "General Info"; + let sectionCompleted = true; + let ruleViolations = []; + + let card = createCollapsibleCard(sectionIdStr, sectionTitle, sectionCompleted, ruleViolations); + let expectedHTML = `<div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-1-collapse">General Info</button><i id="section-1-state" class="fas fa-check-square"></i></h2></div></div>` + assert.deepEqual(card.outerHTML, expectedHTML, "card html and expectedHTML are identical"); + }); + + QUnit.test("complete section with a violation renders", function(assert) { + let sectionIdStr = "section-1-"; + let sectionTitle = "General Info"; + let sectionCompleted = true; + let ruleViolations = [{"label": "Fare limits", "rule_break_text": "You did a bad thing"}] + + let card = createCollapsibleCard(sectionIdStr, sectionTitle, sectionCompleted, ruleViolations); + let expectedHTML = `<div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-1-collapse">General Info</button><i id="section-1-state" class="fas fa-exclamation-triangle"></i></h2></div></div>` + assert.deepEqual(card.outerHTML, expectedHTML, "card html and expectedHTML are identical"); + }); + + + // BEGIN createCollapsibleCard unit tests + QUnit.module("createCollapsibleCardBody"); + // form, sectionIdStr, sectionDescription, sectionCompleted, ruleViolations + + QUnit.test("incomplete section renders", function(assert) { + let form = document.createElement("form"); + let sectionIdStr = "section-1-"; + let sectionDescription = "<p>Section Description</p>"; + let sectionCompleted = false; + let ruleViolations = []; + let collapseDiv = createCollapsibleCardBody(form, sectionIdStr, sectionDescription, sectionCompleted, ruleViolations); + let expectedHTML = `<div id="section-1-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Section Description</p><form></form></div></div>`; + assert.deepEqual(collapseDiv.outerHTML, expectedHTML, "collapseDiv html and expectedHTML are identical"); + }); + + QUnit.test("complete section with no rule violations renders", function(assert) { + let form = document.createElement("form"); + let sectionIdStr = "section-1-"; + let sectionDescription = "<p>Section Description</p>"; + let sectionCompleted = true; + let ruleViolations = []; + let collapseDiv = createCollapsibleCardBody(form, sectionIdStr, sectionDescription, sectionCompleted, ruleViolations); + let expectedHTML = `<div id="section-1-collapse" class="collapse"><div class="card-body"><div></div><p>Section Description</p><form></form></div></div>`; + assert.deepEqual(collapseDiv.outerHTML, expectedHTML, "collapseDiv html and expectedHTML are identical"); + }); + + QUnit.test("complete section with rule violation renders", function(assert) { + let form = document.createElement("form"); + let sectionIdStr = "section-1-"; + let sectionDescription = "<p>Section Description</p>"; + let sectionCompleted = true; + let ruleViolations = [{"label": "Fare limits", "rule_break_text": "You did a bad thing"}] + let collapseDiv = createCollapsibleCardBody(form, sectionIdStr, sectionDescription, sectionCompleted, ruleViolations); + let expectedHTML = `<div id="section-1-collapse" class="collapse show"><div class="card-body"><div></div><p>Section Description</p><form></form></div></div>`; + assert.deepEqual(collapseDiv.outerHTML, expectedHTML, "collapseDiv html and expectedHTML are identical"); + }); </script> </body> </html> From f250e3addaeaf910ac803e7b526b2cdd85224f40 Mon Sep 17 00:00:00 2001 From: Preston Doman <pdoman@pdx.edu> Date: Mon, 4 Mar 2019 13:32:18 -0800 Subject: [PATCH 2/6] Add createCardFooter tests --- front/static/tests/qunit_tests.html | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/front/static/tests/qunit_tests.html b/front/static/tests/qunit_tests.html index a1635d4..6d4ca4b 100644 --- a/front/static/tests/qunit_tests.html +++ b/front/static/tests/qunit_tests.html @@ -267,7 +267,6 @@ // BEGIN createCollapsibleCard unit tests QUnit.module("createCollapsibleCardBody"); - // form, sectionIdStr, sectionDescription, sectionCompleted, ruleViolations QUnit.test("incomplete section renders", function(assert) { let form = document.createElement("form"); @@ -301,6 +300,29 @@ let expectedHTML = `<div id="section-1-collapse" class="collapse show"><div class="card-body"><div></div><p>Section Description</p><form></form></div></div>`; assert.deepEqual(collapseDiv.outerHTML, expectedHTML, "collapseDiv html and expectedHTML are identical"); }); + + // BEGIN createCardFooter unit tests + QUnit.module("createCardFooter"); + + QUnit.test("card footer no rule violations does not render", function(assert) { + let ruleViolations = []; + let cardFooter = createCardFooter(ruleViolations); + assert.strictEqual(cardFooter, null, "cardFooter is null"); + }); + + QUnit.test("card footer with one rule violation renders", function(assert) { + let ruleViolations = [{"label": "Fare limits", "rule_break_text": "You did a bad thing"}]; + let cardFooter = createCardFooter(ruleViolations); + let expectedHTML = `<div class="card-footer"><div class="alert alert-danger"><div class="alert-heading">Rule Violations</div><hr><p><strong>Fare limits</strong><br>You did a bad thing</p></div></div>`; + assert.deepEqual(cardFooter.outerHTML, expectedHTML, "cardFooter html and expectedHTML are identical"); + }); + + QUnit.test("card footer with multiple rule violation renders", function(assert) { + let ruleViolations = [{"label": "Fare limits", "rule_break_text": "You did a bad thing"}, {"label": "Fare limits", "rule_break_text": "Now you've done it"}]; + let cardFooter = createCardFooter(ruleViolations); + let expectedHTML = `<div class="card-footer"><div class="alert alert-danger"><div class="alert-heading">Rule Violations</div><hr><p><strong>Fare limits</strong><br>You did a bad thing</p><p><strong>Fare limits</strong><br>Now you've done it</p></div></div>`; + assert.deepEqual(cardFooter.outerHTML, expectedHTML, "cardFooter html and expectedHTML are identical"); + }); </script> </body> </html> From 839edcf7949bc1c0f7fbb15e4131ddf6424975b4 Mon Sep 17 00:00:00 2001 From: Preston Doman <pdoman@pdx.edu> Date: Mon, 4 Mar 2019 15:34:03 -0800 Subject: [PATCH 3/6] Add createReportForm tests --- front/static/js/testObjects.js | 38 +++++++++++++++ front/static/tests/qunit_tests.html | 76 ++++++++++++++++++++++++++++- 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 front/static/js/testObjects.js diff --git a/front/static/js/testObjects.js b/front/static/js/testObjects.js new file mode 100644 index 0000000..2063aab --- /dev/null +++ b/front/static/js/testObjects.js @@ -0,0 +1,38 @@ +const testReport = {"title": "New Report 1", "report_pk": 2, "date_submitted": "2019-03-04T08:00:00Z", "sections": [{"title": "General Info", "rule_violations": [], "fields": [{"field_type": "boolean", "label": "Have you taken this trip already?", "field_name": "after_trip", "value": false}], "completed": false, "id": 10, "html_description": "<p>Each section of this report is designed to guide you through the reimbursement process. Please read through each and answer as many questions as you can that apply to you.</p><p>Be sure to click 'Save' after completing each section. Your entered data will be saved as you progress. You may also receive feedback from sections regarding policy restrictions and special requirements.</p>"}, {"title": "Pre-trip Planning", "rule_violations": [], "fields": [{"field_type": "date", "label": "Departure date", "field_name": "departure_date", "value": "None"}, {"field_type": "date", "label": "Return date", "field_name": "return_date", "value": "None"}, {"field_type": "file", "label": "Screenshot of least expensive ticket fare", "field_name": "screenshot", "value": ""}, {"field_type": "date", "label": "Date of screenshot", "field_name": "screenshot_date", "value": "None"}, {"field_type": "decimal", "label": "Lowest fare", "field_name": "lowest_fare", "value": "0.00"}, {"field_type": "decimal", "label": "Flight duration of lowest fare (hours)", "field_name": "lowest_fare_duration", "value": "0.00"}, {"field_type": "decimal", "label": "Fare of your preferred flight", "field_name": "preferred_flight_fare", "value": "0.00"}, {"field_type": "decimal", "label": "Flight duration of your preferred flight (hours)", "field_name": "preferred_flight_duration", "value": "0.00"}, {"field_type": "boolean", "label": "Is this an international flight?", "field_name": "international_flight", "value": false}], "completed": false, "id": 11, "html_description": "<p>At least 14 days before buying tickets for your trip, take a screenshot of a flight search showing the least expensive fare available for the dates you need to travel. Include fares from multiple airlines if possible. This information will be used to calculate reimbursable fare amounts.</p>"}, {"title": "Flight Info", "rule_violations": [], "fields": [{"field_type": "date", "label": "Actual departure date", "field_name": "departure_date", "value": "None"}, {"field_type": "date", "label": "Actual return date", "field_name": "return_date", "value": "None"}, {"field_type": "decimal", "label": "Ticket fare", "field_name": "fare", "value": "0.00"}, {"field_type": "file", "label": "Screenshot of confirmation of purchase", "field_name": "confirmation_screenshot", "value": ""}, {"field_type": "boolean", "label": "Was this an international flight?", "field_name": "international_flight", "value": false}], "completed": false, "id": 12, "html_description": "<p>Enter the details of your flight once you have made your purchase.</p>"}, {"title": "Hotel / Lodging", "rule_violations": [], "fields": [{"field_type": "decimal", "label": "USGSA Per diem rate", "field_name": "per_diem_rate", "value": "0.00"}, {"field_type": "decimal", "label": "Total cost for lodging", "field_name": "cost", "value": "0.00"}, {"field_type": "date", "label": "Check-in date", "field_name": "check_in_date", "value": "None"}, {"field_type": "date", "label": "Check-out date", "field_name": "check_out_date", "value": "None"}, {"field_type": "file", "label": "Screenshot of invoice", "field_name": "invoice_screenshot", "value": ""}], "completed": false, "id": 13, "html_description": "<p>Please submit a receipt from your hotel including both the total amount and the dates of your stay. Per diem rates can be found on <a href='https://www.gsa.gov/travel/plan-book/per-diem-rates' target='_blank'>the U.S. GSA website</a>.</p>"}, {"title": "Local Transportation", "rule_violations": [], "fields": [{"field_type": "decimal", "label": "Total cost of local transportation", "field_name": "cost", "value": "0.00"}], "completed": false, "id": 14, "html_description": "<p>This amount includes taxis, uber, and public transportation.</p>"}, {"title": "Per Diem and Other Expenses", "rule_violations": [], "fields": [{"field_type": "decimal", "label": "Per diem rate", "field_name": "rate", "value": "0.00"}, {"field_type": "integer", "label": "Number of full days of travel", "field_name": "full_days", "value": 0}, {"field_type": "integer", "label": "Number of partial days of travel", "field_name": "partial_days", "value": 0}, {"field_type": "decimal", "label": "Total Cost for meals and incidentals", "field_name": "cost", "value": "0.00"}], "completed": false, "id": 15, "html_description": "<p>Your per diem allowance is used to cover meals and incidental expenses. The rate for your travel destination can be found on the following websites:</p><ul><li><a href='https://www.gsa.gov/perdiem' target='_blank'>US General Serices Administration</a> for travel in the United States</li><li><a href='https://aoprals.state.gov/web920/per_diem.asp' target='_blank'>US Department of State</a> for travel outside the United States</li></ul><p>You may request up to 100% of the listed rate for a full day of travel, or 75% for a partial day of travel."}, {"title": "Payment Option - Paypal", "rule_violations": [], "fields": [{"field_type": "string", "label": "Email address used with Paypal", "field_name": "paypal_email", "value": ""}, {"field_type": "string", "label": "Preferred currency", "field_name": "preferred_currency", "value": ""}], "completed": false, "id": 16, "html_description": "<p>Complete this section if you wish to be reimbursed via Paypal. This is the preferred reimbursement method of Software Freedom Conservancy.</p>"}, {"title": "Payment Option - Check", "rule_violations": [], "fields": [{"field_type": "string", "label": "Street address", "field_name": "address_1", "value": ""}, {"field_type": "string", "label": "Street address 2", "field_name": "address_2", "value": ""}, {"field_type": "string", "label": "City", "field_name": "city", "value": ""}, {"field_type": "string", "label": "State", "field_name": "state", "value": ""}, {"field_type": "string", "label": "Zip code", "field_name": "zip", "value": ""}], "completed": false, "id": 17, "html_description": "<p>Complete this section if you wish to be reimbursed in USD via check sent by mail.</p>"}, {"title": "Payment Option - Bank Wire", "rule_violations": [], "fields": [{"field_type": "string", "label": "Full name of account holder", "field_name": "name", "value": ""}, {"field_type": "string", "label": "Street address", "field_name": "address_1", "value": ""}, {"field_type": "string", "label": "Street address 2", "field_name": "address_2", "value": ""}, {"field_type": "string", "label": "City", "field_name": "city", "value": ""}, {"field_type": "string", "label": "State", "field_name": "state", "value": ""}, {"field_type": "string", "label": "Zip code", "field_name": "zip", "value": ""}, {"field_type": "string", "label": "Account number", "field_name": "account", "value": ""}, {"field_type": "string", "label": "Preferred currency", "field_name": "currency", "value": ""}, {"field_type": "string", "label": "Bank name", "field_name": "bank_name", "value": ""}, {"field_type": "string", "label": "Bank address", "field_name": "bank_address", "value": ""}, {"field_type": "string", "label": "Bank ACH/ABA routing number (US) or SWIFT/BIC code (non-US)", "field_name": "routing_number", "value": ""}, {"field_type": "string", "label": "Additional information (see SFC policy)", "field_name": "additional_info", "value": ""}], "completed": false, "id": 18, "html_description": "<p>Complete this section if you wish to be wired the amount to your bank in your local currency. Please fill in as much of the following information as is possible. Please refer to the <a href='https://sfconservancy.org/projects/policies/conservancy-travel-policy.html' target='_blank'>SFC travel policy</a> for additional bank information required for certain countries.</p>"}], "submitted": false, "reference_number": "1234", "date_created": "2019-03-04T08:00:00Z"}; + +const typeNewExpectedHTML = `<div class="modal fade" id="newReportModal" tabindex="-1" role="dialog"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="newReportModalLabel">New Report 1</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body" id="newReportModalBody"><div class="accordion" id="newReportAccordion"><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-10-collapse">General Info</button><i id="section-10-state"></i></h2></div><div id="section-10-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Each section of this report is designed to guide you through the reimbursement process. Please read through each and answer as many questions as you can that apply to you.</p><p>Be sure to click 'Save' after completing each section. Your entered data will be saved as you progress. You may also receive feedback from sections regarding policy restrictions and special requirements.</p><form class="form section-form" id="section-10-form" data-rid="2" data-sid="10"><div class="form-group row"><label class="col-sm-4 col-form" for="section-10-after_trip">Have you taken this trip already?: </label><div class="col-sm-6"><select name="after_trip" id="section-10-after_trip" class="form-control"><option value="true">Yes</option><option value="false" selected="selected">No</option></select></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-11-collapse">Pre-trip Planning</button><i id="section-11-state"></i></h2></div><div id="section-11-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>At least 14 days before buying tickets for your trip, take a screenshot of a flight search showing the least expensive fare available for the dates you need to travel. Include fares from multiple airlines if possible. This information will be used to calculate reimbursable fare amounts.</p><form class="form section-form" id="section-11-form" data-rid="2" data-sid="11"><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-departure_date">Departure date: </label><div class="col-sm-6"><input name="departure_date" id="section-11-departure_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-return_date">Return date: </label><div class="col-sm-6"><input name="return_date" id="section-11-return_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-screenshot">Screenshot of least expensive ticket fare: </label><div class="col-sm-6"><input name="screenshot" id="section-11-screenshot" type="file" class="form-control-file"><p class="form-text"></p></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-screenshot_date">Date of screenshot: </label><div class="col-sm-6"><input name="screenshot_date" id="section-11-screenshot_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-lowest_fare">Lowest fare: </label><div class="col-sm-6"><input name="lowest_fare" id="section-11-lowest_fare" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-lowest_fare_duration">Flight duration of lowest fare (hours): </label><div class="col-sm-6"><input name="lowest_fare_duration" id="section-11-lowest_fare_duration" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-preferred_flight_fare">Fare of your preferred flight: </label><div class="col-sm-6"><input name="preferred_flight_fare" id="section-11-preferred_flight_fare" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-preferred_flight_duration">Flight duration of your preferred flight (hours): </label><div class="col-sm-6"><input name="preferred_flight_duration" id="section-11-preferred_flight_duration" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-international_flight">Is this an international flight?: </label><div class="col-sm-6"><select name="international_flight" id="section-11-international_flight" class="form-control"><option value="true">Yes</option><option value="false" selected="selected">No</option></select></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-12-collapse">Flight Info</button><i id="section-12-state"></i></h2></div><div id="section-12-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Enter the details of your flight once you have made your purchase.</p><form class="form section-form" id="section-12-form" data-rid="2" data-sid="12"><div class="form-group row"><label class="col-sm-4 col-form" for="section-12-departure_date">Actual departure date: </label><div class="col-sm-6"><input name="departure_date" id="section-12-departure_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-12-return_date">Actual return date: </label><div class="col-sm-6"><input name="return_date" id="section-12-return_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-12-fare">Ticket fare: </label><div class="col-sm-6"><input name="fare" id="section-12-fare" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-12-confirmation_screenshot">Screenshot of confirmation of purchase: </label><div class="col-sm-6"><input name="confirmation_screenshot" id="section-12-confirmation_screenshot" type="file" class="form-control-file"><p class="form-text"></p></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-12-international_flight">Was this an international flight?: </label><div class="col-sm-6"><select name="international_flight" id="section-12-international_flight" class="form-control"><option value="true">Yes</option><option value="false" selected="selected">No</option></select></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-13-collapse">Hotel / Lodging</button><i id="section-13-state"></i></h2></div><div id="section-13-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Please submit a receipt from your hotel including both the total amount and the dates of your stay. Per diem rates can be found on <a href="https://www.gsa.gov/travel/plan-book/per-diem-rates" target="_blank">the U.S. GSA website</a>.</p><form class="form section-form" id="section-13-form" data-rid="2" data-sid="13"><div class="form-group row"><label class="col-sm-4 col-form" for="section-13-per_diem_rate">USGSA Per diem rate: </label><div class="col-sm-6"><input name="per_diem_rate" id="section-13-per_diem_rate" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-13-cost">Total cost for lodging: </label><div class="col-sm-6"><input name="cost" id="section-13-cost" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-13-check_in_date">Check-in date: </label><div class="col-sm-6"><input name="check_in_date" id="section-13-check_in_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-13-check_out_date">Check-out date: </label><div class="col-sm-6"><input name="check_out_date" id="section-13-check_out_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-13-invoice_screenshot">Screenshot of invoice: </label><div class="col-sm-6"><input name="invoice_screenshot" id="section-13-invoice_screenshot" type="file" class="form-control-file"><p class="form-text"></p></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-14-collapse">Local Transportation</button><i id="section-14-state"></i></h2></div><div id="section-14-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>This amount includes taxis, uber, and public transportation.</p><form class="form section-form" id="section-14-form" data-rid="2" data-sid="14"><div class="form-group row"><label class="col-sm-4 col-form" for="section-14-cost">Total cost of local transportation: </label><div class="col-sm-6"><input name="cost" id="section-14-cost" type="number" class="form-control" step="0.01" min="0"></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-15-collapse">Per Diem and Other Expenses</button><i id="section-15-state"></i></h2></div><div id="section-15-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Your per diem allowance is used to cover meals and incidental expenses. The rate for your travel destination can be found on the following websites:</p><ul><li><a href="https://www.gsa.gov/perdiem" target="_blank">US General Serices Administration</a> for travel in the United States</li><li><a href="https://aoprals.state.gov/web920/per_diem.asp" target="_blank">US Department of State</a> for travel outside the United States</li></ul><p>You may request up to 100% of the listed rate for a full day of travel, or 75% for a partial day of travel.</p><form class="form section-form" id="section-15-form" data-rid="2" data-sid="15"><div class="form-group row"><label class="col-sm-4 col-form" for="section-15-rate">Per diem rate: </label><div class="col-sm-6"><input name="rate" id="section-15-rate" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-15-full_days">Number of full days of travel: </label><div class="col-sm-6"><input name="full_days" id="section-15-full_days" type="number" class="form-control" step="1" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-15-partial_days">Number of partial days of travel: </label><div class="col-sm-6"><input name="partial_days" id="section-15-partial_days" type="number" class="form-control" step="1" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-15-cost">Total Cost for meals and incidentals: </label><div class="col-sm-6"><input name="cost" id="section-15-cost" type="number" class="form-control" step="0.01" min="0"></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-16-collapse">Payment Option - Paypal</button><i id="section-16-state"></i></h2></div><div id="section-16-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Complete this section if you wish to be reimbursed via Paypal. This is the preferred reimbursement method of Software Freedom Conservancy.</p><form class="form section-form" id="section-16-form" data-rid="2" data-sid="16"><div class="form-group row"><label class="col-sm-4 col-form" for="section-16-paypal_email">Email address used with Paypal: </label><div class="col-sm-6"><input name="paypal_email" id="section-16-paypal_email" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-16-preferred_currency">Preferred currency: </label><div class="col-sm-6"><input name="preferred_currency" id="section-16-preferred_currency" type="text" class="form-control"></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-17-collapse">Payment Option - Check</button><i id="section-17-state"></i></h2></div><div id="section-17-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Complete this section if you wish to be reimbursed in USD via check sent by mail.</p><form class="form section-form" id="section-17-form" data-rid="2" data-sid="17"><div class="form-group row"><label class="col-sm-4 col-form" for="section-17-address_1">Street address: </label><div class="col-sm-6"><input name="address_1" id="section-17-address_1" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-17-address_2">Street address 2: </label><div class="col-sm-6"><input name="address_2" id="section-17-address_2" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-17-city">City: </label><div class="col-sm-6"><input name="city" id="section-17-city" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-17-state">State: </label><div class="col-sm-6"><input name="state" id="section-17-state" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-17-zip">Zip code: </label><div class="col-sm-6"><input name="zip" id="section-17-zip" type="text" class="form-control"></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-18-collapse">Payment Option - Bank Wire</button><i id="section-18-state"></i></h2></div><div id="section-18-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Complete this section if you wish to be wired the amount to your bank in your local currency. Please fill in as much of the following information as is possible. Please refer to the <a href="https://sfconservancy.org/projects/policies/conservancy-travel-policy.html" target="_blank">SFC travel policy</a> for additional bank information required for certain countries.</p><form class="form section-form" id="section-18-form" data-rid="2" data-sid="18"><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-name">Full name of account holder: </label><div class="col-sm-6"><input name="name" id="section-18-name" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-address_1">Street address: </label><div class="col-sm-6"><input name="address_1" id="section-18-address_1" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-address_2">Street address 2: </label><div class="col-sm-6"><input name="address_2" id="section-18-address_2" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-city">City: </label><div class="col-sm-6"><input name="city" id="section-18-city" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-state">State: </label><div class="col-sm-6"><input name="state" id="section-18-state" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-zip">Zip code: </label><div class="col-sm-6"><input name="zip" id="section-18-zip" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-account">Account number: </label><div class="col-sm-6"><input name="account" id="section-18-account" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-currency">Preferred currency: </label><div class="col-sm-6"><input name="currency" id="section-18-currency" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-bank_name">Bank name: </label><div class="col-sm-6"><input name="bank_name" id="section-18-bank_name" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-bank_address">Bank address: </label><div class="col-sm-6"><input name="bank_address" id="section-18-bank_address" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-routing_number">Bank ACH/ABA routing number (US) or SWIFT/BIC code (non-US): </label><div class="col-sm-6"><input name="routing_number" id="section-18-routing_number" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-additional_info">Additional information (see SFC policy): </label><div class="col-sm-6"><input name="additional_info" id="section-18-additional_info" type="text" class="form-control"></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div></div></div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-primary submit-report-button" data-rid="2">Submit Report</button> + </div> + </div> + </div> + </div>`; + +const typeEditExpectedHTML = `<div class="modal fade" id="editReportModal" tabindex="-1" role="dialog"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="editReportModalLabel">New Report 1</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body" id="editReportModalBody"><div class="accordion" id="editReportAccordion"><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-10-collapse">General Info</button><i id="section-10-state"></i></h2></div><div id="section-10-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Each section of this report is designed to guide you through the reimbursement process. Please read through each and answer as many questions as you can that apply to you.</p><p>Be sure to click 'Save' after completing each section. Your entered data will be saved as you progress. You may also receive feedback from sections regarding policy restrictions and special requirements.</p><form class="form section-form" id="section-10-form" data-rid="2" data-sid="10"><div class="form-group row"><label class="col-sm-4 col-form" for="section-10-after_trip">Have you taken this trip already?: </label><div class="col-sm-6"><select name="after_trip" id="section-10-after_trip" class="form-control"><option value="true">Yes</option><option value="false" selected="selected">No</option></select></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-11-collapse">Pre-trip Planning</button><i id="section-11-state"></i></h2></div><div id="section-11-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>At least 14 days before buying tickets for your trip, take a screenshot of a flight search showing the least expensive fare available for the dates you need to travel. Include fares from multiple airlines if possible. This information will be used to calculate reimbursable fare amounts.</p><form class="form section-form" id="section-11-form" data-rid="2" data-sid="11"><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-departure_date">Departure date: </label><div class="col-sm-6"><input name="departure_date" id="section-11-departure_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-return_date">Return date: </label><div class="col-sm-6"><input name="return_date" id="section-11-return_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-screenshot">Screenshot of least expensive ticket fare: </label><div class="col-sm-6"><input name="screenshot" id="section-11-screenshot" type="file" class="form-control-file"><p class="form-text"></p></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-screenshot_date">Date of screenshot: </label><div class="col-sm-6"><input name="screenshot_date" id="section-11-screenshot_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-lowest_fare">Lowest fare: </label><div class="col-sm-6"><input name="lowest_fare" id="section-11-lowest_fare" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-lowest_fare_duration">Flight duration of lowest fare (hours): </label><div class="col-sm-6"><input name="lowest_fare_duration" id="section-11-lowest_fare_duration" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-preferred_flight_fare">Fare of your preferred flight: </label><div class="col-sm-6"><input name="preferred_flight_fare" id="section-11-preferred_flight_fare" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-preferred_flight_duration">Flight duration of your preferred flight (hours): </label><div class="col-sm-6"><input name="preferred_flight_duration" id="section-11-preferred_flight_duration" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-11-international_flight">Is this an international flight?: </label><div class="col-sm-6"><select name="international_flight" id="section-11-international_flight" class="form-control"><option value="true">Yes</option><option value="false" selected="selected">No</option></select></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-12-collapse">Flight Info</button><i id="section-12-state"></i></h2></div><div id="section-12-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Enter the details of your flight once you have made your purchase.</p><form class="form section-form" id="section-12-form" data-rid="2" data-sid="12"><div class="form-group row"><label class="col-sm-4 col-form" for="section-12-departure_date">Actual departure date: </label><div class="col-sm-6"><input name="departure_date" id="section-12-departure_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-12-return_date">Actual return date: </label><div class="col-sm-6"><input name="return_date" id="section-12-return_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-12-fare">Ticket fare: </label><div class="col-sm-6"><input name="fare" id="section-12-fare" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-12-confirmation_screenshot">Screenshot of confirmation of purchase: </label><div class="col-sm-6"><input name="confirmation_screenshot" id="section-12-confirmation_screenshot" type="file" class="form-control-file"><p class="form-text"></p></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-12-international_flight">Was this an international flight?: </label><div class="col-sm-6"><select name="international_flight" id="section-12-international_flight" class="form-control"><option value="true">Yes</option><option value="false" selected="selected">No</option></select></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-13-collapse">Hotel / Lodging</button><i id="section-13-state"></i></h2></div><div id="section-13-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Please submit a receipt from your hotel including both the total amount and the dates of your stay. Per diem rates can be found on <a href="https://www.gsa.gov/travel/plan-book/per-diem-rates" target="_blank">the U.S. GSA website</a>.</p><form class="form section-form" id="section-13-form" data-rid="2" data-sid="13"><div class="form-group row"><label class="col-sm-4 col-form" for="section-13-per_diem_rate">USGSA Per diem rate: </label><div class="col-sm-6"><input name="per_diem_rate" id="section-13-per_diem_rate" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-13-cost">Total cost for lodging: </label><div class="col-sm-6"><input name="cost" id="section-13-cost" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-13-check_in_date">Check-in date: </label><div class="col-sm-6"><input name="check_in_date" id="section-13-check_in_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-13-check_out_date">Check-out date: </label><div class="col-sm-6"><input name="check_out_date" id="section-13-check_out_date" type="date" placeholder="mm-dd-yyyy" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-13-invoice_screenshot">Screenshot of invoice: </label><div class="col-sm-6"><input name="invoice_screenshot" id="section-13-invoice_screenshot" type="file" class="form-control-file"><p class="form-text"></p></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-14-collapse">Local Transportation</button><i id="section-14-state"></i></h2></div><div id="section-14-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>This amount includes taxis, uber, and public transportation.</p><form class="form section-form" id="section-14-form" data-rid="2" data-sid="14"><div class="form-group row"><label class="col-sm-4 col-form" for="section-14-cost">Total cost of local transportation: </label><div class="col-sm-6"><input name="cost" id="section-14-cost" type="number" class="form-control" step="0.01" min="0"></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-15-collapse">Per Diem and Other Expenses</button><i id="section-15-state"></i></h2></div><div id="section-15-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Your per diem allowance is used to cover meals and incidental expenses. The rate for your travel destination can be found on the following websites:</p><ul><li><a href="https://www.gsa.gov/perdiem" target="_blank">US General Serices Administration</a> for travel in the United States</li><li><a href="https://aoprals.state.gov/web920/per_diem.asp" target="_blank">US Department of State</a> for travel outside the United States</li></ul><p>You may request up to 100% of the listed rate for a full day of travel, or 75% for a partial day of travel.</p><form class="form section-form" id="section-15-form" data-rid="2" data-sid="15"><div class="form-group row"><label class="col-sm-4 col-form" for="section-15-rate">Per diem rate: </label><div class="col-sm-6"><input name="rate" id="section-15-rate" type="number" class="form-control" step="0.01" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-15-full_days">Number of full days of travel: </label><div class="col-sm-6"><input name="full_days" id="section-15-full_days" type="number" class="form-control" step="1" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-15-partial_days">Number of partial days of travel: </label><div class="col-sm-6"><input name="partial_days" id="section-15-partial_days" type="number" class="form-control" step="1" min="0"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-15-cost">Total Cost for meals and incidentals: </label><div class="col-sm-6"><input name="cost" id="section-15-cost" type="number" class="form-control" step="0.01" min="0"></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-16-collapse">Payment Option - Paypal</button><i id="section-16-state"></i></h2></div><div id="section-16-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Complete this section if you wish to be reimbursed via Paypal. This is the preferred reimbursement method of Software Freedom Conservancy.</p><form class="form section-form" id="section-16-form" data-rid="2" data-sid="16"><div class="form-group row"><label class="col-sm-4 col-form" for="section-16-paypal_email">Email address used with Paypal: </label><div class="col-sm-6"><input name="paypal_email" id="section-16-paypal_email" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-16-preferred_currency">Preferred currency: </label><div class="col-sm-6"><input name="preferred_currency" id="section-16-preferred_currency" type="text" class="form-control"></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-17-collapse">Payment Option - Check</button><i id="section-17-state"></i></h2></div><div id="section-17-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Complete this section if you wish to be reimbursed in USD via check sent by mail.</p><form class="form section-form" id="section-17-form" data-rid="2" data-sid="17"><div class="form-group row"><label class="col-sm-4 col-form" for="section-17-address_1">Street address: </label><div class="col-sm-6"><input name="address_1" id="section-17-address_1" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-17-address_2">Street address 2: </label><div class="col-sm-6"><input name="address_2" id="section-17-address_2" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-17-city">City: </label><div class="col-sm-6"><input name="city" id="section-17-city" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-17-state">State: </label><div class="col-sm-6"><input name="state" id="section-17-state" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-17-zip">Zip code: </label><div class="col-sm-6"><input name="zip" id="section-17-zip" type="text" class="form-control"></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div><div class="card"><div class="card-header"><h2 class="mb-0"><button class="btn btn-link" type="button" data-toggle="collapse" data-target="#section-18-collapse">Payment Option - Bank Wire</button><i id="section-18-state"></i></h2></div><div id="section-18-collapse" class="collapse show"><div class="card-body"><div class="alert alert-danger section-alert">This section is not complete</div><p>Complete this section if you wish to be wired the amount to your bank in your local currency. Please fill in as much of the following information as is possible. Please refer to the <a href="https://sfconservancy.org/projects/policies/conservancy-travel-policy.html" target="_blank">SFC travel policy</a> for additional bank information required for certain countries.</p><form class="form section-form" id="section-18-form" data-rid="2" data-sid="18"><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-name">Full name of account holder: </label><div class="col-sm-6"><input name="name" id="section-18-name" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-address_1">Street address: </label><div class="col-sm-6"><input name="address_1" id="section-18-address_1" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-address_2">Street address 2: </label><div class="col-sm-6"><input name="address_2" id="section-18-address_2" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-city">City: </label><div class="col-sm-6"><input name="city" id="section-18-city" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-state">State: </label><div class="col-sm-6"><input name="state" id="section-18-state" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-zip">Zip code: </label><div class="col-sm-6"><input name="zip" id="section-18-zip" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-account">Account number: </label><div class="col-sm-6"><input name="account" id="section-18-account" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-currency">Preferred currency: </label><div class="col-sm-6"><input name="currency" id="section-18-currency" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-bank_name">Bank name: </label><div class="col-sm-6"><input name="bank_name" id="section-18-bank_name" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-bank_address">Bank address: </label><div class="col-sm-6"><input name="bank_address" id="section-18-bank_address" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-routing_number">Bank ACH/ABA routing number (US) or SWIFT/BIC code (non-US): </label><div class="col-sm-6"><input name="routing_number" id="section-18-routing_number" type="text" class="form-control"></div></div><div class="form-group row"><label class="col-sm-4 col-form" for="section-18-additional_info">Additional information (see SFC policy): </label><div class="col-sm-6"><input name="additional_info" id="section-18-additional_info" type="text" class="form-control"></div></div><button type="submit" class="btn btn-primary save-section">Save</button></form></div></div></div></div></div> + <div class="modal-footer"> + <button type="button" class="btn btn-danger delete-report" data-rid="2">Delete Report</button> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-primary submit-report-button">Submit Report</button> + </div> + </div> + </div> + </div>`; \ No newline at end of file diff --git a/front/static/tests/qunit_tests.html b/front/static/tests/qunit_tests.html index 6d4ca4b..d1a2191 100644 --- a/front/static/tests/qunit_tests.html +++ b/front/static/tests/qunit_tests.html @@ -5,10 +5,61 @@ <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.9.2.css"> <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script> <script src="../js/viewHistory.js"></script> + <script src="../js/testObjects.js"></script> </head> <body> <div id="qunit"></div> - <div id="qunit-fixture"></div> + <div id="qunit-fixture"> + <div class="modal fade" id="newReportModal" tabindex="-1" role="dialog"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="newReportModalLabel"></h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body" id="newReportModalBody"> + <div class="text-center"> + <i class="fas fa-spinner fa-3x fa-spin"></i> + <br> + <br> + <h5>Creating Report ...</h5> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-primary submit-report-button">Submit Report</button> + </div> + </div> + </div> + </div> + <div class="modal fade" id="editReportModal" tabindex="-1" role="dialog"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="editReportModalLabel"></h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body" id="editReportModalBody"> + <div class="text-center"> + <i class="fas fa-spinner fa-3x fa-spin"></i> + <br> + <br> + <h5>Loading Report ...</h5> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-danger delete-report">Delete Report</button> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-primary submit-report-button">Submit Report</button> + </div> + </div> + </div> + </div> + </div> <script src="https://code.jquery.com/qunit/qunit-2.9.2.js"></script> <script> @@ -323,6 +374,29 @@ let expectedHTML = `<div class="card-footer"><div class="alert alert-danger"><div class="alert-heading">Rule Violations</div><hr><p><strong>Fare limits</strong><br>You did a bad thing</p><p><strong>Fare limits</strong><br>Now you've done it</p></div></div>`; assert.deepEqual(cardFooter.outerHTML, expectedHTML, "cardFooter html and expectedHTML are identical"); }); + + QUnit.module("createReportForm"); + + QUnit.test("new report renders", function(assert) { + createReportForm(testReport, reportType.NEW); + let newReportModal = document.getElementById("newReportModal"); + let expectedHTML = typeNewExpectedHTML; + assert.deepEqual(newReportModal.outerHTML, expectedHTML, "new report form and expectedHTML are identical") + }); + + QUnit.test("edit report renders", function(assert) { + createReportForm(testReport, reportType.EDIT); + let editReportModal = document.getElementById("editReportModal"); + let expectedHTML = typeEditExpectedHTML; + assert.deepEqual(editReportModal.outerHTML, expectedHTML, "edit report form and expectedHTML are identical") + }); + + QUnit.test("undefined report does not render", function(assert) { + let qunitFixture = document.getElementById("qunit-fixture"); + let expectedHTML = qunitFixture.outerHTML; + createReportForm(testReport, undefined); + assert.deepEqual(qunitFixture.outerHTML, expectedHTML, "report forms and expectedHTML are identical") + }); </script> </body> </html> From 5ac57e88e23930bfb0e80f59fa053b5769999cee Mon Sep 17 00:00:00 2001 From: Preston Doman <pdoman@pdx.edu> Date: Tue, 5 Mar 2019 15:58:41 -0800 Subject: [PATCH 4/6] Add displayListOfReports tests --- front/static/js/testObjects.js | 6 ++- front/static/js/viewHistory.js | 18 +++------ front/static/tests/qunit_tests.html | 59 ++++++++++++++++++++++++----- 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/front/static/js/testObjects.js b/front/static/js/testObjects.js index 2063aab..0278d85 100644 --- a/front/static/js/testObjects.js +++ b/front/static/js/testObjects.js @@ -35,4 +35,8 @@ const typeEditExpectedHTML = `<div class="modal fade" id="editReportModal" tabin </div> </div> </div> - </div>`; \ No newline at end of file + </div>`; + +const displayReportsOneReportExpected = `<div class="card-body"><table class="table table-striped table-responsive-sm" style="visibility: visible;"><thead><tr><th>Title</th><th>Date Created</th><th class="d-none d-md-table-cell">Date Submitted</th><th>Action</th></tr></thead><tbody><tr><td>TEST1</td><td>3/5/2019</td><td class="d-none d-md-table-cell">TBD</td><td><button type="submit" data-rid="4" class="btn btn-primary edit-report-button" data-toggle="modal" data-target="#editReportModal">Edit</button></td></tr></tbody></table></div>`; + +const displayReportsTwoReportsExpected = `<div class="card-body"><table class="table table-striped table-responsive-sm" style="visibility: visible;"><thead><tr><th>Title</th><th>Date Created</th><th class="d-none d-md-table-cell">Date Submitted</th><th>Action</th></tr></thead><tbody><tr><td>TEST1</td><td>3/5/2019</td><td class="d-none d-md-table-cell">TBD</td><td><button type="submit" data-rid="4" class="btn btn-primary edit-report-button" data-toggle="modal" data-target="#editReportModal">Edit</button></td></tr><tr><td>TEST2</td><td>3/5/2019</td><td class="d-none d-md-table-cell">TBD</td><td><button type="submit" data-rid="5" class="btn btn-primary edit-report-button" data-toggle="modal" data-target="#editReportModal">Edit</button></td></tr></tbody></table></div>`; \ No newline at end of file diff --git a/front/static/js/viewHistory.js b/front/static/js/viewHistory.js index 3e5b7f7..055011d 100644 --- a/front/static/js/viewHistory.js +++ b/front/static/js/viewHistory.js @@ -295,12 +295,6 @@ function createReportForm(parsedData, type) { const accordion = document.createElement("div"); accordion.classList.add("accordion"); - //submit button - const submitButton = document.querySelector(".submit-report-button"); - if (submitButton) { - submitButton.setAttribute("data-rid", parsedData.report_pk); - } - if (type === reportType.EDIT) { modalBody = document.querySelector("#editReportModalBody"); modalLabel = document.querySelector("#editReportModalLabel"); @@ -317,6 +311,11 @@ function createReportForm(parsedData, type) { return; } + const submitButton = document.querySelector(".submit-report-button"); + if (submitButton) { + submitButton.setAttribute("data-rid", parsedData.report_pk); + } + while (modalBody.firstChild) { modalBody.removeChild(modalBody.firstChild); } @@ -339,13 +338,6 @@ function createReportForm(parsedData, type) { // Traverse the fields of this section let fields = sections[i].fields; for (let j = 0; j < fields.length; j++) { - - /* - console.log("Field label: " + fields[j].label); - console.log("Field type: " + fields[j].field_type); - console.log("Field value: " + fields[j].value); - */ - // Create a form group for each field and add it to the form form.appendChild(createFormGroup(sectionIdStr, fields[j])); } diff --git a/front/static/tests/qunit_tests.html b/front/static/tests/qunit_tests.html index d1a2191..ecd21d9 100644 --- a/front/static/tests/qunit_tests.html +++ b/front/static/tests/qunit_tests.html @@ -10,6 +10,23 @@ <body> <div id="qunit"></div> <div id="qunit-fixture"> + <div class="card-body"> + <div class="text-center"> + <i class="fas fa-spinner fa-3x fa-spin"></i> + </div> + <table class="table table-striped table-responsive-sm" style="visibility:hidden"> + <thead> + <tr> + <th>Title</th> + <th>Date Created</th> + <th class="d-none d-md-table-cell">Date Submitted</th> + <th>Action</th> + </tr> + </thead> + <tbody> + </tbody> + </table> + </div> <div class="modal fade" id="newReportModal" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> @@ -96,9 +113,6 @@ assert.deepEqual(formGroup.outerHTML, expectedHTML, "boolean true renders as yes option selected"); }); - // END: Test rendering of fields with type boolean - - // BEGIN: Test rendering of fields with type date QUnit.test("date input group renders", function(assert) { let sectionIdStr = "section-1-"; @@ -138,7 +152,6 @@ let value = formGroup.querySelector("#section-1-departure_date").value; assert.deepEqual(value, field.value, "date input initialized to a value is rendered with that value"); }); - // END: Test rendering of fields with type date // BEGIN: Test rendering of fields with type string QUnit.test("string input group renders", function(assert) { @@ -166,7 +179,6 @@ let value = formGroup.querySelector("#section-1-city").value; assert.deepEqual(value, field.value, "text input initialized to a value is rendered with that value"); }); - // END: Test rendering of fields with type date // BEGIN: Test rendering of fields with type decimal QUnit.test("decimal input group renders", function(assert) { @@ -207,7 +219,6 @@ let value = formGroup.querySelector("#section-1-lowest_fare").value; assert.deepEqual(value, field.value, "decimal input initialized to 1337 has value 1337"); }); - // END: Test rendering of fields with type decimal // BEGIN: Test rendering of fields with type integer QUnit.test("integer input group renders", function(assert) { @@ -248,8 +259,6 @@ let value = formGroup.querySelector("#section-1-full_days").value; assert.deepEqual(value, field.value.toString(), "integer input initialized to 1234 has string value 1234"); }); - // END: Test rendering of fields with type integer - // BEGIN: Test rendering of fields with type file QUnit.test("file input group renders", function(assert) { @@ -277,7 +286,7 @@ let value = formGroup.querySelector(".form-text").innerHTML; assert.deepEqual(value, field.value, "file input initialized to screenshot.jpg has string value screenshot.jpg"); }); - // END: Test rendering of fields with type file + // BEGIN createCollapsibleCard unit tests QUnit.module("createCollapsibleCard"); @@ -352,6 +361,7 @@ assert.deepEqual(collapseDiv.outerHTML, expectedHTML, "collapseDiv html and expectedHTML are identical"); }); + // BEGIN createCardFooter unit tests QUnit.module("createCardFooter"); @@ -375,6 +385,8 @@ assert.deepEqual(cardFooter.outerHTML, expectedHTML, "cardFooter html and expectedHTML are identical"); }); + + // BEGIN createReportForm unit tests QUnit.module("createReportForm"); QUnit.test("new report renders", function(assert) { @@ -397,6 +409,35 @@ createReportForm(testReport, undefined); assert.deepEqual(qunitFixture.outerHTML, expectedHTML, "report forms and expectedHTML are identical") }); + + + // BEGIN displayListOfReports unit tests + QUnit.module("displayListOfReports"); + + QUnit.test("empty reports", function(assert) { + let expectedHTML = `<div class="card-body"><h5 class="text-center">No reports found.</h5></div>`; + let parsedData = {"reports": []}; + displayListOfReports(parsedData); + let cardBody = document.querySelector(".card-body"); + assert.deepEqual(cardBody.outerHTML.replace(/>\s+</g, "><"), expectedHTML, "card body and expectedHTML are identical"); + }); + + QUnit.test("one report", function(assert) { + let parsedData = {"reports": [{"date_created": "2019-03-05T08:00:00Z", "title": "TEST1", "reference_number": "1234", "date_submitted": "2019-03-05T08:00:00Z", "user_id": 2, "submitted": false, "report_pk": 4}]}; + let expectedHTML = displayReportsOneReportExpected; + displayListOfReports(parsedData); + let cardBody = document.querySelector(".card-body"); + assert.deepEqual(cardBody.outerHTML.replace(/>\s+</g, "><"), expectedHTML, "card body and expectedHTML are identical"); + }); + + + QUnit.test("two reports", function(assert) { + let parsedData = {"reports": [{"date_created": "2019-03-05T08:00:00Z", "title": "TEST1", "reference_number": "1234", "date_submitted": "2019-03-05T08:00:00Z", "user_id": 2, "submitted": false, "report_pk": 4}, {"date_created": "2019-03-05T08:00:00Z", "title": "TEST2", "reference_number": "12345", "date_submitted": "2019-03-05T08:00:00Z", "user_id": 2, "submitted": false, "report_pk": 5}]}; + let expectedHTML = displayReportsTwoReportsExpected; + displayListOfReports(parsedData); + let cardBody = document.querySelector(".card-body"); + assert.deepEqual(cardBody.outerHTML.replace(/>\s+</g, "><"), expectedHTML, "card body and expectedHTML are identical"); + }); </script> </body> </html> From 7ec581b6276b26fa9515145ac0dcaf6ced6f3f9a Mon Sep 17 00:00:00 2001 From: Preston Doman <pdoman@pdx.edu> Date: Tue, 5 Mar 2019 16:20:06 -0800 Subject: [PATCH 5/6] Finish displayListOfReports tests --- front/static/js/testObjects.js | 4 +++- front/static/tests/qunit_tests.html | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/front/static/js/testObjects.js b/front/static/js/testObjects.js index 0278d85..d9284d0 100644 --- a/front/static/js/testObjects.js +++ b/front/static/js/testObjects.js @@ -39,4 +39,6 @@ const typeEditExpectedHTML = `<div class="modal fade" id="editReportModal" tabin const displayReportsOneReportExpected = `<div class="card-body"><table class="table table-striped table-responsive-sm" style="visibility: visible;"><thead><tr><th>Title</th><th>Date Created</th><th class="d-none d-md-table-cell">Date Submitted</th><th>Action</th></tr></thead><tbody><tr><td>TEST1</td><td>3/5/2019</td><td class="d-none d-md-table-cell">TBD</td><td><button type="submit" data-rid="4" class="btn btn-primary edit-report-button" data-toggle="modal" data-target="#editReportModal">Edit</button></td></tr></tbody></table></div>`; -const displayReportsTwoReportsExpected = `<div class="card-body"><table class="table table-striped table-responsive-sm" style="visibility: visible;"><thead><tr><th>Title</th><th>Date Created</th><th class="d-none d-md-table-cell">Date Submitted</th><th>Action</th></tr></thead><tbody><tr><td>TEST1</td><td>3/5/2019</td><td class="d-none d-md-table-cell">TBD</td><td><button type="submit" data-rid="4" class="btn btn-primary edit-report-button" data-toggle="modal" data-target="#editReportModal">Edit</button></td></tr><tr><td>TEST2</td><td>3/5/2019</td><td class="d-none d-md-table-cell">TBD</td><td><button type="submit" data-rid="5" class="btn btn-primary edit-report-button" data-toggle="modal" data-target="#editReportModal">Edit</button></td></tr></tbody></table></div>`; \ No newline at end of file +const displayReportsTwoReportsExpected = `<div class="card-body"><table class="table table-striped table-responsive-sm" style="visibility: visible;"><thead><tr><th>Title</th><th>Date Created</th><th class="d-none d-md-table-cell">Date Submitted</th><th>Action</th></tr></thead><tbody><tr><td>TEST1</td><td>3/5/2019</td><td class="d-none d-md-table-cell">TBD</td><td><button type="submit" data-rid="4" class="btn btn-primary edit-report-button" data-toggle="modal" data-target="#editReportModal">Edit</button></td></tr><tr><td>TEST2</td><td>3/5/2019</td><td class="d-none d-md-table-cell">TBD</td><td><button type="submit" data-rid="5" class="btn btn-primary edit-report-button" data-toggle="modal" data-target="#editReportModal">Edit</button></td></tr></tbody></table></div>`; + +const displayReportsOneViewableExpected = `<div class="card-body"><table class="table table-striped table-responsive-sm" style="visibility: visible;"><thead><tr><th>Title</th><th>Date Created</th><th class="d-none d-md-table-cell">Date Submitted</th><th>Action</th></tr></thead><tbody><tr><td>TEST2</td><td>3/5/2019</td><td class="d-none d-md-table-cell">3/5/2019</td><td><button type="submit" data-rid="5" class="btn btn-success view-report-button" data-toggle="modal" data-target="#viewReportModal">View</button></td></tr></tbody></table></div>`; diff --git a/front/static/tests/qunit_tests.html b/front/static/tests/qunit_tests.html index ecd21d9..d8db4b5 100644 --- a/front/static/tests/qunit_tests.html +++ b/front/static/tests/qunit_tests.html @@ -422,7 +422,7 @@ assert.deepEqual(cardBody.outerHTML.replace(/>\s+</g, "><"), expectedHTML, "card body and expectedHTML are identical"); }); - QUnit.test("one report", function(assert) { + QUnit.test("one editable report", function(assert) { let parsedData = {"reports": [{"date_created": "2019-03-05T08:00:00Z", "title": "TEST1", "reference_number": "1234", "date_submitted": "2019-03-05T08:00:00Z", "user_id": 2, "submitted": false, "report_pk": 4}]}; let expectedHTML = displayReportsOneReportExpected; displayListOfReports(parsedData); @@ -431,13 +431,21 @@ }); - QUnit.test("two reports", function(assert) { + QUnit.test("two editable reports", function(assert) { let parsedData = {"reports": [{"date_created": "2019-03-05T08:00:00Z", "title": "TEST1", "reference_number": "1234", "date_submitted": "2019-03-05T08:00:00Z", "user_id": 2, "submitted": false, "report_pk": 4}, {"date_created": "2019-03-05T08:00:00Z", "title": "TEST2", "reference_number": "12345", "date_submitted": "2019-03-05T08:00:00Z", "user_id": 2, "submitted": false, "report_pk": 5}]}; let expectedHTML = displayReportsTwoReportsExpected; displayListOfReports(parsedData); let cardBody = document.querySelector(".card-body"); assert.deepEqual(cardBody.outerHTML.replace(/>\s+</g, "><"), expectedHTML, "card body and expectedHTML are identical"); }); + + QUnit.test("one viewable report", function(assert) { + let parsedData = {"reports": [{"date_created": "2019-03-05T08:00:00Z", "title": "TEST2", "reference_number": "12345", "date_submitted": "2019-03-05T08:00:00Z", "user_id": 2, "submitted": true, "report_pk": 5}]}; + let expectedHTML = displayReportsOneViewableExpected; + displayListOfReports(parsedData); + let cardBody = document.querySelector(".card-body"); + assert.deepEqual(cardBody.outerHTML.replace(/>\s+</g, "><"), expectedHTML, "card body and expectedHTML are identical"); + }); </script> </body> </html> From 62cebfba0f3d698a686d922c9bd46acfde4751aa Mon Sep 17 00:00:00 2001 From: Preston Doman <pdoman@pdx.edu> Date: Wed, 6 Mar 2019 13:36:51 -0800 Subject: [PATCH 6/6] Move tests directory --- front/{static => }/tests/qunit_tests.html | 4 ++-- front/{static/js => tests}/testObjects.js | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename front/{static => }/tests/qunit_tests.html (99%) rename front/{static/js => tests}/testObjects.js (100%) diff --git a/front/static/tests/qunit_tests.html b/front/tests/qunit_tests.html similarity index 99% rename from front/static/tests/qunit_tests.html rename to front/tests/qunit_tests.html index d8db4b5..6636874 100644 --- a/front/static/tests/qunit_tests.html +++ b/front/tests/qunit_tests.html @@ -4,8 +4,8 @@ <title>QUnit Tests</title> <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.9.2.css"> <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script> - <script src="../js/viewHistory.js"></script> - <script src="../js/testObjects.js"></script> + <script src="../static/js/viewHistory.js"></script> + <script src="testObjects.js"></script> </head> <body> <div id="qunit"></div> diff --git a/front/static/js/testObjects.js b/front/tests/testObjects.js similarity index 100% rename from front/static/js/testObjects.js rename to front/tests/testObjects.js