from mock import Mock, patch
from unittest import TestCase

from distribution import app
from distribution.adapters.serializers import JSONAPIItemSerializer
from distribution.models.feed import FeedItem
from test.utils import get_stored_data


class JSONAPIItemSerializerTestCase(TestCase):
    def setUp(self):
        self.context = app
        self.context.config['DEBUG'] = True
        self.context.config['TESTING'] = True
        self.app = app.test_client()
        self.serializer_class = JSONAPIItemSerializer

    @patch.object(FeedItem, '_validate_taxonomy_topics', Mock())
    @patch.object(JSONAPIItemSerializer, 'process_taxonomic_fields', Mock())
    def test_correct_response_last_update(self):
        item = FeedItem(get_stored_data()[0])

        fields = ['id', 'last_update']
        with self.context.test_request_context():
            serialized_item = self.serializer_class(item, fields=fields)
            self.assertEqual(serialized_item.attributes['last_update'],
                             item.data['meta']['last_update'])

    def test_fields(self):
        item = Mock()
        item.manager.search_by_field.return_value = []
        item.relationships.return_value = {}
        item.default_fields = ['id', 'name']
        item.data = {
            'id': 'News:1000-8000',
            'content_type': 'article:story',
            'language': 'en-us',
            'name': "name"
        }

        def mock_getlist(results):
            def getlist(field):
                if field in results:
                    return results[field]
                return []
            return getlist

        # default fields
        with self.context.test_request_context() as ctx:
            serializer = self.serializer_class(item)
            self.assertEqual(item.default_fields, serializer.fields)

        # separated fields
        with self.context.test_request_context() as ctx:
            ctx.request.args.getlist = mock_getlist({'fields': ['id', 'language']})
            serializer = self.serializer_class(item)
            self.assertEqual(set(['id', 'language']), serializer.fields)

        # with coma separated fields
        with self.context.test_request_context() as ctx:
            ctx.request.args.getlist = mock_getlist({'fields': ['id,language']})
            serializer = self.serializer_class(item)
            self.assertEqual(set(['id', 'language']), serializer.fields)

        # with type specific coma separated fields
        with self.context.test_request_context() as ctx:
            ctx.request.args.getlist = mock_getlist({
                'fields[{}]'.format(item.data['content_type']): ['id,language']})
            serializer = self.serializer_class(item)
            self.assertEqual(set(['id', 'language']), serializer.fields)

        # with general and type specific fields
        with self.context.test_request_context() as ctx:
            ctx.request.args.getlist = mock_getlist({
                'fields': ['id', 'name'],
                'fields[{}]'.format(item.data['content_type']): ['id,language']
            })
            serializer = self.serializer_class(item)
            self.assertEqual(set(['id', 'language', 'name']), serializer.fields)

        item.default_fields = ['id', 'title']
        item.data = {
            "abstract": "",
            "alt_bodies": "",
            "body": "",
            "content_type": "",
            "contributors": "",
            "created_at": "",
            "dek": "",
            "extra_fields": "",
            "id": "",
            "images": "",
            "keywords": "",
            "kickers": "",
            "language": "",
            "last_modified_datetime": "",
            "lead_media": "",
            "localizations": "",
            "meta": "",
            "photo_galleries": "",
            "publication_datetime": "",
            "seo_title": "",
            "short_abstract": "",
            "short_title": "",
            "social_title": "",
            "sponsor_content": "",
            "pointer": "",
            "title": "",
            "uri": "",
            "videos": "",
        }

        # with 'all' value at 'fields' key
        with self.context.test_request_context() as ctx:
            ctx.request.args.getlist = mock_getlist({
                'fields': ['all'],
                'fields[{}]'.format(item.data['content_type']): []
            })
            serializer = self.serializer_class(item)
            self.assertEqual(len(item.data), len(serializer.fields))
            for key, value in item.data.iteritems():
                self.assertTrue(key in serializer.fields)
