Skip to content
Draft
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
1 change: 0 additions & 1 deletion bin/wait-for-deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ set -o errexit
set -o nounset

source $(dirname $0)/wait-for-postgres.sh
source $(dirname $0)/wait-for-elasticsearch.sh

exec "$@"
19 changes: 0 additions & 19 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ services:
command: bin/wait-for-deps.sh ./manage.py runserver 0.0.0.0:8000
depends_on:
- db
- elasticsearch
- rabbitmq
environment:
- CELERY_BROKER_URL=amqp://guest:guest@rabbitmq//
Expand All @@ -23,8 +22,6 @@ services:
- DJANGO_DEBUG_TOOLBAR
- DJANGO_SECRET_KEY=not-secret-in-dev
- DJANGO_TESTING
- ELASTICSEARCH_INDEX=writeinpublic
- ELASTICSEARCH_URL=http://elasticsearch:9200/
- EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend
- SESSION_COOKIE_DOMAIN=127.0.0.1.nip.io

Expand All @@ -36,14 +33,11 @@ services:
command: bin/wait-for-deps.sh celery -A writeit worker
depends_on:
- db
- elasticsearch
- rabbitmq
environment:
- DATABASE_URL=postgresql://writeinpublic:devpassword@db/writeinpublic
- DJANGO_DEBUG=True
- DJANGO_SECRET_KEY=not-secret-in-dev
- ELASTICSEARCH_INDEX=writeinpublic
- ELASTICSEARCH_URL=http://elasticsearch:9200/
- EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend

beat:
Expand All @@ -54,14 +48,11 @@ services:
command: bin/wait-for-deps.sh celery -A writeit beat --pidfile= -s /var/celerybeat/celerybeat-schedule
depends_on:
- db
- elasticsearch
- rabbitmq
environment:
- DATABASE_URL=postgresql://writeinpublic:devpassword@db/writeinpublic
- DJANGO_DEBUG=True
- DJANGO_SECRET_KEY=not-secret-in-dev
- ELASTICSEARCH_INDEX=writeinpublic
- ELASTICSEARCH_URL=http://elasticsearch:9200/
- EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend

db:
Expand All @@ -73,15 +64,6 @@ services:
volumes:
- db-data:/var/lib/postgresql/data

elasticsearch:
image: elasticsearch:1
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
environment:
- ES_MAX_MEM=1g
ports:
- 9200

rabbitmq:
image: rabbitmq:3.7.28-management
volumes:
Expand All @@ -96,6 +78,5 @@ volumes:
web-attachments:
web-coverage:
db-data:
elasticsearch-data:
rabbitmq-data:
beat-data:
13 changes: 1 addition & 12 deletions global_test_case.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import re

from django.test import TestCase
from unittest import skipUnless
from django.core.management import call_command
from tastypie.test import ResourceTestCase
from django.conf import settings
from django.contrib.sites.models import Site
import os
import subprocess
Expand All @@ -13,7 +10,6 @@
from django.test import RequestFactory
from django.test.client import Client
import logging
from haystack.signals import BaseSignalProcessor

_LOCALS = threading.local()

Expand Down Expand Up @@ -150,11 +146,7 @@ class ResourceGlobalTestCase(WriteItTestCaseMixin, ResourceTestCase):
pass


@skipUnless(settings.LOCAL_ELASTICSEARCH, "No local elasticsearch")
class SearchIndexTestCase(GlobalTestCase):
def setUp(self):
super(SearchIndexTestCase, self).setUp()
call_command('rebuild_index', verbosity=0, interactive=False)
SearchIndexTestCase = GlobalTestCase

from djcelery.contrib.test_runner import CeleryTestSuiteRunner
from django_nose import NoseTestSuiteRunner
Expand All @@ -169,9 +161,6 @@ def run_tests(self, test_labels, extra_tests=None, **kwargs):
return super(WriteItTestRunner, self).run_tests(test_labels, extra_tests, **kwargs)


class CeleryTestingSignalProcessor(BaseSignalProcessor):
pass


from vcr import VCR

Expand Down
12 changes: 6 additions & 6 deletions nuntium/forms.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
# coding=utf-8
import urlparse

from django.forms import ModelForm, ModelMultipleChoiceField, SelectMultiple, URLField, Form, Textarea, TextInput, EmailInput
from django.forms import ModelForm, ModelMultipleChoiceField, SelectMultiple, URLField, Form, Textarea, TextInput, EmailInput, CharField
from contactos.models import Contact
from instance.models import WriteItInstance
from .models import Message, Confirmation

from popolo.models import Person
from django.forms import ValidationError
from django.utils.translation import ugettext as _, ungettext, pgettext_lazy
from haystack.forms import SearchForm
from django.utils.html import format_html
from django.utils.encoding import force_text
from django.utils.safestring import mark_safe
Expand Down Expand Up @@ -193,15 +192,16 @@ class Meta:
fields = []


class MessageSearchForm(SearchForm):
pass
class MessageSearchForm(Form):
q = CharField(required=False, label='')


class PerInstanceSearchForm(SearchForm):
class PerInstanceSearchForm(Form):
q = CharField(required=False, label='')

def __init__(self, *args, **kwargs):
self.writeitinstance = kwargs.pop('writeitinstance', None)
super(PerInstanceSearchForm, self).__init__(*args, **kwargs)
self.searchqueryset = self.searchqueryset.filter(writeitinstance=self.writeitinstance.id)


class PopitParsingFormMixin(object):
Expand Down
24 changes: 4 additions & 20 deletions nuntium/search_indexes.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
# coding=utf-8
from haystack import indexes
from celery_haystack.indexes import CelerySearchIndex
from .models import Message, Answer


class MessageIndex(CelerySearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
writeitinstance = indexes.IntegerField(model_attr='writeitinstance__id')
def message_search_queryset():
return Message.public_objects.all()

def get_model(self):
return Message

def index_queryset(self, using=None):
return self.get_model().public_objects.all()


class AnswerIndex(CelerySearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
writeitinstance = indexes.IntegerField(model_attr='message__writeitinstance__id')

def get_model(self):
return Answer

def index_queryset(self, using=None):
return self.get_model().objects.filter(message__in=Message.public_objects.all())
def answer_search_queryset():
return Answer.objects.filter(message__in=Message.public_objects.all())
2 changes: 1 addition & 1 deletion nuntium/subdomain_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
url(r'^from/(?P<message_slug>[-\w]+)/?$', MessagesFromPersonView.as_view(), name='all-messages-from-the-same-author-as'),
url(r'^to/(?P<pk>[-\d]+)/$', MessagesPerPersonView.as_view(), name='thread_to'),

url(r'^search/$', PerInstanceSearchView(), name='instance_search'),
url(r'^search/$', PerInstanceSearchView.as_view(), name='instance_search'),
url(r'^attachment/(?P<pk>[-\d]+)/$', download_attachment_view, name='attachment'),
url(r'^manage/', include(managepatterns)),
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout', kwargs={'next_page': '/'}, name='logout'),
Expand Down
51 changes: 15 additions & 36 deletions nuntium/tests/answers_search_test.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,40 @@
# coding=utf-8
from global_test_case import GlobalTestCase as TestCase, SearchIndexTestCase
from ..search_indexes import AnswerIndex
from ..search_indexes import answer_search_queryset
from subdomains.utils import reverse
from ..models import Answer, Message
from haystack import indexes
import urllib
import urlparse


class AnswerIndexTestCase(TestCase):
class AnswerSearchQuerysetTestCase(TestCase):
def setUp(self):
super(AnswerIndexTestCase, self).setUp()
self.index = AnswerIndex()
super(AnswerSearchQuerysetTestCase, self).setUp()
for message in Message.objects.all():
message.confirmated = True
message.save()

def test_index_parts(self):
self.assertIsInstance(self.index, indexes.SearchIndex)
self.assertIsInstance(self.index, indexes.Indexable)

self.assertEquals(self.index.get_model(), Answer)

def test_public_answers_are_searchable(self):
public_answers = Answer.objects.filter(message__in=Message.public_objects.all())
first_answer = public_answers[0]
public_answers_list = list(public_answers)

self.assertQuerysetEqual(self.index.index_queryset(), [repr(r) for r in public_answers_list])

self.assertTrue(self.index.text.document)
self.assertTrue(self.index.text.use_template)

indexed_text = self.index.text.prepare_template(first_answer)
qs = answer_search_queryset()
for answer in public_answers:
self.assertIn(answer, qs)

self.assertTrue(first_answer.content in indexed_text)
self.assertTrue(first_answer.person.name in indexed_text)
self.assertEquals(self.index.writeitinstance.model_attr, 'message__writeitinstance__id')

self.assertEquals(self.index.writeitinstance.prepare(first_answer), first_answer.message.writeitinstance.id)
def test_private_message_answers_not_searchable(self):
private_message_answers = Answer.objects.exclude(message__in=Message.public_objects.all())
qs = answer_search_queryset()
for answer in private_message_answers:
self.assertNotIn(answer, qs)


class SearchAnswerAccess(SearchIndexTestCase):
def setUp(self):
super(SearchAnswerAccess, self).setUp()
for message in Message.objects.all():
message.confirmated = True
message.save()

def test_access_the_url(self):
# I don't like this test that much
# because it seems to be likely to break if I add more
# public messages
# if it ever fails
# well then I'll fix it

# Based on
# http://stackoverflow.com/questions/2506379/add-params-to-given-url-in-python
url = reverse('search_messages', subdomain=None)
url += "/"
params = {'q': 'Public Answer'}
Expand All @@ -63,10 +45,7 @@ def test_access_the_url(self):
response = self.client.get(url_with_parameters)
self.assertEquals(response.status_code, 200)

#the first one the one that says "Public Answer" in example_data.yml
expected_answer = Answer.objects.get(id=1)
self.assertIn('page', response.context)
results = response.context['page'].object_list

self.assertGreaterEqual(len(results), 1)
self.assertEquals(results[0].object.id, expected_answer.id)
Loading