def profile(): """Shows the user's profile page.""" db = get_session(current_app) user_id = session.get('user_id') if not user_id: return forbidden('You must be logged in to see a profile!') user = db.query(User).get(user_id) if request.method == 'POST': data = request.form else: data = MultiDict(user.dictify()) form = ProfileForm(data) if request.method == 'POST' and form.validate(): user.name = data['name'] user.username = data['username'] user.slug = data['username'] user.github_handle = data['github_handle'] db.add(user) db.commit() flash('Your profile was updated.', 'success') return render_template('users/profile.html', form=form)
def test_destroy(self): """Test removing a team.""" response = self.client.post(self.url, data=self.data) eq_(response.status_code, 200) db = get_session(self.app) eq_(0, db.query(Team).count())
def profile(): """Shows the user's profile page.""" db = get_session(current_app) user_id = session.get('user_id') if not user_id: return forbidden('You must be logged in to see a profile!') user = db.query(User).get(user_id) if request.method == 'POST': data = request.form else: data = MultiDict(user.dictify()) form = ProfileForm(data) if request.method == 'POST' and form.validate(): user.name = data['name'] user.username = data['username'] user.slug = data['username'] user.github_handle = data['github_handle'] db.add(user) db.commit() flash('Your profile was updated.', 'success') return render_template('users/profile.html', form=form)
def test_update_user(self): """Test that a user can update their own settings""" db = get_session(self.app) with self.app.app_context(): u = user(save=True) id = u.id data = json.dumps({ 'api_key': self.app.config.get('API_KEY'), 'user': u.username, 'email': '*****@*****.**', 'github_handle': 'test', 'name': 'Test' }) response = self.client.post('/api/v1/user/%s/' % u.username, data=data, content_type='application/json') eq_(response.status_code, 200) u = db.query(User).get(id) eq_(u.email, '*****@*****.**') eq_(u.github_handle, 'test') eq_(u.name, 'Test')
def test_create_first_status(self): """Test creating the very first status for a project and user.""" db = get_session(self.app) with self.app.app_context(): u = user(username='******', save=True) data = json.dumps({ 'api_key': self.app.config.get('API_KEY'), 'user': u.username, 'project': 'sumodev', 'content': 'bug 123456' }) response = self.client.post('/api/v1/status/', data=data, content_type='application/json') eq_(response.status_code, 200) assert 'bug 123456' in response.data # Verify the user was created. eq_(db.query(User).first().username, 'r1cky') # Verify the project was created. eq_(db.query(Project).first().slug, 'sumodev') # Verify the status was created. eq_(db.query(Status).first().content, 'bug 123456')
def globals(): db = get_session(app) ctx = dict() # Projects, teams and current user ctx['projects'] = db.query(Project).order_by(Project.name) ctx['teams'] = db.query(Team).order_by(Team.name) ctx['weeks'] = get_weeks() ctx['current_user'] = None if session and 'user_id' in session: user = db.query(User).get(session['user_id']) if user: ctx['current_user'] = user # Time stuff ctx['today'] = date.today() ctx['yesterday'] = date.today() - timedelta(1) # CSRF def csrf_field(): return ('<div style="display: none;">' '<input type="hidden" name="_csrf_token" value="%s">' '</div>' % csrf._get_token()) ctx['csrf'] = csrf_field return ctx
def statusize(): """Posts a status from the web.""" db = get_session(current_app) user_id = session.get('user_id') if not user_id: return forbidden('You must be logged in to statusize!') user = db.query(User).get(user_id) message = request.form.get('message', '') if not message: return page_not_found('You cannot statusize nothing!') status = Status(user_id=user.id, content=message, content_html=message) project = request.form.get('project', '') if project: project = db.query(Project).filter_by(id=project).first() if project: status.project_id = project.id # TODO: reply handling db.add(status) db.commit() # Try to go back from where we came. referer = request.headers.get('referer', url_for('status.index')) redirect_url = request.form.get('redirect_to', referer) return redirect(redirect_url)
def statusize(): """Posts a status from the web.""" db = get_session(current_app) user_id = session.get('user_id') if not user_id: return forbidden('You must be logged in to statusize!') user = db.query(User).get(user_id) message = request.form.get('message', '') if not message: return page_not_found('You cannot statusize nothing!') status = Status(user_id=user.id, content=message, content_html=message) project = request.form.get('project', '') if project: project = db.query(Project).filter_by(id=project).first() if project: status.project_id = project.id # TODO: reply handling db.add(status) db.commit() # Try to go back from where we came. referer = request.headers.get('referer', url_for('status.index')) redirect_url = request.form.get('redirect_to', referer) return redirect(redirect_url)
def test_new_profile_create_missing_data(self): """Test profile creation attempts with missing data.""" db = get_session(self.app) u = db.query(User) # No email data = {'email': '', 'username': '******', 'github_handle': 'test-handle', 'name': 'Test User'} response = self.client.post('/profile/new/', data=data) eq_(response.status_code, 200) eq_(u.count(), 0) # No username data = {'email': '*****@*****.**', 'username': '', 'github_handle': 'test-handle', 'name': 'Test User'} response = self.client.post('/profile/new/', data=data) eq_(response.status_code, 200) eq_(u.count(), 0) # No name data = {'email': '*****@*****.**', 'username': '******', 'github_handle': 'test-handle', 'name': ''} response = self.client.post('/profile/new/', data=data) eq_(response.status_code, 200) eq_(u.count(), 0) # No GitHub handle data = {'email': '*****@*****.**', 'username': '******', 'github_handle': '', 'name': 'Test User'} response = self.client.post('/profile/new/', data=data) eq_(response.status_code, 302) eq_(u.count(), 1)
def globals(): db = get_session(app) ctx = dict() # Projects, teams and current user ctx['projects'] = db.query(Project).order_by(Project.name) ctx['teams'] = db.query(Team).order_by(Team.name) ctx['weeks'] = get_weeks() ctx['current_user'] = None if session and 'user_id' in session: user = db.query(User).get(session['user_id']) if user: ctx['current_user'] = user # Time stuff ctx['today'] = date.today() ctx['yesterday'] = date.today() - timedelta(1) # CSRF def csrf_field(): return ('<div style="display: none;">' '<input type="hidden" name="_csrf_token" value="%s">' '</div>' % csrf._get_token()) ctx['csrf'] = csrf_field return ctx
def new_profile(): """Create a new user profile""" if (not (session or request.method == 'POST') or 'user_id' in session or not ('email' in session or 'email' in request.form)): return redirect(url_for('status.index')) data = MultiDict() try: data['email'] = session['email'] session.pop('email') except KeyError: pass if request.method == 'POST': data = request.form form = ProfileForm(data) if request.method == 'POST' and form.validate(): db = get_session(current_app) u = User(name=data['name'], email=data['email'], username=data['username'], slug=data['username'], github_handle=data['github_handle']) db.add(u) db.commit() session['email'] = u.email session['user_id'] = u.id flash('Your profile was created.', 'success') return redirect(url_for('status.index')) return render_template('users/new_profile.html', form=form)
def test_destroy(self): """Test removing a team.""" response = self.client.post(self.url, data=self.data) eq_(response.status_code, 200) db = get_session(self.app) eq_(0, db.query(Team).count())
def update_team(): """Update a team's info.""" db = get_session(current_app) try: team = _get_team() except ApiError, e: return api_error(e.code, str(e))
def timesince_last_update(): """Get the time since the users last update in seconds""" db = get_session(current_app) try: user = _get_user() except ApiError, e: return api_error(e.code, str(e))
def test_update(self): """Test update team info.""" response = self.client.post(self.url, data=self.data) eq_(response.status_code, 200) db = get_session(self.app) team = db.query(Team).filter_by(slug=self.data['slug']).one() eq_(team.name, self.data['name'])
def index_feed(): """Output every status in an Atom feed.""" db = get_session(current_app) statuses = db.query(Status).filter_by(reply_to=None)\ .order_by(desc(Status.created)) return render_feed('All status updates', statuses)
def timesince_last_update(): """Get the time since the users last update in seconds""" db = get_session(current_app) try: user = _get_user() except ApiError, e: return api_error(e.code, str(e))
def saving_func(*args, **kwargs): save = kwargs.pop('save', False) ret = func(*args, **kwargs) if save: db = get_session(current_app) db.add(ret) db.commit() return ret
def test_update(self): """Test update team info.""" response = self.client.post(self.url, data=self.data) eq_(response.status_code, 200) db = get_session(self.app) team = db.query(Team).filter_by(slug=self.data['slug']).one() eq_(team.name, self.data['name'])
def destroy_team(): """Removes a team.""" db = get_session(current_app) try: team = _get_team() except ApiError, e: return api_error(e.code, str(e))
def destroy_team(): """Removes a team.""" db = get_session(current_app) try: team = _get_team() except ApiError, e: return api_error(e.code, str(e))
def index_feed(): """Output every status in an Atom feed.""" db = get_session(current_app) statuses = db.query(Status).filter_by(reply_to=None)\ .order_by(desc(Status.created)) return render_feed('All status updates', statuses)
def update_team(): """Update a team's info.""" db = get_session(current_app) try: team = _get_team() except ApiError, e: return api_error(e.code, str(e))
def saving_func(*args, **kwargs): save = kwargs.pop('save', False) ret = func(*args, **kwargs) if save: db = get_session(current_app) db.add(ret) db.commit() return ret
def create_team_member(): """Add a user to the team.""" db = get_session(current_app) try: team = _get_team() user = _get_user() except ApiError, e: return api_error(e.code, str(e))
def create_team_member(): """Add a user to the team.""" db = get_session(current_app) try: team = _get_team() user = _get_user() except ApiError, e: return api_error(e.code, str(e))
def destroy_team_member(): """Remove a user from the team.""" db = get_session(current_app) try: team = _get_team() user = _get_user() except ApiError, e: return api_error(e.code, str(e))
def test_no_name(self): """Test team creation with no name.""" self.data.pop('name') response = self.client.post(self.url, data=self.data) eq_(response.status_code, 200) db = get_session(self.app) team = db.query(Team).filter_by(slug=self.data['slug']).one() eq_(team.name, self.data['slug'])
def test_no_name(self): """Test team creation with no name.""" self.data.pop('name') response = self.client.post(self.url, data=self.data) eq_(response.status_code, 200) db = get_session(self.app) team = db.query(Team).filter_by(slug=self.data['slug']).one() eq_(team.name, self.data['slug'])
def destroy_team_member(): """Remove a user from the team.""" db = get_session(current_app) try: team = _get_team() user = _get_user() except ApiError, e: return api_error(e.code, str(e))
def test_create(self): """Test creation of a team.""" response = self.client.post(self.url, data=self.data) eq_(response.status_code, 200) db = get_session(self.app) team = db.query(Team).filter_by(slug=self.data["slug"]).one() eq_(team.slug, self.data["slug"]) eq_(team.name, self.data["name"])
def project_timeline(): """Get a collection of the project's recent status updates.""" db = get_session(current_app) MAX = current_app.config.get('API2_TIMELINE_MAX_RESULTS', TIMELINE_MAX_RESULTS) try: params = _get_timeline_params() except ApiError, e: return api_error(e.code, str(e))
def user_timeline(): """Get a collection of the user's recent status updates.""" app = current_app db = get_session(app) MAX = app.config.get("API2_TIMELINE_MAX_RESULTS", TIMELINE_MAX_RESULTS) try: params = _get_params(request) except ApiError, e: return api_error(400, str(e))
def test_destroy_team_member(self): """Test team member deletion.""" eq_(1, self.team.users.count()) response = self.client.post(self.url, data=self.data) eq_(response.status_code, 200) db = get_session(self.app) team = db.query(Team).filter_by(slug=self.data['slug']).one() eq_(0, team.users.count())
def test_destroy_team_member(self): """Test team member deletion.""" eq_(1, self.team.users.count()) response = self.client.post(self.url, data=self.data) eq_(response.status_code, 200) db = get_session(self.app) team = db.query(Team).filter_by(slug=self.data['slug']).one() eq_(0, team.users.count())
def project_timeline(): """Get a collection of the project's recent status updates.""" db = get_session(current_app) MAX = current_app.config.get('API2_TIMELINE_MAX_RESULTS', TIMELINE_MAX_RESULTS) try: params = _get_timeline_params() except ApiError, e: return api_error(e.code, str(e))
def statuses(self): """Return all statuses from this team.""" db = get_session(current_app) user_ids = [u.id for u in self.users] if user_ids: return db.query(Status).filter(Status.user_id.in_(user_ids)) else: # There are no users in this team but SQLAlchemy doesn't like # in_([]) queries so we short circuit with `0=1`. This also allows # other calls to be chained onto the query. return db.query(Status).filter('0=1')
def setUp(self): super(BaseTestCase, self).setUp() self.app = create_app(test_settings) self.client = self.app.test_client() for app in self.app.installed_apps: try: __import__('%s.models' % app) except ImportError: pass db = get_session(self.app) Model.metadata.create_all(db.bind)
def setUp(self): super(BaseTestCase, self).setUp() self.app = create_app(test_settings) self.client = self.app.test_client() for app in self.app.installed_apps: try: __import__('%s.models' % app) except ImportError: pass db = get_session(self.app) Model.metadata.create_all(db.bind)
def statuses(self): """Return all statuses from this team.""" db = get_session(current_app) user_ids = [u.id for u in self.users] if user_ids: return db.query(Status).filter(Status.user_id.in_(user_ids)) else: # There are no users in this team but SQLAlchemy doesn't like # in_([]) queries so we short circuit with `0=1`. This also allows # other calls to be chained onto the query. return db.query(Status).filter('0=1')
def index(): """The home page.""" db = get_session(current_app) return render_template( 'status/index.html', statuses=paginate( db.query(Status).filter_by(reply_to=None).order_by( desc(Status.created)), request.args.get('page', 1), startdate(request), enddate(request)), )
def validate_user(): db = get_session(app) if session and 'email' in session and not 'user_id' in session: user = db.query(User).filter_by(email=session['email']).first() if not user: if request.endpoint not in ('users.new_profile', 'users.authenticate', 'users.logout', 'static'): return redirect(url_for('users.new_profile'))
def team_feed(slug): """The team status feed. Shows all updates from a team in Atom format.""" db = get_session(current_app) team = db.query(Team).filter_by(slug=slug).first() if not team: return page_not_found('Team not found.') statuses = team.statuses().filter_by(reply_to=None)\ .order_by(desc(Status.created)) return render_feed('Updates from %s' % team.name, statuses)
def project_feed(slug): """Project Atom feed. Shows all statuses for a project.""" db = get_session(current_app) project = db.query(Project).filter_by(slug=slug).first() if not project: return page_not_found('Project not found.') statuses = project.statuses.filter_by(reply_to=None)\ .order_by(desc(Status.created)) return render_feed('Updates for %s' % project.name, statuses)
def user_feed(slug): """A user's Atom feed. Output every status from this user.""" db = get_session(current_app) user = db.query(User).filter_by(slug=slug).first() if not user: return page_not_found('User not found.') statuses = user.statuses.filter_by(reply_to=None)\ .order_by(desc(Status.created)) return render_feed('Updates by %s' % user.username, statuses)
def test_team_members(self): """Test list members when members are in team.""" url = '%s?%s' % (self.url, urlencode(self.query)) db = get_session(self.app) self.team.users.append(self.user) data = json.dumps({'users': [self.user.dictify()]}) db.commit() response = self.client.get(url) eq_(response.status_code, 200) eq_(response.data, data)
def project_feed(slug): """Project Atom feed. Shows all statuses for a project.""" db = get_session(current_app) project = db.query(Project).filter_by(slug=slug).first() if not project: return page_not_found('Project not found.') statuses = project.statuses.filter_by(reply_to=None)\ .order_by(desc(Status.created)) return render_feed('Updates for %s' % project.name, statuses)
def index(): """The home page.""" db = get_session(current_app) return render_template( 'status/index.html', statuses=paginate( db.query(Status).filter_by(reply_to=None).order_by( desc(Status.created)), request.args.get('page', 1), startdate(request), enddate(request)),)
def team_feed(slug): """The team status feed. Shows all updates from a team in Atom format.""" db = get_session(current_app) team = db.query(Team).filter_by(slug=slug).first() if not team: return page_not_found('Team not found.') statuses = team.statuses().filter_by(reply_to=None)\ .order_by(desc(Status.created)) return render_feed('Updates from %s' % team.name, statuses)
def validate_user(): db = get_session(app) if session and 'email' in session and not 'user_id' in session: user = db.query(User).filter_by(email=session['email']).first() if not user: if request.endpoint not in ('users.new_profile', 'users.authenticate', 'users.logout', 'static'): return redirect(url_for('users.new_profile'))
def user(slug): """The user page. Shows a user's statuses.""" db = get_session(current_app) user = db.query(User).filter_by(slug=slug).first() if not user: return page_not_found('User not found.') return render_template('status/user.html', user=user, statuses=user.recent_statuses( request.args.get('page', 1), startdate(request), enddate(request)))
def test_team_members(self): """Test list members when members are in team.""" url = '%s?%s' % (self.url, urlencode(self.query)) db = get_session(self.app) self.team.users.append(self.user) data = json.dumps({'users': [self.user.dictify()]}) db.commit() response = self.client.get(url) eq_(response.status_code, 200) eq_(response.data, data)
def test_paginate(self): """Test the paginate helper function.""" db = get_session(self.app) statuses = [] with self.app.app_context(): p = project(save=True) u = user(save=True) # Create 100 statuses for i in range(30): statuses.append(status(project=p, user=u, created=datetime(2012, 5, 25), save=True)) for i in range(30): statuses.append(status(project=p, user=u, created=datetime(2012, 6, 25), save=True)) for i in range(40): statuses.append(status(project=p, user=u, created=datetime(2012, 7, 25), save=True)) s = db.query(Status).order_by(Status.id) # Test simple pagination page = paginate(s, page=1) eq_(page.pages, 5) eq_(page.has_prev, False) eq_(page.has_next, True) page = paginate(s, page=3) eq_(page.has_prev, True) eq_(page.has_next, True) page = paginate(s, page=5) eq_(page.has_prev, True) eq_(page.has_next, False) # Test date filtered pagination page = paginate(s, page=1, startdate=datetime(2012, 5, 28)) eq_(page.pages, 4) page = paginate(s, page=1, startdate=datetime(2012, 5, 28), enddate=datetime(2012, 6, 28)) eq_(page.pages, 2) page = paginate(s, page=1, enddate=datetime(2012, 6, 28)) eq_(page.pages, 3)
def user_feed(slug): """A user's Atom feed. Output every status from this user.""" db = get_session(current_app) user = db.query(User).filter_by(slug=slug).first() if not user: return page_not_found('User not found.') statuses = user.statuses.filter_by(reply_to=None)\ .order_by(desc(Status.created)) return render_feed('Updates by %s' % user.username, statuses)
def test_create_reply(self): """Test creation of replies""" db = get_session(self.app) with self.app.app_context(): u = user(save=True) s = status(user=u, save=True) sid = s.id data = json.dumps({ 'api_key': self.app.config.get('API_KEY'), 'user': u.username, 'content': 'reply to status', 'reply_to': sid }) response = self.client.post('/api/v1/status/', data=data, content_type='application/json') eq_(response.status_code, 200) # Verify that the status is actually a reply r = db.query(Status).filter(Status.reply_to_id == sid).first() eq_(r.content, 'reply to status') # Verify that the reply is included in the list of replies s = db.query(Status).get(sid) assert r in s.replies().items # You should not be able to reply to the reply data = json.dumps({ 'api_key': self.app.config.get('API_KEY'), 'user': '******', 'content': 'should not work', 'reply_to': r.id }) response = self.client.post('/api/v1/status/', data=data, content_type='application/json') eq_(response.status_code, 400) # You should not be able to reply to a status that does not exist data = json.dumps({ 'api_key': self.app.config.get('API_KEY'), 'user': '******', 'content': 'reply to status', 'reply_to': 9999 }) response = self.client.post('/api/v1/status/', data=data, content_type='application/json') eq_(response.status_code, 400)
def test_format_update(self): db = get_session(self.app) p = Project(name='mdndev', slug='mdndev', repo_url='https://github.com/mozilla/kuma') db.add(p) db.commit() content = "#merge pull #1 and pR 2 to fix bug #3 and BUg 4" formatted_update = format_update(content, project=p) ok_('tag-merge' in formatted_update) ok_('pull/1' in formatted_update) ok_('pull/2' in formatted_update) ok_('show_bug.cgi?id=3' in formatted_update) ok_('show_bug.cgi?id=4' in formatted_update)
def user(slug): """The user page. Shows a user's statuses.""" db = get_session(current_app) user = db.query(User).filter_by(slug=slug).first() if not user: return page_not_found('User not found.') return render_template( 'status/user.html', user=user, statuses=user.recent_statuses( request.args.get('page', 1), startdate(request), enddate(request)))
def status(id): """The status page. Shows a single status.""" db = get_session(current_app) statuses = db.query(Status).filter_by(id=id) if not statuses.count(): return page_not_found('Status not found.') status = statuses[0] return render_template('status/status.html', user=status.user, statuses=paginate(statuses), replies=status.replies(request.args.get('page', 1)))
def test_format_update(self): db = get_session(self.app) p = Project(name='mdndev', slug='mdndev', repo_url='https://github.com/mozilla/kuma') db.add(p) db.commit() content = "#merge pull #1 and pR 2 to fix bug #3 and BUg 4" formatted_update = format_update(content, project=p) ok_('tag-merge' in formatted_update) ok_('pull/1' in formatted_update) ok_('pull/2' in formatted_update) ok_('show_bug.cgi?id=3' in formatted_update) ok_('show_bug.cgi?id=4' in formatted_update)
def team(slug): """The team page. Shows statuses for all users in the team.""" db = get_session(current_app) team = db.query(Team).filter_by(slug=slug).first() if not team: return page_not_found('Team not found.') return render_template('status/team.html', team=team, users=team.users, teams=db.query(Team).order_by(Team.name).all(), statuses=team.recent_statuses( request.args.get('page', 1), startdate(request), enddate(request)))