Skip to content

Commit

Permalink
Merge branch 'ggi/add_style_guide'
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanfox1985 committed Jan 21, 2017
2 parents 8aecea2 + e6180b8 commit f8b0473
Show file tree
Hide file tree
Showing 32 changed files with 40 additions and 134 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


[![Build Status](https://travis-ci.org/tgndevs/testing-example.svg?branch=master)](https://travis-ci.org/tgndevs/testing-example)
[![Style Status](https://app.snap-ci.com/tgndevs/testing-example/branch/master/build_image)](https://app.snap-ci.com/tgndevs/testing-example/branch/master)
[![Coverage Status](https://coveralls.io/repos/github/tgndevs/testing-example/badge.svg?branch=master)](https://coveralls.io/github/tgndevs/testing-example?branch=master)
[![Code Climate](https://codeclimate.com/github/tgndevs/testing-example/badges/gpa.svg)](https://codeclimate.com/github/tgndevs/testing-example)
[![Code Health](https://landscape.io/github/tgndevs/testing-example/master/landscape.svg?style=flat)](https://landscape.io/github/tgndevs/testing-example/master)
Expand Down
2 changes: 1 addition & 1 deletion accounts/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from django.contrib import admin
from django.contrib import admin # noqa: F401

# Register your models here.
3 changes: 1 addition & 2 deletions accounts/authentication.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from accounts.models import User, Token


class PasswordlessAuthenticationBackend(object):

def authenticate(self, uid):
Expand All @@ -11,10 +12,8 @@ def authenticate(self, uid):
except Token.DoesNotExist:
return None


def get_user(self, email):
try:
return User.objects.get(email=email)
except User.DoesNotExist:
return None

2 changes: 0 additions & 2 deletions accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ class User(models.Model):
is_authenticated = True



class Token(models.Model):
email = models.EmailField()
uid = models.CharField(default=uuid.uuid4, max_length=40)

6 changes: 1 addition & 5 deletions accounts/tests/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.contrib.auth import get_user_model
from accounts.authentication import PasswordlessAuthenticationBackend
from accounts.models import Token

User = get_user_model()


Expand All @@ -13,15 +14,13 @@ def test_returns_None_if_no_such_token(self):
)
self.assertIsNone(result)


def test_returns_new_user_with_correct_email_if_token_exists(self):
email = '[email protected]'
token = Token.objects.create(email=email)
user = PasswordlessAuthenticationBackend().authenticate(token.uid)
new_user = User.objects.get(email=email)
self.assertEqual(user, new_user)


def test_returns_existing_user_with_correct_email_if_token_exists(self):
email = '[email protected]'
existing_user = User.objects.create(email=email)
Expand All @@ -30,7 +29,6 @@ def test_returns_existing_user_with_correct_email_if_token_exists(self):
self.assertEqual(user, existing_user)



class GetUserTest(TestCase):

def test_gets_user_by_email(self):
Expand All @@ -41,9 +39,7 @@ def test_gets_user_by_email(self):
)
self.assertEqual(found_user, desired_user)


def test_returns_None_if_no_user_with_that_email(self):
self.assertIsNone(
PasswordlessAuthenticationBackend().get_user('[email protected]')
)

4 changes: 1 addition & 3 deletions accounts/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.test import TestCase
from django.contrib import auth
from accounts.models import Token

User = auth.get_user_model()


Expand All @@ -10,19 +11,16 @@ def test_user_is_valid_with_email_only(self):
user = User(email='[email protected]')
user.full_clean() # should not raise


def test_no_problem_with_auth_login(self):
user = User.objects.create(email='[email protected]')
user.backend = ''
request = self.client.request().wsgi_request
auth.login(request, user) # should not raise



class TokenModelTest(TestCase):

def test_links_user_with_auto_generated_uid(self):
token1 = Token.objects.create(email='[email protected]')
token2 = Token.objects.create(email='[email protected]')
self.assertNotEqual(token1.uid, token2.uid)

9 changes: 0 additions & 9 deletions accounts/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ def test_redirects_to_home_page(self):
})
self.assertRedirects(response, '/')


def test_adds_success_message(self):
response = self.client.post('/accounts/send_login_email', data={
'email': '[email protected]'
Expand All @@ -24,7 +23,6 @@ def test_adds_success_message(self):
)
self.assertEqual(message.tags, "success")


@patch('accounts.views.send_mail')
def test_sends_mail_to_address_from_post(self, mock_send_mail):
self.client.post('/accounts/send_login_email', data={
Expand All @@ -37,15 +35,13 @@ def test_sends_mail_to_address_from_post(self, mock_send_mail):
self.assertEqual(from_email, 'noreply@superlists')
self.assertEqual(to_list, ['[email protected]'])


def test_creates_token_associated_with_email(self):
self.client.post('/accounts/send_login_email', data={
'email': '[email protected]'
})
token = Token.objects.first()
self.assertEqual(token.email, '[email protected]')


@patch('accounts.views.send_mail')
def test_sends_link_to_login_using_token_uid(self, mock_send_mail):
self.client.post('/accounts/send_login_email', data={
Expand All @@ -60,33 +56,28 @@ def test_sends_link_to_login_using_token_uid(self, mock_send_mail):
self.assertIn(expected_url, body)



@patch('accounts.views.auth')
class LoginViewTest(TestCase):

def test_redirects_to_home_page(self, mock_auth):
response = self.client.get('/accounts/login?token=abcd123')
self.assertRedirects(response, '/')


def test_calls_authenticate_with_uid_from_get_request(self, mock_auth):
self.client.get('/accounts/login?token=abcd123')
self.assertEqual(
mock_auth.authenticate.call_args,
call(uid='abcd123')
)


def test_calls_auth_login_with_user_if_there_is_one(self, mock_auth):
response = self.client.get('/accounts/login?token=abcd123')
self.assertEqual(
mock_auth.login.call_args,
call(response.wsgi_request, mock_auth.authenticate.return_value)
)


def test_does_not_login_if_user_is_not_authenticated(self, mock_auth):
mock_auth.authenticate.return_value = None
self.client.get('/accounts/login?token=abcd123')
self.assertEqual(mock_auth.login.called, False)

1 change: 0 additions & 1 deletion accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,3 @@ def login(request):
if user:
auth.login(request, user)
return redirect('/')

18 changes: 4 additions & 14 deletions functional_tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def setUp(self):
self.browser = webdriver.PhantomJS()
self.browser.implicitly_wait(DEFAULT_WAIT)


def tearDown(self):
if self._test_has_failed():
if not os.path.exists(SCREEN_DUMP_LOCATION):
Expand All @@ -49,29 +48,26 @@ def tearDown(self):
self.browser.switch_to_window(handle)
self.take_screenshot()
self.dump_html()
self.browser.service.process.send_signal(signal.SIGTERM) # kill the specific phantomjs child proc
# kill the specific phantomjs child process
self.browser.service.process.send_signal(signal.SIGTERM)
self.browser.quit()
super().tearDown()


def _test_has_failed(self):
# slightly obscure but couldn't find a better way!
return any(error for (method, error) in self._outcome.errors)


def take_screenshot(self):
filename = self._get_filename() + '.png'
print('screenshotting to', filename)
self.browser.get_screenshot_as_file(filename)


def dump_html(self):
filename = self._get_filename() + '.html'
print('dumping page HTML to', filename)
with open(filename, 'w') as f:
f.write(self.browser.page_source)


def _get_filename(self):
timestamp = datetime.now().isoformat().replace(':', '.')[:19]
return '{folder}/{classname}.{method}-window{windowid}-{timestamp}'.format(
Expand All @@ -82,7 +78,6 @@ def _get_filename(self):
timestamp=timestamp
)


def wait_for(self, function_with_assertion, timeout=DEFAULT_WAIT):
start_time = time.time()
while time.time() - start_time < timeout:
Expand All @@ -93,36 +88,31 @@ def wait_for(self, function_with_assertion, timeout=DEFAULT_WAIT):
# one more try, which will raise any errors if they are outstanding
return function_with_assertion()


def get_item_input_box(self):
return self.browser.find_element_by_id('id_text')


def check_for_row_in_list_table(self, row_text):
table = self.browser.find_element_by_id('id_list_table')
rows = table.find_elements_by_tag_name('tr')
self.assertIn(row_text, [row.text for row in rows])


def assert_logged_in(self, email):
self.browser.find_element_by_link_text('Log out')
navbar = self.browser.find_element_by_css_selector('.navbar')
self.assertIn(email, navbar.text)


def assert_logged_out(self, email):
self.browser.find_element_by_name('email')
navbar = self.browser.find_element_by_css_selector('.navbar')
self.assertNotIn(email, navbar.text)


def create_pre_authenticated_session(self, email):
if self.against_staging:
session_key = create_session_on_server(self.server_host, email)
else:
session_key = create_pre_authenticated_session(email)
## to set a cookie we need to first visit the domain.
## 404 pages load the quickest!
# to set a cookie we need to first visit the domain.
# 404 pages load the quickest!
self.browser.get(self.server_url + "/404_no_such_url/")
cookie_script = "document.cookie = '{name}={value}; path={path}; domain={domain}';\n".format(
name=settings.SESSION_COOKIE_NAME,
Expand Down
2 changes: 1 addition & 1 deletion functional_tests/fabfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
def _get_base_folder(host):
return '~/sites/' + host


def _get_manage_dot_py(host):
return '{path}/virtualenv/bin/python {path}/source/manage.py'.format(
path=_get_base_folder(host)
Expand All @@ -22,4 +23,3 @@ def create_session_on_server(email):
email=email,
))
print(session_key)

13 changes: 1 addition & 12 deletions functional_tests/home_and_list_pages.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
ITEM_INPUT_ID = 'id_text'


class HomePage(object):

def __init__(self, test):
self.test = test


def go_to_home_page(self):
self.test.browser.get(self.test.server_url)
self.test.wait_for(self.get_item_input)
return self


def get_item_input(self):
return self.test.browser.find_element_by_id(ITEM_INPUT_ID)


def start_new_list(self, item_text):
self.go_to_home_page()
inputbox = self.get_item_input()
Expand All @@ -24,7 +22,6 @@ def start_new_list(self, item_text):
list_page.wait_for_new_item_in_list(item_text, 1)
return list_page


def go_to_my_lists_page(self):
self.test.browser.find_element_by_link_text('My lists').click()
self.test.wait_for(lambda: self.test.assertEqual(
Expand All @@ -33,7 +30,6 @@ def go_to_my_lists_page(self):
))



class ListPage(object):

def __init__(self, test):
Expand All @@ -51,37 +47,30 @@ def wait_for_new_item_in_list(self, item_text, position):
[row.text for row in self.get_list_table_rows()]
))


def get_share_box(self):
return self.test.browser.find_element_by_css_selector(
'input[name=email]'
)


def get_shared_with_list(self):
return self.test.browser.find_elements_by_css_selector(
'.list-sharee'
)


def share_list_with(self, email):
self.get_share_box().send_keys(email + '\n')
self.test.wait_for(lambda: self.test.assertIn(
email,
[item.text for item in self.get_shared_with_list()]
))


def get_item_input(self):
return self.test.browser.find_element_by_id(ITEM_INPUT_ID)


def add_new_item(self, item_text):
current_pos = len(self.get_list_table_rows())
self.get_item_input().send_keys(item_text + '\n')
self.wait_for_new_item_in_list(item_text, current_pos + 1)


def get_list_owner(self):
return self.test.browser.find_element_by_id('id_list_owner').text

4 changes: 2 additions & 2 deletions functional_tests/management/commands/create_session.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.conf import settings
from django.contrib.auth import BACKEND_SESSION_KEY, SESSION_KEY, get_user_model
User = get_user_model()
from django.contrib.sessions.backends.db import SessionStore
from django.core.management.base import BaseCommand

User = get_user_model()


class Command(BaseCommand):

Expand All @@ -22,4 +23,3 @@ def create_pre_authenticated_session(email):
session[BACKEND_SESSION_KEY] = settings.AUTHENTICATION_BACKENDS[0]
session.save()
return session.session_key

2 changes: 1 addition & 1 deletion functional_tests/server_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import subprocess
THIS_FOLDER = path.dirname(path.abspath(__file__))


def reset_database(host):
subprocess.check_call(
['fab', 'reset_database', '--host=elspeth@{}'.format(host)],
Expand All @@ -19,4 +20,3 @@ def create_session_on_server(host, email):
],
cwd=THIS_FOLDER
).decode().strip()

2 changes: 1 addition & 1 deletion functional_tests/test_layout_and_styling.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .base import FunctionalTest


class LayoutAndStylingTest(FunctionalTest):

def test_layout_and_styling(self):
Expand All @@ -25,4 +26,3 @@ def test_layout_and_styling(self):
512,
delta=5
)

Loading

0 comments on commit f8b0473

Please sign in to comment.