<commit_before>import sqlite3
from twisted.trial.unittest import TestCase
from twisted.python.util import sibpath
from twisted.internet import defer
from frack.db import TicketStore, DBStore, UnauthorizedError, NotFoundError
from norm.sqlite import SqliteTranslator
from norm.common import BlockingRunner
from norm.operation import SQL



class TicketStoreTest(TestCase):


    def populatedStore(self):
        db = sqlite3.connect(":memory:")
        db.executescript(open(sibpath(__file__, "trac_test.sql")).read())
        translator = SqliteTranslator()
        runner = BlockingRunner(db, translator)
        store = TicketStore(runner, user='foo')
        return store


    @defer.inlineCallbacks
    def test_createTicket_minimal(self):
        """
        You can create tickets
        """
        store = self.populatedStore()
        # a minimal ticket
        data = {
            'summary': 'the summary',
            }
        ticket_id = yield store.createTicket(data)
        self.assertNotEqual(ticket_id, None,
            "Should return the new id: %s" % (ticket_id,))

        ticket = yield store.fetchTicket(ticket_id)
        # Assert for each of the fields:
        # http://trac.edgewall.org/wiki/TracDev/DatabaseSchema/TicketSystem#Tableticket
        # XXX should these be '' instead of None?
        self.assertEqual(ticket['id'], ticket_id)
        self.assertEqual(ticket['type'], None)
        self.assertTrue(ticket['time'])
        self.assertTrue(ticket['changetime'])
        self.assertEqual(ticket['time'], ticket['changetime'])

        self.assertEqual(ticket['component'], None)
        self.assertEqual(ticket['severity'], None)
        self.assertEqual(ticket['priority'], None)
        self.assertEqual(ticket['owner'], None)
        self.assertEqual(ticket['reporter'], 'foo', "Should use the Store's "
                         "user as the report")
        self.assertEqual(ticket['cc'], None)
        self.assertEqual(ticket['version'], None)
        self.assertEqual(ticket['milestone'], None)
        self.assertEqual(ticket['status'], 'new')
        self.assertEqual(ticket['resolution'], None)
        self.assertEqual(ticket['summary'], 'the summary')
        self.assertEqual(ticket['description'], None)
        self.assertEqual(ticket['keywords'], None)


    @defer.inlineCallbacks
    def test_createTicket_maximal(self):
        """
        You can create a ticket with all kinds of options.
        """
        store = self.populatedStore()
        # Do I need to enforce that all the values are valid options in their
        # specific join tables?
        data = {
            # do I need to enforce that this is in enum type=ticket_type? 
            'type': 'type',
            'component': 'component',
            'severity': 'severity',
            'priority': 'priority',
            'owner': 'owner',
            'cc': 'cc',
            'version': 'version',
            'milestone': 'milestone',
            'status': 'status',
            'resolution': 'resolution',
            'summary': 'summary',
            'description': 'description',
            'keywords': 'keywords',
            }
        ticket_id = yield store.createTicket(data)
        ticket = yield store.fetchTicket(ticket_id)
        
        self.assertEqual(ticket['id'], ticket_id)
        self.assertEqual(ticket['type'], 'type')
        self.assertTrue(ticket['time'])
        self.assertTrue(ticket['changetime'])
        self.assertEqual(ticket['time'], ticket['changetime'])

        self.assertEqual(ticket['component'], 'component')
        self.assertEqual(ticket['severity'], 'severity')
        self.assertEqual(ticket['priority'], 'priority')
        self.assertEqual(ticket['owner'], 'owner')
        self.assertEqual(ticket['reporter'], 'foo', "Should use the Store's "
                         "user as the report")
        self.assertEqual(ticket['cc'], 'cc')
        self.assertEqual(ticket['version'], 'version')
        self.assertEqual(ticket['milestone'], 'milestone')
        self.assertEqual(ticket['status'], 'new')
        self.assertEqual(ticket['resolution'], 'resolution')
        self.assertEqual(ticket['summary'], 'summary')
        self.assertEqual(ticket['description'], 'description')
        self.assertEqual(ticket['keywords'], 'keywords')


    @defer.inlineCallbacks
    def test_createTicket_customFields(self):
        """
        You can create a ticket with custom fields
        """
        store = self.populatedStore()

        data = {
            'branch': 'foo',
            'summary': 'something',
            'launchpad_bug': '1234',
        }
        ticket_id = yield store.createTicket(data)
        ticket = yield store.fetchTicket(ticket_id)

        self.assertEqual(ticket['branch'], 'foo')
        self.assertEqual(ticket['summary'], 'something')
        self.assertEqual(ticket['launchpad_bug'], '1234')


    @defer.inlineCallbacks
    def test_createTicket_customFields_fail(self):
        """
        If the custom fields can't be created, the whole transaction should be
        rolled back and the ticket should not be added.
        """
        store = self.populatedStore()

        count = yield store.runner.run(SQL('select count(*) from ticket'))

        bad_data = {
            'summary': 'good summary',
            'branch': object(),
        }
        try:
            ticket_id = yield store.createTicket(bad_data)
        except Exception as e:
            pass
        else:
            self.fail("Should have raised an exception")

        after_count = yield store.runner.run(SQL('select count(*) from ticket'))
        self.assertEqual(count, after_count, "Should NOT have created a ticket")


    @defer.inlineCallbacks
    def test_fetchTicket(self):
        """
        You can fetch existing ticket information
        """
        store = self.populatedStore()

        ticket = yield store.fetchTicket(5622)

        # look in test/trac_test.sql to see the values
        self.assertEqual(ticket['id'], 5622)
        self.assertEqual(ticket['type'], 'enhancement')
        self.assertEqual(ticket['time'], 1333844383)
        self.assertEqual(ticket['changetime'], 1334260992)
        self.assertEqual(ticket['component'], 'core')
        self.assertEqual(ticket['severity'], None)
        self.assertEqual(ticket['priority'], 'normal')
        self.assertEqual(ticket['owner'], '')
        self.assertEqual(ticket['reporter'], 'exarkun')
        self.assertEqual(ticket['cc'], '')
        self.assertEqual(ticket['version'], None)
        self.assertEqual(ticket['milestone'], '')
        self.assertEqual(ticket['status'], 'closed')
        self.assertEqual(ticket['resolution'], 'duplicate')
        # ignore summary and description because they're long
        self.assertEqual(ticket['keywords'], 'tests')

        # custom fields
        self.assertEqual(ticket['branch'], 'branches/tcp-endpoints-tests-refactor-5622')
        self.assertEqual(ticket['branch_author'], 'exarkun')
        self.assertEqual(ticket['launchpad_bug'], '')


    @defer.inlineCallbacks
    def test_fetchComments(self):
        """
        You can get all the comments for a ticket.
        """
        store = self.populatedStore()

        comments = yield store.fetchComments(5622)

        # look in test/trac_test.sql to see where these assertions come from
        self.assertEqual(len(comments), 4, "There are 4 comments")
        c = comments[0]
        self.assertEqual(c['ticket'], 5622)
        self.assertEqual(c['time'], 1333844456)
        self.assertEqual(c['author'], 'exarkun')
        self.assertEqual(c['number'], '1')
        self.assertEqual(c['comment'], "(In [34131]) Branching to 'tcp-endpoints-tests-refactor-5622'")
        self.assertEqual(len(c['changes']), 2)
        self.assertIn({
            'field': 'branch',
            'oldvalue': '',
            'newvalue': 'branches/tcp-endpoints-tests-refactor-5622',
        }, c['changes'])
        self.assertIn({
            'field': 'branch_author',
            'oldvalue': '',
            'newvalue': 'exarkun',<commit_msg>Add test for comments.  Oops<commit_after>import sqlite3
from twisted.trial.unittest import TestCase
from twisted.python.util import sibpath
from twisted.internet import defer
from frack.db import TicketStore, DBStore, UnauthorizedError, NotFoundError
from norm.sqlite import SqliteTranslator
from norm.common import BlockingRunner
from norm.operation import SQL



class TicketStoreTest(TestCase):


    def populatedStore(self):
        db = sqlite3.connect(":memory:")
        db.executescript(open(sibpath(__file__, "trac_test.sql")).read())
        translator = SqliteTranslator()
        runner = BlockingRunner(db, translator)
        store = TicketStore(runner, user='foo')
        return store


    @defer.inlineCallbacks
    def test_createTicket_minimal(self):
        """
        You can create tickets
        """
        store = self.populatedStore()
        # a minimal ticket
        data = {
            'summary': 'the summary',
            }
        ticket_id = yield store.createTicket(data)
        self.assertNotEqual(ticket_id, None,
            "Should return the new id: %s" % (ticket_id,))

        ticket = yield store.fetchTicket(ticket_id)
        # Assert for each of the fields:
        # http://trac.edgewall.org/wiki/TracDev/DatabaseSchema/TicketSystem#Tableticket
        # XXX should these be '' instead of None?
        self.assertEqual(ticket['id'], ticket_id)
        self.assertEqual(ticket['type'], None)
        self.assertTrue(ticket['time'])
        self.assertTrue(ticket['changetime'])
        self.assertEqual(ticket['time'], ticket['changetime'])

        self.assertEqual(ticket['component'], None)
        self.assertEqual(ticket['severity'], None)
        self.assertEqual(ticket['priority'], None)
        self.assertEqual(ticket['owner'], None)
        self.assertEqual(ticket['reporter'], 'foo', "Should use the Store's "
                         "user as the report")
        self.assertEqual(ticket['cc'], None)
        self.assertEqual(ticket['version'], None)
        self.assertEqual(ticket['milestone'], None)
        self.assertEqual(ticket['status'], 'new')
        self.assertEqual(ticket['resolution'], None)
        self.assertEqual(ticket['summary'], 'the summary')
        self.assertEqual(ticket['description'], None)
        self.assertEqual(ticket['keywords'], None)


    @defer.inlineCallbacks
    def test_createTicket_maximal(self):
        """
        You can create a ticket with all kinds of options.
        """
        store = self.populatedStore()
        # Do I need to enforce that all the values are valid options in their
        # specific join tables?
        data = {
            # do I need to enforce that this is in enum type=ticket_type? 
            'type': 'type',
            'component': 'component',
            'severity': 'severity',
            'priority': 'priority',
            'owner': 'owner',
            'cc': 'cc',
            'version': 'version',
            'milestone': 'milestone',
            'status': 'status',
            'resolution': 'resolution',
            'summary': 'summary',
            'description': 'description',
            'keywords': 'keywords',
            }
        ticket_id = yield store.createTicket(data)
        ticket = yield store.fetchTicket(ticket_id)
        
        self.assertEqual(ticket['id'], ticket_id)
        self.assertEqual(ticket['type'], 'type')
        self.assertTrue(ticket['time'])
        self.assertTrue(ticket['changetime'])
        self.assertEqual(ticket['time'], ticket['changetime'])

        self.assertEqual(ticket['component'], 'component')
        self.assertEqual(ticket['severity'], 'severity')
        self.assertEqual(ticket['priority'], 'priority')
        self.assertEqual(ticket['owner'], 'owner')
        self.assertEqual(ticket['reporter'], 'foo', "Should use the Store's "
                         "user as the report")
        self.assertEqual(ticket['cc'], 'cc')
        self.assertEqual(ticket['version'], 'version')
        self.assertEqual(ticket['milestone'], 'milestone')
        self.assertEqual(ticket['status'], 'new')
        self.assertEqual(ticket['resolution'], 'resolution')
        self.assertEqual(ticket['summary'], 'summary')
        self.assertEqual(ticket['description'], 'description')
        self.assertEqual(ticket['keywords'], 'keywords')


    @defer.inlineCallbacks
    def test_createTicket_customFields(self):
        """
        You can create a ticket with custom fields
        """
        store = self.populatedStore()

        data = {
            'branch': 'foo',
            'summary': 'something',
            'launchpad_bug': '1234',
        }
        ticket_id = yield store.createTicket(data)
        ticket = yield store.fetchTicket(ticket_id)

        self.assertEqual(ticket['branch'], 'foo')
        self.assertEqual(ticket['summary'], 'something')
        self.assertEqual(ticket['launchpad_bug'], '1234')


    @defer.inlineCallbacks
    def test_createTicket_customFields_fail(self):
        """
        If the custom fields can't be created, the whole transaction should be
        rolled back and the ticket should not be added.
        """
        store = self.populatedStore()

        count = yield store.runner.run(SQL('select count(*) from ticket'))

        bad_data = {
            'summary': 'good summary',
            'branch': object(),
        }
        try:
            ticket_id = yield store.createTicket(bad_data)
        except Exception as e:
            pass
        else:
            self.fail("Should have raised an exception")

        after_count = yield store.runner.run(SQL('select count(*) from ticket'))
        self.assertEqual(count, after_count, "Should NOT have created a ticket")


    @defer.inlineCallbacks
    def test_fetchTicket(self):
        """
        You can fetch existing ticket information
        """
        store = self.populatedStore()

        ticket = yield store.fetchTicket(5622)

        # look in test/trac_test.sql to see the values
        self.assertEqual(ticket['id'], 5622)
        self.assertEqual(ticket['type'], 'enhancement')
        self.assertEqual(ticket['time'], 1333844383)
        self.assertEqual(ticket['changetime'], 1334260992)
        self.assertEqual(ticket['component'], 'core')
        self.assertEqual(ticket['severity'], None)
        self.assertEqual(ticket['priority'], 'normal')
        self.assertEqual(ticket['owner'], '')
        self.assertEqual(ticket['reporter'], 'exarkun')
        self.assertEqual(ticket['cc'], '')
        self.assertEqual(ticket['version'], None)
        self.assertEqual(ticket['milestone'], '')
        self.assertEqual(ticket['status'], 'closed')
        self.assertEqual(ticket['resolution'], 'duplicate')
        # ignore summary and description because they're long
        self.assertEqual(ticket['keywords'], 'tests')

        # custom fields
        self.assertEqual(ticket['branch'], 'branches/tcp-endpoints-tests-refactor-5622')
        self.assertEqual(ticket['branch_author'], 'exarkun')
        self.assertEqual(ticket['launchpad_bug'], '')

        # comments
        self.assertEqual(len(ticket['comments']), 4)


    @defer.inlineCallbacks
    def test_fetchComments(self):
        """
        You can get all the comments for a ticket.
        """
        store = self.populatedStore()

        comments = yield store.fetchComments(5622)

        # look in test/trac_test.sql to see where these assertions come from
        self.assertEqual(len(comments), 4, "There are 4 comments")
        c = comments[0]
        self.assertEqual(c['ticket'], 5622)
        self.assertEqual(c['time'], 1333844456)
        self.assertEqual(c['author'], 'exarkun')
        self.assertEqual(c['number'], '1')
        self.assertEqual(c['comment'], "(In [34131]) Branching to 'tcp-endpoints-tests-refactor-5622'")
        self.assertEqual(len(c['changes']), 2)
        self.assertIn({
            'field': 'branch',
            'oldvalue': '',
            'newvalue': 'branches/tcp-endpoints-tests-refactor-5622',
        }, c['changes'])
        self.assertIn({
            'field': 'branch_author',
            'oldvalue': '',
            'newvalue': 'exarkun',
{'fraction_non_alphanumeric': 0.1323529411764706, 'fraction_numerical': 0.009620098039215687, 'mean_word_length': 2.602074597219157, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5485078', 'n_tokens_mistral': 4610, 'n_tokens_neox': 4256, 'n_words': 970}