Skip to content

Commit

Permalink
Merge branch 'develop' into 'master' to keep it up to date with the m…
Browse files Browse the repository at this point in the history
…ost recent changes, mainly to address in a minor way #47, #66 and #105. Now the UI has a slightly different aspect, but the UX remains.

I'll work on it in the future, adding things like django-channels support for a better realtime/asynchronous workflow.
I guess I'll have to learn how to do it.
  • Loading branch information
sebastian-code committed Aug 26, 2017
2 parents e082f3d + 28e4080 commit 8d45249
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 38 deletions.
13 changes: 11 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
# PostgreSQL conf
POSTGRES_PASSWORD=mysecretpass
POSTGRES_USER=my_super_user
POSTGRES_DB=bootcamp
DATABASE_URL=postgresql://my_super_user:mysecretpass@127.0.0.1:5432/bootcamp

# Main environmental variables
DEBUG=True
SECRET_KEY=s3cr3t_key
DATABASE_URL=sqlite:////tmp/db.sqlite3
ALLOWED_HOSTS=*
# Different URL to have sqlite example
# DATABASE_URL=sqlite:////path/to/workspace/dir/db.sqlite3
ALLOWED_HOSTS=*
REDIS_URL=redis://redis_ip_address:port
14 changes: 9 additions & 5 deletions bootcamp/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.shortcuts import get_object_or_404
from django.conf import settings as django_settings
from django.contrib import messages
from django.db.models import Q
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
Expand All @@ -16,6 +17,7 @@
from bootcamp.articles.models import Article, ArticleComment
from bootcamp.questions.models import Question, Answer
from bootcamp.activities.models import Activity
from bootcamp.messenger.models import Message

from PIL import Image

Expand Down Expand Up @@ -61,19 +63,21 @@ def profile(request, username):
question_count = Question.objects.filter(user=page_user).count()
answer_count = Answer.objects.filter(user=page_user).count()
activity_count = Activity.objects.filter(user=page_user).count()
messages_count = Message.objects.filter(
Q(from_user=page_user) | Q(user=page_user)).count()
data, datepoints = Activity.daily_activity(page_user)
data = {
'page_user': page_user,
'feeds_count': feeds_count,
'article_count': article_count,
'article_comment_count': article_comment_count,
'question_count': question_count,
'global_interactions': activity_count,
'global_interactions': activity_count + article_comment_count + answer_count + messages_count, # noqa: E501
'answer_count': answer_count,
'bar_data': [feeds_count, article_count, article_comment_count,
question_count, answer_count, activity_count],
'bar_labels': json.dumps(
'["Feeds", "Articles", "Comments", "Questions", "Answers", "Activities"]'), # noqa: E501
'bar_data': [
feeds_count, article_count, article_comment_count, question_count,
answer_count, activity_count],
'bar_labels': json.dumps('["Feeds", "Articles", "Comments", "Questions", "Answers", "Activities"]'), # noqa: E501
'line_labels': datepoints,
'line_data': data,
'feeds': feeds,
Expand Down
File renamed without changes.
108 changes: 108 additions & 0 deletions bootcamp/questions/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
from django.contrib.auth import get_user_model
from django.http import HttpResponseBadRequest
from django.core.urlresolvers import reverse
from django.test import Client, TestCase

from bootcamp.questions.models import Question, Answer


class TestViews(TestCase):
"""
Includes tests for all the functionality
associated with Views
"""
def setUp(self):
self.client = Client()
self.other_client = Client()
self.user = get_user_model().objects.create_user(
username='test_user',
email='test@gmail.com',
password='top_secret'
)
self.other_user = get_user_model().objects.create_user(
username='other_test_user',
email='other_test@gmail.com',
password='top_secret'
)
self.client.login(username='test_user', password='top_secret')
self.other_client.login(
username='other_test_user', password='top_secret')
self.question_one = Question.objects.create(
user=self.user, title='This is a sample question',
description='This is a sample question description',
tags='test1,test2')
self.question_two = Question.objects.create(
user=self.user,
title='A Short Title',
description='''This is a really good content, just if somebody
published it, that would be awesome, but no, nobody wants to
publish it, because they know this is just a test, and you
know than nobody wants to publish a test, just a test;
everybody always wants the real deal.''',
favorites=0,
has_accepted_answer=True
)
self.answer = Answer.objects.create(
user=self.user,
question=self.question_two,
description='A reaaaaally loooong content',
votes=0,
is_accepted=True
)

def test_index_questions(self):
response = self.client.get(reverse('questions'))
self.assertEqual(response.status_code, 200)
self.assertTrue(
'This is a sample question' in str(response.context['question']))

def test_create_question_view(self):
"""
"""
current_question_count = Question.objects.count()
response = self.client.post(reverse('ask'),
{'title': 'Not much of a title',
'description': 'babla',
'tags': 'test, tag'})
self.assertEqual(response.status_code, 302)
new_question = Question.objects.first()
self.assertEqual(new_question.title, 'Not much of a title')
self.assertEqual(Question.objects.count(),
current_question_count + 1)

def test_answered_questions(self):
response = self.client.get(reverse('answered'))
self.assertEqual(response.status_code, 200)
self.assertTrue('A Short Title' in str(response.context['question']))

def test_all_questions_view(self):
response = self.client.get(reverse('all'))
self.assertEqual(response.status_code, 200)
self.assertTrue('A Short Title' in str(response.context['question']))

def test_individual_question(self):
response = self.client.get(
'/questions/{}/'.format(self.question_one.id))
self.assertEqual(response.status_code, 200)
self.assertTrue(
'This is a sample question' in str(response.context['question']))

def test_answer_question(self):
current_answer_count = Answer.objects.count()
response = self.client.post(
reverse('answer'),
{'question': self.question_one.id,
'description': 'A reaaaaally loooong content'})
self.assertEqual(response.status_code, 302)
self.assertEqual(Answer.objects.count(), current_answer_count + 1)

def test_empty_answer(self):
current_answer_count = Answer.objects.count()
response = self.client.post(reverse('answer'),
{'question': self.question_one.id})
self.assertEqual(response.status_code, 200)
self.assertEqual(Answer.objects.count(), current_answer_count)

def test_answer_redirects(self):
response = self.other_client.get(reverse('answer'))
self.assertRedirects(response, reverse('questions'), status_code=302)
4 changes: 3 additions & 1 deletion bootcamp/questions/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def _questions(request, questions, active):
except PageNotAnInteger:
questions = paginator.page(1)

except EmptyPage:
except EmptyPage: # pragma: no cover
questions = paginator.page(paginator.num_pages)

return render(request, 'questions/questions.html', {
Expand Down Expand Up @@ -90,12 +90,14 @@ def answer(request):
answer.save()
user.profile.notify_answered(answer.question)
return redirect('/questions/{0}/'.format(answer.question.pk))

else:
question = form.cleaned_data.get('question')
return render(request, 'questions/question.html', {
'question': question,
'form': form
})

else:
return redirect('/questions/')

Expand Down
28 changes: 13 additions & 15 deletions bootcamp/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,23 @@
<li><a href="{% url 'articles' %}">{% trans 'Articles' %}</a></li>
<li><a href="{% url 'questions' %}">{% trans 'Q&A' %}</a></li>
<li><a href="{% url 'network' %}">{% trans 'Network' %}</a></li>
<li><a href="{% url 'inbox' %}">Inbox <span class="badge" id="unread-count">0</span></a></li>
</ul>
{% if not hide_search %}
<form class="navbar-form navbar-left" role="search" action="{% url 'search' %}">
<div class="input-group" style="width:210px">
<input type="text" class="form-control" name="q" placeholder="Search">
<span class="input-group-btn">
<button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
</span>
</div>
</form>
{% endif %}
<ul class="nav navbar-nav navbar-right">
<li>
<a href="{% url 'profile' user.username %}">{{ user.profile.get_screen_name }}</a>
</li>
{% if not hide_search %}
<form class="navbar-form navbar-left" role="search" action="{% url 'search' %}">
<div class="input-group" style="width:210px">
<input type="text" class="form-control" name="q" placeholder="Search">
<span class="input-group-btn">
<button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
</span>
</div>
</form>
{% endif %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><b class="caret"></b></a>
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ user.profile.get_screen_name }} <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="{% url 'inbox' %}"><span class="badge pull-right" id="unread-count">0</span> Inbox</a></li>
<li><a href="{% url 'profile' user.username %}">{% trans 'My Profile' %}</a></li>
<li><a href="{% url 'settings' %}">{% trans 'Account Settings' %}</a></li>
<li class="divider"></li>
<li><a href="{% url 'logout' %}">{% trans 'Log out' %}</a></li>
Expand Down
33 changes: 18 additions & 15 deletions dev.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
postgres:
image: postgres
volumes:
# If you are using boot2docker, postgres data has to live in the VM for now until #581 is fixed
# for more info see here: https://github.com/boot2docker/boot2docker/issues/581
- /data/bootcamp/postgres:/var/lib/postgresql/data
version: '2'

django:
build: .
command: python /bootcamp/manage.py runserver 0.0.0.0:8000
volumes:
- .:/bootcamp
ports:
- "8000:8000"
links:
- postgres
volumes:
postgres_data: {}

services:

postgres:
image: postgres:latest
volumes:
- postgres_data:/var/lib/postgresql/data
env_file: .env
ports:
- '5432:5432'

redis:
image: redis:3.0
ports:
- '6379:6379'

0 comments on commit 8d45249

Please sign in to comment.