Add basic test infrastructure using unittest. Add tests to verify the 3 mechanisms of determining that a username is *not* supported on a given site.
Created SherlockBaseTest() class that provides infrastructure for the tests. TODO: It seems that devRant is not detecting users that certainly exist. TODO: While running tests, there is a ResourceWarning from an unclosed SSLSocket. This needs work.
This commit is contained in:
parent
7c196a0d7a
commit
f6860510ea
22
README.md
22
README.md
|
|
@ -1,5 +1,5 @@
|
|||
# Sherlock
|
||||
> Find usernames across [social networks](https://github.com/theyahya/sherlock/blob/master/sites.md)
|
||||
> Find usernames across [social networks](https://github.com/theyahya/sherlock/blob/master/sites.md)
|
||||
|
||||
<p align="center">
|
||||
<img src="./screenshot/preview.png">
|
||||
|
|
@ -77,6 +77,26 @@ Or you can simply use "Docker Hub" to run `sherlock`:
|
|||
docker run theyahya/sherlock user123
|
||||
```
|
||||
|
||||
## Tests
|
||||
If you are contributing to Sherlock, then Thank You!
|
||||
|
||||
Before creating a pull request with new development, please run the tests
|
||||
to ensure that all is well. It would also be a good idea to run the tests
|
||||
before starting development to distinguish problems between your
|
||||
environment and the Sherlock software.
|
||||
|
||||
The following is an example of the command line to run all the tests for
|
||||
Sherlock. This invocation hides the progress text that Sherlock normally
|
||||
outputs, and instead shows the verbose output of the tests.
|
||||
|
||||
```
|
||||
% python3 -m unittest tests.all --buffer --verbose
|
||||
```
|
||||
|
||||
Note that the tests are very much a work in progress. Significant work is
|
||||
required to get full test coverage. But, the current tests are working
|
||||
properly, and will be expanded as time goes by.
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Yahya SayadArbabi](https://theyahya.com)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
"""Sherlock Tests
|
||||
|
||||
This package contains various submodules used to run tests.
|
||||
"""
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
"""Sherlock Tests
|
||||
|
||||
This module contains various tests.
|
||||
"""
|
||||
from tests.base import SherlockBaseTest
|
||||
import unittest
|
||||
|
||||
|
||||
class SherlockDetectTests(SherlockBaseTest):
|
||||
def test_detect_true(self):
|
||||
"""Test Username Existence Detection.
|
||||
|
||||
This test ensures that the mechanism of ensuring that a Username
|
||||
exists works properly.
|
||||
|
||||
Keyword Arguments:
|
||||
self -- This object.
|
||||
|
||||
Return Value:
|
||||
N/A.
|
||||
Will trigger an assert if Usernames which are known to exist are
|
||||
not detected.
|
||||
"""
|
||||
|
||||
self.username_check(['jack'], ['Twitter'], exist_check=True)
|
||||
#self.username_check(['dfox'], ['devRant'], exist_check=True)
|
||||
self.username_check(['blue'], ['Pinterest'], exist_check=True)
|
||||
self.username_check(['kevin'], ['Instagram'], exist_check=True)
|
||||
self.username_check(['zuck'], ['Facebook'], exist_check=True)
|
||||
|
||||
return
|
||||
|
||||
def test_detect_false_via_message(self):
|
||||
"""Test Username Does Not Exist (Via Message).
|
||||
|
||||
This test ensures that the "message" detection mechanism of
|
||||
ensuring that a Username does *not* exist works properly.
|
||||
|
||||
Keyword Arguments:
|
||||
self -- This object.
|
||||
|
||||
Return Value:
|
||||
N/A.
|
||||
Will trigger an assert if detection mechanism did not work as expected.
|
||||
"""
|
||||
|
||||
self.username_check(['jackkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk'],
|
||||
['Instagram'],
|
||||
exist_check=False
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
def test_detect_false_via_status_code(self):
|
||||
"""Test Username Does Not Exist (Via Status Code).
|
||||
|
||||
This test ensures that the "status code" detection mechanism of
|
||||
ensuring that a Username does *not* exist works properly.
|
||||
|
||||
Keyword Arguments:
|
||||
self -- This object.
|
||||
|
||||
Return Value:
|
||||
N/A.
|
||||
Will trigger an assert if detection mechanism did not work as expected.
|
||||
"""
|
||||
|
||||
self.username_check(['jackkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk'],
|
||||
['Facebook'],
|
||||
exist_check=False
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
def test_detect_false_via_response_url(self):
|
||||
"""Test Username Does Not Exist (Via Response URL).
|
||||
|
||||
This test ensures that the "response URL" detection mechanism of
|
||||
ensuring that a Username does *not* exist works properly.
|
||||
|
||||
Keyword Arguments:
|
||||
self -- This object.
|
||||
|
||||
Return Value:
|
||||
N/A.
|
||||
Will trigger an assert if detection mechanism did not work as expected.
|
||||
"""
|
||||
|
||||
self.username_check(['jackkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk'],
|
||||
['Pinterest'],
|
||||
exist_check=False
|
||||
)
|
||||
|
||||
return
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
"""Sherlock Base Tests
|
||||
|
||||
This module contains various utilities for running tests.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import unittest
|
||||
import sherlock
|
||||
import warnings
|
||||
|
||||
|
||||
class SherlockBaseTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Sherlock Base Test Setup.
|
||||
|
||||
Does common setup tasks for base Sherlock tests.
|
||||
|
||||
Keyword Arguments:
|
||||
self -- This object.
|
||||
|
||||
Return Value:
|
||||
N/A.
|
||||
"""
|
||||
|
||||
#This ignores the ResourceWarning from an unclosed SSLSocket.
|
||||
#TODO: Figure out how to fix the code so this is not needed.
|
||||
warnings.simplefilter("ignore", ResourceWarning)
|
||||
|
||||
# Load the data file with all site information.
|
||||
data_file_path = os.path.join(os.path.dirname(os.path.realpath(sherlock.__file__)), "data.json")
|
||||
with open(data_file_path, "r", encoding="utf-8") as raw:
|
||||
self.site_data_all = json.load(raw)
|
||||
|
||||
self.verbose=False
|
||||
self.tor=False
|
||||
self.unique_tor=False
|
||||
|
||||
return
|
||||
|
||||
def site_data_filter(self, site_list):
|
||||
"""Filter Site Data.
|
||||
|
||||
Keyword Arguments:
|
||||
self -- This object.
|
||||
site_list -- List of strings corresponding to sites which
|
||||
should be filtered.
|
||||
|
||||
Return Value:
|
||||
Dictionary containing sub-set of site data specified by 'site_list'.
|
||||
"""
|
||||
|
||||
# Create new dictionary that has filtered site data based on input.
|
||||
# Note that any site specified which is not understood will generate
|
||||
# an error.
|
||||
site_data = {}
|
||||
for site in site_list:
|
||||
with self.subTest(f"Checking test vector Site '{site}' "
|
||||
f"exists in total site data."
|
||||
):
|
||||
site_data[site] = self.site_data_all[site]
|
||||
|
||||
return site_data
|
||||
|
||||
def username_check(self, username_list, site_list, exist_check=True):
|
||||
"""Username Exist Check.
|
||||
|
||||
Keyword Arguments:
|
||||
self -- This object.
|
||||
username_list -- List of strings corresponding to usernames
|
||||
which should exist on *all* of the sites.
|
||||
site_list -- List of strings corresponding to sites which
|
||||
should be filtered.
|
||||
exist_check -- Boolean which indicates if this should be
|
||||
a check for Username existence,
|
||||
or non-existence.
|
||||
|
||||
Return Value:
|
||||
N/A.
|
||||
Will trigger an assert if Username does not have the expected
|
||||
existence state.
|
||||
"""
|
||||
|
||||
#Filter all site data down to just what is needed for this test.
|
||||
site_data = self.site_data_filter(site_list)
|
||||
|
||||
if exist_check:
|
||||
check_type_text = "exists"
|
||||
exist_result_desired = "yes"
|
||||
else:
|
||||
check_type_text = "does not exist"
|
||||
exist_result_desired = "no"
|
||||
|
||||
for username in username_list:
|
||||
results = sherlock.sherlock(username,
|
||||
site_data,
|
||||
verbose=self.verbose,
|
||||
tor=self.tor,
|
||||
unique_tor=self.unique_tor
|
||||
)
|
||||
for site, result in results.items():
|
||||
with self.subTest(f"Checking Username '{username}' "
|
||||
f"{check_type_text} on Site '{site}'"
|
||||
):
|
||||
self.assertEqual(result['exists'], exist_result_desired)
|
||||
|
||||
return
|
||||
Loading…
Reference in New Issue