diff --git a/qa327/backend.py b/qa327/backend.py index 78b6c62..50f0f96 100644 --- a/qa327/backend.py +++ b/qa327/backend.py @@ -49,3 +49,15 @@ def register_user(email, name, password, password2): def get_all_tickets(): """Going to be implemented when /sell and /buy is implemented""" return [] + +def buy_ticket(form): + '''buy a ticket, returns a message''' + raise "TODO" + +def sell_ticket(form): + '''sell a ticket, returns a message''' + raise 'TODO' + +def update_ticket(form): + '''update a ticket, returns a message''' + raise 'TODO' \ No newline at end of file diff --git a/qa327/frontend.py b/qa327/frontend.py index da37f89..e74f61e 100644 --- a/qa327/frontend.py +++ b/qa327/frontend.py @@ -110,18 +110,21 @@ def login_post(): @app.route('/buy', methods=['POST']) def buy_post(): - flash('ticket bought successfully') - return redirect('/',303) + '''buy a ticket using the HTML form''' + flash(bn.buy_ticket(request.form)) + return redirect('/', 303) @app.route('/sell', methods=['POST']) def sell_post(): - flash('ticket sold successfully') - return redirect('/',303) + '''sell a ticket using the HTML form''' + flash(bn.sell_ticket(request.form)) + return redirect('/', 303) @app.route('/update', methods=['POST']) def update_post(): - flash('ticket updated successfully') - return redirect('/',303) + '''update a ticket using the HTML form''' + flash(bn.update_ticket(request.form)) + return redirect('/', 303) @app.route('/logout') diff --git a/qa327_test/conftest.py b/qa327_test/conftest.py index 4ee7e86..febcd42 100644 --- a/qa327_test/conftest.py +++ b/qa327_test/conftest.py @@ -9,14 +9,17 @@ import threading from werkzeug.serving import make_server +# separate port allows tests to be run while hosting +# actual app +FLASK_TEST_PORT = 8082 -base_url = 'http://localhost:{}'.format(FLASK_PORT) +base_url = 'http://localhost:{}'.format(FLASK_TEST_PORT) class ServerThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) - self.srv = make_server('127.0.0.1', FLASK_PORT, app) + self.srv = make_server('127.0.0.1', FLASK_TEST_PORT, app) self.ctx = app.app_context() self.ctx.push() diff --git a/qa327_test/frontend/geek_base.py b/qa327_test/frontend/geek_base.py new file mode 100644 index 0000000..03b1dfe --- /dev/null +++ b/qa327_test/frontend/geek_base.py @@ -0,0 +1,32 @@ +from seleniumbase import BaseCase +from werkzeug.security import generate_password_hash +from qa327_test.conftest import base_url +from qa327.models import User + +# Mock a sample user +TEST_USER = User( + email='test_frontend@test.com', + name='test_frontend', + password=generate_password_hash('test_frontend'), + balance=140 +) + +class GeekBaseCase(BaseCase): + ''' + Selenium base case with some + GeekSeek utilities + ''' + + def assert_flash(self, text): + '''asserts that message exists in flashes''' + for flash_dom in self.find_elements('.flash'): + if flash_dom.text == text: + return + raise AssertionError(f'Flash not found for text "{text}"') + + def login_test_user(self, email=TEST_USER.email, password='test_frontend'): + '''login our test user''' + self.open(base_url+'/login') + self.input('#email', email) + self.input('#password', password) + self.click('#btn-submit') \ No newline at end of file diff --git a/qa327_test/frontend/test_r1.py b/qa327_test/frontend/test_r1.py index 3f1b6e8..f178172 100644 --- a/qa327_test/frontend/test_r1.py +++ b/qa327_test/frontend/test_r1.py @@ -8,31 +8,16 @@ from qa327_test.conftest import base_url from qa327.models import User - -# Mock a sample user -TEST_USER = User( - email='test_frontend@test.com', - name='test_frontend', - password=generate_password_hash('test_frontend'), - balance=140 -) +from qa327_test.frontend.geek_base import GeekBaseCase, TEST_USER INVALID_EMAILS = ['test_frontendtest.com', 'test_frontend@.com', 'test\frontend@test.com'] - INVALID_PASSWORDS = ['Pass!', 'password123!', 'PASSWORD123!', 'Password123'] -class R1Test(BaseCase): +class R1Test(GeekBaseCase): ''' Contains test cases specific to R1 ''' - def login_test_user(self): - '''login our test user''' - self.open(base_url+'/login') - self.input('#email', TEST_USER.email) - self.input('#password', 'test_frontend') - self.click('#btn-submit') - def test_login_redirects(self, *_): '''see r1.1''' self.open(base_url) @@ -71,7 +56,7 @@ def test_form_password_missing(self, *_): self.open(base_url+'/login') self.input('#email', TEST_USER.email) self.click('#btn-submit') - #leave password empty + # leave password empty message = self.driver.find_element_by_id('password') assert message.get_attribute('validationMessage') == 'Please fill out this field.' @@ -81,7 +66,7 @@ def test_form_email_missing(self, *_): self.open(base_url+'/login') self.input('#password', 'test_frontend') self.click('#btn-submit') - #leave password empty + # leave password empty message = self.driver.find_element_by_id('email') assert message.get_attribute('validationMessage') == 'Please fill out this field.' @@ -93,7 +78,7 @@ def test_email_rfc_specs(self, *_): def test_invalid_email_rfc_specs(self, *_): '''see r1.7 (negative)''' - #invalid email format + # invalid email format for invalid_email in INVALID_EMAILS: self.open(base_url+'/login') self.input('#email', invalid_email) @@ -111,7 +96,7 @@ def test_password_complexity(self, *_): def test_invalid_password_complexity(self, *_): '''see r1.8 (negative)''' - #invalid password complexity + # invalid password complexity for invalid_pass in INVALID_PASSWORDS: self.open(base_url+'/login') self.input('#email', TEST_USER.email) diff --git a/qa327_test/frontend/test_R2.py b/qa327_test/frontend/test_r2.py similarity index 88% rename from qa327_test/frontend/test_R2.py rename to qa327_test/frontend/test_r2.py index e2c7a69..8f0850e 100644 --- a/qa327_test/frontend/test_R2.py +++ b/qa327_test/frontend/test_r2.py @@ -4,54 +4,45 @@ from unittest.mock import patch from werkzeug.security import generate_password_hash -from seleniumbase import BaseCase -from qa327_test.conftest import base_url - -import qa327.models - -# Defines user class to make testing more streamlined -class User: - def __init__(self, email=None, name=None, password=None): - self.email = email - self.name = name - self.password = password +from qa327.models import User +from qa327_test.conftest import base_url +from qa327_test.frontend.geek_base import GeekBaseCase # Defines test information -TEST_USER_A = qa327.models.User( +TEST_USER_A = User( email='test_frontend@test.com', name='test_frontend', password=generate_password_hash('Password123!', method='sha256'), balance=5000 ) -TEST_USER_B = qa327.models.User( - email='test_frontend@test.com', - name='test_frontend', - password='Password123!' -) - - VALID_USER = User( email='test_frontend@test.com', name='test_frontend', password='Password123!' ) -INVALID_USER_NAME_FORMATS = ['', 'test_frontend123!', ' test_frontend123', - 'test_frontend123 '] +INVALID_USER_NAME_FORMATS = [ + '', 'test_frontend123!', + ' test_frontend123', 'test_frontend123 ' +] INVALID_USER_NAME_LENGTHS = ['te', 'test_frontend1234567890'] -INVALID_USER_EMAILS = ['', 'test_frontendtest.com', 'test_frontend@testcom', - '.test_frontend@test.com'] +INVALID_USER_EMAILS = [ + '', 'test_frontendtest.com', + 'test_frontend@testcom', '.test_frontend@test.com' +] -INVALID_USER_PASSWORDS = ['', 'Pass!', 'password123!', 'PASSWORD123!', - 'Password123'] +INVALID_USER_PASSWORDS = [ + '', 'Pass!', 'password123!', + 'PASSWORD123!','Password123' +] MISMATCHED_PASSWORD2 = 'Password123! ' -class R2Test(BaseCase): +class R2Test(GeekBaseCase): ''' Contains test cases specific to R2 ''' @@ -71,27 +62,6 @@ def register_test_user(self, *_): # Submits the inputted information self.click('#register-submit') - - def login_test_user(self): - '''login our test user''' - # Opens login page - self.open(base_url+'/login') - - # Logins in with user information - self.input('#email', TEST_USER_A.email) - self.input('#password', VALID_USER.password) - - # Submits the inputted information - self.click('#btn-submit') - - def assert_flash(self, text): - '''asserts that message exists in flashes''' - for flash_dom in self.find_elements('.flash'): - if flash_dom.text == text: - return - raise AssertionError(f'Flash not found for text "{text}"') - - @patch('qa327.backend.get_user', return_value=TEST_USER_A) def test_r2_1(self, *_): ''' @@ -100,7 +70,10 @@ def test_r2_1(self, *_): ''' # Logs in user to - self.login_test_user() + self.login_test_user( + email=TEST_USER_A.email, + password='Password123!' + ) # Opens the user profile page / self.open(base_url) @@ -354,7 +327,7 @@ def test_r2_9(self, *_): assert self.get_current_url() == base_url+'/login' - @patch('qa327.backend.get_user', return_value=TEST_USER_B) + @patch('qa327.backend.get_user', return_value=VALID_USER) def test_r2_10(self, *_): ''' 10) Test Case R2.10 - If the email already exists, show message @@ -398,7 +371,10 @@ def test_r2_11(self, get_user_function, *_): get_user_function.return_value = TEST_USER_A # Logs in user with newly registered user - self.login_test_user() + self.login_test_user( + email=TEST_USER_A.email, + password='Password123!' + ) # Opens the user profile page / self.open(base_url) diff --git a/qa327_test/frontend/test_r3.py b/qa327_test/frontend/test_r3.py index 888d551..840704d 100644 --- a/qa327_test/frontend/test_r3.py +++ b/qa327_test/frontend/test_r3.py @@ -3,19 +3,9 @@ ''' from unittest.mock import patch -from seleniumbase import BaseCase -from werkzeug.security import generate_password_hash from qa327_test.conftest import base_url -from qa327.models import User - -# Moch a sample user -TEST_USER = User( - email='test_frontend@test.com', - name='test_frontend', - password=generate_password_hash('test_frontend'), - balance=140 -) +from qa327_test.frontend.geek_base import GeekBaseCase, TEST_USER # Moch some sample tickets TEST_TICKETS = [ @@ -23,26 +13,11 @@ {'name': 't2', 'price': '90', 'owner': 'geek', 'count': 3}, ] - -class R3Test(BaseCase): +class R3Test(GeekBaseCase): ''' Contains test cases specific to R3 ''' - def login_test_user(self): - '''login our test user''' - self.open(base_url+'/login') - self.input('#email', TEST_USER.email) - self.input('#password', 'test_frontend') - self.click('#btn-submit') - - def assert_flash(self, text): - '''asserts that message exists in flashes''' - for flash_dom in self.find_elements('.flash'): - if flash_dom.text == text: - return - raise AssertionError(f'Flash not found for text "{text}"') - def test_login_redirects(self, *_): '''see r3.1''' self.open(base_url) @@ -124,6 +99,7 @@ def test_update_form(self, *_): self.assert_element('#update-ticket-expiration-date') @patch('qa327.backend.get_user', return_value=TEST_USER) + @patch('qa327.backend.sell_ticket', return_value='ticket sold successfully') def test_sell_posts(self, *_): '''see r3.9''' self.login_test_user() @@ -136,6 +112,7 @@ def test_sell_posts(self, *_): self.assert_flash('ticket sold successfully') @patch('qa327.backend.get_user', return_value=TEST_USER) + @patch('qa327.backend.buy_ticket', return_value='ticket bought successfully') def test_buy_posts(self, *_): '''see r3.10''' self.login_test_user() @@ -146,6 +123,7 @@ def test_buy_posts(self, *_): self.assert_flash('ticket bought successfully') @patch('qa327.backend.get_user', return_value=TEST_USER) + @patch('qa327.backend.update_ticket', return_value='ticket updated successfully') def test_update_posts(self, *_): '''see r3.11''' self.login_test_user() @@ -155,4 +133,4 @@ def test_update_posts(self, *_): self.input('#update-ticket-price', 'dont-care') self.input('#update-ticket-expiration-date', 'dont-care') self.click('#update-submit') - self.assert_flash('ticket updated successfully') \ No newline at end of file + self.assert_flash('ticket updated successfully') diff --git a/qa327_test/frontend/test_r7.py b/qa327_test/frontend/test_r7.py index 700b2f0..98660da 100644 --- a/qa327_test/frontend/test_r7.py +++ b/qa327_test/frontend/test_r7.py @@ -8,31 +8,16 @@ from qa327.models import User from qa327_test.conftest import base_url +from qa327_test.frontend.geek_base import GeekBaseCase, TEST_USER -#Mock a sample user -TEST_USER = User( - email='test_frontend@test.com', - name='test_frontend', - password=generate_password_hash('test_frontend'), - balance=140 -) - -class R7Test(BaseCase): +class R7Test(GeekBaseCase): ''' Contains test cases specific to R7. Test only test the frontend portion, and will patch the backend specific values ''' - def login_test_user(self): - '''login our test user''' - self.open(base_url+'/login') - self.input('#email', TEST_USER.email) - self.input('#password', 'test_frontend') - self.click('#btn-submit') - @patch('qa327.backend.get_user', return_value=TEST_USER) - def test_logout_redirect(self, *_): '''see r7.1''' self.open(base_url) diff --git a/qa327_test/frontend/test_404.py b/qa327_test/frontend/test_r8.py similarity index 56% rename from qa327_test/frontend/test_404.py rename to qa327_test/frontend/test_r8.py index 1f8b587..08e78d2 100644 --- a/qa327_test/frontend/test_404.py +++ b/qa327_test/frontend/test_r8.py @@ -1,12 +1,18 @@ -import pytest +from unittest.mock import patch from seleniumbase import BaseCase +from qa327_test.frontend.geek_base import GeekBaseCase from qa327_test.conftest import base_url -from unittest.mock import patch -class Http404Test(BaseCase): +class R8Test(GeekBaseCase): + ''' + contains test cases for R8 requirements + ''' def test_404_text(self, *_): + ''' + verifies that our 404 page is actually displayed + ''' # open home page self.open(base_url+'/randomtest') # test if the page loads correctly