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

Integration tests #181

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 24 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[run]
source = lastuser_core,lastuser_oauth

[report]
# Regexes for lines to exclude from consideration
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover

# Don't complain about missing debug-only code
def __repr__
if self\.debug

# Don't complain about importerror handlers
except ImportError

# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError

# Don't complain if non-runnable code isn't run:
if 0:
if False:
if __name__ == .__main__.:
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.DS_Store
*.pyc
settings.py
test.db
*.wpr
.project
Expand All @@ -13,6 +12,7 @@ error.log
.webassets-cache
instance/development.py
instance/production.py
instance/settings.py
packed.css
packed.js
baseframe-packed.css
Expand Down
15 changes: 8 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
language: python
python:
- "2.7"
- "pypy"
install:
- pip --default-timeout=180 install -r requirements.txt --use-mirrors
- pip --default-timeout=180 install -r test_requirements.txt --use-mirrors
- 'if [[ "$TRAVIS_PYTHON_VERSION" != "pypy" ]]; then pip install psycopg2 --use-mirrors; fi'
- pip --default-timeout=180 install -r requirements.txt
- pip --default-timeout=180 install -r test_requirements.txt
- npm install casperjs
before_script:
- psql -c 'create database lastuser_test_app;' -U postgres
script:
- 'if [[ "$TRAVIS_PYTHON_VERSION" != "pypy" ]]; then nosetests ; fi'
- 'if [[ "$TRAVIS_PYTHON_VERSION" == "pypy" ]]; then SQLALCHEMY_DATABASE_URI="sqlite://" nosetests ; fi'
- nosetests --with-timer
- nohup python runtestserver.py &
- sleep 10
- casperjs test tests

notifications:
email: false
irc: "irc.freenode.net#hasgeek-dev"
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
Lastuser
========

User management is a pain. There's no need to write new user management code for
each new app to do basic things like logging in, managing the profile and
verifying email addresses. Setup one Lastuser instance for all your apps and
defer all user management to it. Use the API to integrate with your app.

Usage
-----

To install and run Lastuser on your computer:

$ git clone https://github.com/hasgeek/lastuser
$ cd lastuser
$ cp instance/settings-sample.py instance/development.py

Edit to customize `instance/development.py` as needed.

$ python manage.py db create

Setup [Virtualenv](https://virtualenv.readthedocs.org/) for this directory.

$ pip install -r requirements.txt
$ python runserver.py

Your Lastuser server will now be accessible at `http://localhost:7000`.

Tests
-----

### Integration

Integration tests serve to verify server responses are correct.

$ which npm # Check if you have NPM installed
$ npm install -g casperjs phantomjs # Install CasperJS and PhantomJS system-wide
$ dropdb lastuser_test_app && createdb lastuser_test_app # Drop any old testing db that may have remained and create again

At this point, please note that `instance/testing.py` requires third-party services' API keys. We suggest you create a `secrets.test` and export all confidential keys required for testing in it.

$ source secrets.test
$ python runtestserver.py # Run the test server
$ source tests/integration/set_test_credentials.sh # Populate the required environment variables
$ casperjs test /path/to/casperjs_test_file

Support
-------

Feel free to file a bug report for anything that doesn't work or is amiss in our code. When in doubt, leave us a message in #tech on [friendsofhasgeek.slack.com](http://friendsofhasgeek.slack.com).
32 changes: 0 additions & 32 deletions README.rst

This file was deleted.

127 changes: 66 additions & 61 deletions instance/testing.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,80 @@
# -*- coding: utf-8 -*-
from flask import Markup
from os import environ
from flask import Markup

TESTING = True
SITE_TITLE = 'Lastuser test'
DEBUG_TB_ENABLED = False
DEBUG_TB_INTERCEPT_REDIRECTS = False
LOGFILE = 'error.log'
SQLALCHEMY_BINDS = {
'lastuser': environ.get('SQLALCHEMY_DATABASE_URI', 'postgres://@localhost:5432/lastuser_test_app'),
}
SQLALCHEMY_ECHO = False
SECRET_KEY = 'random_string_here'
TIMEZONE = 'Asia/Calcutta'
CACHE_TYPE = 'redis'

#: Use SSL for some URLs
USE_SSL = False

#: The title of this site
SITE_TITLE = 'Lastuser'
#: Mail settings
MAIL_SUPRESS_SEND = True
MAIL_FAIL_SILENTLY = False
DEFAULT_MAIL_SENDER = environ.get('DEFAULT_MAIL_SENDER')
MAIL_DEFAULT_SENDER = DEFAULT_MAIL_SENDER # For new versions of Flask-Mail
SITE_SUPPORT_EMAIL = environ.get('SITE_SUPPORT_EMAIL')
# Mail secrets
MAIL_SERVER = environ.get('MAIL_SERVER')
MAIL_PORT = environ.get('MAIL_PORT')
MAIL_USE_SSL = environ.get('MAIL_USE_SSL')
MAIL_USE_TLS = environ.get('MAIL_USE_TLS')
MAIL_DEFAULT_SENDER = environ.get('MAIL_DEFAULT_SENDER')
MAIL_USERNAME = environ.get('MAIL_USERNAME')
MAIL_PASSWORD = environ.get('MAIL_PASSWORD')

#: Logging: recipients of error emails
ADMINS = environ.get('ADMINS')

#: Twitter integration
OAUTH_TWITTER_KEY = environ.get('OAUTH_TWITTER_KEY')
OAUTH_TWITTER_SECRET = environ.get('OAUTH_TWITTER_SECRET')

#: Support contact email
SITE_SUPPORT_EMAIL = '[email protected]'
# : GitHub integration
OAUTH_GITHUB_KEY = environ.get('OAUTH_GITHUB_KEY')
OAUTH_GITHUB_SECRET = environ.get('OAUTH_GITHUB_KEY')

# : Google integration
OAUTH_GOOGLE_KEY = environ.get('OAUTH_GOOGLE_KEY')
OAUTH_GOOGLE_SECRET = environ.get('OAUTH_GOOGLE_SECRET')
# : Default is ['email', 'profile']
OAUTH_GOOGLE_SCOPE = ['email', 'profile']

#: LinkedIn integration
OAUTH_LINKEDIN_KEY = environ.get('OAUTH_LINKEDIN_KEY')
OAUTH_LINKEDIN_SECRET = environ.get('OAUTH_LINKEDIN_SECRET')

#: TypeKit code for fonts
TYPEKIT_CODE = ''
TYPEKIT_CODE = environ.get('TYPEKIT_CODE')

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

#: Database backend
SQLALCHEMY_BINDS = {
'lastuser': environ.get('SQLALCHEMY_DATABASE_URI', 'postgres://:@localhost:5432/lastuser_test_app'),
}
SQLALCHEMY_ECHO = False
GA_CODE = environ.get('GA_CODE')

#: Cache type
CACHE_TYPE = 'redis'
#: Recaptcha for the registration form
RECAPTCHA_USE_SSL = USE_SSL
RECAPTCHA_PUBLIC_KEY = environ.get('RECAPTCHA_PUBLIC_KEY')
RECAPTCHA_PRIVATE_KEY = environ.get('RECAPTCHA_PRIVATE_KEY')
RECAPTCHA_OPTIONS = ''

#: Secret key
SECRET_KEY = 'random_string_here'
#: Exotel support is active
SMS_EXOTEL_SID = environ.get('SMS_EXOTEL_SID')
SMS_EXOTEL_TOKEN = environ.get('SMS_EXOTEL_TOKEN')
SMS_EXOTEL_FROM = environ.get('SMS_EXOTEL_FROM')

#: Timezone
TIMEZONE = 'Asia/Calcutta'
#: Twilio support for non-indian numbers
SMS_TWILIO_SID = environ.get('SMS_TWILIO_SID')
SMS_TWILIO_TOKEN = environ.get('SMS_TWILIO_TOKEN')
SMS_TWILIO_FROM = environ.get('SMS_TWILIO_FROM')

#: Reserved usernames
#: Add to this list but do not remove any unless you want to break
Expand All @@ -48,48 +95,6 @@
'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', '[email protected]')
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 = ''
Expand Down
2 changes: 1 addition & 1 deletion lastuserapp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def init_for(env):
db.app = app # To make it work without an app context
RQ(app) # Pick up RQ configuration from the app
baseframe.init_app(app, requires=['lastuser-oauth'],
ext_requires=['baseframe-bs3', 'fontawesome>=4.0.0', 'jquery.cookie', 'timezone'],
ext_requires=['baseframe-bs3', 'fontawesome>=4.3.0', 'jquery.cookie', 'timezone'],
enable_csrf=True)

lastuser_oauth.lastuser_oauth.init_app(app)
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ unicodecsv
oauth2client
ua-parser
itsdangerous
psycopg2
git+https://github.com/hasgeek/coaster
git+https://github.com/hasgeek/baseframe
git+https://github.com/jace/flask-alembic
37 changes: 37 additions & 0 deletions runtestserver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

from lastuserapp import app, init_for, db
from lastuser_core.models import *

init_for('testing')
#incase data exists from previously run tests
db.drop_all()
#create schema again
db.create_all()

# Add fixtures for test app
# user for CRUD workflow: creating client app
gustav = User(username=u"gustav", fullname=u"Gustav 'world' Dachshund", password='worldismyball')

# org for associating with client
# client for CRUD workflow of defining perms *in* client
# spare user for CRUD workflow of assigning permissions
oakley = User(username=u"oakley", fullname=u"Oakley 'huh' Dachshund")
dachsunited = Organization(name=u'dachsunited', title=u'Dachs United')
dachsunited.owners.users.append(gustav)
dachsunited.members.users.append(oakley)
dachshundworld = Client(title=u"Dachshund World", org=dachsunited, confidential=True, website=u"http://gustavsdachshundworld.com")
partyanimal = Permission(name=u"partyanimal", title=u"Party Animal", org=dachsunited)

db.session.add(gustav)
db.session.add(oakley)
db.session.add(dachsunited)
db.session.add(dachshundworld)
db.session.add(partyanimal)
db.session.commit()

app.run('0.0.0.0', port=7500)
3 changes: 3 additions & 0 deletions test_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
nose
coverage
nose-timer
nose-progressive
bs4
4 changes: 2 additions & 2 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def make_fixtures():
user1 = User(username=u"user1", fullname=u"User 1")
user2 = User(username=u"user2", fullname=u"User 2")
db.session.add_all([user1, user2])

email1 = UserEmail(email=u"[email protected]", user=user1)
phone1 = UserPhone(phone=u"1234567890", user=user1)
email2 = UserEmail(email=u"[email protected]", user=user2)
Expand All @@ -19,7 +19,7 @@ def make_fixtures():
org.owners.users.append(user1)
db.session.add(org)

client = Client(title=u"Test Application", org=org, user=user1, website=u"http://example.com")
client = Client(title=u"Test Application", org=org, confidential=True, website=u"http://example.com", namespace=u"123.example.com")
db.session.add(client)

resource = Resource(name=u"test_resource", title=u"Test Resource", client=client)
Expand Down
Empty file added tests/integration/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions tests/integration/set_test_crendetials.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

export TEST_USERNAME="gustav"
export TEST_PASSWORD="worldismyball"
Loading