def testSruTermDrilldown(self):
        sruTermDrilldown = SruTermDrilldown()

        drilldownData = [
                {'fieldname': 'field0', 'terms': [{'term': 'value0_0', 'count': 14}]},
                {'fieldname': 'field1', 'terms': [{'term': 'value1_0', 'count': 13}, {'term': 'value1_1', 'count': 11}]},
                {'fieldname': 'field2', 'terms': [{'term': 'value2_0', 'count': 3}, {'term': 'value2_1', 'count': 2}, {'term': 'value2_2', 'count': 1}]}
        ]

        response = ''.join(compose(sruTermDrilldown.extraResponseData(drilldownData, sruArguments={})))

        self.assertEqualsWS(DRILLDOWN_HEADER + """<dd:term-drilldown><dd:navigator name="field0">
    <dd:item count="14">value0_0</dd:item>
</dd:navigator>
<dd:navigator name="field1">
    <dd:item count="13">value1_0</dd:item>
    <dd:item count="11">value1_1</dd:item>
</dd:navigator>
<dd:navigator name="field2">
    <dd:item count="3">value2_0</dd:item>
    <dd:item count="2">value2_1</dd:item>
    <dd:item count="1">value2_2</dd:item>
</dd:navigator></dd:term-drilldown></dd:drilldown>""", response)

        xsdFilename = self._getXsdFilename(response)
        assertValid(response, join(schemasPath, xsdFilename))
    def testSruTermDrilldown(self):
        sruTermDrilldown = SruTermDrilldown()

        drilldownData = [{
            'fieldname': 'field0',
            'terms': [{
                'term': 'value0_0',
                'count': 14
            }]
        }, {
            'fieldname':
            'field1',
            'terms': [{
                'term': 'value1_0',
                'count': 13
            }, {
                'term': 'value1_1',
                'count': 11
            }]
        }, {
            'fieldname':
            'field2',
            'terms': [{
                'term': 'value2_0',
                'count': 3
            }, {
                'term': 'value2_1',
                'count': 2
            }, {
                'term': 'value2_2',
                'count': 1
            }]
        }]

        response = ''.join(
            compose(
                sruTermDrilldown.extraResponseData(drilldownData,
                                                   sruArguments={})))

        self.assertEqualsWS(
            DRILLDOWN_HEADER +
            """<dd:term-drilldown><dd:navigator name="field0">
    <dd:item count="14">value0_0</dd:item>
</dd:navigator>
<dd:navigator name="field1">
    <dd:item count="13">value1_0</dd:item>
    <dd:item count="11">value1_1</dd:item>
</dd:navigator>
<dd:navigator name="field2">
    <dd:item count="3">value2_0</dd:item>
    <dd:item count="2">value2_1</dd:item>
    <dd:item count="1">value2_2</dd:item>
</dd:navigator></dd:term-drilldown></dd:drilldown>""", response)

        xsdFilename = self._getXsdFilename(response)
        assertValid(response, join(schemasPath, xsdFilename))
    def testDrilldownNoResults(self):
        sruTermDrilldown = SruTermDrilldown()
        drilldownData = [
                {'fieldname': 'field0', 'terms': []},
            ]

        composedGenerator = compose(sruTermDrilldown.extraResponseData(drilldownData, sruArguments={}))
        result = "".join(composedGenerator)

        expected = DRILLDOWN_HEADER + """
            <dd:term-drilldown>
                <dd:navigator name="field0"/>
            </dd:term-drilldown>
        """ + DRILLDOWN_FOOTER
        self.assertEqualsWS(expected, result)
    def testWrongFormat(self):
        sruTermDrilldown = SruTermDrilldown()
        drilldownData = [
                {
                    'fieldname': 'field0',
                    'terms': [
                        {
                            'term': 'value0',
                            'count': 1,
                        }
                    ]
                }
            ]

        response = parse(StringIO(''.join(compose(sruTermDrilldown.extraResponseData(drilldownData, sruArguments={'x-drilldown-format':'text'})))))

        self.assertEqualsWS("Expected x-drilldown-format to be one of: ['xml', 'json']", xpathFirst(response, '//drilldown:term-drilldown/diag:diagnostic/diag:message/text()'))
    def testDefaultFormat(self):
        self.assertRaises(ValueError, lambda: SruTermDrilldown(defaultFormat='text'))
        sruTermDrilldown = SruTermDrilldown(defaultFormat='json')
        drilldownData = [
                {
                    'fieldname': 'field0',
                    'terms': [
                        {
                            'term': 'value0',
                            'count': 1,
                        }
                    ]
                }
            ]

        response = parse(StringIO(''.join(compose(sruTermDrilldown.extraResponseData(drilldownData, sruArguments={})))))

        self.assertEquals(drilldownData, loads(xpathFirst(response, '//drilldown:term-drilldown/drilldown:json/text()')))
    def testDrilldownNoResults(self):
        sruTermDrilldown = SruTermDrilldown()
        drilldownData = [
            {
                'fieldname': 'field0',
                'terms': []
            },
        ]

        composedGenerator = compose(
            sruTermDrilldown.extraResponseData(drilldownData, sruArguments={}))
        result = "".join(composedGenerator)

        expected = DRILLDOWN_HEADER + """
            <dd:term-drilldown>
                <dd:navigator name="field0"/>
            </dd:term-drilldown>
        """ + DRILLDOWN_FOOTER
        self.assertEqualsWS(expected, result)
    def testSruTermDrilldownWithSubTerms(self):
        sruTermDrilldown = SruTermDrilldown(defaultFormat=FORMAT_XML)

        drilldownData = [
                {
                    'fieldname': 'field0',
                    'terms': [
                        {
                            'term': 'value0',
                            'count': 1,
                            'subterms': [
                                {
                                    'term': 'value0_0',
                                    'count': 10,
                                },
                                {
                                    'term': 'value0_1',
                                    'count': 20
                                }
                            ]
                        },
                        {
                            'term': 'value1',
                            'count': 2
                        }
                    ]
                }
            ]

        response = ''.join(compose(sruTermDrilldown.extraResponseData(drilldownData, sruArguments={})))

        self.assertEqualsWS(_DRILLDOWN_HEADER % _DRILLDOWN_XSD_2013 + """<dd:term-drilldown><dd:navigator name="field0">
    <dd:item count="1" value="value0">
        <dd:navigator name="subterms">
            <dd:item count="10" value="value0_0"/>
            <dd:item count="20" value="value0_1"/>
        </dd:navigator>
    </dd:item>
    <dd:item count="2" value="value1"/>
</dd:navigator></dd:term-drilldown></dd:drilldown>""", response)
        xsdFilename = self._getXsdFilename(response)
        assertValid(response, join(schemasPath, xsdFilename))
    def testSruTermDrilldownWithSubTerms(self):
        sruTermDrilldown = SruTermDrilldown(defaultFormat=FORMAT_XML)

        drilldownData = [{
            'fieldname':
            'field0',
            'terms': [{
                'term':
                'value0',
                'count':
                1,
                'subterms': [{
                    'term': 'value0_0',
                    'count': 10,
                }, {
                    'term': 'value0_1',
                    'count': 20
                }]
            }, {
                'term': 'value1',
                'count': 2
            }]
        }]

        response = ''.join(
            compose(
                sruTermDrilldown.extraResponseData(drilldownData,
                                                   sruArguments={})))

        self.assertEqualsWS(
            _DRILLDOWN_HEADER % _DRILLDOWN_XSD_2013 +
            """<dd:term-drilldown><dd:navigator name="field0">
    <dd:item count="1" value="value0">
        <dd:navigator name="subterms">
            <dd:item count="10" value="value0_0"/>
            <dd:item count="20" value="value0_1"/>
        </dd:navigator>
    </dd:item>
    <dd:item count="2" value="value1"/>
</dd:navigator></dd:term-drilldown></dd:drilldown>""", response)
        xsdFilename = self._getXsdFilename(response)
        assertValid(response, join(schemasPath, xsdFilename))
    def testSruTermDrilldownWithPivotsInJson(self):
        sruTermDrilldown = SruTermDrilldown(defaultFormat=FORMAT_JSON)

        drilldownData = [{
            'fieldname':
            'field0',
            'terms': [{
                'term': 'value0',
                'count': 1,
                'pivot': {
                    'fieldname':
                    'field1',
                    'terms': [{
                        'term': 'value0_0',
                        'count': 10,
                    }, {
                        'term': 'value0 & 1',
                        'count': 20
                    }]
                }
            }, {
                'term': 'value1',
                'count': 2
            }]
        }]

        response = ''.join(
            compose(
                sruTermDrilldown.extraResponseData(
                    drilldownData,
                    sruArguments={'x-drilldown-format': ['json']})))
        self.assertEqual(
            drilldownData,
            loads(
                xpathFirst(
                    XML(response),
                    '//drilldown:term-drilldown/drilldown:json/text()')))

        xsdFilename = self._getXsdFilename(response)
        assertValid(response, join(schemasPath, xsdFilename))
    def testWrongFormat(self):
        sruTermDrilldown = SruTermDrilldown()
        drilldownData = [{
            'fieldname': 'field0',
            'terms': [{
                'term': 'value0',
                'count': 1,
            }]
        }]

        response = parse(
            StringIO(''.join(
                compose(
                    sruTermDrilldown.extraResponseData(
                        drilldownData,
                        sruArguments={'x-drilldown-format': 'text'})))))

        self.assertEqualsWS(
            "Expected x-drilldown-format to be one of: ['xml', 'json']",
            xpathFirst(
                response,
                '//drilldown:term-drilldown/diag:diagnostic/diag:message/text()'
            ))
    def testSruTermDrilldownWithPivotsInJson(self):
        sruTermDrilldown = SruTermDrilldown(defaultFormat=FORMAT_JSON)

        drilldownData = [
                {
                    'fieldname': 'field0',
                    'terms': [
                        {
                            'term': 'value0',
                            'count': 1,
                            'pivot': {
                                'fieldname': 'field1',
                                'terms': [
                                    {
                                        'term': 'value0_0',
                                        'count': 10,
                                    },
                                    {
                                        'term': 'value0 & 1',
                                        'count': 20
                                    }
                                ]
                            }
                        },
                        {
                            'term': 'value1',
                            'count': 2
                        }
                    ]
                }
            ]

        response = ''.join(compose(sruTermDrilldown.extraResponseData(drilldownData, sruArguments={'x-drilldown-format': ['json']})))
        self.assertEquals(drilldownData, loads(xpathFirst(XML(response), '//drilldown:term-drilldown/drilldown:json/text()')))

        xsdFilename = self._getXsdFilename(response)
        assertValid(response, join(schemasPath, xsdFilename))
    def testDefaultFormat(self):
        self.assertRaises(ValueError,
                          lambda: SruTermDrilldown(defaultFormat='text'))
        sruTermDrilldown = SruTermDrilldown(defaultFormat='json')
        drilldownData = [{
            'fieldname': 'field0',
            'terms': [{
                'term': 'value0',
                'count': 1,
            }]
        }]

        response = parse(
            StringIO(''.join(
                compose(
                    sruTermDrilldown.extraResponseData(drilldownData,
                                                       sruArguments={})))))

        self.assertEqual(
            drilldownData,
            loads(
                xpathFirst(
                    response,
                    '//drilldown:term-drilldown/drilldown:json/text()')))