Пример #1
0
class SummaryTest(TestCase):
    def setUp(self):
        self.user = User(username='******')
        self.user.save()
        
        self.topic = Topic(name='test_topic', ticket_expenses=True, grant=Grant.objects.create(full_name='g', short_name='g'))
        self.topic.save()
        
        self.ticket = Ticket(summary='foo', requested_user=self.user, topic=self.topic, rating_percentage=50)
        self.ticket.save()
        self.ticket.add_acks('content', 'docs', 'archive')
        self.ticket.expediture_set.create(description='foo', amount=200)
        self.ticket.expediture_set.create(description='foo', amount=100)
        self.ticket.mediainfo_set.create(description='foo', count=5)
        
        self.ticket2 = Ticket(summary='foo', requested_user=self.user, topic=self.topic, rating_percentage=100)
        self.ticket2.save()
        self.ticket2.add_acks('content', 'docs', 'archive')
        self.ticket2.expediture_set.create(description='foo', amount=600)
        self.ticket2.expediture_set.create(description='foo', amount=10)
        self.ticket2.mediainfo_set.create(description='foo', count=5)
        self.ticket2.mediainfo_set.create(description='foo', count=3)
    
    def test_topic_ticket_counts(self):
        self.assertEqual({'unpaid':2}, self.topic.tickets_per_payment_status())
        trans = Transaction.objects.create(date=datetime.date.today(), other=self.user, amount=150)
        trans.tickets.add(self.ticket)
        self.assertEqual({'unpaid':1, 'paid':1}, self.topic.tickets_per_payment_status())

    def test_ticket_summary(self):
        self.ticket.ticketack_set.filter(ack_type='archive').delete()
        self.ticket.rating_percentage = None
        self.ticket.save()
        
        self.assertEqual({'objects':1, 'media':5}, self.ticket.media_count())
        self.assertEqual({'count':2, 'amount':300}, self.ticket.expeditures())
        self.assertEqual(0, self.ticket.accepted_expeditures())
        
        self.ticket.rating_percentage = 50
        self.ticket.save()
        self.assertEqual(0, self.ticket.accepted_expeditures())
        
        self.ticket.add_acks('archive')
        self.assertEqual(150, self.ticket.accepted_expeditures())

    def test_topic_summary(self):
        self.assertEqual({'objects':3, 'media':13}, self.topic.media_count())
        self.assertEqual({'count':4, 'amount':910}, self.topic.expeditures())
        self.assertEqual(150 + 610, self.topic.accepted_expeditures())
    
    def test_user_summary(self):
        profile = self.user.get_profile()
        self.assertEqual({'objects':3, 'media':13}, profile.media_count())
        self.assertEqual(150 + 610, profile.accepted_expeditures())
        self.assertEqual({'count':0, 'amount':None}, profile.transactions())
    
    def test_transaction_summary(self):
        def add_trans(amount):
            self.user.transaction_set.create(date=datetime.date.today(), amount=amount, description='foo')
        
        add_trans(500)
        self.assertEqual({'count':1, 'amount':500}, self.user.get_profile().transactions())
Пример #2
0
 def test_ticket_edit(self):
     topic = Topic(name='topic', grant=Grant.objects.create(full_name='g', short_name='g'))
     topic.save()
     
     password = '******'
     user = User(username='******')
     user.set_password(password)
     user.save()
     
     ticket = Ticket(summary='ticket', topic=topic, requested_user=None, requested_text='foo')
     ticket.save()
     ticket.add_acks('close')
     
     c = Client()
     response = c.get(reverse('edit_ticket', kwargs={'pk':ticket.id}))
     self.assertEqual(302, response.status_code) # should be redirect to login page
     
     c.login(username=user.username, password=password)
     response = c.get(reverse('edit_ticket', kwargs={'pk':ticket.id}))
     self.assertEqual(403, response.status_code) # denies edit of non-own ticket
     
     ticket.requested_user = user
     ticket.requested_text = ''
     ticket.save()
     response = c.get(reverse('edit_ticket', kwargs={'pk':ticket.id}))
     self.assertEqual(403, response.status_code) # still deny edit, ticket locked
     
     ticket.ticketack_set.filter(ack_type='close').delete()
     response = c.get(reverse('edit_ticket', kwargs={'pk':ticket.id}))
     self.assertEqual(200, response.status_code) # now it should pass
     
     # try to submit the form
     response = c.post(reverse('edit_ticket', kwargs={'pk':ticket.id}), {
             'summary': 'new summary',
             'topic': ticket.topic.id,
             'description': 'new desc',
             'mediainfo-INITIAL_FORMS': '0',
             'mediainfo-TOTAL_FORMS': '0',
             'expediture-INITIAL_FORMS': '0',
             'expediture-TOTAL_FORMS': '0',
         })
     self.assertRedirects(response, reverse('ticket_detail', kwargs={'pk':ticket.id}))
     
     # check changed ticket data
     ticket = Ticket.objects.get(id=ticket.id)
     self.assertEqual(user, ticket.requested_user)
     self.assertEqual('new summary', ticket.summary)
     self.assertEqual('new desc', ticket.description)
     
     # b0rked media item aborts the submit
     response = c.post(reverse('edit_ticket', kwargs={'pk':ticket.id}), {
             'summary': 'ticket',
             'topic': ticket.topic.id,
             'description': 'some desc',
             'mediainfo-INITIAL_FORMS': '0',
             'mediainfo-TOTAL_FORMS': '1',
             'mediainfo-0-count': 'foo',
             'mediainfo-0-description': 'image 1',
             'mediainfo-0-url': 'http://www.example.com/image1.jpg',
             'expediture-INITIAL_FORMS': '0',
             'expediture-TOTAL_FORMS': '0',
         })
     self.assertEqual(200, response.status_code)
     self.assertEqual('Enter a whole number.', response.context['mediainfo'].forms[0].errors['count'][0])
     
     # b0rked expediture items aborts the submit
     response = c.post(reverse('edit_ticket', kwargs={'pk':ticket.id}), {
             'summary': 'ticket',
             'topic': ticket.topic.id,
             'description': 'some desc',
             'mediainfo-INITIAL_FORMS': '0',
             'mediainfo-TOTAL_FORMS': '0',
             'expediture-INITIAL_FORMS': '0',
             'expediture-TOTAL_FORMS': '1',
             'expediture-0-description': 'foo',
             'expediture-0-amount': '',
         })
     self.assertEqual(200, response.status_code)
     self.assertEqual('This field is required.', response.context['expeditures'].forms[0].errors['amount'][0])
     
     # add some inline items
     response = c.post(reverse('edit_ticket', kwargs={'pk':ticket.id}), {
             'summary': 'new summary',
             'topic': ticket.topic.id,
             'description': 'new desc',
             'mediainfo-INITIAL_FORMS': '0',
             'mediainfo-TOTAL_FORMS': '3',
             'mediainfo-0-count': '',
             'mediainfo-0-description': 'image 1',
             'mediainfo-0-url': 'http://www.example.com/image1.jpg',
             'mediainfo-1-count': '',
             'mediainfo-1-description': '', 
             'mediainfo-1-url': '',
             'mediainfo-2-count': '3',
             'mediainfo-2-description': 'image 2 - group',
             'mediainfo-2-url': 'http://www.example.com/imagegroup/',
             'expediture-INITIAL_FORMS': '0',
             'expediture-TOTAL_FORMS': '2',
             'expediture-0-description': 'ten fifty',
             'expediture-0-amount': '10.50',
             'expediture-1-description': 'hundred',
             'expediture-1-amount': '100',
         })
     self.assertRedirects(response, reverse('ticket_detail', kwargs={'pk':ticket.id}))
     media = ticket.mediainfo_set.order_by('description')
     self.assertEqual(2, len(media))
     self.assertEqual('image 1', media[0].description)
     self.assertEqual('http://www.example.com/image1.jpg', media[0].url)
     self.assertEqual(None, media[0].count)
     self.assertEqual('image 2 - group', media[1].description)
     self.assertEqual('http://www.example.com/imagegroup/', media[1].url)
     self.assertEqual(3, media[1].count)
     expeditures = ticket.expediture_set.order_by('amount')
     self.assertEqual(2, len(expeditures))
     self.assertEqual('ten fifty', expeditures[0].description)
     self.assertEqual(10.5, expeditures[0].amount)
     self.assertEqual('hundred', expeditures[1].description)
     self.assertEqual(100, expeditures[1].amount)
     
     # edit inline items
     response = c.post(reverse('edit_ticket', kwargs={'pk':ticket.id}), {
             'summary': 'new summary',
             'topic': ticket.topic.id,
             'description': 'new desc',
             'mediainfo-INITIAL_FORMS': '2',
             'mediainfo-TOTAL_FORMS': '3',
             'mediainfo-0-id': media[0].id,
             'mediainfo-0-count': '1',
             'mediainfo-0-description': 'image 1 - edited',
             'mediainfo-0-url': 'http://www.example.com/second.jpg',
             'mediainfo-1-id': media[1].id,
             'mediainfo-1-DELETE': 'on',
             'mediainfo-1-count': '3',
             'mediainfo-1-description': 'image 2 - group',
             'mediainfo-1-url': 'http://www.example.com/imagegroup/',
             'mediainfo-2-count': '',
             'mediainfo-2-description': '', 
             'mediainfo-2-url': '',
             'expediture-INITIAL_FORMS': '2',
             'expediture-TOTAL_FORMS': '3',
             'expediture-0-id': expeditures[0].id,
             'expediture-0-description': 'ten fifty',
             'expediture-0-amount': '10.50',
             'expediture-0-DELETE': 'on',
             'expediture-1-id': expeditures[1].id,
             'expediture-1-description': 'hundred+1',
             'expediture-1-amount': '101',
             'expediture-2-description': '',
             'expediture-2-amount': '',
         })
     self.assertRedirects(response, reverse('ticket_detail', kwargs={'pk':ticket.id}))
     media = ticket.mediainfo_set.all()
     self.assertEqual(1, len(media))
     self.assertEqual('image 1 - edited', media[0].description)
     self.assertEqual('http://www.example.com/second.jpg', media[0].url)
     self.assertEqual(1, media[0].count)
     expeditures = ticket.expediture_set.order_by('amount')
     self.assertEqual(1, len(expeditures))
     self.assertEqual('hundred+1', expeditures[0].description)
     self.assertEqual(101, expeditures[0].amount)
Пример #3
0
class SimpleTicketTest(TestCase):
    def setUp(self):
        self.topic = Topic(name='topic1', grant=Grant.objects.create(full_name='g', short_name='g', slug='g'))
        self.topic.save()
        
        self.ticket1 = Ticket(summary='foo', requested_text='req1', topic=self.topic, description='foo foo')
        self.ticket1.save()
        
        self.ticket2 = Ticket(summary='bar', requested_text='req2', topic=self.topic, description='bar bar')
        self.ticket2.save()
    
    def test_ticket_sort_date(self):
        # sort date is equal to event date (when applicable) and default to creation date
        self.assertEqual(self.ticket1.created.date(), self.ticket1.sort_date)
        
        self.ticket1.event_date = datetime.date(2011, 10, 13)
        self.ticket1.save()
        self.assertEqual(datetime.date(2011, 10, 13), self.ticket1.sort_date)
        
        self.ticket1.event_date = None
        self.ticket1.save()
        self.assertEqual(self.ticket1.created.date(), self.ticket1.sort_date)
    
    def test_ticket_timestamps(self):
        self.assertTrue(self.ticket2.created > self.ticket1.created) # check ticket 2 is newer
        
        # check new update of ticket changed updated ts
        old_updated = self.ticket1.updated
        self.ticket1.description = 'updated description'
        self.ticket1.save()
        self.assertTrue(self.ticket1.updated > old_updated)
    
    def test_ticket_list(self):
        response = Client().get(reverse('ticket_list'))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.context['ticket_list']), 2)

    def test_ticket_detail(self):
        response = Client().get(reverse('ticket_detail', kwargs={'pk':self.ticket1.id}))
        self.assertEqual(response.status_code, 200)
    
    def test_ticket_url_escape(self):
        url = 'http://meta.wikimedia.org/wiki/Mediagrant/Fotografie_um%C4%9Bleck%C3%BDch_pam%C3%A1tek_v_%C4%8Cesk%C3%A9m_Krumlov%C4%9B'
        self.ticket1.description = '<a href="%s">foo link</a>' % url
        self.ticket1.save()
        response = Client().get(reverse('ticket_detail', kwargs={'pk':self.ticket1.id}))
        self.assertContains(response, 'href="%s"' % url, 1)
    
    def test_ticket_absolute_url(self):
        t = self.ticket1
        self.assertEqual(reverse('ticket_detail', kwargs={'pk':t.id}), t.get_absolute_url())
    
    def test_topic_list(self):
        response = Client().get(reverse('topic_list'))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.context['topic_list']), 1)
    
    def test_javascript_topic_list(self):
        response = Client().get(reverse('topics_js'))
        self.assertEqual(response.status_code, 200)
    
    def test_topic_detail(self):
        response = Client().get(reverse('topic_detail', kwargs={'pk':self.topic.id}))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.context['topic'].ticket_set.all()), 2)
    
    def test_topic_absolute_url(self):
        t = self.topic
        self.assertEqual(reverse('topic_detail', kwargs={'pk':t.id}), t.get_absolute_url())
    
    def _test_one_feed(self, url_name, topic_id, expected_ticket_count):
        url_kwargs = {'pk':topic_id} if topic_id is not None else {}
        response = Client().get(reverse(url_name, kwargs=url_kwargs))
        self.assertEqual(response.status_code, 200)
        items_in_response = re.findall(r'<item>', response.content) # ugly, mostly works
        self.assertEqual(expected_ticket_count, len(items_in_response))
    
    def test_feeds(self):
        self.ticket1.add_acks('user_content')
        self._test_one_feed('ticket_list_feed', None, 2)
        self._test_one_feed('ticket_submitted_feed', None, 1)
        self._test_one_feed('topic_ticket_feed', self.topic.id, 2)
        self._test_one_feed('topic_submitted_ticket_feed', self.topic.id, 1)
Пример #4
0
class SummaryTest(TestCase):
    def setUp(self):
        self.user = User(username='******')
        self.user.save()

        self.topic = Topic(name='test_topic', ticket_expenses=True, grant=Grant.objects.create(full_name='g', short_name='g', slug='g'))
        self.topic.save()

        self.ticket = Ticket(name='foo', requested_user=self.user, topic=self.topic, rating_percentage=50)
        self.ticket.save()
        self.ticket.add_acks('content', 'docs', 'archive')
        self.ticket.expediture_set.create(description='foo', amount=200)
        self.ticket.expediture_set.create(description='foo', amount=100)
        self.ticket.mediainfoold_set.create(description='foo', count=5)
        self.ticket.mediainfo_set.create(name='test.jpg')
        self.ticket.mediainfo_set.create(name='test2.jpg')

        self.ticket2 = Ticket(name='foo', requested_user=self.user, topic=self.topic, rating_percentage=100)
        self.ticket2.save()
        self.ticket2.add_acks('content', 'docs', 'archive')
        self.ticket2.expediture_set.create(description='foo', amount=600)
        self.ticket2.expediture_set.create(description='foo', amount=10)
        self.ticket2.mediainfoold_set.create(description='foo', count=5)
        self.ticket2.mediainfoold_set.create(description='foo', count=3)
        self.ticket2.mediainfo_set.create(name='test.jpg')

    def test_topic_ticket_counts(self):
        self.assertEqual({'unpaid': 2}, self.topic.tickets_per_payment_status())
        for e in self.ticket.expediture_set.all():
            e.paid = True
            e.save()
        self.assertEqual({'unpaid': 1, 'paid': 1}, self.topic.tickets_per_payment_status())

    def test_topic_ticket_counts2(self):
        """ change event_date (and thus sort_date) of one ticket, make sure it
            does not break grouping
        """
        self.ticket.event_date = datetime.date(2016, 1, 1)
        self.ticket.save()
        self.assertEqual({'unpaid': 2}, self.topic.tickets_per_payment_status())

    def test_ticket_name(self):
        self.ticket.ticketack_set.filter(ack_type='content').delete()
        self.ticket.rating_percentage = None
        self.ticket.save()

        self.assertEqual(7, self.ticket.media_count())
        self.assertEqual({'objects': 1, 'media': 5}, self.ticket.media_old_count())
        self.assertEqual({'count': 2, 'amount': 300}, self.ticket.expeditures())
        self.assertEqual(0, self.ticket.accepted_expeditures())

        self.ticket.rating_percentage = 50
        self.ticket.save()
        self.assertEqual(0, self.ticket.accepted_expeditures())

        self.ticket.add_acks('content')
        self.assertEqual(150, self.ticket.accepted_expeditures())

    def test_topic_name(self):
        self.assertEqual(16, self.topic.media_count())
        self.assertEqual({'count': 4, 'amount': 910}, self.topic.expeditures())
        self.assertEqual(150 + 610, self.topic.accepted_expeditures())

    def test_user_name(self):
        profile = self.user.trackerprofile
        self.assertEqual(16, profile.media_count())
        self.assertEqual(150 + 610, profile.accepted_expeditures())

    def test_topic_finance(self):
        response = Client().get(reverse('topic_finance'))
        self.assertEqual(response.status_code, 200)
Пример #5
0
    def test_ticket_edit(self):
        topic = Topic(name='topic', grant=Grant.objects.create(full_name='g', short_name='g', slug='g'))
        topic.save()

        statutory_topic = Topic(name='statutory_topic', ticket_statutory_declaration=True, grant=Grant.objects.get(short_name='g'))
        statutory_topic.save()

        subtopic = Subtopic(name='subtopic', topic=topic)
        subtopic2 = Subtopic(name='subtopic2', topic=statutory_topic)
        subtopic.save()
        subtopic2.save()

        password = '******'
        user = User(username='******')
        user.set_password(password)
        user.save()

        ticket = Ticket(name='ticket', topic=topic, requested_user=None, requested_text='foo')
        ticket.save()
        ticket.add_acks('close')

        c = Client()
        response = c.get(reverse('edit_ticket', kwargs={'pk': ticket.id}))
        self.assertEqual(302, response.status_code)  # should be redirect to login page

        c.login(username=user.username, password=password)
        response = c.get(reverse('edit_ticket', kwargs={'pk': ticket.id}))
        self.assertEqual(403, response.status_code)  # denies edit of non-own ticket

        ticket.requested_user = user
        ticket.requested_text = ''
        ticket.save()
        response = c.get(reverse('edit_ticket', kwargs={'pk': ticket.id}))
        self.assertEqual(403, response.status_code)  # still deny edit, ticket locked

        ticket.ticketack_set.filter(ack_type='close').delete()
        response = c.get(reverse('edit_ticket', kwargs={'pk': ticket.id}))
        self.assertEqual(200, response.status_code)  # now it should pass

        # try to submit the form
        response = c.post(reverse('edit_ticket', kwargs={'pk': ticket.id}), {
            'name': 'new name',
            'topic': ticket.topic.id,
            'description': 'new desc',
            'deposit': '0',
            'expediture-INITIAL_FORMS': '0',
            'expediture-TOTAL_FORMS': '0',
            'preexpediture-INITIAL_FORMS': '0',
            'preexpediture-TOTAL_FORMS': '0',
        })
        self.assertRedirects(response, reverse('ticket_detail', kwargs={'pk': ticket.id}))

        # check changed ticket data
        ticket = Ticket.objects.get(id=ticket.id)
        self.assertEqual(user, ticket.requested_user)
        self.assertEqual('new name', ticket.name)
        self.assertEqual('new desc', ticket.description)

        # b0rked expediture items aborts the submit
        response = c.post(reverse('edit_ticket', kwargs={'pk': ticket.id}), {
            'name': 'ticket',
            'topic': ticket.topic.id,
            'description': 'some desc',
            'deposit': '0',
            'expediture-INITIAL_FORMS': '0',
            'expediture-TOTAL_FORMS': '1',
            'expediture-0-description': 'foo',
            'expediture-0-amount': '',
            'preexpediture-INITIAL_FORMS': '0',
            'preexpediture-TOTAL_FORMS': '0',
        })
        self.assertEqual(200, response.status_code)
        self.assertEqual('This field is required.', response.context['expeditures'].forms[0].errors['amount'][0])

        # add some inline items
        response = c.post(reverse('edit_ticket', kwargs={'pk': ticket.id}), {
            'name': 'new name',
            'topic': ticket.topic.id,
            'description': 'new desc',
            'deposit': '0',
            'expediture-INITIAL_FORMS': '0',
            'expediture-TOTAL_FORMS': '2',
            'expediture-0-description': 'ten fifty',
            'expediture-0-amount': '10.50',
            'expediture-1-description': 'hundred',
            'expediture-1-amount': '100',
            'preexpediture-INITIAL_FORMS': '0',
            'preexpediture-TOTAL_FORMS': '0',
        })
        self.assertRedirects(response, reverse('ticket_detail', kwargs={'pk': ticket.id}))
        expeditures = ticket.expediture_set.order_by('amount')
        self.assertEqual(2, len(expeditures))
        self.assertEqual('ten fifty', expeditures[0].description)
        self.assertEqual(10.5, expeditures[0].amount)
        self.assertEqual('hundred', expeditures[1].description)
        self.assertEqual(100, expeditures[1].amount)

        # edit inline items
        response = c.post(reverse('edit_ticket', kwargs={'pk': ticket.id}), {
            'name': 'new name',
            'topic': ticket.topic.id,
            'description': 'new desc',
            'deposit': '0',
            'expediture-INITIAL_FORMS': '2',
            'expediture-TOTAL_FORMS': '3',
            'expediture-0-id': expeditures[0].id,
            'expediture-0-description': 'ten fifty',
            'expediture-0-amount': '10.50',
            'expediture-0-DELETE': 'on',
            'expediture-1-id': expeditures[1].id,
            'expediture-1-description': 'hundred+1',
            'expediture-1-amount': '101',
            'expediture-2-description': '',
            'expediture-2-amount': '',
            'preexpediture-INITIAL_FORMS': '0',
            'preexpediture-TOTAL_FORMS': '0',
        })
        self.assertRedirects(response, reverse('ticket_detail', kwargs={'pk': ticket.id}))
        expeditures = ticket.expediture_set.order_by('amount')
        self.assertEqual(1, len(expeditures))
        self.assertEqual('hundred+1', expeditures[0].description)
        self.assertEqual(101, expeditures[0].amount)

        # add preexpeditures, and amount flag preack
        deposit_amount = Decimal('12324.37')
        ticket = Ticket.objects.get(id=ticket.id)
        ticket.deposit = deposit_amount
        ticket.preexpediture_set.create(description='some preexp', amount=15)
        ticket.save()
        ticket.add_acks('precontent')

        # edit should work and ignore new data
        response = c.post(reverse('edit_ticket', kwargs={'pk': ticket.id}), {
            'name': 'new name',
            'topic': ticket.topic.id,
            'description': 'new desc',
            'deposit': '333',
            'expediture-INITIAL_FORMS': '0',
            'expediture-TOTAL_FORMS': '0',
            'preexpediture-INITIAL_FORMS': '0',
            'preexpediture-TOTAL_FORMS': '0',
        })
        self.assertRedirects(response, reverse('ticket_detail', kwargs={'pk': ticket.id}))
        ticket = Ticket.objects.get(id=ticket.id)
        self.assertEqual(deposit_amount, ticket.deposit)
        self.assertEqual(1, ticket.preexpediture_set.count())

        # also, edit should work and not fail on missing preack-ignored fields
        response = c.post(reverse('edit_ticket', kwargs={'pk': ticket.id}), {
            'name': 'new name',
            'topic': ticket.topic.id,
            'description': 'new desc',
            'expediture-INITIAL_FORMS': '0',
            'expediture-TOTAL_FORMS': '0',
        })
        self.assertRedirects(response, reverse('ticket_detail', kwargs={'pk': ticket.id}))
        ticket = Ticket.objects.get(id=ticket.id)
        self.assertEqual(deposit_amount, ticket.deposit)
        self.assertEqual(1, ticket.preexpediture_set.count())
Пример #6
0
class SimpleTicketTest(TestCase):
    def setUp(self):
        self.topic = Topic(name='topic1', grant=Grant.objects.create(full_name='g', short_name='g', slug='g'))
        self.topic.save()

        self.ticket1 = Ticket(name='foo', requested_text='req1', topic=self.topic, description='foo foo')
        self.ticket1.save()

        self.ticket2 = Ticket(name='bar', requested_text='req2', topic=self.topic, description='bar bar')
        self.ticket2.save()

    def test_ticket_timestamps(self):
        self.assertTrue(self.ticket2.created > self.ticket1.created)  # check ticket 2 is newer

        # check new update of ticket changed updated ts
        old_updated = self.ticket1.updated
        self.ticket1.description = 'updated description'
        self.ticket1.save()
        self.assertTrue(self.ticket1.updated > old_updated)

    def test_ticket_list(self):
        response = Client().get(reverse('ticket_list'))
        self.assertEqual(response.status_code, 200)

    def test_ticket_json(self):
        for langcode, langname in settings.LANGUAGES:
            response = Client().get(reverse('tickets', kwargs={'lang': langcode}))
            self.assertEqual(response.status_code, 200)

    def test_ticket_detail(self):
        response = Client().get(reverse('ticket_detail', kwargs={'pk': self.ticket1.id}))
        self.assertEqual(response.status_code, 200)

    def test_ticket_absolute_url(self):
        t = self.ticket1
        self.assertEqual(reverse('ticket_detail', kwargs={'pk': t.id}), t.get_absolute_url())

    def test_topic_list(self):
        response = Client().get(reverse('topic_list'))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.context['topic_list']), 1)

    def test_topic_detail(self):
        response = Client().get(reverse('topic_detail', kwargs={'pk': self.topic.id}))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.context['topic'].ticket_set.all()), 2)

    def test_topic_absolute_url(self):
        t = self.topic
        self.assertEqual(reverse('topic_detail', kwargs={'pk': t.id}), t.get_absolute_url())

    def _test_one_feed(self, url_name, topic_id, expected_ticket_count):
        url_kwargs = {'pk': topic_id} if topic_id is not None else {}
        response = Client().get(reverse(url_name, kwargs=url_kwargs))
        self.assertEqual(response.status_code, 200)
        items_in_response = re.findall(r'<item>', response.content.decode('utf-8'))  # ugly, mostly works
        self.assertEqual(expected_ticket_count, len(items_in_response))

    def test_feeds(self):
        self.ticket1.add_acks('user_content')
        self._test_one_feed('ticket_list_feed', None, 2)
        self._test_one_feed('ticket_submitted_feed', None, 1)
        self._test_one_feed('topic_ticket_feed', self.topic.id, 2)
        self._test_one_feed('topic_submitted_ticket_feed', self.topic.id, 1)

    def test_historical(self):
        self.ticket1.imported = True
        self.ticket1.save()
        self.assertEqual(self.ticket1.state_str(), 'historical')

    def test_is_completed(self):
        self.assertFalse(self.ticket1.is_completed)
        self.ticket1.add_acks('archive')
        self.assertTrue(self.ticket1.is_completed)
        self.ticket1.ticketack_set.filter(ack_type='archive').delete()
        self.assertFalse(self.ticket1.is_completed)

        self.ticket1.add_acks('close')
        self.assertTrue(self.ticket1.is_completed)
        self.ticket1.ticketack_set.filter(ack_type='close').delete()
        self.assertFalse(self.ticket1.is_completed)