# Path: contentious/views.py
# @require_POST
# @require_edit_mode
# def save_content(request):
#     """ View for creating/updating a piece of content. """
#     #Make a copy of request.POST, but as a single-value (not multi-value dict)
#     post = request.POST
#     data = {k: post.get(k) for k in post.keys()}
#     key = data.pop('key')
#     data.pop('csrfmiddlewaretoken', None)
#     try:
#         api.save_content_data(key, data, get_request_context(request))
#         return HttpResponse('ok')
#     except ValidationError as e:
#         return json_response_from_exception(e)
# 
# Path: contentious/tests/mocks.py
# class EditModeNoOpAPI(NoOpAPI):
#     """ Same as NoOpAPI but returns True for in_edit_mode. """
# 
#     def in_edit_mode(self, context):
#         return True


import json
import mock
from django.core.exceptions import ValidationError
from django.http import HttpRequest
from django.test import TestCase
from contentious.views import save_content as save_content_view
from contentious.tests.mocks import (
    EditModeNoOpAPI,
)
    """ Tests for the contentious view function(s). """

    def test_save_content(self):
        """ Test the save_content() view. """
        data = {'key': 'my_key', 'content': 'my content', 'onlick': 'rabbits()'}
        mock_api = EditModeNoOpAPI()
        request = HttpRequest()
        request.method = 'POST'
        request.POST = data
        #Test that in a 'normal' situation our view calls the api's save_content_data
        #method and returns a 200 response
        with mock.patch.object(mock_api, "save_content_data") as mock_api_save_data:
            with mock.patch("contentious.views.api", new=mock_api):
                with mock.patch("contentious.decorators.api", new=mock_api):
                    response = save_content_view(request)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(mock_api_save_data.call_count, 1)
            expected_data_for_save = data.copy()
            expected_key_for_save = expected_data_for_save.pop('key') #cunning
            self.assertEqual( mock_api_save_data.call_args[0][0], expected_key_for_save)
            self.assertEqual( mock_api_save_data.call_args[0][1], expected_data_for_save)
        #Test that if the api raises a ValidationError that the view function returns a
        #JSON response containing the errors dict
        error_dict = {'onlick': 'Sorry, rabbits() is not valid.'}
        def raise_error(*args, **kwargs):
            """ Mock for the save_content_data method of the api. """
            raise ValidationError(error_dict)
        with mock.patch.object(mock_api, "save_content_data", new=raise_error):
            with mock.patch("contentious.views.api", new=mock_api):
                with mock.patch("contentious.decorators.api", new=mock_api):

# Path: contentious/views.py
# @require_POST
# @require_edit_mode
# def save_content(request):
#     """ View for creating/updating a piece of content. """
#     #Make a copy of request.POST, but as a single-value (not multi-value dict)
#     post = request.POST
#     data = {k: post.get(k) for k in post.keys()}
#     key = data.pop('key')
#     data.pop('csrfmiddlewaretoken', None)
#     try:
#         api.save_content_data(key, data, get_request_context(request))
#         return HttpResponse('ok')
#     except ValidationError as e:
#         return json_response_from_exception(e)
# 
# Path: contentious/tests/mocks.py
# class EditModeNoOpAPI(NoOpAPI):
#     """ Same as NoOpAPI but returns True for in_edit_mode. """
# 
#     def in_edit_mode(self, context):
#         return True


# Path: contentious/tests/views.py
import json
import mock
from django.core.exceptions import ValidationError
from django.http import HttpRequest
from django.test import TestCase
from contentious.views import save_content as save_content_view
from contentious.tests.mocks import (
    EditModeNoOpAPI,
)

    """ Tests for the contentious view function(s). """

    def test_save_content(self):
        """ Test the save_content() view. """
        data = {'key': 'my_key', 'content': 'my content', 'onlick': 'rabbits()'}
        mock_api = EditModeNoOpAPI()
        request = HttpRequest()
        request.method = 'POST'
        request.POST = data
        #Test that in a 'normal' situation our view calls the api's save_content_data
        #method and returns a 200 response
        with mock.patch.object(mock_api, "save_content_data") as mock_api_save_data:
            with mock.patch("contentious.views.api", new=mock_api):
                with mock.patch("contentious.decorators.api", new=mock_api):
                    response = save_content_view(request)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(mock_api_save_data.call_count, 1)
            expected_data_for_save = data.copy()
            expected_key_for_save = expected_data_for_save.pop('key') #cunning
            self.assertEqual( mock_api_save_data.call_args[0][0], expected_key_for_save)
            self.assertEqual( mock_api_save_data.call_args[0][1], expected_data_for_save)
        #Test that if the api raises a ValidationError that the view function returns a
        #JSON response containing the errors dict
        error_dict = {'onlick': 'Sorry, rabbits() is not valid.'}
        def raise_error(*args, **kwargs):
            """ Mock for the save_content_data method of the api. """
            raise ValidationError(error_dict)
        with mock.patch.object(mock_api, "save_content_data", new=raise_error):
            with mock.patch("contentious.views.api", new=mock_api):
                with mock.patch("contentious.decorators.api", new=mock_api):

                    response = save_content_view(request)