Skip to content

Commit

Permalink
Merge pull request #167 from colab/widget_profile
Browse files Browse the repository at this point in the history
Widget profile
  • Loading branch information
msfernandes committed Apr 4, 2016
2 parents 99cd8f0 + 40c4152 commit 3ee7475
Show file tree
Hide file tree
Showing 10 changed files with 314 additions and 22 deletions.
13 changes: 13 additions & 0 deletions colab/accounts/templates/accounts/user_update_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@
{{ block.super }}
{% endblock %}

{% block bootstrap_js %}
<script>jQuery.noConflict();</script>
{% if not bootstrap_conflict %}
{{block.super}}
{% endif %}
{% endblock%}

{% block jquery_js %}
{% if not jquery_conflict %}
{{block.super}}
{% endif %}
{% endblock %}

{% block head_js %}
{% for widget in widgets_profile %}
{{widget.get_header}}
Expand Down
6 changes: 4 additions & 2 deletions colab/accounts/tests/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def authenticate_user(self):
def validate_mandatory_fields(self, expected_first_name,
expected_last_name, first_name, last_name):
data = {'first_name': first_name,
'last_name': last_name}
'last_name': last_name,
'colab_form': 'true'}
self.client.post('/account/' + self.user.username + '/edit', data)
user = User.objects.get(id=1)
self.assertEqual(expected_first_name, user.first_name)
Expand All @@ -51,7 +52,8 @@ def validate_mandatory_fields(self, expected_first_name,
def validate_non_mandatory_fields(self, field_name, expected_value, value):
data = {'first_name': 'usertestcolab',
'last_name': 'colab',
field_name: value}
field_name: value,
'colab_form': 'true'}
self.client.post('/account/' + self.user.username + '/edit', data)
user = User.objects.get(id=1)
self.assertEqual(expected_value, getattr(user, field_name))
Expand Down
2 changes: 1 addition & 1 deletion colab/accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class UserProfileUpdateView(UserProfileBaseMixin, UpdateView):
form_class = UserUpdateForm

def post(self, request, *args, **kwargs):
if request.GET.get('path', '') and not request.POST.get('colab_form'):
if not request.POST.get('colab_form'):
request.method = 'GET'
result = super(UserProfileUpdateView, self).get(request, *args,
**kwargs)
Expand Down
12 changes: 8 additions & 4 deletions colab/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,16 @@
<![endif]-->
{% endif %}


<!-- JQuery 2+ won't work for IE < 9 -->
<script type="text/javascript" src="{% static 'third-party/jquery-2.0.3.min.js' %}"></script>
{% block jquery_js%}
<!-- JQuery 2+ won't work for IE < 9 -->
<script type="text/javascript" src="{% static 'third-party/jquery-2.0.3.min.js' %}"></script>
{% endblock %}
{% block bootstrap_js%}
<script type="text/javascript" src="{% static 'third-party/bootstrap/js/bootstrap.min.js' %}"></script>
{% endblock%}
<script type="text/javascript" src="{% static 'third-party/jquery.debouncedresize.js' %}"></script>
<script type="text/javascript" src="{% static 'third-party/jquery.cookie.js' %}"></script>
<script src="{% static 'third-party/bootstrap/js/bootstrap.min.js' %}"></script>


{% include "includes/google_analytics.html" %}

Expand Down
68 changes: 68 additions & 0 deletions colab/widgets/profile_widget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from colab.widgets.widget_manager import Widget
from django.conf import settings


class ProfileWidget(Widget):
app_name = None
colab_form = None
request = None
_prefix = None
bootstrap_conflict = False
jquery_conflict = False

@property
def prefix(self):
if self._prefix is None:
urls = settings.COLAB_APPS[self.app_name].get('urls')
self._prefix = urls.get('prefix').replace('^', '/')
return self._prefix

def default_url(self, request):
raise NotImplementedError("Please Implement this method")

def fix_url(self, url):
cut = 0
if self.prefix in url:
cut = url.find(self.prefix) + len(self.prefix)
return url[cut:]

def is_colab_form(self, request):
if self.colab_form is None:
self.colab_form = request.POST.get('colab_form', False)
return self.colab_form

def must_respond(self, request):
if self.is_colab_form(request):
return False
return self.prefix in request.GET.get('path', '') or \
self.prefix in request.POST.get('path', '')

def change_request_method(self, request):
request.method = 'GET'

if self.must_respond(request) and len(request.POST) > 0:
if not request.POST.get('_method', None):
request.method = "POST"
else:
request.method = request.POST.get("_method").upper()

def requested_url(self, request):
url = request.POST.get('path', request.GET.get('path', ''))

if not url or not self.must_respond(request):
url = self.default_url(request)

return self.fix_url(url)

def dispatch(self, request, url):
raise NotImplementedError("Please Implement this method")

def generate_content(self, **kwargs):
request = kwargs.get('context', {}).get('request', None)
self.change_request_method(request)
response = self.dispatch(request, self.requested_url(request))

if hasattr(response, 'content'):
self.content = response.content
else:
self.content = "".join(response.streaming_content)
2 changes: 2 additions & 0 deletions colab/widgets/templatetags/widgets_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ def import_widgets(context, area_id, widget_var=None):
widget_var = "widgets_{}".format(area_id)

context[widget_var] = WidgetManager.get_widgets(area_id, context=context)
context['bootstrap_conflict'] = WidgetManager.bootstrap_conflict
context['jquery_conflict'] = WidgetManager.jquery_conflict

return ""
174 changes: 174 additions & 0 deletions colab/widgets/tests/test_profile_widget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import unittest
from mock import patch

from colab.widgets.profile_widget import ProfileWidget
from django.http import HttpRequest, HttpResponse, StreamingHttpResponse

MOCK_APPS = {'mock_app': {
'urls': {'prefix': '^mock_app'}
}}


class WidgetProfileMock(ProfileWidget):
app_name = 'mock_app'

def __init__(self, content=""):
self.content = content


@patch.dict('django.conf.settings.COLAB_APPS', MOCK_APPS)
class WidgetProfileTest(unittest.TestCase):

def setUp(self):
self.widget_prifile_mock = WidgetProfileMock()
self.current_request = HttpRequest()
self.response = HttpResponse()
self.streaming_response = StreamingHttpResponse()

def test_prefix(self):
result = self.widget_prifile_mock.prefix
self.assertEquals(result, '/mock_app')

def test_default_url_exception(self):
with self.assertRaises(NotImplementedError):
self.widget_prifile_mock.default_url('request')

def test_dispatch_exception(self):
with self.assertRaises(NotImplementedError):
self.widget_prifile_mock.dispatch('request', 'url')

def test_fix_url(self):
url = 'https://test:3000/mock_app/test'
result = self.widget_prifile_mock.fix_url(url)
self.assertEquals(result, '/test')

url = 'https://test:3000/account/test'
result = self.widget_prifile_mock.fix_url(url)
self.assertEquals(result, url)

def test_is_colab_form_with_colab_form(self):
self.current_request.GET = {'path': '/'}
self.current_request.POST = {'colab_form': 'true'}
result = self.widget_prifile_mock.is_colab_form(self.current_request)
self.assertTrue(result)

def test_is_colab_form_without_colab_form(self):
self.current_request.GET = {'path': '/'}
self.current_request.POST = {}
result = self.widget_prifile_mock.is_colab_form(self.current_request)
self.assertFalse(result)

def test_must_respond_without_path_in_request(self):
self.current_request.GET = {}
self.current_request.POST = {}
result = self.widget_prifile_mock.must_respond(self.current_request)
self.assertFalse(result)

def test_must_respond_with_path_in_request(self):
self.current_request.GET = {'path': '/test/mock_app/test_uri'}
result = self.widget_prifile_mock.must_respond(self.current_request)
self.assertTrue(result)

self.current_request.GET = {}
self.current_request.POST = {'path': '/test/mock_app/test_uri'}
result = self.widget_prifile_mock.must_respond(self.current_request)
self.assertTrue(result)

def test_must_respond_with_colab_form_in_request(self):
self.current_request.GET = {'path': '/mock_app/'}
self.current_request.POST = {'path': '/mock_app/test',
'colab_form': 'true'}
result = self.widget_prifile_mock.must_respond(self.current_request)
self.assertFalse(result)

def test_change_request_method_without_post(self):
self.current_request.POST = {}
self.widget_prifile_mock.change_request_method(self.current_request)
self.assertEquals(self.current_request.method, 'GET')

def test_change_request_method_with_path(self):
self.current_request.GET = {'path': '/mock_app/uri'}
self.widget_prifile_mock.change_request_method(self.current_request)
self.assertEquals(self.current_request.method, 'GET')

def test_change_request_method_with_post(self):
self.current_request.GET = {'path': '/mock_app/'}
self.current_request.POST = {'path': '/'}
self.widget_prifile_mock.change_request_method(self.current_request)
self.assertEquals(self.current_request.method, 'POST')

def test_change_request_method_with__method(self):
self.current_request.POST = {'path': '/mock_app/uri_post',
'_method': 'DELETE'}
self.widget_prifile_mock.change_request_method(self.current_request)
self.assertEquals(self.current_request.method, 'DELETE')

@patch.object(WidgetProfileMock, 'default_url')
def test_requested_url_without_path(self, default_url_mock):
default_url = '/default/path'
default_url_mock.return_value = default_url
self.current_request.GET = {}
self.current_request.POST = {}
url = self.widget_prifile_mock.requested_url(self.current_request)
self.assertEquals(url, default_url)

@patch.object(WidgetProfileMock, 'default_url')
def test_requested_url_with_path_and_no_colab_form(self, default_url_mock):
default_url = '/default/path'
path1 = '/mock_app/uri_1'
path2 = '/mock_app/uri_2'
default_url_mock.return_value = default_url

self.current_request.GET = {'path': path1}
self.current_request.POST = {}
url = self.widget_prifile_mock.requested_url(self.current_request)
self.assertEquals(url, '/uri_1')

self.current_request.POST = {'path': path2}
url = self.widget_prifile_mock.requested_url(self.current_request)
self.assertEquals(url, '/uri_2')

@patch.object(WidgetProfileMock, 'default_url')
def test_requested_url_with_path_and_colab_form(self, default_url_mock):
default_url = '/mock_app/default/path'
path1 = '/mock_app/uri_1'
path2 = '/mock_app/uri_2'
default_url_mock.return_value = default_url
self.current_request.GET = {'path': path1}
self.current_request.POST = {'path': path2,
'colab_form': 'true'}
url = self.widget_prifile_mock.requested_url(self.current_request)
self.assertEquals(url, '/default/path')

@patch.object(WidgetProfileMock, 'dispatch')
@patch.object(WidgetProfileMock, 'change_request_method')
@patch.object(WidgetProfileMock, 'requested_url')
def test_generate_content_with_content(self,
requested_url_mock,
change_request_method_mock,
dispatch_mock):
content = '<body>Content</body>'
self.response.content = content
dispatch_mock.return_value = self.response
change_request_method_mock.return_value = None
requested_url_mock.return_value = None

self.widget_prifile_mock.generate_content(context={})
self.assertEquals(self.widget_prifile_mock.content, content)

@patch.object(WidgetProfileMock, 'dispatch')
@patch.object(WidgetProfileMock, 'change_request_method')
@patch.object(WidgetProfileMock, 'requested_url')
def test_generate_content_with_streaming_content(
self, requested_url_mock, change_request_method_mock,
dispatch_mock):

content = '<body>test streaming</body>'
streaming_content = list(content)
self.streaming_response.streaming_content = streaming_content
dispatch_mock.return_value = self.streaming_response
change_request_method_mock.return_value = None
requested_url_mock.return_value = None

self.widget_prifile_mock.generate_content(context={})
self.assertEquals(self.widget_prifile_mock.content, content)

0 comments on commit 3ee7475

Please sign in to comment.