Skip to content

Commit

Permalink
fix/add missing/disabled integration tests (DefectDojo#5159)
Browse files Browse the repository at this point in the history
* add/fix integration tests

* set waiting time for exports to 20 seconds

* GHA: log always

Co-authored-by: Stefan Fleckenstein <[email protected]>
  • Loading branch information
valentijnscholten and StefanFl authored Sep 28, 2021
1 parent 5ecfef0 commit cb9f187
Show file tree
Hide file tree
Showing 11 changed files with 215 additions and 35 deletions.
1 change: 1 addition & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ jobs:
run: docker-compose up --exit-code-from integration-tests integration-tests

- name: Logs
if: always()
run: docker-compose logs --tail="2500"

- name: Shutdown
Expand Down
16 changes: 8 additions & 8 deletions docker/entrypoint-integration-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ function success() {
echo "Success: $1 test passed\n"
}

test="Finding integration tests"
echo "Running: $test"
if python3 tests/finding_test.py ; then
success $test
else
fail $test
fi

test="Report Builder tests"
echo "Running: $test"
if python3 tests/report_builder_test.py ; then
Expand Down Expand Up @@ -102,14 +110,6 @@ else
fail $test
fi

test="Finding integration tests"
echo "Running: $test"
if python3 tests/finding_test.py ; then
success $test
else
fail $test
fi

test="Test integration tests"
echo "Running: $test"
if python3 tests/test_test.py ; then
Expand Down
11 changes: 11 additions & 0 deletions dojo/finding/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -903,13 +903,24 @@ def simple_risk_accept(request, fid):

ra_helper.simple_risk_accept(finding)

messages.add_message(request,
messages.WARNING,
'Finding risk accepted.',
extra_tags='alert-success')

return redirect_to_return_url_or_else(request, reverse('view_finding', args=(finding.id, )))


@user_is_authorized(Finding, Permissions.Risk_Acceptance, 'fid', 'staff')
def risk_unaccept(request, fid):
finding = get_object_or_404(Finding, id=fid)
ra_helper.risk_unaccept(finding)

messages.add_message(request,
messages.WARNING,
'Finding risk unaccepted.',
extra_tags='alert-success')

return redirect_to_return_url_or_else(request, reverse('view_finding', args=(finding.id, )))


Expand Down
2 changes: 1 addition & 1 deletion dojo/templates/dojo/add_findings.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ <h4>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input class="btn btn-primary" type="submit" value="Add Another Finding"/>
<input class="btn btn-primary" type="submit" value="Finished"/>
<input class="btn btn-primary" type="submit" id="id_finished" value="Finished"/>
</div>
</div>
</form>
Expand Down
2 changes: 1 addition & 1 deletion dojo/templates/dojo/findings_list_snippet.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ <h3 class="has-filters">
{% endif %}
<div class="btn-group mr-2" role="group" aria-label="Bulk Actions">
{% if product_tab and not 'DISABLE_FINDING_MERGE'|setting_enabled %}
<button type="button" class="btn btn-sm btn-primary" data-toggle="tooltip" data-placement="bottom" title="Merge Findings">
<button type="button" id="merge_findings" class="btn btn-sm btn-primary" data-toggle="tooltip" data-placement="bottom" title="Merge Findings">
<a class="white-color merge" href="#" alt="Merge Findings">
<i class="fa fa-compress"></i>
</a>
Expand Down
2 changes: 1 addition & 1 deletion dojo/templates/dojo/templates.html
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ <h3 class="has-filters">
style="display: inline" class="form-inline form">
{% csrf_token %}
<input type="hidden" name="id" value="{{ finding.id }}"/>
<button type="submit" class="btn btn-danger btn-sm template-delete">Delete
<button type="submit" id="id_delete" class="btn btn-danger btn-sm template-delete">Delete
</button>
</form>
</td>
Expand Down
6 changes: 3 additions & 3 deletions dojo/templates/dojo/view_test.html
Original file line number Diff line number Diff line change
Expand Up @@ -466,12 +466,12 @@ <h4 class="has-filters"> Findings ({{findings.total_count}}) <small>{{ test.id|g
<div id="test-pulldown" class="dropdown pull-right">
&nbsp;<button id="show-filters" data-toggle="collapse" data-target="#the-filters" class="btn btn-primary toggle-filters"> <i class="fa fa-filter"></i> <i class="caret"></i> </button>
{% if test|has_object_permission:"Finding_Add" or user|is_authorized_for_change:test %}
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenu1"
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenu_test_add"
data-toggle="dropdown" aria-expanded="true">
<span class="fa fa-plus"></span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="dropdownMenu1">
<ul class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="dropdownMenu_test_add">
<li role="presentation">
<a title="Add Finding" href="{% url 'add_findings' test.id %}">
<span class="fa fa-bug"></span> New Finding
Expand Down Expand Up @@ -533,7 +533,7 @@ <h4 class="has-filters"> Findings ({{findings.total_count}}) <small>{{ test.id|g
{% endif %}
<div class="btn-group mr-2" role="group" aria-label="Bulk Actions">
{% if product_tab and not 'DISABLE_FINDING_MERGE'|setting_enabled %}
<button type="button" class="btn btn-info btn-sm btn-primary" data-toggle="tooltip" data-placement="bottom" title="Merge Findings">
<button type="button" id="merge_findings" class="btn btn-info btn-sm btn-primary" data-toggle="tooltip" data-placement="bottom" title="Merge Findings">
<a class="white-color merge" href="#" alt="Merge Findings">
<i class="fa fa-compress"></i>
</a>
Expand Down
16 changes: 14 additions & 2 deletions tests/base_test_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ def delete_product_if_exists(self, name="QA Test"):
if len(qa_products) > 0:
self.test_delete_product(name)

@on_exception_html_source_logger
def delete_finding_template_if_exists(self, name="App Vulnerable to XSS"):
driver = self.driver

driver.get(self.base_url + "template")
# Click on `Delete Template` button
templates = driver.find_elements(By.LINK_TEXT, name)
if len(templates) > 0:
driver.find_element_by_id("id_delete").click()
# Click 'Yes' on Alert popup
driver.switch_to.alert.accept()

# used to load some page just to get started
# we choose /user because it's lightweight and fast
def goto_some_page(self):
Expand Down Expand Up @@ -273,7 +285,7 @@ def enable_github(self):
def set_block_execution(self, block_execution=True):
# we set the admin user (ourselves) to have block_execution checked
# this will force dedupe to happen synchronously, among other things like notifications, rules, ...
print('setting lbock execution to: ', str(block_execution))
print('setting block execution to: ', str(block_execution))
driver = self.driver
driver.get(self.base_url + 'profile')
if driver.find_element_by_id('id_block_execution').is_selected() != block_execution:
Expand Down Expand Up @@ -340,7 +352,7 @@ def assertNoConsoleErrors(self):
if self.accept_javascript_errors:
print('WARNING: skipping SEVERE javascript error because accept_javascript_errors is True!')
elif re.search(accepted_javascript_messages, entry['message']):
print('WARNING: skipping javascript errors related to finding images, see https://github.com/DefectDojo/django-DefectDojo/issues/2045')
print('WARNING: skipping javascript errors related to known issues images, see https://github.com/DefectDojo/django-DefectDojo/blob/master/tests/base_test_class.py#L324')
else:
self.assertNotEqual(entry['level'], 'SEVERE')

Expand Down
126 changes: 119 additions & 7 deletions tests/finding_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def test_csv_export(self):
driver.find_element_by_id("csv_export").click()

file_found = False
for i in range(1, 10):
for i in range(1, 20):
time.sleep(1)
if Path("/tmp/findings.csv").is_file():
file_found = True
Expand All @@ -86,7 +86,7 @@ def test_excel_export(self):
driver.find_element_by_id("excel_export").click()

file_found = False
for i in range(1, 10):
for i in range(1, 20):
time.sleep(1)
if Path("/tmp/findings.xlsx").is_file():
file_found = True
Expand Down Expand Up @@ -146,6 +146,26 @@ def test_add_image(self):
# Assert ot the query to dtermine status of failure
self.assertTrue(self.is_success_message_present(text='Files updated successfully.'))

@on_exception_html_source_logger
def test_add_note_to_finding(self):
# The Name of the Finding created by test_add_product_finding => 'App Vulnerable to XSS'
# Test To Add Finding To product
# login to site, password set to fetch from environ
driver = self.driver
# Navigate to All Finding page
self.goto_all_findings_list(driver)
# Select and click on the particular finding to edit
driver.find_element_by_link_text("App Vulnerable to XSS").click()

# Notes are on the view_test page
driver.find_element_by_id("id_entry").clear()
driver.find_element_by_id("id_entry").send_keys("This is a sample note for all to see.")
# "Click" the submit button to complete the transaction
driver.find_element_by_xpath("//input[@value='Add Note']").click()

# Assert ot the query to dtermine status of failure
self.assertTrue(self.is_success_message_present(text='Note saved.'))

def test_mark_finding_for_review(self):
# login to site, password set to fetch from environ
driver = self.driver
Expand Down Expand Up @@ -275,6 +295,55 @@ def test_open_finding(self):
# Assert ot the query to dtermine status of failure
self.assertTrue(pre_status != post_status)

@on_exception_html_source_logger
def test_simple_accept_finding(self):
driver = self.driver
# Navigate to All Finding page
self.goto_all_findings_list(driver)
# Select and click on the particular finding to edit
driver.find_element_by_link_text("App Vulnerable to XSS").click()
# Get the status of the current endpoint
pre_status = driver.find_element_by_xpath('//*[@id="vuln_endpoints"]/tbody/tr/td[3]').text
# Click on the 'dropdownMenu1 button'
driver.find_element_by_id("dropdownMenu1").click()
# Click on `Close Finding`
driver.find_element_by_link_text("Accept Risk").click()
# Query the site to determine if the finding has been added
# Assert ot the query to dtermine status of failure
self.assertTrue(self.is_success_message_present(text='Finding risk accepted.'))
# Check to see if the endpoint was mitigated
# Select and click on the particular finding to edit
driver.find_element_by_link_text("App Vulnerable to XSS").click()
# Get the status of the current endpoint
# This will throw exception if the test fails due to invalid xpath
# TODO risk acceptance doesn't mitigate endpoints currently
# post_status = driver.find_element_by_xpath('//*[@id="remd_endpoints"]/tbody/tr/td[3]').text
# self.assertTrue(pre_status != post_status)

def test_unaccept_finding(self):
driver = self.driver
# Navigate to All Finding page
self.goto_all_findings_list(driver)
# Select and click on the particular finding to edit
driver.find_element_by_link_text("App Vulnerable to XSS").click()
# Get the status of the current endpoint
pre_status = driver.find_element_by_xpath('//*[@id="vuln_endpoints"]/tbody/tr/td[3]').text
# Click on the 'dropdownMenu1 button'
driver.find_element_by_id("dropdownMenu1").click()
# Click on `Close Finding`
driver.find_element_by_link_text("Unaccept Risk").click()
# Query the site to determine if the finding has been added
# Assert ot the query to dtermine status of failure
self.assertTrue(self.is_success_message_present(text='Finding risk unaccepted.'))
# Check to see if the endpoint was mitigated
# Select and click on the particular finding to edit
driver.find_element_by_link_text("App Vulnerable to XSS").click()
# Get the status of the current endpoint
# This will throw exception if the test fails due to invalid xpath
# TODO risk acceptance doesn't mitigate endpoints currently
# post_status = driver.find_element_by_xpath('//*[@id="remd_endpoints"]/tbody/tr/td[3]').text
# self.assertTrue(pre_status != post_status)

def test_make_finding_a_template(self):
driver = self.driver
# Navigate to All Finding page
Expand Down Expand Up @@ -323,6 +392,44 @@ def test_apply_template_to_a_finding(self):
# Assert ot the query to dtermine status of failure
self.assertTrue(self.is_text_present_on_page(text='App Vulnerable to XSS'))

@on_exception_html_source_logger
def test_create_finding_from_template(self):
driver = self.driver
# Navigate to All Finding page
# goto engagemnent list (and wait for javascript to load)
self.goto_all_engagements_overview(driver)

# Select a previously created engagement title
driver.find_element_by_partial_link_text("Ad Hoc Engagement").click()
driver.find_element_by_partial_link_text("Pen Test").click()

# Click on the 'dropdownMenu1 button'
# print("\nClicking on dropdown menu \n")
driver.find_element_by_id("dropdownMenu_test_add").click()
self.assertNoConsoleErrors()

# Click on `Apply Template to Finding`
# print("\nClicking on apply template \n")
driver.find_element_by_link_text("Finding From Template").click()
self.assertNoConsoleErrors()
# click on the template of 'App Vulnerable to XSS'
print("\nClicking on the template \n")
driver.find_element_by_link_text("Use This Template").click()
self.assertNoConsoleErrors()

driver.find_element_by_id("id_title").clear()
driver.find_element_by_id("id_title").send_keys("App Vulnerable to XSS from Template")
self.assertNoConsoleErrors()
# Click the 'finished' button to submit
# print("\nClicking on finished \n")
driver.find_element_by_id("id_finished").click()
self.assertNoConsoleErrors()
# Query the site to determine if the finding has been added

# Assert to the query to determine status of failure
self.assertTrue(self.is_success_message_present(text='Finding from template added successfully.'))
self.assertTrue(self.is_text_present_on_page(text='App Vulnerable to XSS From Template'))

@on_exception_html_source_logger
def test_delete_finding_template(self):
driver = self.driver
Expand Down Expand Up @@ -400,27 +507,32 @@ def add_finding_tests_to_suite(suite, jira=False, github=False, block_execution=

# Add each test the the suite to be run
# success and failure is output by the test
suite.addTest(BaseTestCase('delete_finding_template_if_exists'))
suite.addTest(ProductTest('test_create_product'))
suite.addTest(ProductTest('test_add_product_finding'))
# TODO add some more findings with different statuses
suite.addTest(FindingTest('test_list_findings_all'))
# The next 3 tests don't work and need to be reworked
# suite.addTest(FindingTest('test_list_findings_closed'))
# suite.addTest(FindingTest('test_list_findings_accepted'))
# suite.addTest(FindingTest('test_list_findings_open'))
suite.addTest(FindingTest('test_list_findings_open'))
suite.addTest(FindingTest('test_quick_report'))
suite.addTest(FindingTest('test_csv_export'))
suite.addTest(FindingTest('test_excel_export'))
suite.addTest(FindingTest('test_list_components'))
suite.addTest(FindingTest('test_edit_finding'))
suite.addTest(FindingTest('test_add_note_to_finding'))
suite.addTest(FindingTest('test_add_image'))
suite.addTest(FindingTest('test_delete_image'))
suite.addTest(FindingTest('test_mark_finding_for_review'))
suite.addTest(FindingTest('test_clear_review_from_finding'))
suite.addTest(FindingTest('test_close_finding'))
suite.addTest(FindingTest('test_list_findings_closed'))
suite.addTest(FindingTest('test_open_finding'))
suite.addTest(ProductTest('test_enable_simple_risk_acceptance'))
suite.addTest(FindingTest('test_simple_accept_finding'))
suite.addTest(FindingTest('test_list_findings_accepted'))
suite.addTest(FindingTest('test_list_findings_all'))
suite.addTest(FindingTest('test_unaccept_finding'))
suite.addTest(FindingTest('test_make_finding_a_template'))
suite.addTest(FindingTest('test_apply_template_to_a_finding'))
suite.addTest(FindingTest('test_create_finding_from_template'))
suite.addTest(FindingTest('test_import_scan_result'))
suite.addTest(FindingTest('test_delete_finding'))
suite.addTest(FindingTest('test_delete_finding_template'))
Expand Down
28 changes: 28 additions & 0 deletions tests/product_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,34 @@ def test_edit_product_description(self):
self.is_success_message_present(text='Product with this Name already exists.'))
self.assertFalse(self.is_error_message_present())

# For product consistency sake, We won't be editting the product title
# instead We can edit the product description
@on_exception_html_source_logger
def test_enable_simple_risk_acceptance(self):
# Login to the site. Password will have to be modified
# to match an admin password in your own container
driver = self.driver
# Navigate to the product page
self.goto_product_overview(driver)
# Select and click on the particular product to edit
driver.find_element_by_link_text("QA Test").click()
# "Click" the dropdown option
# driver.execute_script("window.scrollTo(0, 0)")
driver.find_element_by_id("dropdownMenu1").click()
# Click on the 'Edit' option
driver.find_element_by_link_text("Edit").click()
# Enable simple risk acceptance
driver.find_element_by_xpath('//*[@id="id_enable_simple_risk_acceptance"]').click()

# "Click" the submit button to complete the transaction
driver.find_element_by_css_selector("input.btn.btn-primary").click()
# Query the site to determine if the product has been added

# Assert ot the query to dtermine status of failure
self.assertTrue(self.is_success_message_present(text='Product updated successfully') or
self.is_success_message_present(text='Product with this Name already exists.'))
self.assertFalse(self.is_error_message_present())

@on_exception_html_source_logger
def test_add_product_engagement(self):
# Test To Add Engagement To product
Expand Down
Loading

0 comments on commit cb9f187

Please sign in to comment.