diff --git a/src/db/create_tables_insert_data/Users.sql b/src/db/create_tables_insert_data/Users.sql index aff12712041332e3ce6b1b23f3c42c9652289efc..7699f1d9bff0d36419637830104fdf1dcb7aff06 100644 --- a/src/db/create_tables_insert_data/Users.sql +++ b/src/db/create_tables_insert_data/Users.sql @@ -25,6 +25,7 @@ CREATE TABLE public."Users" ( INSERT INTO public."Users" (user_id, display_name, email, password_hash, creation_time, preferences_json, created_from, login_allowed) VALUES (0, 'Debug User', 'debug@thebookworm.com', '$2b$10$AMucDjhYc1I.TWtHUCudb.mcwh5AIkrUQfFyD/wKJ1JqPq6.J6RO.', '2019-02-21 18:27:36.3877', '{}', 'DEBUG', 0); INSERT INTO public."Users" (user_id, display_name, email, password_hash, creation_time, preferences_json, created_from, login_allowed) VALUES (1, 'Jon Shahen', 'jonathan.shahen@gmail.com', '$2b$10$AMucDjhYc1I.TWtHUCudb.mcwh5AIkrUQfFyD/wKJ1JqPq6.J6RO.', '2019-02-21 18:27:36.3877', '{}', 'Website Signin Page', 1); +INSERT INTO public."Users" (user_id, display_name, email, password_hash, creation_time, preferences_json, created_from, login_allowed) VALUES (3, 'automation_test@gmail.com', 'automation_test@gmail.com', '$2b$10$AMucDjhYc1I.TWtHUCudb.mcwh5AIkrUQfFyD/wKJ1JqPq6.J6RO.', '2019-02-21 18:27:36.3877', '{}', 'Website Signin Page', 1); INSERT INTO public."Users" (user_id, display_name, email, password_hash, creation_time, preferences_json, created_from, login_allowed) VALUES (2292, 'Whittie Pie', 'AHTRMUOZ3MW5PZMK7BJIYHOPIKNQ@gmail.com', ' ', '2019-03-10 11:39:45.25783', '{}', 'Amazon', 0); diff --git a/src/db/grant_tables_add_constraint.sql b/src/db/grant_tables_add_constraint.sql index 14f8baaad28d21c60b86496296600a25d7542533..d950deb705667a550a87813ddccdf1ae4e088edb 100644 --- a/src/db/grant_tables_add_constraint.sql +++ b/src/db/grant_tables_add_constraint.sql @@ -121,6 +121,8 @@ ALTER TABLE ONLY public."Users" GRANT ALL ON TABLE public."Users" TO ece651_ml; GRANT ALL ON TABLE public."Users" TO ece651_web; GRANT ALL ON TABLE public."Users" TO ece651_scraper; +GRANT ALL ON SEQUENCE public."Users_user_id_sequence" TO ece651_web; +GRANT ALL ON SEQUENCE public."Users_user_id_sequence" TO ece651_ml; --- Reviews ALTER TABLE ONLY public."Reviews" diff --git a/src/scraper/get_book_information.py b/src/scraper/get_book_information.py index b8f51067f511b0f405bdf8517c577ee2d53203a1..2cd67a9b3703e79679d68ef4b98cf4d11d17f9f7 100644 --- a/src/scraper/get_book_information.py +++ b/src/scraper/get_book_information.py @@ -43,7 +43,7 @@ def grab_url_request(url, headers=DEFAULT_HEADERS, params=None, return_soup=Fals if not driver: chrome_options = Options() chrome_options.add_argument("--log-level=3") - chrome_options.add_argument("headless") # remove this line if you want to see the browser popup + # chrome_options.add_argument("headless") # remove this line if you want to see the browser popup driver = webdriver.Chrome(options=chrome_options) driver.get(url) @@ -89,7 +89,7 @@ def search_amazon_for_book(thread_id, book_title, book_author): all_links = soup.select('a') count_links = 0 - print(f'Number of links found via soup: {len(all_links)}') + # print(f'Number of links found via soup: {len(all_links)}') for a in all_links: if not a.has_attr('href'): continue diff --git a/src/scraper/test_amazon_requests.py b/src/scraper/test_amazon_requests.py index e7529b46daac8e4231bbc0a477e136d9ae142641..db05267bde44217754217cce3aca7bd9166f65cb 100644 --- a/src/scraper/test_amazon_requests.py +++ b/src/scraper/test_amazon_requests.py @@ -13,9 +13,10 @@ class TestAmazonRequests(unittest.TestCase): raise Exception("Must be using Python 3") self.pp = pprint.PrettyPrinter(indent=4) - def tearDown(self): + @classmethod + def tearDownClass(cls): + # print('Calling TearDown') getInfo.close() - return super().tearDown() def test_simple_search(self): r = getInfo.grab_url_request(getInfo.AMAZON_SEARCH_URL, return_soup=False) @@ -41,7 +42,7 @@ class TestAmazonRequests(unittest.TestCase): def test_search_Macbeth(self): book_url = getInfo.search_amazon_for_book(1,'Macbeth','William Shakespeare') - getInfo.close() + # getInfo.close() self.assertIsNotNone(book_url) # self.pp.pprint(book_url) diff --git a/src/testing/run_all_system_tests.py b/src/testing/run_all_system_tests.py index 416789ed9121ca092756ad911a4e31c30b166a5b..b83c4c51a712be1a276cd570e220282508d4837d 100644 --- a/src/testing/run_all_system_tests.py +++ b/src/testing/run_all_system_tests.py @@ -27,5 +27,6 @@ if __name__ == "__main__": abspath = os.path.abspath(__file__) dname = os.path.dirname(abspath) os.chdir(dname) + os.chdir('..') run_all() \ No newline at end of file diff --git a/src/testing/run_all_unit_tests.py b/src/testing/run_all_unit_tests.py index 374344a95de21eeace7fe36d9f837d643192659b..2943d987c06948fd04f6bb271f448453cc471408 100644 --- a/src/testing/run_all_unit_tests.py +++ b/src/testing/run_all_unit_tests.py @@ -59,5 +59,6 @@ if __name__ == "__main__": abspath = os.path.abspath(__file__) dname = os.path.dirname(abspath) os.chdir(dname) + os.chdir('..') run_all() \ No newline at end of file diff --git a/src/testing/run_everything.py b/src/testing/run_everything.py index 6c236dbf5ef920a6e3e8bfb5d1abe9b9e91e5a48..3cd3f7996ea2a8e00cd5183bc4a2d708752c5cb9 100644 --- a/src/testing/run_everything.py +++ b/src/testing/run_everything.py @@ -21,7 +21,7 @@ def run_all(): print('\n') print('*'*50) - print('* UNIT TESTS') + print('* SYSTEM TESTS') print('*'*50) run_all_system_tests.run_all() diff --git a/src/web/routes/account.js b/src/web/routes/account.js index 61518fc6846846351aeb7a188426012bd15db84d..b10cadbd5b4e8d3295285af1d40f3da4289ea137 100644 --- a/src/web/routes/account.js +++ b/src/web/routes/account.js @@ -91,6 +91,7 @@ router.post('/signup', async function(req, res, next) { error = 'Unable to add user to table'; } } catch (e) { + console.warn(e); error = 'Duplicate Email found in table, did you forget your password?'; } } else { diff --git a/src/web/test/gui_tests/config.py b/src/web/test/gui_tests/config.py new file mode 100644 index 0000000000000000000000000000000000000000..3a3664e9394c6d8f698a71e0e918a9678ef79701 --- /dev/null +++ b/src/web/test/gui_tests/config.py @@ -0,0 +1,26 @@ +import os +from configparser import ConfigParser + + +def config(filename='database.ini', test_filename='database_test.ini', section='postgresql'): + # create a parser + parser = ConfigParser() + # read config file + cwd = os.getcwd() + os.chdir(os.path.dirname(__file__)) + if 'TESTENV' in os.environ: + parser.read(test_filename) + else: + parser.read(filename) + os.chdir(cwd) + + # get section, default to postgresql + db = {} + if parser.has_section(section): + params = parser.items(section) + for param in params: + db[param[0]] = param[1] + else: + raise Exception('Section {0} not found in the {1} file'.format(section, filename)) + + return db \ No newline at end of file diff --git a/src/web/test/gui_tests/database.ini b/src/web/test/gui_tests/database.ini new file mode 100644 index 0000000000000000000000000000000000000000..e56c4ca20a1da97163aa85e260d43f218e679687 --- /dev/null +++ b/src/web/test/gui_tests/database.ini @@ -0,0 +1,5 @@ +[postgresql] +host=localhost +database=ece651 +user=ece651_scraper +password=wxJcTdJYUU3mMAsAa5YD \ No newline at end of file diff --git a/src/web/test/gui_tests/database_test.ini b/src/web/test/gui_tests/database_test.ini new file mode 100644 index 0000000000000000000000000000000000000000..e56c4ca20a1da97163aa85e260d43f218e679687 --- /dev/null +++ b/src/web/test/gui_tests/database_test.ini @@ -0,0 +1,5 @@ +[postgresql] +host=localhost +database=ece651 +user=ece651_scraper +password=wxJcTdJYUU3mMAsAa5YD \ No newline at end of file diff --git a/src/web/test/gui_tests/test_authordetails.py b/src/web/test/gui_tests/test_authordetails.py index e38ba417f3b3ddaf1ea9fdf100261d6dd3fc39d6..e0fd2ecf409ba2d7d5c67d3a4d0e9413e6fd8e01 100644 --- a/src/web/test/gui_tests/test_authordetails.py +++ b/src/web/test/gui_tests/test_authordetails.py @@ -101,12 +101,10 @@ class AuthorDetailsTest(unittest.TestCase): self.driver = webdriver.Chrome() def test_authordetails(self): - self.driver.get("http://127.0.0.1:3000/author/1509/Aaron%20Dembski-Bowden") # Case 1 : Verify Routing using matching Title of Author - elem= self.driver.find_element_by_class_name('no-bottom-pm') name='Aaron Dembski-Bowden' @@ -131,7 +129,9 @@ class AuthorDetailsTest(unittest.TestCase): bookDeals(self) - tearDown(self) + def tearDown(self): + if self.driver: + self.driver.quit() diff --git a/src/web/test/gui_tests/test_bookdetails.py b/src/web/test/gui_tests/test_bookdetails.py index 3d9530dfd44c168bc6754ca375ea2326b10640cd..c1018604773167dddedd1b0ae78dcf4ae788a22c 100644 --- a/src/web/test/gui_tests/test_bookdetails.py +++ b/src/web/test/gui_tests/test_bookdetails.py @@ -7,40 +7,60 @@ from selenium.webdriver.common.action_chains import ActionChains import unittest +import psycopg2 +from psycopg2.pool import ThreadedConnectionPool +from config import config + +driver = None + +remove_reviews_sql = 'DELETE FROM "Reviews" where user_id = %s' +def remove_user_reviews(user_id): + try: + params = config() + tcp = ThreadedConnectionPool(1, 10, **params) + conn = tcp.getconn() + cur = conn.cursor() + cur.execute(remove_reviews_sql, (user_id,)) + conn.commit() + except Exception as err: + pass def review(self): - elem = self.driver.find_element_by_xpath("//a[contains (@href,'/account/signin')]") + global driver + elem = driver.find_element_by_xpath("//a[contains (@href,'/account/signin')]") elem.click() + remove_user_reviews(3) + try: - elem = self.driver.find_element_by_id("email") + elem = driver.find_element_by_id("email") elem.send_keys("automation_test@gmail.com") - elem = self.driver.find_element_by_id("password") - elem.send_keys("bookworm123") + elem = driver.find_element_by_id("password") + elem.send_keys("password") - login = self.driver.find_element_by_id("login") + login = driver.find_element_by_id("login") login.click() except: self.fail('Test Failed: Login to review failed') try: - self.driver.get("http://127.0.0.1:3000/book/372/The%20Horus%20Heresy:%20Master%20of%20Mankind") + driver.get("http://127.0.0.1:3000/book/372/The%20Horus%20Heresy:%20Master%20of%20Mankind") - elem = self.driver.find_element_by_xpath("//select[@name='rating']/option[text()='3']") + elem = driver.find_element_by_xpath("//select[@name='rating']/option[text()='3']") elem.click() - elem1 = self.driver.find_element_by_class_name('review-comment') + elem1 = driver.find_element_by_class_name('review-comment') elem1.clear() elem1.send_keys('This is a test review by automation user') - elem2 = self.driver.find_element_by_class_name('review-btn') + elem2 = driver.find_element_by_class_name('review-btn') elem2.click() # review verification - elem = self.driver.find_element_by_class_name('user-review-text') + elem = driver.find_element_by_class_name('user-review-text') if 'This is a test review by automation user' in elem.text: pass else: @@ -51,23 +71,27 @@ def review(self): self.fail('Test Failed: Review Add failed') -def tearDown(self): - self.driver.quit() - class BookDetailsTest(unittest.TestCase): def setUp(self): - #self.driver = webdriver.Chrome('/home/nasheen/Documents/ECE651/chromedriver') - self.driver = webdriver.Chrome() + global driver + #driver = webdriver.Chrome('/home/nasheen/Documents/ECE651/chromedriver') + if not driver: + driver = webdriver.Chrome() - def test_bookdetails(self): + @classmethod + def tearDownClass(cls): + # print('Calling TearDown') + if driver: + driver.quit() - self.driver.get("http://127.0.0.1:3000/book/372/The%20Horus%20Heresy:%20Master%20of%20Mankind") + def test_bookdetails(self): + global driver + driver.get("http://127.0.0.1:3000/book/372/The%20Horus%20Heresy:%20Master%20of%20Mankind") # Case 1 : Verify Routing using matching ISBN of Book - - elem = self.driver.find_element_by_class_name('product-detail') + elem = driver.find_element_by_class_name('product-detail') x = '978-1784967116' if x in elem.text: pass @@ -75,26 +99,23 @@ class BookDetailsTest(unittest.TestCase): self.fail('Test Failed: Book detail mismatch') # Case 2 : Verify author information is loaded and correct - - elem = self.driver.find_element_by_xpath("//*[contains (@href,'/author/1509/Aaron Dembski-Bowden')]") + elem = driver.find_element_by_xpath("//*[contains (@href,'/author/1509/Aaron Dembski-Bowden')]") if 'Aaron Dembski-Bowden' in elem.text: pass else: self.fail('Test Failed: Author mismatch') # Case 3: Synopsis loaded and correct - synopsis='While Horus’ rebellion burns across the galaxy, a very different kind of war rages beneath the Imperial Palace.' - elem=self.driver.find_element_by_xpath("//p[contains (@class,'font-normal')]") + elem=driver.find_element_by_xpath("//p[contains (@class,'font-normal')]") if synopsis in elem.text: pass else: self.fail('Test Failed: Synopsis mismatch') # Case 4: Review block verification - review_text='Customer Reviews' - elem = self.driver.find_element_by_xpath("//h4[contains (@class,'no-bottom-pm')]") + elem = driver.find_element_by_xpath("//h4[contains (@class,'no-bottom-pm')]") if review_text in elem.text: pass else: @@ -102,18 +123,15 @@ class BookDetailsTest(unittest.TestCase): # Case 5 : Thumbnail verification - #cover_image = '/images/book_covers/372.jpeg' - elem = self.driver.find_element_by_xpath("//img[contains(@src,'372.jpeg')]") + elem = driver.find_element_by_xpath("//img[contains(@src,'372.jpeg')]") if elem.size != 0: pass else: self.fail('Test Failed: Cover not found') # Case 6: sign in and review - - - elem = self.driver.find_element_by_class_name('submit-review') + elem = driver.find_element_by_class_name('submit-review') sign_in_review='Please login to write a review for this book' if sign_in_review in elem.text: @@ -124,12 +142,8 @@ class BookDetailsTest(unittest.TestCase): review(self) - tearDown(self) - - - - - +if __name__ == '__main__': + unittest.main() diff --git a/src/web/test/gui_tests/test_regression_authentication.py b/src/web/test/gui_tests/test_regression_authentication.py index 89823d9b67ae6e49bc76ea836ccbbcd7ceab50e5..96852019e2c6330828c2963de4d087ce53da931d 100644 --- a/src/web/test/gui_tests/test_regression_authentication.py +++ b/src/web/test/gui_tests/test_regression_authentication.py @@ -8,6 +8,21 @@ from selenium.webdriver.common.action_chains import ActionChains import unittest +import psycopg2 +from psycopg2.pool import ThreadedConnectionPool +from config import config + +remove_user_by_email_sql = 'DELETE FROM "Users" where email = %s' +def remove_user(email): + try: + params = config() + tcp = ThreadedConnectionPool(1, 10, **params) + conn = tcp.getconn() + cur = conn.cursor() + cur.execute(remove_user_by_email_sql, (email,)) + conn.commit() + except Exception as err: + pass def signup(self): elem = self.driver.find_element_by_id("signup") @@ -173,28 +188,28 @@ class RegressionTestAuthenticationSystem(unittest.TestCase): elem = self.driver.find_element_by_xpath("//*[contains(text(), 'Sign up')]") elem.click() + ######## NOT ALL BROWSERS SUPPORT THIS #case 1 : signing up without any input - signup(self) - fieldvalidation(self) - - #case 2: signing up with only name - - elem=self.driver.find_element_by_id("fullname") - elem.send_keys("Test User") - signup(self) - fieldvalidation(self) - - # case 3: signing up with only name and email - elem = self.driver.find_element_by_id("email") - elem.send_keys("tuser@gmail.com") - signup(self) - fieldvalidation(self) - - # case 3: signing up with only name and email and password - elem = self.driver.find_element_by_id("password") - elem.send_keys("abcd123") - signup(self) - fieldvalidation(self) + # signup(self) + # fieldvalidation(self) + + # #case 2: signing up with only name + # elem=self.driver.find_element_by_id("fullname") + # elem.send_keys("Test User") + # signup(self) + # fieldvalidation(self) + + # # case 3: signing up with only name and email + # elem = self.driver.find_element_by_id("email") + # elem.send_keys("tuser@gmail.com") + # signup(self) + # fieldvalidation(self) + + # # case 3: signing up with only name and email and password + # elem = self.driver.find_element_by_id("password") + # elem.send_keys("abcd123") + # signup(self) + # fieldvalidation(self) # case 4: signing up with password mismatch elem = self.driver.find_element_by_id("confirmation_password") @@ -208,7 +223,7 @@ class RegressionTestAuthenticationSystem(unittest.TestCase): elem.send_keys("Test User06") elem = self.driver.find_element_by_id("email") - elem.send_keys("testuser6@gmail.com") + elem.send_keys("jonathan.shahen@gmail.com") elem = self.driver.find_element_by_id("password") elem.send_keys("usertest04") @@ -220,11 +235,13 @@ class RegressionTestAuthenticationSystem(unittest.TestCase): # case 6: regression user sign up + remove_user("regression_DELETE_ME@mail.com") + elem = self.driver.find_element_by_id("fullname") elem.send_keys("Regression Test") elem = self.driver.find_element_by_id("email") - elem.send_keys("regression@mail.com") + elem.send_keys("regression_DELETE_ME@mail.com") elem = self.driver.find_element_by_id("password") elem.send_keys("password") @@ -291,6 +308,12 @@ class RegressionTestAuthenticationSystem(unittest.TestCase): signin_button(self) signin_validation(self) + def tearDown(self): + if self.driver: + self.driver.quit() + +if __name__ == '__main__': + unittest.main() diff --git a/src/web/test/gui_tests/test_search_functionality.py b/src/web/test/gui_tests/test_search_functionality.py index 4d4c4b2ce6ae39f9b493b5adfcd61349dc0b7e7b..88fbc53e41ae6427d311d6242820beb1d3a89b4d 100644 --- a/src/web/test/gui_tests/test_search_functionality.py +++ b/src/web/test/gui_tests/test_search_functionality.py @@ -55,9 +55,9 @@ class Searchtest(unittest.TestCase): def setUp(self): #self.driver = webdriver.Chrome('/home/nasheen/Documents/ECE651/chromedriver') self.driver = webdriver.Chrome() - self.driver.get("http://127.0.0.1:3000/") def test_search(self): + self.driver.get("http://127.0.0.1:3000/") search_box = self.driver.find_element_by_class_name("input-field") # case 1: test with positive case: should find result @@ -79,7 +79,9 @@ class Searchtest(unittest.TestCase): searchResultCount(self) nullResultVerification(self) - #tearDown(self) + def tearDown(self): + if self.driver: + self.driver.quit() diff --git a/src/web/test/gui_tests/test_signin.py b/src/web/test/gui_tests/test_signin.py index ecad53440c7b5196176833900f13079d234c6e30..6fd881b60a119c3b345a7591fb9ae40628a5bc7a 100644 --- a/src/web/test/gui_tests/test_signin.py +++ b/src/web/test/gui_tests/test_signin.py @@ -24,7 +24,7 @@ class TestSignInUpSystem(unittest.TestCase): elem.send_keys("automation_test23@gmail.com") elem = self.driver.find_element_by_id("password") - elem.send_keys("bookworm123") + elem.send_keys("password") login = self.driver.find_element_by_id("login") login.click() @@ -34,7 +34,7 @@ class TestSignInUpSystem(unittest.TestCase): elem.send_keys("automation_test@gmail.com") elem = self.driver.find_element_by_id("password") - elem.send_keys("bookworm123") + elem.send_keys("password") login = self.driver.find_element_by_id("login") login.click() @@ -46,7 +46,7 @@ class TestSignInUpSystem(unittest.TestCase): pass if elem: - if 'Hello Automation User' in elem.text: + if 'Hello automation_test@gmail.com' in elem.text: #self.driver.implicitly_wait(200) # print("Test Passed : signin completed") pass diff --git a/src/web/test/gui_tests/test_signup.py b/src/web/test/gui_tests/test_signup.py index 48c187b46927c0274e7634cec875fbfa2b8d53d8..a364a3512499232d9816aee47ffb7d545b1b3da8 100644 --- a/src/web/test/gui_tests/test_signup.py +++ b/src/web/test/gui_tests/test_signup.py @@ -44,10 +44,10 @@ class TestSignInUpSystem(unittest.TestCase): elem.send_keys("automation_test@gmail.com") elem = self.driver.find_element_by_id("password") - elem.send_keys("bookworm123") + elem.send_keys("password") elem = self.driver.find_element_by_id("confirmation_password") - elem.send_keys("bookworm123") + elem.send_keys("password") signup = self.driver.find_element_by_id("signup") signup.click() @@ -67,10 +67,12 @@ class TestSignInUpSystem(unittest.TestCase): if elem_error: if 'did you forget' in elem_error.text: - print("Test Passed: Error - User Already Exists") + # print("Test Passed: Error - User Already Exists") + pass elif elem_welcome: if 'Automation User' in elem_welcome.text: - print ("Test Passed: User created") + # print ("Test Passed: User created") + pass else: self.fail('Test Failed: Wrong Username Displayed')