Skip to content
This repository has been archived by the owner on Apr 28, 2020. It is now read-only.

Testing environment bootstrapping #53

Merged
merged 18 commits into from
Aug 20, 2013
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
language: python
python:
- 2.7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add pypy as a build target. Lastuser fails under pypy for some reason. We have to figure it out.

install:
- pip install -r requirements.txt --use-mirrors
- pip install -r test_requirements.txt --use-mirrors
script:
- nosetests tests --with-coverage
notifications:
email: false
irc: "irc.freenode.net#hasgeek-dev"
101 changes: 101 additions & 0 deletions instance/testing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
from flask import Markup

#: The title of this site
SITE_TITLE = 'Lastuser'

#: Support contact email
SITE_SUPPORT_EMAIL = 'test@example.com'

#: TypeKit code for fonts
TYPEKIT_CODE = ''

#: Google Analytics code UA-XXXXXX-X
GA_CODE = ''

#: Database backend
SQLALCHEMY_BINDS = {
'lastuser': 'postgresql://postgres@localhost/myapp_test',
}

#: Cache type
CACHE_TYPE = 'redis'

#: Secret key
SECRET_KEY = 'random_string_here'

#: Timezone
TIMEZONE = 'Asia/Calcutta'

#: Reserved usernames
#: Add to this list but do not remove any unless you want to break
#: the website
RESERVED_USERNAMES = set([
'app',
'apps',
'auth',
'client',
'confirm',
'login',
'logout',
'new',
'profile',
'reset',
'register',
'token',
'organizations',
])

#: Mail settings
#: MAIL_FAIL_SILENTLY : default True
#: MAIL_SERVER : default 'localhost'
#: MAIL_PORT : default 25
#: MAIL_USE_TLS : default False
#: MAIL_USE_SSL : default False
#: MAIL_USERNAME : default None
#: MAIL_PASSWORD : default None
#: DEFAULT_MAIL_SENDER : default None
MAIL_FAIL_SILENTLY = False
MAIL_SERVER = 'localhost'
DEFAULT_MAIL_SENDER = ('Lastuser', 'test@example.com')
MAIL_DEFAULT_SENDER = DEFAULT_MAIL_SENDER # For new versions of Flask-Mail

#: Logging: recipients of error emails
ADMINS = []

#: Log file
LOGFILE = 'error.log'

#: Use SSL for some URLs
USE_SSL = False

#: Twitter integration
OAUTH_TWITTER_KEY = ''
OAUTH_TWITTER_SECRET = ''

#: GitHub integration
OAUTH_GITHUB_KEY = ''
OAUTH_GITHUB_SECRET = ''

#: Recaptcha for the registration form
RECAPTCHA_USE_SSL = USE_SSL
RECAPTCHA_PUBLIC_KEY = ''
RECAPTCHA_PRIVATE_KEY = ''
RECAPTCHA_OPTIONS = ''

#: SMS gateways
SMS_SMSGUPSHUP_MASK = ''
SMS_SMSGUPSHUP_USER = ''
SMS_SMSGUPSHUP_PASS = ''

#: Messages (text or HTML)
MESSAGE_FOOTER = Markup('Copyright &copy; <a href="http://hasgeek.com/">HasGeek</a>. Powered by <a href="https://github.com/hasgeek/lastuser" title="GitHub project page">Lastuser</a>, open source software from <a href="https://github.com/hasgeek">HasGeek</a>.')
USERNAME_REASON = ''
EMAIL_REASON = 'Please provide an email address to complete your profile'
BIO_REASON = ''
TIMEZONE_REASON = 'Dates and times will be shown in your preferred timezone'
ORG_NAME_REASON = u"Your company’s name as it will appear in the URL. Letters, numbers and dashes only"
ORG_TITLE_REASON = u"Your organization’s given name, preferably without legal suffixes"
ORG_DESCRIPTION_REASON = u"A few words about your organization (optional). Plain text only"
LOGIN_MESSAGE_1 = ""
LOGIN_MESSAGE_2 = ""
8 changes: 8 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[nosetests]
match=^test
nocapture=1
cover-package=lastuser_core
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should cover all three blueprints.

with-coverage=1
cover-erase=1
with-doctest=1
where=tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline required at end of all files.

1 change: 1 addition & 0 deletions sitecustomize.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Required to make OpenID work with Wordpress (first instance where it came up)
import sys
reload(sys)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't know what side effects this has since sitecustomize.py is called at Python startup time. Perhaps change this to:

import sys
if not hasttr(sys, 'setdefaultencoding'):
    reload(sys)
sys.setdefaultencoding('utf-8')

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, on quotes, I'm tending towards this convention: 'single' quotes for keywords and anything where the app's behaviour will change if the content changes, and "double" quotes for user-facing content that doesn't affect app behaviour. So in this case, both strings are in single quotes.

sys.setdefaultencoding("utf-8")
2 changes: 2 additions & 0 deletions test_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
nose
coverage
Empty file added tests/__init__.py
Empty file.
31 changes: 31 additions & 0 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-

from coaster import buid
from lastuserapp import db, app
from lastuser_core.models import *

def make_fixtures():
user1 = User(username=u"user1", fullname=u"User 1")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8 compliance required. Indentation is four spaces. Install SublimeLinter and drop these exceptions to PEP8 in SublimeLinter.sublime-settings (Sublime Text -> Preferences -> Package Settings -> SublimeLinter -> Settings - User):

{
    "pep8_ignore":
    [
        "E501",
        "E128",
        "E123",
        "E124"
    ]
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do this. Thanks. Have been lately facing lots of issues with indentation.

user2 = User(username=u"user2", fullname=u"User 2")
db.session.add_all([user1, user2])

email1 = UserEmail(email=u"user1@example.com", user=user1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add API calls:

user.add_email(email, verified=False)  # False is default and creates UserEmailClaim
user.add_phone(phone, verified=False)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be a part of the CRUD API abstraction. My current roadblock is whether I am taking the correct approach with fixtures. Have taken note of this and will handle this in the next pull request. Currently, please review for correctness of fixtures.

phone1 = UserPhone(phone=u"1234567890", user=user1)
email2 = UserEmail(email=u"user2@example.com", user=user2)
phone2 = UserPhone(phone=u"1234567891", user=user2)
db.session.add_all([email1, phone1, email2, phone2])

org = Organization(name=u"org", title=u"Organization")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add owners list parameter to Organization.__init__ that adds those users to the owners team. Do not accept a Team as the parameter since teams can't be shared across organizations.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, Organization.ownerlist can be an association_proxy pointing to Organization.owners.users. That will make this automatic.

org.owners.users.append(user1)
db.session.add(org)

client = Client(title=u"Test Application", org=org, user=user1, website=u"http://example.com")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clients can belong to an org or a user, not both. This operation should fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

db.session.add(client)

resource = Resource(name=u"test_resource", title=u"Test Resource", client=client)
db.session.add(resource)

action = ResourceAction(name=u"read", title=u"Read", resource=resource)
db.session.add(action)

db.session.commit()
21 changes: 21 additions & 0 deletions tests/test_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-

import unittest
from lastuserapp import app, db, init_for
from .fixtures import make_fixtures

class TestDatabaseFixture(unittest.TestCase):
def setUp(self):
init_for('testing')
app.config['TESTING'] = True
db.app = app
db.drop_all()
db.create_all()
self.db = db
make_fixtures()

def test_noop(self):
pass

def tearDown(self):
self.db.drop_all()