Esempio n. 1
0
 def setUp(self):
     super(MstrReportTestCase, self).setUp()
     self.report = Report(self.client, 'report_id')
     self.report_response = (
         "<response><report_data_list><report_data>"
         "<prs></prs><objects><attribute rfd='0' id='header1_id' "
         "name='header1_name' type='header1_type'><form rfd='1' id='frm1_id'"
         " base_form_type='frm1_basetype' name='frm1_name' id_form='1' "
         "type='frm1_type'/></attribute><attribute rfd='2' id='header2_id' "
         "name='header2_name' type='header2_type'><form/></attribute>"
         "</objects><template></template><raw_data><headers><oi rfd='0'/>"
         "<oi rfd='2'/></headers><rows cn='100000'><r fr='1'>"
         "<v id='BB:header1_id:1:1:0:2:col1_val1'>col1_val1</v>"
         "<v id='BB:header2_id:1:1:0:3:col2_val1'>col2_val1</v></r>"
         "<r><v id='BB:header1_id:1:1:0:2:col1_val2'>col1_val2</v>"
         "<v id='BB:header2_id:1:1:0:3:col2_val2'>col2_val2</v></r></rows>"
         "</raw_data></report_data></report_data_list></response>")
     self.report_args = {
         'taskId': 'reportExecute',
         'startRow': 0,
         'startCol': 0,
         'maxRows': 100000,
         'maxCols': 255,
         'styleName': 'ReportDataVisualizationXMLStyle',
         'resultFlags': '393216',
         'reportID': 'report_id',
         'sessionState': 'session'
     }
Esempio n. 2
0
 def setUp(self):
     mox.MoxTestBase.setUp(self)
     s = stubout.StubOutForTesting()
     s.Set(MstrClient, '_login',
           lambda self, source, name, username, password: None)
     self.client = MstrClient('url?', 'username', 'pw', 'source', 'name')
     self.client._session = 'session'
     self.mox.StubOutWithMock(self.client, "_request")
     self.report = Report(self.client, 'report_id')
     self.report_response = "<response><report_data_list><report_data>" + \
         "<prs></prs><objects><attribute rfd='0' id='header1_id' " +\
         "name='header1_name' type='header1_type'><form rfd='1' id='frm1_id'" +\
         " base_form_type='frm1_basetype' name='frm1_name' id_form='1' " +\
         "type='frm1_type'/></attribute><attribute rfd='2' id='header2_id' " +\
         "name='header2_name' type='header2_type'><form/></attribute>" +\
         "</objects><template></template><raw_data><headers><oi rfd='0'/>" +\
         "<oi rfd='2'/></headers><rows cn='100000'><r fr='1'>" +\
         "<v id='BB:header1_id:1:1:0:2:col1_val1'>col1_val1</v>" +\
         "<v id='BB:header2_id:1:1:0:3:col2_val1'>col2_val1</v></r>" +\
         "<r><v id='BB:header1_id:1:1:0:2:col1_val2'>col1_val2</v>" +\
         "<v id='BB:header2_id:1:1:0:3:col2_val2'>col2_val2</v></r></rows>" +\
         "</raw_data></report_data></report_data_list></response>"
     self.report_args = {
         'taskId': 'reportExecute',
         'startRow': 0,
         'startCol': 0,
         'maxRows': 100000,
         'maxCols': 10,
         'styleName': 'ReportDataVisualizationXMLStyle',
         'resultFlags': '393216',
         'reportID': 'report_id',
         'sessionState': 'session'
     }
Esempio n. 3
0
 def setUp(self):
     mox.MoxTestBase.setUp(self)
     s = stubout.StubOutForTesting()
     s.Set(MstrClient, '_login', lambda self, source, name, username, password: None)
     self.client = MstrClient('url?', 'username', 'pw', 'source', 'name')
     self.client._session = 'session'
     self.mox.StubOutWithMock(self.client, "_request")
     self.report = Report(self.client, 'report_id')
     self.report_response = "<response><report_data_list><report_data>" + \
         "<prs></prs><objects><attribute rfd='0' id='header1_id' " +\
         "name='header1_name' type='header1_type'><form rfd='1' id='frm1_id'" +\
         " base_form_type='frm1_basetype' name='frm1_name' id_form='1' " +\
         "type='frm1_type'/></attribute><attribute rfd='2' id='header2_id' " +\
         "name='header2_name' type='header2_type'><form/></attribute>" +\
         "</objects><template></template><raw_data><headers><oi rfd='0'/>" +\
         "<oi rfd='2'/></headers><rows cn='100000'><r fr='1'>" +\
         "<v id='BB:header1_id:1:1:0:2:col1_val1'>col1_val1</v>" +\
         "<v id='BB:header2_id:1:1:0:3:col2_val1'>col2_val1</v></r>" +\
         "<r><v id='BB:header1_id:1:1:0:2:col1_val2'>col1_val2</v>" +\
         "<v id='BB:header2_id:1:1:0:3:col2_val2'>col2_val2</v></r></rows>" +\
         "</raw_data></report_data></report_data_list></response>"
     self.report_args = {
         'taskId': 'reportExecute',
         'startRow': 0,
         'startCol': 0,
         'maxRows': 100000,
         'maxCols': 10,
         'styleName': 'ReportDataVisualizationXMLStyle',
         'resultFlags': '393216',
         'reportID': 'report_id',
         'sessionState': 'session'
     }
Esempio n. 4
0
 def setUp(self):
     super(MstrReportTestCase, self).setUp()
     self.report = Report(self.client, 'report_id')
     self.report_response = (
         "<response><report_data_list><report_data>"
         "<prs></prs><objects><attribute rfd='0' id='header1_id' "
         "name='header1_name' type='header1_type'><form rfd='1' id='frm1_id'"
         " base_form_type='frm1_basetype' name='frm1_name' id_form='1' "
         "type='frm1_type'/></attribute><attribute rfd='2' id='header2_id' "
         "name='header2_name' type='header2_type'><form/></attribute>"
         "</objects><template></template><raw_data><headers><oi rfd='0'/>"
         "<oi rfd='2'/></headers><rows cn='100000'><r fr='1'>"
         "<v id='BB:header1_id:1:1:0:2:col1_val1'>col1_val1</v>"
         "<v id='BB:header2_id:1:1:0:3:col2_val1'>col2_val1</v></r>"
         "<r><v id='BB:header1_id:1:1:0:2:col1_val2'>col1_val2</v>"
         "<v id='BB:header2_id:1:1:0:3:col2_val2'>col2_val2</v></r></rows>"
         "</raw_data></report_data></report_data_list></response>"
     )
     self.report_args = {
         'taskId': 'reportExecute',
         'startRow': 0,
         'startCol': 0,
         'maxRows': 100000,
         'maxCols': 255,
         'styleName': 'ReportDataVisualizationXMLStyle',
         'resultFlags': '393216',
         'reportID': 'report_id',
         'sessionState': 'session'
     }
Esempio n. 5
0
class MstrReportTestCase(mox.MoxTestBase):

    def setUp(self):
        mox.MoxTestBase.setUp(self)
        s = stubout.StubOutForTesting()
        s.Set(MstrClient, '_login', lambda self, source, name, username, password: None)
        self.client = MstrClient('url?', 'username', 'pw', 'source', 'name')
        self.client._session = 'session'
        self.mox.StubOutWithMock(self.client, "_request")
        self.report = Report(self.client, 'report_id')
        self.report_response = "<response><report_data_list><report_data>" + \
            "<prs></prs><objects><attribute rfd='0' id='header1_id' " +\
            "name='header1_name' type='header1_type'><form rfd='1' id='frm1_id'" +\
            " base_form_type='frm1_basetype' name='frm1_name' id_form='1' " +\
            "type='frm1_type'/></attribute><attribute rfd='2' id='header2_id' " +\
            "name='header2_name' type='header2_type'><form/></attribute>" +\
            "</objects><template></template><raw_data><headers><oi rfd='0'/>" +\
            "<oi rfd='2'/></headers><rows cn='100000'><r fr='1'>" +\
            "<v id='BB:header1_id:1:1:0:2:col1_val1'>col1_val1</v>" +\
            "<v id='BB:header2_id:1:1:0:3:col2_val1'>col2_val1</v></r>" +\
            "<r><v id='BB:header1_id:1:1:0:2:col1_val2'>col1_val2</v>" +\
            "<v id='BB:header2_id:1:1:0:3:col2_val2'>col2_val2</v></r></rows>" +\
            "</raw_data></report_data></report_data_list></response>"
        self.report_args = {
            'taskId': 'reportExecute',
            'startRow': 0,
            'startCol': 0,
            'maxRows': 100000,
            'maxCols': 10,
            'styleName': 'ReportDataVisualizationXMLStyle',
            'resultFlags': '393216',
            'reportID': 'report_id',
            'sessionState': 'session'
        }
    def tearDown(self):
        mox.MoxTestBase.tearDown(self)

    def test_no_prompts_gives_error(self):
        """ Test that if a user tries to retrieve prompts for a report
            and the report has no prompts, that the actual report is returned,
            and subsequently an error is raised.
        """

        args = {'reportID': 'report_id', 'sessionState': 'session', 'taskId':
            'reportExecute'}
        self.client._request(args).AndReturn(self.report_response)

        self.mox.ReplayAll()

        self.assertRaises(MstrReportException, self.report.get_prompts)

    def test_valid_prompts(self):
        """ Test a proper use case of retrieving the prompts for a report and
            that the message id is correctly forwarded to retrieve the prompts.
        """

        args1 = {'reportID': 'report_id', 'sessionState': 'session', 'taskId':
            'reportExecute'}
        self.client._request(args1).AndReturn("<response><msg><id>msg_id</id>" +
            "</msg></response>")
        args2 = {'taskId': 'getPrompts', 'objectType': '3', 'msgID': 'msg_id',
            'sessionState': 'session'}
        result = "<response><rsl><prompts><block><reqd>false</reqd><mn>msg1</mn><junk>junk</junk><orgn><did>" +\
            "attr1_id</did><t>12</t><n>attr1_name</n><desc/></orgn><loc><did>guid1</did></loc></block>" +\
            "<block><mn>msg2</mn><reqd>true</reqd><orgn><did>attr2_id</did><t>type2</t><n>attr2_name</n>" +\
            "<desc/></orgn><loc><did>guid2</did></loc></block></prompts></rsl></response>"
        self.client._request(args2).AndReturn(result)

        self.mox.ReplayAll()

        prompts = self.report.get_prompts()
        self.assertEqual(2, len(prompts))
        self.assertEqual(Prompt, type(prompts[0]))
        self.assertEqual('attr1_name', prompts[0].attribute.name)
        self.assertEqual('attr1_id', prompts[0].attribute.guid)
        self.assertEqual('msg1', prompts[0].prompt_str)

    def test_get_attributes(self):
        """ Test getting the attributes (or headers) for a report returns
            valid Attribute/Metric objects. Also test that headers are saved
            once a report has been executed or headers have been requested.
        """

        args = {'taskId': 'browseAttributeForms', 'contentType': 3,
            'sessionState': 'session', 'reportID': 'report_id'}
        result = "<response><forms><attrs><a><did>attr1_id</did><n>attr1_name" +\
            "</n><fms><block><did>form1_id</did><n>DESC</n></block></fms></a>"+\
            "<a><did>attr2_id</did><n>attr2_name</n><fms></fms></a></attrs>"+\
            "</forms></response>"
        self.client._request(args).AndReturn(result)

        self.mox.ReplayAll()

        attrs = self.report.get_attributes()
        self.assertEqual(2, len(attrs))
        self.assertEqual('attr1_id', attrs[0].guid)
        self.assertEqual('attr1_name', attrs[0].name)
        self.assertEqual('attr2_id', attrs[1].guid)
        self.assertEqual('attr2_name', attrs[1].name)

        # when called a second time, should immediately
        # return same list without issuing a request
        attrs2 = self.report.get_attributes()
        self.assertEqual(attrs, attrs2)

    def test_get_headers_without_execution(self):
        self.assertRaises(MstrReportException, self.report.get_headers)

    def test_get_headers_with_execution(self):
        self.report._headers = ['h1', 'h2']
        self.assertEquals(self.report._headers, self.report.get_headers())

    def test_get_values_without_execution(self):
        self.assertRaises(MstrReportException, self.report.get_values)

    def test_get_values_with_execution(self):
        self.report._values = ['v1', 'v2']
        self.assertEquals(self.report._values, self.report.get_values())

    def test_error_execute(self):
        """ Test that when an error is returned by MicroStrategy,
        execute raises an exception
        """
        self.client._request(self.report_args).AndReturn("<taskResponse>" +
            "<report_data_list><report_data><error>Object executed is in " +
            "prompt status. Please resolve prompts and use the message ID." +
            "</error></report_data></report_data_list></taskResponse>")

        self.mox.ReplayAll()

        self.assertRaises(MstrReportException, self.report.execute)
        self.assertRaises(MstrReportException, self.report.get_values)
        self.assertEqual(None, self.report._values)

    def test_basic_execute(self):
        """ Test parsing of a report for a report with no prompts.
        """

        self.client._request(self.report_args).AndReturn(self.report_response)
        self.mox.ReplayAll()

        self.report.execute()

        self.assertEqual(2, len(self.report._headers))
        self.assertEqual(2, len(self.report._values))
        attr1 = Attribute('header1_id', 'header1_name')
        attr2 = Attribute('header2_id', 'header2_name')
        self.assertEqual(attr1, self.report._headers[0])
        self.assertEqual(attr2, self.report._headers[1])
        self.assertEqual([(attr1, 'col1_val1'), (attr2, 'col2_val1')],
            self.report._values[0])
        self.assertEqual([(attr1, 'col1_val2'), (attr2, 'col2_val2')],
            self.report._values[1])

    def test_element_prompt_execute(self):
        """ Test element prompt answers are configured correctly before
            executing the report. Prompt answers do not impact the format of
            the returned report
        """

        import copy
        args1 = copy.deepcopy(self.report_args)
        args1['elementsPromptAnswers'] = 'attr1_id;attr1_id:value'
        self.client._request(args1).AndReturn(None)

        args2 = copy.deepcopy(self.report_args)
        args2['elementsPromptAnswers'] = 'attr1_id;attr1_id:val1;attr1_id:val2'
        self.client._request(args2).AndReturn(None)

        self.mox.ReplayAll()

        attr1 = Attribute('attr1_id', 'attr1_name')
        prompt1 = Prompt('p1guid', 'Prompt 1', False, attr1)
        attr2 = Attribute('attr2_id', 'attr2_name')
        prompt2 = Prompt('p2guid', 'Prompt 2', False, attr2)
        self.report.execute(element_prompt_answers={prompt1: ['value']})
        self.report.execute(element_prompt_answers={prompt1: ['val1', 'val2']})
        # test with optional prompt

        # dict iteration is non-deterministic, so test it separately
        result = self.report._format_element_prompts({prompt1: ['value1'],
            prompt2: ['value2']})
        self.failUnless(result['elementsPromptAnswers'] in
            ['attr2_id;attr2_id:value2,attr1_id;attr1_id:value1',
            'attr1_id;attr1_id:value1,attr2_id;attr2_id:value2'])
        
        result = self.report._format_element_prompts({prompt1: ['val1', 'val2'],
            prompt2: ['val3']})
        self.failUnless(result['elementsPromptAnswers'] in
            ['attr2_id;attr2_id:val3,attr1_id;attr1_id:val1;attr1_id:val2',
            'attr1_id;attr1_id:val1;attr1_id:val2,attr2_id;attr2_id:val3'])

    def test_value_prompt_execute(self):
        """ Test value prompt answers are correctly formated before executing the
            report.
        """

        import copy
        args1 = copy.deepcopy(self.report_args)
        args1['valuePromptAnswers'] = 'prompt1'
        self.client._request(args1).AndReturn(None)

        # multiple prompts
        args2 = copy.deepcopy(self.report_args)
        args2['valuePromptAnswers'] = 'prompt1^prompt2'
        self.client._request(args2).AndReturn(None)
        
        # optional prompts
        self.report_args.update({'valuePromptAnswers': '^prompt2^^prompt4^'})
        self.client._request(self.report_args).AndReturn(None)

        self.mox.ReplayAll()

        p1 = Prompt('guid1', 'P1', False)
        p2 = Prompt('guid2', 'P2', True)
        p3 = Prompt('guid3', 'P3', False)
        p4 = Prompt('guid4', 'P4', True)
        p5 = Prompt('guid5', 'P5', False)

        self.report.execute(value_prompt_answers=[(p1, 'prompt1')])
        self.report.execute(value_prompt_answers=[(p1, 'prompt1'),
                                                 (p2, 'prompt2')])
        self.report.execute(value_prompt_answers=[(p1, ''), (p2, 'prompt2'),
                                                 (p3, ''), (p4, 'prompt4'),
                                                 (p5, '')])

    def test_value_and_element_prompt_execute(self):
        """ Test that when both value prompt answers and element prompt
        answers are included, the data is correctly formatted.
        """
        import copy
        args1 = copy.deepcopy(self.report_args)
        args1['elementsPromptAnswers'] = 'attr1_id;attr1_id:value'
        args1['promptsAnswerXML'] = "<rsl><pa pt='5' pin='0' did='p2guid' " + \
            "tp='10'>value2</pa><pa pt='5' pin='0' did='p3guid' tp='10'></pa></rsl>"
        self.client._request(args1).AndReturn(None)

        self.mox.ReplayAll()

        attr1 = Attribute('attr1_id', 'attr1_name')
        prompt1 = Prompt('p1guid', 'Prompt 1', False, attr1)
        prompt2 = Prompt('p2guid', 'Prompt 2', False)
        prompt3 = Prompt('p3guid', 'Prompt 3', False)
        self.report.execute(element_prompt_answers={prompt1: ['value']},
            value_prompt_answers=[(prompt2, 'value2'), (prompt3, '')])
Esempio n. 6
0
class MstrReportTestCase(MstrTestCase):
    def setUp(self):
        super(MstrReportTestCase, self).setUp()
        self.report = Report(self.client, 'report_id')
        self.report_response = (
            "<response><report_data_list><report_data>"
            "<prs></prs><objects><attribute rfd='0' id='header1_id' "
            "name='header1_name' type='header1_type'><form rfd='1' id='frm1_id'"
            " base_form_type='frm1_basetype' name='frm1_name' id_form='1' "
            "type='frm1_type'/></attribute><attribute rfd='2' id='header2_id' "
            "name='header2_name' type='header2_type'><form/></attribute>"
            "</objects><template></template><raw_data><headers><oi rfd='0'/>"
            "<oi rfd='2'/></headers><rows cn='100000'><r fr='1'>"
            "<v id='BB:header1_id:1:1:0:2:col1_val1'>col1_val1</v>"
            "<v id='BB:header2_id:1:1:0:3:col2_val1'>col2_val1</v></r>"
            "<r><v id='BB:header1_id:1:1:0:2:col1_val2'>col1_val2</v>"
            "<v id='BB:header2_id:1:1:0:3:col2_val2'>col2_val2</v></r></rows>"
            "</raw_data></report_data></report_data_list></response>")
        self.report_args = {
            'taskId': 'reportExecute',
            'startRow': 0,
            'startCol': 0,
            'maxRows': 100000,
            'maxCols': 255,
            'styleName': 'ReportDataVisualizationXMLStyle',
            'resultFlags': '393216',
            'reportID': 'report_id',
            'sessionState': 'session'
        }

    @mock.patch.object(MstrClient, '_request')
    def test_no_prompts_gives_error(self, mock_mstr_client_request):
        """ Test that if a user tries to retrieve prompts for a report
            and the report has no prompts, that the actual report is returned,
            and subsequently an error is raised.
        """
        args = {
            'reportID': 'report_id',
            'sessionState': 'session',
            'taskId': 'reportExecute'
        }
        mock_mstr_client_request.return_value = self.report_response

        self.assertRaises(MstrReportException, self.report.get_prompts)
        mock_mstr_client_request.assert_called_with(args)

    @mock.patch.object(MstrClient, '_request')
    def test_valid_prompts(self, mock_mstr_client_request):
        """ Test a proper use case of retrieving the prompts for a report and
            that the message id is correctly forwarded to retrieve the prompts.
        """
        args1 = {
            'reportID': 'report_id',
            'sessionState': 'session',
            'taskId': 'reportExecute'
        }
        args2 = {
            'taskId': 'getPrompts',
            'objectType': '3',
            'msgID': 'msg_id',
            'sessionState': 'session'
        }
        result = (
            "<response><rsl><prompts><block><reqd>false</reqd><mn>msg1</mn><junk>junk</junk><orgn><did>"
            "attr1_id</did><t>12</t><n>attr1_name</n><desc/></orgn><loc><did>guid1</did></loc></block>"
            "<block><mn>msg2</mn><reqd>true</reqd><orgn><did>attr2_id</did><t>type2</t><n>attr2_name</n>"
            "<desc/></orgn><loc><did>guid2</did></loc></block></prompts></rsl></response>"
        )
        mock_mstr_client_request.side_effect = [
            "<response><msg><id>msg_id</id></msg></response>", result
        ]

        prompts = self.report.get_prompts()
        mock_mstr_client_request.assert_has_calls(
            [mock.call(args1), mock.call(args2)])
        self.assertEqual(2, len(prompts))
        self.assertEqual(Prompt, type(prompts[0]))
        self.assertEqual('attr1_name', prompts[0].attribute.name)
        self.assertEqual('attr1_id', prompts[0].attribute.guid)
        self.assertEqual('msg1', prompts[0].prompt_str)

    @mock.patch.object(MstrClient, '_request')
    def test_get_attributes(self, mock_mstr_client_request):
        """ Test getting the attributes (or headers) for a report returns
            valid Attribute/Metric objects. Also test that headers are saved
            once a report has been executed or headers have been requested.
        """
        args = {
            'taskId': 'browseAttributeForms',
            'contentType': 3,
            'sessionState': 'session',
            'reportID': 'report_id'
        }
        result = (
            "<response><forms><attrs><a><did>attr1_id</did><n>attr1_name"
            "</n><fms><block><did>form1_id</did><n>DESC</n></block></fms></a>"
            "<a><did>attr2_id</did><n>attr2_name</n><fms></fms></a></attrs>"
            "</forms></response>")
        mock_mstr_client_request.return_value = result

        attrs = self.report.get_attributes()
        mock_mstr_client_request.assert_called_with(args)
        self.assertEqual(2, len(attrs))
        self.assertEqual('attr1_id', attrs[0].guid)
        self.assertEqual('attr1_name', attrs[0].name)
        self.assertEqual('attr2_id', attrs[1].guid)
        self.assertEqual('attr2_name', attrs[1].name)

        # when called a second time, should immediately
        # return same list without issuing a request
        attrs2 = self.report.get_attributes()
        self.assertEqual(attrs, attrs2)

    def test_get_headers_without_execution(self):
        self.assertRaises(MstrReportException, self.report.get_headers)

    def test_get_headers_with_execution(self):
        self.report._headers = ['h1', 'h2']
        self.assertEquals(self.report._headers, self.report.get_headers())

    def test_get_values_without_execution(self):
        self.assertRaises(MstrReportException, self.report.get_values)

    def test_get_values_with_execution(self):
        self.report._values = ['v1', 'v2']
        self.assertEquals(self.report._values, self.report.get_values())

    @mock.patch.object(MstrClient, '_request')
    def test_error_execute(self, mock_mstr_client_request):
        """ Test that when an error is returned by MicroStrategy,
        execute raises an exception
        """
        mock_mstr_client_request.return_value = (
            "<taskResponse>"
            "<report_data_list><report_data><error>Object executed is in "
            "prompt status. Please resolve prompts and use the message ID."
            "</error></report_data></report_data_list></taskResponse>")

        self.assertRaises(MstrReportException, self.report.execute)
        mock_mstr_client_request.assert_called_with(self.report_args)
        self.assertRaises(MstrReportException, self.report.get_values)
        mock_mstr_client_request.assert_called_with(self.report_args)
        self.assertEqual(None, self.report._values)

    @mock.patch.object(MstrClient, '_request')
    def test_basic_execute(self, mock_mstr_client_request):
        """ Test parsing of a report for a report with no prompts.
        """
        mock_mstr_client_request.return_value = self.report_response

        self.report.execute()
        mock_mstr_client_request.assert_called_with(self.report_args)

        self.assertEqual(2, len(self.report._headers))
        self.assertEqual(2, len(self.report._values))
        attr1 = Attribute('header1_id', 'header1_name')
        attr2 = Attribute('header2_id', 'header2_name')
        self.assertEqual(attr1, self.report._headers[0])
        self.assertEqual(attr2, self.report._headers[1])
        self.assertEqual([(attr1, 'col1_val1'), (attr2, 'col2_val1')],
                         self.report._values[0])
        self.assertEqual([(attr1, 'col1_val2'), (attr2, 'col2_val2')],
                         self.report._values[1])

    @mock.patch.object(MstrClient, '_request')
    def test_element_prompt_execute(self, mock_mstr_client_request):
        """ Test element prompt answers are configured correctly before
            executing the report. Prompt answers do not impact the format of
            the returned report
        """
        import copy
        args1 = copy.deepcopy(self.report_args)
        args1['elementsPromptAnswers'] = 'attr1_id;attr1_id:value'

        args2 = copy.deepcopy(self.report_args)
        args2['elementsPromptAnswers'] = 'attr1_id;attr1_id:val1;attr1_id:val2'

        attr1 = Attribute('attr1_id', 'attr1_name')
        prompt1 = Prompt('p1guid', 'Prompt 1', False, attr1)
        attr2 = Attribute('attr2_id', 'attr2_name')
        prompt2 = Prompt('p2guid', 'Prompt 2', False, attr2)
        self.report.execute(element_prompt_answers={prompt1: ['value']})
        mock_mstr_client_request.assert_called_with(args1)
        self.report.execute(element_prompt_answers={prompt1: ['val1', 'val2']})
        mock_mstr_client_request.assert_called_with(args2)
        # test with optional prompt

        # dict iteration is non-deterministic, so test it separately
        result = self.report._format_element_prompts({
            prompt1: ['value1'],
            prompt2: ['value2']
        })
        mock_mstr_client_request.assert_called_with(args2)
        self.failUnless(result['elementsPromptAnswers'] in [
            'attr2_id;attr2_id:value2,attr1_id;attr1_id:value1',
            'attr1_id;attr1_id:value1,attr2_id;attr2_id:value2',
        ])

        result = self.report._format_element_prompts({
            prompt1: ['val1', 'val2'],
            prompt2: ['val3']
        })
        mock_mstr_client_request.assert_called_with(args2)
        self.failUnless(result['elementsPromptAnswers'] in [
            'attr2_id;attr2_id:val3,attr1_id;attr1_id:val1;attr1_id:val2',
            'attr1_id;attr1_id:val1;attr1_id:val2,attr2_id;attr2_id:val3',
        ])

    @mock.patch.object(MstrClient, '_request')
    def test_value_prompt_execute(self, mock_mstr_client_request):
        """ Test value prompt answers are correctly formated before executing the
            report.
        """
        import copy
        args1 = copy.deepcopy(self.report_args)
        args1['valuePromptAnswers'] = 'prompt1'

        # multiple prompts
        args2 = copy.deepcopy(self.report_args)
        args2['valuePromptAnswers'] = 'prompt1^prompt2'

        # optional prompts
        self.report_args.update({'valuePromptAnswers': '^prompt2^^prompt4^'})

        p1 = Prompt('guid1', 'P1', False)
        p2 = Prompt('guid2', 'P2', True)
        p3 = Prompt('guid3', 'P3', False)
        p4 = Prompt('guid4', 'P4', True)
        p5 = Prompt('guid5', 'P5', False)

        self.report.execute(value_prompt_answers=[(p1, 'prompt1')])
        mock_mstr_client_request.assert_called_with(args1)
        self.report.execute(value_prompt_answers=[(p1,
                                                   'prompt1'), (p2,
                                                                'prompt2')])
        mock_mstr_client_request.assert_called_with(args2)
        self.report.execute(
            value_prompt_answers=[(p1,
                                   ''), (p2,
                                         'prompt2'), (p3,
                                                      ''), (p4,
                                                            'prompt4'), (p5,
                                                                         '')])
        mock_mstr_client_request.assert_called_with(self.report_args)

    @mock.patch.object(MstrClient, '_request')
    def test_value_and_element_prompt_execute(self, mock_mstr_client_request):
        """ Test that when both value prompt answers and element prompt
        answers are included, the data is correctly formatted.
        """
        import copy
        args1 = copy.deepcopy(self.report_args)
        args1['elementsPromptAnswers'] = 'attr1_id;attr1_id:value'
        args1['promptsAnswerXML'] = (
            "<rsl><pa pt='5' pin='0' did='p2guid' "
            "tp='10'>value2</pa><pa pt='5' pin='0' did='p3guid' tp='10'></pa></rsl>"
        )

        attr1 = Attribute('attr1_id', 'attr1_name')
        prompt1 = Prompt('p1guid', 'Prompt 1', False, attr1)
        prompt2 = Prompt('p2guid', 'Prompt 2', False)
        prompt3 = Prompt('p3guid', 'Prompt 3', False)
        self.report.execute(element_prompt_answers={prompt1: ['value']},
                            value_prompt_answers=[(prompt2, 'value2'),
                                                  (prompt3, '')])
        mock_mstr_client_request.assert_called_with(args1)