Skip to content
Snippets Groups Projects
Commit 169fbed5 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch '34-contact-attempts' into 'master'

Resolve "Contact attempts"

Closes #34

See merge request !32
parents 6e4dc583 42819eef
No related branches found
No related tags found
1 merge request!32Resolve "Contact attempts"
Pipeline #
Showing
with 368 additions and 118 deletions
......@@ -16,8 +16,8 @@ appointment-import/tmp.sql
*.iml
out
.idea
<<<<<<< HEAD
#coverage tool
.coverage
smash/htmlcov/*
smash/htmlcov/
......@@ -17,6 +17,6 @@ test:
script:
- cp "local_settings_ci.py" "smash/smash/local_settings.py"
- cd smash
- python manage.py makemigrations && python manage.py migrate
- python manage.py makemigrations web && python manage.py migrate
- coverage run --source web manage.py test
- coverage report -m
from django.contrib import admin
from models import Subject, Item, Room, AppointmentType, Language, Location, Worker, FlyingTeam, Avaibility, Holiday, \
from models import Subject, Item, Room, AppointmentType, Language, Location, Worker, FlyingTeam, Availability, Holiday, \
Visit, Appointment
......@@ -18,6 +18,6 @@ admin.site.register(Language, LanguageAdmin)
admin.site.register(Location)
admin.site.register(Worker)
admin.site.register(FlyingTeam)
admin.site.register(Avaibility)
admin.site.register(Availability)
admin.site.register(Holiday)
admin.site.register(Appointment)
from datetime import datetime
import datetime
from django import forms
from django.forms import ModelForm, Form
from django.utils.dates import MONTHS
from models import Subject, Worker, Appointment, Visit, AppointmentType
from models import Subject, Worker, Appointment, Visit, AppointmentType, ContactAttempt
from models.constants import SUBJECT_TYPE_CHOICES
"""
Possible redundancy, but if need arises, contents of forms can be easily customized
"""
CURRENT_YEAR = datetime.now().year
CURRENT_YEAR = datetime.datetime.now().year
YEAR_CHOICES = tuple(range(CURRENT_YEAR, CURRENT_YEAR - 120, -1))
FUTURE_YEAR_CHOICES = tuple(range(CURRENT_YEAR, CURRENT_YEAR + 5, 1))
DATEPICKER_DATE_ATTRS = {
......@@ -79,6 +79,7 @@ class SubjectAddForm(ModelForm):
validate_subject_nd_number(self)
def get_new_screening_number(screening_number_prefix):
result_number = 0
subjects = Subject.objects.filter(screening_number__contains=screening_number_prefix)
......@@ -95,12 +96,14 @@ def get_new_screening_number(screening_number_prefix):
return screening_number_prefix + str(result_number + 1).zfill(3)
def get_prefix_screening_number(user):
prefix_screening_number = ''
if (user is not None) and (user.screening_number_prefix is not None) and (user.screening_number_prefix != ""):
prefix_screening_number = user.screening_number_prefix + "-"
return prefix_screening_number
class SubjectDetailForm(ModelForm):
class Meta:
model = Subject
......@@ -268,6 +271,29 @@ class VisitAddForm(ModelForm):
self.add_error('datetime_end', "End date must be after start date")
class ContactAttemptForm(ModelForm):
datetime_when = forms.DateTimeField(label='Contact on (YYYY-MM-DD HH:MM)',
widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
)
class Meta:
model = ContactAttempt
fields = '__all__'
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
if user is None:
raise TypeError("User not defined")
self.user = Worker.get_by_user(user)
if self.user is None:
raise TypeError("Worker not defined for: " + user.username)
subject = kwargs.pop('subject', None)
super(ContactAttemptForm, self).__init__(*args, **kwargs)
self.fields['subject'].initial = subject.id
self.fields['subject'].disabled = True
self.fields['worker'].initial = self.user
class KitRequestForm(Form):
start_date = forms.DateField(label="From date",
widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
......@@ -286,7 +312,7 @@ class StatisticsForm(Form):
visit_choices = kwargs['visit_choices']
month = kwargs['month']
year = kwargs['year']
now = datetime.now()
now = datetime.datetime.now()
year_now = now.year
number_of_years_for_statistics = year_now - START_YEAR_STATISTICS + 2
......
......@@ -12,16 +12,17 @@ from visit import Visit
from worker import Worker
from appointment import Appointment
from appointment_type import AppointmentType
from avaibility import Avaibility
from availability import Availability
from holiday import Holiday
from item import Item
from language import Language
from subject import Subject
from contact_attempt import ContactAttempt
def get_current_year():
return datetime.datetime.now().year
__all__ = [FlyingTeam, Appointment, AppointmentType, Avaibility, Holiday, Item, Language, Location, Room, Subject,
Visit, Worker]
__all__ = [FlyingTeam, Appointment, AppointmentType, Availability, Holiday, Item, Language, Location, Room, Subject,
Visit, Worker, ContactAttempt]
......@@ -2,7 +2,7 @@
from django.db import models
class Avaibility(models.Model):
class Availability(models.Model):
class Meta:
app_label = 'web'
......@@ -13,10 +13,10 @@ class Avaibility(models.Model):
verbose_name='Day of the week'
)
available_from = models.TimeField(
verbose_name='Avaible since'
verbose_name='Available since'
)
available_till = models.TimeField(
verbose_name='Avaible until'
verbose_name='Available until'
)
is_current = models.BooleanField(
verbose_name='Is current?',
......
......@@ -13,3 +13,17 @@ SUBJECT_TYPE_CHOICES = {
}
APPOINTMENT_TYPE_DEFAULT_COLOR = '#cfc600'
APPOINTMENT_TYPE_DEFAULT_FONT_COLOR = '#00000'
CONTACT_TYPES_EMAIL = 'E'
CONTACT_TYPES_PHONE = 'P'
CONTACT_TYPES_SMS = 'S'
CONTACT_TYPES_FAX = 'X'
CONTACT_TYPES_FACE2FACE = 'F'
CONTACT_TYPES_CHOICES = (
(CONTACT_TYPES_EMAIL, 'Email'),
(CONTACT_TYPES_FACE2FACE, 'Face to face'),
(CONTACT_TYPES_FAX, 'Fax'),
(CONTACT_TYPES_PHONE, 'Phone'),
(CONTACT_TYPES_SMS, 'SMS'),
)
# coding=utf-8
from django.db import models
from constants import CONTACT_TYPES_CHOICES, CONTACT_TYPES_PHONE
__author__ = 'Valentin Grouès'
class ContactAttempt(models.Model):
subject = models.ForeignKey("web.Subject",
verbose_name='Subject'
)
worker = models.ForeignKey("web.Worker", null=True,
verbose_name='Worker'
)
type = models.CharField(max_length=2, default=CONTACT_TYPES_PHONE, choices=CONTACT_TYPES_CHOICES)
datetime_when = models.DateTimeField(verbose_name="Contact on", help_text='When did the contact occurred?')
success = models.BooleanField(default=False)
comment = models.TextField(max_length=1024, null=True, blank=True)
def __str__(self):
return "%s %s" % (self.subject, self.worker)
def __unicode__(self):
return "%s %s" % (self.subject, self.worker)
......@@ -18,7 +18,7 @@
{% block page_header %}New appointment{% endblock page_header %}
{% block page_description %}{% endblock page_description %}
{% block title %}{{ block.super }} - Add new appoitnment{% endblock %}
{% block title %}{{ block.super }} - Add new appointment{% endblock %}
{% block breadcrumb %}
{% include "appointments/breadcrumb.html" %}
......
{% extends "_base.html" %}
{% load static %}
{% load filters %}
{% block styles %}
{{ block.super }}
<link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/>
{% include "includes/datepicker.css.html" %}
{% endblock styles %}
{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %}
{% block page_header %}New contact attempt{% endblock page_header %}
{% block page_description %}{% endblock page_description %}
{% block title %}{{ block.super }} - Add new contact attempt{% endblock %}
{% block breadcrumb %}
{% include "subjects/breadcrumb.html" %}
{% endblock breadcrumb %}
{% block maincontent %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="box box-success">
<div class="box-header with-border">
<h3 class="box-title">Enter contact attempt details</h3>
</div>
<form method="post" action="" class="form-horizontal">
{% csrf_token %}
<div class="box-body">
{% for field in form %}
<div class="form-group {% if field.errors %}has-error{% endif %}">
<label class="col-sm-4 col-lg-offset-1 col-lg-2 control-label">
{{ field.label }}
</label>
<div class="col-sm-8 col-lg-4">
{{ field|add_class:'form-control' }}
</div>
{% if field.errors %}
<span class="help-block">
{{ field.errors }}
</span>
{% endif %}
</div>
{% endfor %}
</div><!-- /.box-body -->
<div class="box-footer">
<div class="col-sm-6">
<button type="submit" class="btn btn-block btn-success">Add</button>
</div>
<div class="col-sm-6">
<a href="{% url 'web.views.subject_edit' subject_id %}"
class="btn btn-block btn-default">Cancel</a>
</div>
</div><!-- /.box-footer -->
</form>
</div>
</div>
</div>
{% endblock %}
{% endblock maincontent %}
{% block scripts %}
{{ block.super }}
<script src="{% static 'AdminLTE/plugins/awesomplete/awesomplete.min.js' %}"></script>
{% include "includes/datetimepicker.js.html" %}
{% endblock scripts %}
......@@ -9,7 +9,7 @@
{% block ui_active_tab %}'workers'{% endblock ui_active_tab %}
{% block page_header %}Workers{% endblock page_header %}
{% block page_description %}avaibility{% endblock page_description %}
{% block page_description %}availability{% endblock page_description %}
{% block breadcrumb %}
{% include "doctors/breadcrumb.html" %}
......@@ -45,13 +45,13 @@
{% else %}
<p>No avaibilities on Monday.</p>
<p>No availabilities on Monday.</p>
{% endif %}
<div>
<a href="{% url 'web.views.doctor_add' %}" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
<h3>Tuesday</h3>
......@@ -80,13 +80,13 @@
{% else %}
<p>No avaibilities on Tuesday.</p>
<p>No availabilities on Tuesday.</p>
{% endif %}
<div>
<a href="{% url 'web.views.doctor_add' %}" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
<h3>Wednesday</h3>
......@@ -115,13 +115,13 @@
{% else %}
<p>No avaibilities on Wednesday.</p>
<p>No availabilities on Wednesday.</p>
{% endif %}
<div>
<a href="{% url 'web.views.doctor_add' %}" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
<h3>Thursday</h3>
......@@ -150,13 +150,13 @@
{% else %}
<p>No avaibilities on Thursday.</p>
<p>No availabilities on Thursday.</p>
{% endif %}
<div>
<a href="{% url 'web.views.doctor_add' %}" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
<h3>Friday</h3>
......@@ -185,13 +185,13 @@
{% else %}
<p>No avaibilities on Friday.</p>
<p>No availabilities on Friday.</p>
{% endif %}
<div>
<a href="{% url 'web.views.doctor_add' %}" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
<h3>Saturday</h3>
......@@ -220,13 +220,13 @@
{% else %}
<p>No avaibilities on Saturday.</p>
<p>No availabilities on Saturday.</p>
{% endif %}
<div>
<a href="{% url 'web.views.doctor_add' %}" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
</div>
......
......@@ -9,7 +9,7 @@
{% block ui_active_tab %}'workers'{% endblock ui_active_tab %}
{% block page_header %}Workers{% endblock page_header %}
{% block page_description %}avaibility{% endblock page_description %}
{% block page_description %}availability{% endblock page_description %}
{% block breadcrumb %}
{% include "doctors/breadcrumb.html" %}
......@@ -42,7 +42,7 @@
<div class="new-availability">
<a href="#" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
{% if avmon %}
......@@ -69,7 +69,7 @@
</table>
{% else %}
<p>No avaibilities on Monday.</p>
<p>No availabilities on Monday.</p>
{% endif %}
</div>
......@@ -81,7 +81,7 @@
<div class="new-availability">
<a href="#" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
{% if avtue %}
......@@ -108,7 +108,7 @@
</table>
{% else %}
<p>No avaibilities on Tuesday.</p>
<p>No availabilities on Tuesday.</p>
{% endif %}
</div>
......@@ -120,7 +120,7 @@
<div class="new-availability">
<a href="#" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
{% if avwed %}
......@@ -147,7 +147,7 @@
</table>
{% else %}
<p>No avaibilities on Wednesday.</p>
<p>No availabilities on Wednesday.</p>
{% endif %}
</div>
......@@ -159,7 +159,7 @@
<div class="new-availability">
<a href="#" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
{% if avthu %}
......@@ -186,7 +186,7 @@
</table>
{% else %}
<p>No avaibilities on Thursday.</p>
<p>No availabilities on Thursday.</p>
{% endif %}
</div>
......@@ -198,7 +198,7 @@
<div class="new-availability">
<a href="#" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
{% if avfri %}
......@@ -225,7 +225,7 @@
</table>
{% else %}
<p>No avaibilities on Friday.</p>
<p>No availabilities on Friday.</p>
{% endif %}
</div>
......@@ -237,7 +237,7 @@
<div class="new-availability">
<a href="#" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
{% if avsat %}
......@@ -264,7 +264,7 @@
</table>
{% else %}
<p>No avaibilities on Saturday.</p>
<p>No availabilities on Saturday.</p>
{% endif %}
</div>
......@@ -274,7 +274,7 @@
<div class="new-availability">
<a href="#" class="btn btn-app">
<i class="fa fa-plus"></i>
Add new avaibility</a>
Add new availability</a>
</div>
{% if avsun %}
......@@ -301,7 +301,7 @@
</table>
{% else %}
<p>No avaibilities on Sunday.</p>
<p>No availabilities on Sunday.</p>
{% endif %}
</div>
......
......@@ -23,53 +23,103 @@
{% block maincontent %}
{% block content %}
<div class="box box-info">
<div class="box-header with-border">
<a href="{% url 'web.views.subjects' %}" class="btn btn-block btn-default" onclick="history.back()">Go
back (without changes)</a>
<div class="row">
<p class="col-lg-3 pull-left">
<a href="{% url 'web.views.subjects' %}" class="btn btn-block btn-default"
onclick="history.back()">Go
back (discard changes)</a>
</p>
<p class="col-md-2 pull-right">
<a href="{% url 'web.views.subject_visit_details' subject.id %}" type="button"
class="btn btn-block btn-default">Subject's visits</a>
</div>
{% comment %} <div class="box-header with-border">
<h3 class="box-title">Details of subject</h3>
</div>{% endcomment %}
<form method="post" action="" class="form-horizontal">
{% csrf_token %}
<div class="box-body">
<div class="col-md-12">
{% for field in form %}
<div class="col-md-6 form-group {% if field.errors %}has-error{% endif %}">
<label for="{# TODO #}" class="col-sm-4 control-label">
{{ field.label }}
</label>
<div class="col-sm-8">
{{ field|add_class:'form-control' }}
</div>
{% if field.errors %}
<span class="help-block"> {{ field.errors }} </span>
{% endif %}
</div>
{% endfor %}
</p>
</div>
<div class="row">
<div class="col-md-12">
<div class="box box-success">
<div class="box-header with-border">
<h3>Subject details</h3>
</div>
</div><!-- /.box-body -->
<div class="box-footer">
<div class="col-sm-6">
<button type="submit" class="btn btn-block btn-success">Save</button>
<div class="box-body">
<div class="col-md-12">
<form method="post" action="" class="form-horizontal">
{% csrf_token %}
{% for field in form %}
<div class="col-md-6 form-group {% if field.errors %}has-error{% endif %}">
<label for="{# TODO #}" class="col-sm-4 control-label">
{{ field.label }}
</label>
<div class="col-sm-8">
{{ field|add_class:'form-control' }}
</div>
{% if field.errors %}
<span class="help-block"> {{ field.errors }} </span>
{% endif %}
</div>
{% endfor %}
</form>
</div>
</div><!-- /.box-body -->
<div class="box-footer">
<div class="col-sm-6">
<button type="submit" class="btn btn-block btn-success">Save</button>
</div>
<div class="col-sm-6">
<a href="{% url 'web.views.subjects' %}" class="btn btn-block btn-default"
onclick="history.back()">Cancel</a>
</div>
</div><!-- /.box-footer -->
</div><!-- /.box -->
</div><!-- /.col-md-12 -->
</div><!-- /.row -->
<div class="row">
<div class="col-lg-12">
<div class="box box-success">
<div class="box-header with-border">
<h3>Contact attempts <a title="add a new contact attempt"
id="add-contact-attempt"
href="{% url 'web.views.contact_add' subject.id %}" class="text-primary"
><i class="fa fa-plus-circle text-success"></i></a></h3>
</div>
<div class="col-sm-6">
<a href="{% url 'web.views.subjects' %}" class="btn btn-block btn-default"
onclick="history.back()">Cancel</a>
<div class="box-body">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th class="text-center">When</th>
<th class="text-center">Who</th>
<th class="text-center">Type</th>
<th class="text-center">Success</th>
<th class="text-center">Comment</th>
</tr>
</thead>
<tbody>
{% for contact_attempt in contact_attempts %}
<tr>
<td>{{ contact_attempt.datetime_when }}</td>
<td>{{ contact_attempt.worker }}</td>
<td class="text-center">{{ contact_attempt.get_type_display }}</td>
<td class="text-center">
<i class="fa {% if contact_attempt.success %}fa-check text-success{% else %}fa-times text-danger{% endif %}"></i>
</td>
<td>{{ contact_attempt.comment }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div><!-- /.box-footer -->
</form>
</div>
</div>
</div>
<div class="modal modal-danger fade" id="confirm-dead-resigned-mark-dialog" tabindex="-1" role="dialog">
......
from django.contrib.auth.models import User
from django.test import Client
from django.test import TestCase
from functions import create_worker
class LoggedInTestCase(TestCase):
def setUp(self):
self.client = Client()
username = 'piotr'
password = 'top_secret'
self.user = User.objects.create_user(
username=username, email='jacob@bla', password=password)
self.client.login(username=username, password=password)
class LoggedInWithWorkerTestCase(LoggedInTestCase):
def setUp(self):
super(LoggedInWithWorkerTestCase, self).setUp()
self.worker = create_worker(self.user)
# coding=utf-8
import datetime
import json
from django.contrib.auth.models import User
from django.test import TestCase
from django.test import Client
from django.urls import reverse
from web.models import Visit
from web.api_views import cities
from web.tests.functions import create_subject, create_worker, create_appointment_type
from web.tests.functions import create_subject, create_appointment_type
from . import LoggedInWithWorkerTestCase
__author__ = 'Piotr Gawron'
class TestApi(TestCase):
class TestApi(LoggedInWithWorkerTestCase):
def setUp(self):
super(TestApi, self).setUp()
self.subject = create_subject()
self.client = Client()
username = 'piotr'
password = 'top_secret'
self.user = User.objects.create_user(
username=username, email='jacob@bla', password=password)
self.worker = create_worker(self.user)
self.client.login(username=username, password=password)
def test_cities(self):
city_name = "some city"
......@@ -130,7 +119,7 @@ class TestApi(TestCase):
found = False
for type in appointment_types:
if type['type']==type_name:
if type['type'] == type_name:
found = True
self.assertTrue(found)
from django.test import TestCase
from functions import create_subject, create_appointment
from functions import create_visit
from web.models import Appointment
from web.models import Visit
from functions import create_appointment
class AppointmentModelTests(TestCase):
......
......@@ -27,8 +27,8 @@ class SubjectModelTests(TestCase):
subject.mark_as_resigned()
appointment_status = Appointment.objects.filter(id=appointment.id)[0].status
visit_finsihed = Visit.objects.filter(id=visit.id)[0].is_finished
visit_finished = Visit.objects.filter(id=visit.id)[0].is_finished
self.assertTrue(subject.resigned)
self.assertTrue(visit_finsihed)
self.assertTrue(visit_finished)
self.assertEquals(Appointment.APPOINTMENT_STATUS_CANCELLED, appointment_status)
import datetime
from django.contrib.auth.models import User
from django.test import Client
from django.test import TestCase
from django.urls import reverse
from functions import create_subject, create_visit, create_appointment, create_worker
from web.forms import AppointmentEditForm, SubjectEditForm
from web.models import Appointment, Subject
from . import LoggedInTestCase
class AppointmentsViewTests(TestCase):
def setUp(self):
self.client = Client()
username = 'piotr'
password = 'top_secret'
self.user = User.objects.create_user(
username=username, email='jacob@bla', password=password)
self.client.login(username=username, password=password)
class AppointmentsViewTests(LoggedInTestCase):
def test_appointments_list_request(self):
response = self.client.get(reverse('web.views.appointments'))
self.assertEqual(response.status_code, 200)
......
import datetime
from django.urls import reverse
from django.utils import timezone
from functions import create_subject
from web.models import ContactAttempt
from web.models.constants import CONTACT_TYPES_EMAIL
from . import LoggedInWithWorkerTestCase
class ContactAttemptViewTests(LoggedInWithWorkerTestCase):
def test_contact_attempt_add_get(self):
subject = create_subject()
response = self.client.get(reverse('web.views.contact_add', kwargs={'subject_id': subject.id}))
self.assertContains(response, 'selected">{}'.format(self.worker), 1)
self.assertContains(response, 'selected">{}'.format(subject), 1)
def test_contact_attempt_add_post_valid(self):
subject = create_subject()
self.assertEqual(0, ContactAttempt.objects.filter(subject=subject).count())
now = datetime.datetime.now()
now_aware = timezone.make_aware(now, timezone.get_default_timezone())
contact_type = CONTACT_TYPES_EMAIL
comment = "this is a comment"
form_data = {'datetime_when': now, 'worker': self.worker.id, 'type': contact_type, 'comment': comment}
response = self.client.post(
reverse('web.views.contact_add', kwargs={'subject_id': subject.id}), data=form_data)
# check correct redirection to suject edit page
self.assertRedirects(response, reverse('web.views.subject_edit', kwargs={'id': subject.id}))
contact_attempts = ContactAttempt.objects.filter(subject=subject).all()
self.assertEqual(1, len(contact_attempts))
contact_attempt = contact_attempts[0]
self.assertEqual(now_aware, contact_attempt.datetime_when)
self.assertEqual(contact_type, contact_attempt.type)
self.assertEqual(subject, contact_attempt.subject)
self.assertEqual(self.worker, contact_attempt.worker)
self.assertEqual(comment, contact_attempt.comment)
self.assertFalse(contact_attempt.success)
# follow redirect to check if the new contact attempt is correctly listed
response = self.client.get(response.url)
self.assertContains(response, comment, 1)
def test_contact_attempt_add_post_invalid(self):
subject = create_subject()
self.assertEqual(0, ContactAttempt.objects.filter(subject=subject).count())
contact_type = CONTACT_TYPES_EMAIL
comment = "this is a comment"
form_data = {'type': contact_type, 'comment': comment}
response = self.client.post(
reverse('web.views.contact_add', kwargs={'subject_id': subject.id}), data=form_data)
self.assertContains(response, "This field is required", 2)
self.assertEqual(0, ContactAttempt.objects.filter(subject=subject).count())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment