import unittest
import six
import rdflib
# from mock import patch

from grlc.fileLoaders import LocalLoader
from grlc import gquery

from flask import Flask


class TestGQuery(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        self.loader = LocalLoader('./tests/repo/')
        self.app = Flask('unittests')

    def test_guess_endpoint(self):
        with self.app.test_request_context('/?endpoint=http://url-endpoint/from-url/sparql'):
            endpoint, _ = gquery.guess_endpoint_uri('', self.loader)
            self.assertIn('from-url', endpoint,
                          'Should match endpoint given in url')

        with self.app.test_request_context('/'):
            endpoint, _ = gquery.guess_endpoint_uri('', self.loader)
            self.assertIn('from-file', endpoint,
                          'Should match endpoint in endpoint.txt')

            rq, _ = self.loader.getTextForQueryName('test-rq')
            endpoint, _ = gquery.guess_endpoint_uri(rq, self.loader)
            self.assertIn('from-decorator', endpoint,
                          'Should match endpoint in test-rq.rq')

    def test_get_parameters(self):
        rq, _ = self.loader.getTextForQueryName('test-rq')

        params = gquery.get_parameters(rq, '')
        for paramName, param in params.iteritems():
            self.assertIn('name', param, 'Should have a name')
            self.assertIn('type', param, 'Should have a type')
            self.assertIn('required', param, 'Should have a required')

            orig = param['original']
            if '_iri' in orig:
                self.assertEqual(param['type'], 'iri', 'Should be type iri')
            if '_number' in orig:
                self.assertEqual(param['type'], 'number',
                                 'Should be type number')
            if '_literal' in orig:
                self.assertEqual(param['type'], 'literal',
                                 'Should be type literal')
            if '_en' in orig:
                self.assertEqual(param['type'], 'literal',
                                 'Should be type literal')
                self.assertEqual(param['lang'], 'en', 'Should be en language')
            if '_integer' in orig:
                self.assertEqual(
                    param['datatype'], 'xsd:integer', 'Should be type xsd:integer')
            if '_xsd_date' in orig:
                self.assertEqual(param['datatype'],
                                 'xsd:date', 'Should be type xsd:date')

    def test_get_enumeration(self):
        # Might need to mock requests.get(endpoint) for this one.
        self.skipTest('Not implemented')

    def test_get_yaml_decorators(self):
        rq, _ = self.loader.getTextForQueryName('test-sparql')

        decorators = gquery.get_yaml_decorators(rq)

        # Query always exist -- the rest must be present on the file.
        self.assertIn('query', decorators, 'Should have a query field')
        self.assertIn('summary', decorators, 'Should have a summary field')
        self.assertIn('pagination', decorators,
                      'Should have a pagination field')
        self.assertIn('enumerate', decorators, 'Should have a enumerate field')

        self.assertIsInstance(
            decorators['summary'], six.string_types, 'Summary should be text')
        self.assertIsInstance(
            decorators['pagination'], int, 'Pagination should be numeric')
        self.assertIsInstance(
            decorators['enumerate'], list, 'Enumerate should be a list')

    def test_get_metadata(self):
        rq, _ = self.loader.getTextForQueryName('test-sparql')

        metadata = gquery.get_metadata(rq)
        self.assertIn('type', metadata, 'Should have a type field')
        self.assertIn('variables', metadata, 'Should have a variables field')
        self.assertEqual(metadata['type'], 'SelectQuery',
                         'Should be type SelectQuery')
        self.assertIsInstance(
            metadata['variables'], list, 'Should be a list of variables')
        for var in metadata['variables']:
            self.assertIsInstance(var, rdflib.term.Variable,
                                  'Should be of type Variable')

    def test_paginate_query(self):
        rq, _ = self.loader.getTextForQueryName('test-sparql')

        rq_pag = gquery.paginate_query(rq, {})

        self.assertNotIn(
            'LIMIT', rq, 'Original query should not contain LIMIT keyword')
        self.assertIn('LIMIT', rq_pag,
                      'Paginated query should contain LIMIT keyword')
        self.assertNotIn(
            'OFFSET', rq, 'Original query should not contain OFFSET keyword')
        self.assertIn('OFFSET', rq_pag,
                      'Paginated query should contain OFFSET keyword')

    def test_rewrite_query(self):
        rq, _ = self.loader.getTextForQueryName('test-rq')
        parameters = {
            'o1': 'x1',
            'o2': 'x2',
            'o3': 'x3',
            'o4': 'x4',
            'o5': 'x5',
            'o6': 'x6',
            'o7': 'x7'
        }
        rq_rw = gquery.rewrite_query(rq, parameters, '')

        for pName, pValue in parameters.iteritems():
            self.assertIn(
                pName, rq, 'Original query should contain original parameter name')
            self.assertNotIn(
                pName, rq_rw, 'Rewritten query should not contain original parameter name')
            self.assertNotIn(
                pValue, rq, 'Original query should not contain replacement parameter value')
            self.assertIn(
                pValue, rq_rw, 'Rewritten query should contain replacement parameter value')


if __name__ == '__main__':
    unittest.main()

@@ -34,18 +34,16 @@
  rdflib%0A
-# 
 from moc
@@ -56,16 +56,22 @@
 rt patch
+, Mock
 %0A%0Afrom g
@@ -2501,24 +2501,51 @@
 xsd:date')%0A%0A
+    @patch('requests.get')%0A
     def test
@@ -2561,24 +2561,34 @@
 eration(self
+, mock_get
 ):%0A        #
@@ -2590,65 +2590,518 @@
     
-# Might need to mock requests.get(endpoint) for th
+mock_get.return_value = Mock(ok=True)%0A        mock_get.return_value.json.return_value = %7B%0A            'results': %7B%0A                'bindings': %5B%0A                    %7B 'o1': %7B 'value': 'v1'%7D %7D,%0A                    %7B 'o1': %7B 'value': 'v2'%7D %7D%0A                %5D%0A            %7D%0A        %7D%0A%0A        rq, _ = self.loader.getTextForQueryName('test-rq')%0A        enumeration = gquery.get_enumeration(rq, 'o1', 'http://mock-endpoint/sparql')%0A        self.assertIsInstance(enumeration, list, 'Should return a l
 is
+t
  o
-ne.
+f values')
 %0A   
@@ -3114,33 +3114,67 @@
 elf.
-skipTest('Not imp
+assertEquals(len(enumeration), 2, 'Should have two e
 lement
-ed
+s
 ')%0A%0A

Add tests for gquery.get_enumeration