예제 #1
0
    def test_validate_ticket_custom_field_max_size(self):
        """The [ticket-custom] max_size attribute is enforced."""
        module = BatchModifyModule(self.env)
        req1 = MockRequest(self.env, authname='has_bm', method='POST',
                           path_info='/batchmodify', args={
            'batchmod_value_text1': '12345',
            'action': 'leave',
            'selected_tickets': '1,2',
        })
        req2 = MockRequest(self.env, authname='has_bm', method='POST',
                           path_info='/batchmodify', args={
            'batchmod_value_text1': '123456',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        self.assertTrue(module.match_request(req1))
        with self.assertRaises(RequestDone):
            module.process_request(req1)

        self.assertEqual([], req1.chrome['warnings'])
        self.assertEqual('12345', model.Ticket(self.env, 1)['text1'])
        self.assertEqual('12345', model.Ticket(self.env, 2)['text1'])

        self.assertTrue(module.match_request(req2))
        with self.assertRaises(RequestDone):
            module.process_request(req2)

        self.assertEqual(1, len(req2.chrome['warnings']))
        self.assertEqual("The ticket field <strong>Text1</strong> is "
                         "invalid: Must be less than or equal to 5 "
                         "characters", unicode(req2.chrome['warnings'][0]))
        self.assertEqual('12345', model.Ticket(self.env, 1)['text1'])
        self.assertEqual('12345', model.Ticket(self.env, 2)['text1'])
예제 #2
0
    def test_validate_ticket_comment_size(self):
        """The [ticket] max_comment_size value is enforced."""
        module = BatchModifyModule(self.env)
        self.env.config.set('ticket', 'max_comment_size', 5)
        req1 = MockRequest(self.env, authname='has_bm', method='POST',
                           path_info='/batchmodify', args={
            'batchmod_value_comment': '12345',
            'action': 'leave',
            'selected_tickets': '1,2',
        })
        req2 = MockRequest(self.env, authname='has_bm', method='POST',
                           path_info='/batchmodify', args={
            'batchmod_value_comment': '123456',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        self.assertTrue(module.match_request(req1))
        with self.assertRaises(RequestDone):
            module.process_request(req1)

        self.assertEqual([], req1.chrome['warnings'])
        self.assertCommentAdded(1, '12345')
        self.assertCommentAdded(2, '12345')

        self.assertTrue(module.match_request(req2))
        with self.assertRaises(RequestDone):
            module.process_request(req2)

        self.assertEqual(1, len(req2.chrome['warnings']))
        self.assertEqual("The ticket comment is invalid: Must be less than or "
                         "equal to 5 characters",
                         unicode(req2.chrome['warnings'][0]))
        self.assertEqual(1, len(model.Ticket(self.env, 1).get_changelog()))
        self.assertEqual(1, len(model.Ticket(self.env, 2).get_changelog()))
예제 #3
0
    def test_timeline_events(self):
        """Regression test for #11288"""
        req1 = MockRequest(self.env)
        tktmod = web_ui.TicketModule(self.env)
        now = datetime_now(utc)
        start = now - timedelta(hours=1)
        stop = now + timedelta(hours=1)
        events = tktmod.get_timeline_events(req1, start, stop,
                                            ['ticket_details'])
        self.assertTrue(all(ev[0] != 'batchmodify' for ev in events))

        prio_ids = {}
        for i in xrange(20):
            priority = ('', 'minor', 'major', 'critical')[i % 4]
            t = insert_ticket(self.env, summary='Ticket %d' % i,
                              priority=priority)
            prio_ids.setdefault(t['priority'], []).append(t.id)
        tktids = prio_ids['critical'] + prio_ids['major'] + \
                 prio_ids['minor'] + prio_ids['']

        req2 = MockRequest(self.env, method='POST', authname='has_ta_&_bm',
                          path_info='/batchmodify', args={
            'batchmod_value_summary': 'batch updated ticket',
            'batchmod_value_owner': 'ticket11288',
            'batchmod_value_reporter': 'ticket11288',
            'action': 'leave',
            'selected_tickets': ','.join(str(t) for t in tktids),
        })

        batch = BatchModifyModule(self.env)
        self.assertTrue(batch.match_request(req2))
        with self.assertRaises(RequestDone):
            batch.process_request(req2)

        # shuffle ticket_change records
        with self.env.db_transaction as db:
            rows = db('SELECT * FROM ticket_change')
            db.execute('DELETE FROM ticket_change')
            rows = rows[0::4] + rows[1::4] + rows[2::4] + rows[3::4]
            db.executemany('INSERT INTO ticket_change VALUES (%s)' %
                           ','.join(('%s',) * len(rows[0])),
                           rows)

        events = tktmod.get_timeline_events(req1, start, stop,
                                            ['ticket_details'])
        events = [ev for ev in events if ev[0] == 'batchmodify']
        self.assertEqual(1, len(events))
        batch_ev = events[0]
        self.assertEqual('has_ta_&_bm', batch_ev[2])
        self.assertEqual(tktids, batch_ev[3][0])
        self.assertEqual('updated', batch_ev[3][1])

        context = web_context(req2)
        self.assertEqual(req2.href.query(id=','.join(str(t) for t in tktids)),
                         tktmod.render_timeline_event(context, 'url',
                                                      batch_ev))
예제 #4
0
    def test_action_with_state_change(self):
        """Actions can have change status."""
        req = MockRequest(self.env, method='POST', authname='has_bm',
                          path_info='/batchmodify', args={
            'action': 'acknowledge',
            'batchmod_value_comment': '',
            'selected_tickets': '1,2',
        })

        batch = BatchModifyModule(self.env)
        self.assertTrue(batch.match_request(req))
        with self.assertRaises(RequestDone):
            batch.process_request(req)

        self.assertFieldValue(1, 'status', 'acknowledged')
        self.assertFieldValue(2, 'status', 'acknowledged')
예제 #5
0
    def test_save_comment(self):
        """Comments are saved to all selected tickets."""
        req = MockRequest(self.env, method='POST', authname='has_bm',
                          path_info='/batchmodify', args={
            'batchmod_value_comment': 'the comment',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        batch = BatchModifyModule(self.env)
        self.assertTrue(batch.match_request(req))
        with self.assertRaises(RequestDone):
            batch.process_request(req)

        self.assertCommentAdded(1, 'the comment')
        self.assertCommentAdded(2, 'the comment')
예제 #6
0
    def test_modify_reporter_without_ticket_admin(self):
        """User without TICKET_ADMIN cannot batch modify the reporter."""
        req = MockRequest(self.env, method='POST', authname='has_bm',
                          path_info='/batchmodify', args={
            'batchmod_value_reporter': 'user2',
            'batchmod_value_comment': '',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        module = BatchModifyModule(self.env)
        self.assertTrue(module.match_request(req))
        with self.assertRaises(RequestDone):
            module.process_request(req)

        self.assertFieldValue(1, 'reporter', 'user1')
        self.assertFieldValue(2, 'reporter', 'user1')
예제 #7
0
    def test_list_fields_set(self):
        req = MockRequest(self.env, method='POST', authname='has_bm',
                          path_info='/batchmodify', args={
            'batchmod_mode_keywords': '=',
            'batchmod_primary_keywords': 'orange',
            'batchmod_secondary_keywords': '*****',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        batch = BatchModifyModule(self.env)
        self.assertTrue(batch.match_request(req))
        with self.assertRaises(RequestDone):
            batch.process_request(req)

        self.assertFieldValue(1, 'keywords', 'orange')
        self.assertFieldValue(2, 'keywords', 'orange')
예제 #8
0
    def test_list_fields_addrem(self):
        req = MockRequest(self.env, method='POST', authname='has_bm',
                          path_info='/batchmodify', args={
            'batchmod_mode_keywords': '+-',
            'batchmod_primary_keywords': 'one three four',
            'batchmod_secondary_keywords': 'baz missing',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        batch = BatchModifyModule(self.env)
        self.assertTrue(batch.match_request(req))
        with self.assertRaises(RequestDone):
            batch.process_request(req)

        self.assertFieldValue(1, 'keywords', 'foo, one, three, four')
        self.assertFieldValue(2, 'keywords', 'two, one, three, four')
예제 #9
0
    def test_require_post_method(self):
        """Request must use POST method."""
        module = BatchModifyModule(self.env)
        req = MockRequest(self.env, method='GET', path_info='/batchmodify')
        req.session['query_href'] = req.href.query()

        self.assertTrue(module.match_request(req))
        with self.assertRaises(HTTPBadRequest):
            module.process_request(req)

        req = MockRequest(self.env, method='POST', path_info='/batchmodify',
                          args={'selected_tickets': ''})
        req.session['query_href'] = req.href.query()

        self.assertTrue(module.match_request(req))
        with self.assertRaises(RequestDone):
            module.process_request(req)
예제 #10
0
    def test_validate_select_fields(self):
        """The select field values are validated."""
        req = MockRequest(self.env, authname='has_bm', method='POST',
                          path_info='/batchmodify', args={
            'batchmod_value_component': 'component3',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        module = BatchModifyModule(self.env)
        self.assertTrue(module.match_request(req))
        with self.assertRaises(RequestDone):
            module.process_request(req)

        self.assertEqual(1, len(req.chrome['warnings']))
        self.assertEqual('The ticket field <strong>component</strong> is '
                         'invalid: "component3" is not a valid value',
                         unicode(req.chrome['warnings'][0]))
예제 #11
0
    def test_validate_time_fields(self):
        """The time fields are validated."""
        module = BatchModifyModule(self.env)
        req1 = MockRequest(self.env,
                           authname='has_bm',
                           method='POST',
                           path_info='/batchmodify',
                           args={
                               'batchmod_value_time1': '2016-01-02T12:34:56Z',
                               'action': 'leave',
                               'selected_tickets': '1,2',
                           })
        req2 = MockRequest(self.env,
                           authname='has_bm',
                           method='POST',
                           path_info='/batchmodify',
                           args={
                               'batchmod_value_time1': 'invalid',
                               'action': 'leave',
                               'selected_tickets': '1,2',
                           })
        dt = datetime(2016, 1, 2, 12, 34, 56, tzinfo=utc)

        self.assertTrue(module.match_request(req1))
        with self.assertRaises(RequestDone):
            module.process_request(req1)

        self.assertEqual(dt, model.Ticket(self.env, 1)['time1'])
        self.assertEqual(dt, model.Ticket(self.env, 2)['time1'])
        self.assertEqual([], req1.chrome['warnings'])

        self.assertTrue(module.match_request(req2))
        with self.assertRaises(RequestDone):
            module.process_request(req2)

        self.assertEqual(1, len(req2.chrome['warnings']))
        self.assertRegexpMatches(
            unicode(req2.chrome['warnings'][0]),
            'The ticket field <strong>Time1</strong> is invalid: "invalid" '
            'is an invalid date, or the date format is not known. '
            'Try "[^"]+" or "[^"]+" instead.')
        self.assertEqual(dt, model.Ticket(self.env, 1)['time1'])
        self.assertEqual(dt, model.Ticket(self.env, 2)['time1'])
예제 #12
0
    def test_action_with_side_effects(self):
        """Actions can have operations with side effects."""
        req = MockRequest(self.env, method='POST', authname='has_bm',
                          path_info='/batchmodify', args={
            'action': 'reassign',
            'action_reassign_reassign_owner': 'user3',
            'batchmod_value_comment': '',
            'selected_tickets': '1,2',
        })

        batch = BatchModifyModule(self.env)
        self.assertTrue(batch.match_request(req))
        with self.assertRaises(RequestDone):
            batch.process_request(req)

        self.assertFieldValue(1, 'owner', 'user3')
        self.assertFieldValue(2, 'owner', 'user3')
        self.assertFieldValue(1, 'status', 'assigned')
        self.assertFieldValue(2, 'status', 'assigned')
예제 #13
0
    def test_modify_summary_and_description(self):
        """The ticket summary and description cannot be modified."""
        req = MockRequest(self.env, authname='has_ta_&_bm', method='POST',
                          path_info='/batchmodify', args={
            'batchmod_value_summary': 'the new summary',
            'batchmod_value_description': 'the new description',
            'batchmod_value_comment': '',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        module = BatchModifyModule(self.env)
        self.assertTrue(module.match_request(req))
        with self.assertRaises(RequestDone):
            module.process_request(req)

        self.assertFieldValue(1, 'description', 'the desc')
        self.assertFieldValue(1, 'summary', 'Ticket 1')
        self.assertFieldValue(2, 'description', 'the desc')
        self.assertFieldValue(2, 'summary', 'Ticket 2')
예제 #14
0
    def test_ticket_manipulators(self):
        """The ticket manipulators are called to valid the ticket."""
        module = BatchModifyModule(self.env)
        self._insert_component('component3')
        self._insert_component('component4')
        self.env.enable_component(self.ticket_manipulators[0])
        self.env.enable_component(self.ticket_manipulators[1])
        req1 = MockRequest(self.env, authname='has_bm', method='POST',
                           path_info='/batchmodify', args={
            'batchmod_value_component': 'component3',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        self.assertTrue(module.match_request(req1))
        with self.assertRaises(RequestDone):
            module.process_request(req1)

        self.assertEqual(1, len(req1.chrome['warnings']))
        self.assertEqual("The ticket field <strong>component</strong> is "
                         "invalid: Invalid Component",
                         unicode(req1.chrome['warnings'][0]))
        self.assertFieldValue(1, 'component', 'component1')
        self.assertFieldValue(2, 'component', 'component2')

        req2 = MockRequest(self.env, authname='has_bm', method='POST',
                           path_info='/batchmodify', args={
            'batchmod_value_component': 'component4',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        self.assertTrue(module.match_request(req2))
        with self.assertRaises(RequestDone):
            module.process_request(req2)

        self.assertEqual([], req2.chrome['warnings'])
        self.assertFieldValue(1, 'component', 'component4')
        self.assertFieldValue(2, 'component', 'component4')

        req3 = MockRequest(self.env, authname='has_bm', method='POST',
                           path_info='/batchmodify', args={
            'batchmod_value_comment': 'this comment has the badword!',
            'batchmod_value_component': 'component3',
            'action': 'leave',
            'selected_tickets': '1,2',
        })

        self.assertTrue(module.match_request(req3))
        with self.assertRaises(RequestDone):
            module.process_request(req3)

        self.assertEqual("The ticket comment is invalid: Word is not allowed "
                         "in comment", unicode(req3.chrome['warnings'][0]))
        self.assertFieldValue(1, 'component', 'component4')
        self.assertFieldValue(2, 'component', 'component4')