def setUp(self):
     unittest.TestCase.setUp(self)
     self.jira_ = SingleJira().instance()
     self.pivotal_ = SinglePivotal().instance()
     AcceptanceTesting.mapStatuses(self.jira_)
     AcceptanceTesting.mapUsers()
     pass
 def setUp(self):
     unittest.TestCase.setUp(self)
     self.jira_ = SingleJira().instance()
     self.pivotal_ = SinglePivotal().instance()
     AcceptanceTesting.mapStatuses(self.jira_)
     AcceptanceTesting.mapUsers()
     pass
 def setUp(self):
     unittest.TestCase.setUp(self)
     self.pivotal_ = SinglePivotal().instance()
     pass
class PivotalAcceptanceTest(unittest.TestCase):
    def setUp(self):
        unittest.TestCase.setUp(self)
        self.pivotal_ = SinglePivotal().instance()
        pass
    
    def tearDown(self):
        self.pivotal_.deleteAllItems()
        unittest.TestCase.tearDown(self)
    
    def test_canConnectToPivotalTrackerTestProject(self):
        tracker = self.pivotal_
        self.assertTrue(tracker.valid())
        pass

    def test_canDownloadStoriesFromPivotalTracker(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary("test_canDownloadStoriesFromPivotalTracker-1")
        tracker.update(item)
        item.withSummary("test_canDownloadStoriesFromPivotalTracker-2")
        tracker.update(item)
        itemIterator = tracker.items()
        next(itemIterator)
        next(itemIterator)
        self.assertRaises(StopIteration, next, itemIterator)
        pass
    
    def test_canAddStoryToPivotal(self):
        tracker = self.pivotal_
        name = "test_canAddStoryToPivotal"
        description = "this is a test"
        item = PivotalTrackerItem(Story()).withSummary(name).withDescription(description)
        tracker.update(item)
        item = next(tracker.items())
        self.assertEqual(item.summary(), name)
        self.assertEqual(item.description(), description)
        
    def test_canRemoveAllStoriesFromPivotal(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary("test_canRemoveAllStoriesFromPivotal-1")
        tracker.update(item)
        item.withSummary("test_canRemoveAllStoriesFromPivotal-2")
        tracker.update(item)
        tracker.deleteAllItems()
        self.assertRaises(StopIteration, next, tracker.items())
        
    def test_canUpdateItemAlreadyInPivotal(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary("test_canUpdateItemAlreadyInPivotal-to update").withDescription("can update?")
        tracker.update(item)
        item = next(tracker.items())
        newSummary = "test_canUpdateItemAlreadyInPivotal-1"
        newDescription = "yep - updated"
        item.withSummary(newSummary).withDescription(newDescription)
        tracker.update(item)
        item = next(tracker.items())
        self.assertEqual(item.summary(), newSummary)
        self.assertEqual(item.description(), newDescription)
        
    def test_canAddAndUpdateJiraLinksToPivotalStories(self):
        tracker = self.pivotal_
        newUrl = "https://www.jira.com/TEST-pa1234"
        jiraTicketKey = "TEST-pa1234"
        description = "this is a test\nwith\nmultiple\nlines"
        item = PivotalTrackerItem().withSummary("test_canAddAndUpdateJiraLinksToPivotalStories").withDescription(description)
        item.withJiraUrl("http://www.jira.com/TEST-pa1234").withJiraKey(jiraTicketKey)
        tracker.update(item)
        item = next(tracker.items())
        item.withJiraUrl(newUrl)
        tracker.update(item)
        item = next(tracker.items())
        self.assertEqual(item.jiraUrl(), newUrl)
        self.assertEqual(item.jiraKey(), jiraTicketKey)
        self.assertEqual(item.description(), description)

    def test_canAddCommentsToStory(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary("test_canAddCommentsToStory").withDescription("description")
        tracker.update(item)
        aComment = Testing.addCommentToItemIn(tracker)
        item = next(tracker.items())
        self.assertEqual(item.comments()[0], aComment)
        
    def test_canFilterStoriesReturnedFromTrackerSoNoMatchesAreFound(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary("test_canFilterStoriesReturnedFromTracker").withDescription("description")
        tracker.update(item)
        forFilter = "label:garabage"
        self.assertRaises(StopIteration, next, tracker.items(forFilter))
        
    def test_canFilterStoriesReturnedFromTrackerOnlyOneMatchIsFound(self):
        tracker = self.pivotal_
        forFilter = "searchForMe"
        item = PivotalTrackerItem().withSummary(forFilter).withDescription("description")
        tracker.update(item)
        time.sleep(2)
        item = PivotalTrackerItem().withSummary("test_canFilterStoriesReturnedFromTrackerOnlyOneMatchIsFound").withDescription("description")
        tracker.update(item)
        time.sleep(4)
        itemIterator = tracker.items(forFilter)
        next(itemIterator)
        self.assertRaises(StopIteration, next, itemIterator)
                
    def test_storyUpdatedWhenNotChangedDoesNotModifyStory(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary("test_storyUpdatedWhenNotChangedDoesNotModifyStory").withDescription("description")
        tracker.update(item)
        itemInPivotal = next(tracker.items())
        itemInPivotal.syncWith(itemInPivotal)
        tracker.update(itemInPivotal)
        updatedItem = next(tracker.items())
        self.assertEquals(itemInPivotal.updatedAt(), updatedItem.updatedAt())         
         
    def test_canChangeStoryType(self):
        tracker = self.pivotal_
        itemType = "bug"
        item = PivotalTrackerItem().withSummary("test_canChangeStoryType-1").withDescription("can change the type of this ticket?")
        tracker.update(item)
        item = next(tracker.items())
        item.withType(itemType)
        tracker.update(item)
        updatedItem = next(tracker.items())
        self.assertEqual(itemType, updatedItem.type())

    def test_canAdjustStateOfTicket(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary("test_canAdjustStateOfTicket-1").withDescription("can change the status of this ticket?").withType("bug")  
        done = Testing.putItemToTrackerAndChangeStatusTo("accepted", item, tracker)
        item = next(tracker.items())
        self.assertEqual(item.status(), done)       

    def test_canGetRequestor(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary("test_canGetRequestor-1").withDescription("can get the requestor of this ticket?")  
        tracker.update(item)
        item = next(tracker.items())
        self.assertTrue(Env().get("pivotal", "username") in item.requestor().pivotal())       
        
    def test_canChangeRequestor(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary("test_canChangeRequestor-1").withDescription("can change the requestor of this ticket?")  
        tracker.update(item)
        item = next(tracker.items())
        newRequestor = PivotalUser(Env().get("pivotal", "otherUser"))
        item.withRequestor(newRequestor)
        tracker.update(item)
        item = next(tracker.items())
        self.assertTrue(Env().get("pivotal", "otherUser") in item.requestor().pivotal())
        
    def test_canChangeOwner(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary("test_canChangeOwner-1").withDescription("can change the owner of this ticket?").withType("bug")  
        Testing.putItemToTrackerAndChangeStatusTo("started", item, tracker)
        item = next(tracker.items())
        newOwner = PivotalUser(Env().get("pivotal", "otherUser"))
        item.withOwner(newOwner)
        tracker.update(item)
        item = next(tracker.items())
        self.assertTrue(Env().get("pivotal", "otherUser") in item.owner().pivotal())   
 def setUp(self):
     unittest.TestCase.setUp(self)
     self.pivotal_ = SinglePivotal().instance()
     pass
class PivotalAcceptanceTest(unittest.TestCase):
    def setUp(self):
        unittest.TestCase.setUp(self)
        self.pivotal_ = SinglePivotal().instance()
        pass

    def tearDown(self):
        self.pivotal_.deleteAllItems()
        unittest.TestCase.tearDown(self)

    def test_canConnectToPivotalTrackerTestProject(self):
        tracker = self.pivotal_
        self.assertTrue(tracker.valid())
        pass

    def test_canDownloadStoriesFromPivotalTracker(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary(
            "test_canDownloadStoriesFromPivotalTracker-1")
        tracker.update(item)
        item.withSummary("test_canDownloadStoriesFromPivotalTracker-2")
        tracker.update(item)
        itemIterator = tracker.items()
        next(itemIterator)
        next(itemIterator)
        self.assertRaises(StopIteration, next, itemIterator)
        pass

    def test_canAddStoryToPivotal(self):
        tracker = self.pivotal_
        name = "test_canAddStoryToPivotal"
        description = "this is a test"
        item = PivotalTrackerItem(
            Story()).withSummary(name).withDescription(description)
        tracker.update(item)
        item = next(tracker.items())
        self.assertEqual(item.summary(), name)
        self.assertEqual(item.description(), description)

    def test_canRemoveAllStoriesFromPivotal(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary(
            "test_canRemoveAllStoriesFromPivotal-1")
        tracker.update(item)
        item.withSummary("test_canRemoveAllStoriesFromPivotal-2")
        tracker.update(item)
        tracker.deleteAllItems()
        self.assertRaises(StopIteration, next, tracker.items())

    def test_canUpdateItemAlreadyInPivotal(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary(
            "test_canUpdateItemAlreadyInPivotal-to update").withDescription(
                "can update?")
        tracker.update(item)
        item = next(tracker.items())
        newSummary = "test_canUpdateItemAlreadyInPivotal-1"
        newDescription = "yep - updated"
        item.withSummary(newSummary).withDescription(newDescription)
        tracker.update(item)
        item = next(tracker.items())
        self.assertEqual(item.summary(), newSummary)
        self.assertEqual(item.description(), newDescription)

    def test_canAddAndUpdateJiraLinksToPivotalStories(self):
        tracker = self.pivotal_
        newUrl = "https://www.jira.com/TEST-pa1234"
        jiraTicketKey = "TEST-pa1234"
        description = "this is a test\nwith\nmultiple\nlines"
        item = PivotalTrackerItem().withSummary(
            "test_canAddAndUpdateJiraLinksToPivotalStories").withDescription(
                description)
        item.withJiraUrl("http://www.jira.com/TEST-pa1234").withJiraKey(
            jiraTicketKey)
        tracker.update(item)
        item = next(tracker.items())
        item.withJiraUrl(newUrl)
        tracker.update(item)
        item = next(tracker.items())
        self.assertEqual(item.jiraUrl(), newUrl)
        self.assertEqual(item.jiraKey(), jiraTicketKey)
        self.assertEqual(item.description(), description)

    def test_canAddCommentsToStory(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary(
            "test_canAddCommentsToStory").withDescription("description")
        tracker.update(item)
        aComment = Testing.addCommentToItemIn(tracker)
        item = next(tracker.items())
        self.assertEqual(item.comments()[0], aComment)

    def test_canFilterStoriesReturnedFromTrackerSoNoMatchesAreFound(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary(
            "test_canFilterStoriesReturnedFromTracker").withDescription(
                "description")
        tracker.update(item)
        forFilter = "label:garabage"
        self.assertRaises(StopIteration, next, tracker.items(forFilter))

    def test_canFilterStoriesReturnedFromTrackerOnlyOneMatchIsFound(self):
        tracker = self.pivotal_
        forFilter = "searchForMe"
        item = PivotalTrackerItem().withSummary(forFilter).withDescription(
            "description")
        tracker.update(item)
        time.sleep(2)
        item = PivotalTrackerItem().withSummary(
            "test_canFilterStoriesReturnedFromTrackerOnlyOneMatchIsFound"
        ).withDescription("description")
        tracker.update(item)
        time.sleep(4)
        itemIterator = tracker.items(forFilter)
        next(itemIterator)
        self.assertRaises(StopIteration, next, itemIterator)

    def test_storyUpdatedWhenNotChangedDoesNotModifyStory(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary(
            "test_storyUpdatedWhenNotChangedDoesNotModifyStory"
        ).withDescription("description")
        tracker.update(item)
        itemInPivotal = next(tracker.items())
        itemInPivotal.syncWith(itemInPivotal)
        tracker.update(itemInPivotal)
        updatedItem = next(tracker.items())
        self.assertEquals(itemInPivotal.updatedAt(), updatedItem.updatedAt())

    def test_canChangeStoryType(self):
        tracker = self.pivotal_
        itemType = "bug"
        item = PivotalTrackerItem().withSummary(
            "test_canChangeStoryType-1").withDescription(
                "can change the type of this ticket?")
        tracker.update(item)
        item = next(tracker.items())
        item.withType(itemType)
        tracker.update(item)
        updatedItem = next(tracker.items())
        self.assertEqual(itemType, updatedItem.type())

    def test_canAdjustStateOfTicket(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary(
            "test_canAdjustStateOfTicket-1").withDescription(
                "can change the status of this ticket?").withType("bug")
        done = Testing.putItemToTrackerAndChangeStatusTo(
            "accepted", item, tracker)
        item = next(tracker.items())
        self.assertEqual(item.status(), done)

    def test_canGetRequestor(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary(
            "test_canGetRequestor-1").withDescription(
                "can get the requestor of this ticket?")
        tracker.update(item)
        item = next(tracker.items())
        self.assertTrue(
            Env().get("pivotal", "username") in item.requestor().pivotal())

    def test_canChangeRequestor(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary(
            "test_canChangeRequestor-1").withDescription(
                "can change the requestor of this ticket?")
        tracker.update(item)
        item = next(tracker.items())
        newRequestor = PivotalUser(Env().get("pivotal", "otherUser"))
        item.withRequestor(newRequestor)
        tracker.update(item)
        item = next(tracker.items())
        self.assertTrue(
            Env().get("pivotal", "otherUser") in item.requestor().pivotal())

    def test_canChangeOwner(self):
        tracker = self.pivotal_
        item = PivotalTrackerItem().withSummary(
            "test_canChangeOwner-1").withDescription(
                "can change the owner of this ticket?").withType("bug")
        Testing.putItemToTrackerAndChangeStatusTo("started", item, tracker)
        item = next(tracker.items())
        newOwner = PivotalUser(Env().get("pivotal", "otherUser"))
        item.withOwner(newOwner)
        tracker.update(item)
        item = next(tracker.items())
        self.assertTrue(
            Env().get("pivotal", "otherUser") in item.owner().pivotal())
class SyncAcceptanceTest(unittest.TestCase):
    def setUp(self):
        unittest.TestCase.setUp(self)
        self.jira_ = SingleJira().instance()
        self.pivotal_ = SinglePivotal().instance()
        AcceptanceTesting.mapStatuses(self.jira_)
        AcceptanceTesting.mapUsers()
        pass

    def tearDown(self):
        self.jira_.deleteAllItems()
        self.pivotal_.deleteAllItems()
        PivotalToJiraStatusMap().reset()
        PivotalToJiraUserMap().reset()
        unittest.TestCase.tearDown(self)

    def syncNewItemToPivotal(self, newJiraItem, jira, pivotal):
        jira.update(newJiraItem)
        syncByAddingItems = TrackerSyncBy.addingItemsOfType(PivotalTrackerItem)
        syncByAddingItems(fromTracker=jira, toTracker=pivotal)

    def syncExistingItemFrom(self, fromTracker, toTracker):
        item = next(fromTracker.items())
        syncItem = TrackerSyncBy.syncingItem()
        syncItem(item, toTracker)

    def create_getOtherUserAfterUpdatingJiraItem(self, attributeSetter):
        def getOtherUserAfterUpdatingJiraItem_(jira, pivotal, newJiraItem):
            self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
            jiraItem = next(jira.items())
            user = JiraUser(Env().get("jira", "otherUser"))
            attributeSetter(jiraItem, user)
            jira.update(jiraItem)
            return user

        return getOtherUserAfterUpdatingJiraItem_

    def create_updatePivotalAndSyncJiraItem(self, attributeSetter):
        def updatePivotalAndSyncJiraItem_(jira, pivotal):
            item = next(pivotal.items())
            attributeSetter(item, PivotalUser(Env().get("pivotal",
                                                        "username")))
            pivotal.update(item)
            item = next(pivotal.items())
            attributeSetter(item, PivotalUser(None))
            syncItem = TrackerSyncBy.syncingItem()
            syncItem(item, jira)
            return next(jira.items())

        return updatePivotalAndSyncJiraItem_

    def tryToSyncUnknownUser(self, jira, pivotal):
        PivotalToJiraUserMap().reset()
        PivotalToJiraUserMap().addMapping(jira=Env().get("jira", "username"),
                                          pivotal=Env().get(
                                              "pivotal", "username"))
        self.syncExistingItemFrom(jira, toTracker=pivotal)
        self.syncExistingItemFrom(pivotal, toTracker=jira)
        PivotalToJiraUserMap().addMapping(jira=Env().get("jira", "otherUser"),
                                          pivotal=Env().get(
                                              "pivotal", "otherUser"))
        jiraItem = next(jira.items())
        return jiraItem

    def test_newIssueInJiraIsCopiedToPivotal(self):
        jira = self.jira_
        pivotal = self.pivotal_
        summary = "test_newIssueInJiraIsCopiedToPivotal"
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), summary,
                                      "a test description")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        pivotalItem = next(pivotal.items())
        self.assertEqual(pivotalItem.summary(), summary)
        self.assertEqual(pivotalItem.type(), 'bug')

    def test_existingIssueInJiraIsSyncedWithExistingIssueInPivotal(self):
        jira = self.jira_
        pivotal = self.pivotal_
        desiredSummary = "test_existingIssueInJiraIsSyncedWithExistingIssueInPivotal"
        desiredDescription = "overwritten!"
        newJiraItem = jiraItemFactory(Env().get("jira", "project"),
                                      "to be overwritten", "also overwritten")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        jiraItem = next(jira.items())
        jiraItem.withDescription(desiredDescription)
        jiraItem.withSummary(desiredSummary)
        jira.update(jiraItem)
        self.syncExistingItemFrom(jira, pivotal)
        updatedPivotalItem = next(pivotal.items())
        self.assertEqual(updatedPivotalItem.summary(), desiredSummary)
        self.assertEqual(updatedPivotalItem.description(), desiredDescription)
        pass

    def test_commentOnIssueInJiraIsSyncedToPivotal(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"),
                                      "to test comments", "blah")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        commentOnJira = TrackerItemComment("this commentOnJira can be synced")
        jiraItem = next(jira.items())
        jiraItem.addComment(commentOnJira)
        jira.update(jiraItem)
        self.syncExistingItemFrom(jira, pivotal)
        updatedPivotalItem = next(pivotal.items())
        self.assertEqual(updatedPivotalItem.comments()[0], commentOnJira)
        pass

    def test_commentOnIssueInPivotalIsSyncedToJira(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_commentOnIssueInPivotalIsSyncedToJira", "blah")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        commentOnPivotal = TrackerItemComment(
            "this commentOnPivotal can be synced")
        pivotalItem = next(pivotal.items())
        pivotalItem.addComment(commentOnPivotal)
        pivotal.update(pivotalItem)
        self.syncExistingItemFrom(pivotal, jira)
        updatedJiraItem = next(jira.items())
        self.assertEqual(updatedJiraItem.comments()[0], commentOnPivotal)
        pass

    def test_issueInJiraAndInPivotalAreSyncable(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_issueInJiraAndInPivotalAreSyncable", "a test description")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        jiraItem = next(jira.items())
        pivotalItem = next(pivotal.items())
        self.assertTrue(pivotalItem.canBeSyncedWith(jiraItem))

    def test_20000PlusCharacterCommentsAreNotSyned(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_20000PlusCharacterCommentsAreNotSyned", "blah")
        commentOnJira = TrackerItemComment(Testing.stringOfAsOfSize(20002))
        newJiraItem.addComment(commentOnJira)
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        pivotalItem = next(pivotal.items())
        self.assertEqual(len(pivotalItem.comments()), 0)

    def test_canSyncStatusToPivotalForExistingItems(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_canSyncStatusToPivotalForExistingItems",
            "a test description")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        jiraItem = next(jira.items())
        status = TrackerItemStatus("accepted")
        jiraItem.withStatus(status)
        jira.update(jiraItem)
        self.syncExistingItemFrom(jira, pivotal)
        pivotalItem = next(pivotal.items())
        self.assertEqual(pivotalItem.status(), status)

    def test_canSyncReporterToPivotalForExistingItems(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_canSyncReporterToPivotalForExistingItems",
            "a test description")
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(
            JiraTrackerItem.withRequestor)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        self.syncExistingItemFrom(jira, toTracker=pivotal)
        pivotalItem = next(pivotal.items())
        self.assertEqual(pivotalItem.requestor(), user)

    def test_doNotOverwriteJiraReporterWhenUnknown(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_doNotOverwriteJiraReporterWhenUnknown", "a test description")
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(
            JiraTrackerItem.withRequestor)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        jiraItem = self.tryToSyncUnknownUser(jira, pivotal)
        self.assertEqual(jiraItem.requestor(), user)

    def test_canSyncOwnerToPivotalForExistingItems(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_canSyncOwnerToPivotalForExistingItems", "a test description")
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(
            JiraTrackerItem.withOwner)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        self.syncExistingItemFrom(jira, toTracker=pivotal)
        pivotalItem = next(pivotal.items())
        self.assertEqual(pivotalItem.owner(), user)

    def test_doNotOverwriteJiraOwnerWhenUnknown(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_doNotOverwriteJiraOwnerWhenUnknown", "a test description")
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(
            JiraTrackerItem.withOwner)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        jiraItem = self.tryToSyncUnknownUser(jira, pivotal)
        self.assertEqual(jiraItem.owner(), user)

    def test_doNotOverwriteJiraReporterWhenUnassignedInPivotal(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_doNotOverwriteJiraReporterWhenUnassignedInPivotal",
            "a test description")
        newJiraItem.withRequestor(
            PivotalUser(Env().get("pivotal", "otherUser")))
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(
            JiraTrackerItem.withRequestor)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        updatePivotalAndSyncJiraItem = self.create_updatePivotalAndSyncJiraItem(
            PivotalTrackerItem.withRequestor)
        jiraItem = updatePivotalAndSyncJiraItem(jira, pivotal)
        self.assertEqual(jiraItem.requestor(), user)

    def test_doNotOverwriteJiraOwnerWhenUnassignedInPivotal(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_doNotOverwriteJiraOwnerWhenUnassignedInPivotal",
            "a test description")
        newJiraItem.withOwner(PivotalUser(Env().get("pivotal", "otherUser")))
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(
            JiraTrackerItem.withRequestor)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        updatePivotalAndSyncJiraItem = self.create_updatePivotalAndSyncJiraItem(
            PivotalTrackerItem.withOwner)
        jiraItem = updatePivotalAndSyncJiraItem(jira, pivotal)
        self.assertEqual(jiraItem.owner(), user)

    def test_whenTicketNumberInCommentsOfOtherTickerTheRightSyncOccurs(self):
        jira = self.jira_
        pivotal = self.pivotal_
        desiredSummary = "test_whenTicketNumberInCommentsOfOtherTickerTheRightSyncOccurs-1"
        desiredDescription = "overwritten!"
        newJiraItem = jiraItemFactory(Env().get("jira", "project"),
                                      "to be overwritten", "also overwritten")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        jiraItem = next(jira.items())

        newJiraItem = jiraItemFactory(
            Env().get("jira", "project"),
            "test_whenTicketNumberInCommentsOfOtherTickerTheRightSyncOccurs-2",
            "don't overwrite")
        newJiraItem.addComment(TrackerItemComment(jiraItem.Id()))
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)

        for item in jira.items():
            jiraItem = item

        jiraItem.withDescription(desiredDescription)
        jiraItem.withSummary(desiredSummary)
        jira.update(jiraItem)

        syncItem = TrackerSyncBy.syncingItem()
        for item in jira.items():
            syncItem(item, toTracker=pivotal)

        for item in pivotal.items():
            updatedPivotalItem = item

        self.assertEqual(updatedPivotalItem.summary(), desiredSummary)
        self.assertEqual(updatedPivotalItem.description(), desiredDescription)
        pass
class SyncAcceptanceTest(unittest.TestCase):
    def setUp(self):
        unittest.TestCase.setUp(self)
        self.jira_ = SingleJira().instance()
        self.pivotal_ = SinglePivotal().instance()
        AcceptanceTesting.mapStatuses(self.jira_)
        AcceptanceTesting.mapUsers()
        pass

    def tearDown(self):
        self.jira_.deleteAllItems()
        self.pivotal_.deleteAllItems()
        PivotalToJiraStatusMap().reset()
        PivotalToJiraUserMap().reset()
        unittest.TestCase.tearDown(self)

    def syncNewItemToPivotal(self, newJiraItem, jira, pivotal):
        jira.update(newJiraItem)
        syncByAddingItems = TrackerSyncBy.addingItemsOfType(PivotalTrackerItem)
        syncByAddingItems(fromTracker=jira, toTracker=pivotal)
    
    def syncExistingItemFrom(self, fromTracker, toTracker):
        item = next(fromTracker.items())
        syncItem = TrackerSyncBy.syncingItem()
        syncItem(item, toTracker)
        
    def create_getOtherUserAfterUpdatingJiraItem(self, attributeSetter):
        def getOtherUserAfterUpdatingJiraItem_(jira, pivotal, newJiraItem):
            self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
            jiraItem = next(jira.items())
            user = JiraUser(Env().get("jira", "otherUser"))
            attributeSetter(jiraItem, user)
            jira.update(jiraItem)
            return user
        return getOtherUserAfterUpdatingJiraItem_
    
    def create_updatePivotalAndSyncJiraItem(self, attributeSetter):
        def updatePivotalAndSyncJiraItem_(jira, pivotal):
            item = next(pivotal.items())
            attributeSetter(item, PivotalUser(Env().get("pivotal", "username")))
            pivotal.update(item)
            item = next(pivotal.items())
            attributeSetter(item, PivotalUser(None))
            syncItem = TrackerSyncBy.syncingItem()
            syncItem(item, jira)
            return next(jira.items())
        return updatePivotalAndSyncJiraItem_

    def tryToSyncUnknownUser(self, jira, pivotal):
        PivotalToJiraUserMap().reset()
        PivotalToJiraUserMap().addMapping(jira=Env().get("jira", "username"), pivotal=Env().get("pivotal", "username"))
        self.syncExistingItemFrom(jira, toTracker=pivotal)
        self.syncExistingItemFrom(pivotal, toTracker=jira)
        PivotalToJiraUserMap().addMapping(jira=Env().get("jira", "otherUser"), pivotal=Env().get("pivotal", "otherUser"))
        jiraItem = next(jira.items())
        return jiraItem

    def test_newIssueInJiraIsCopiedToPivotal(self):
        jira = self.jira_
        pivotal = self.pivotal_
        summary = "test_newIssueInJiraIsCopiedToPivotal"
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), summary, "a test description")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        pivotalItem = next(pivotal.items())
        self.assertEqual(pivotalItem.summary(), summary)
        self.assertEqual(pivotalItem.type(), 'bug')
    
    def test_existingIssueInJiraIsSyncedWithExistingIssueInPivotal(self):
        jira = self.jira_
        pivotal = self.pivotal_
        desiredSummary = "test_existingIssueInJiraIsSyncedWithExistingIssueInPivotal"
        desiredDescription = "overwritten!"
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "to be overwritten", "also overwritten" )
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        jiraItem = next(jira.items())
        jiraItem.withDescription(desiredDescription)
        jiraItem.withSummary(desiredSummary)
        jira.update(jiraItem)
        self.syncExistingItemFrom(jira, pivotal)
        updatedPivotalItem = next(pivotal.items())
        self.assertEqual(updatedPivotalItem.summary(), desiredSummary)
        self.assertEqual(updatedPivotalItem.description(), desiredDescription)
        pass
    
    def test_commentOnIssueInJiraIsSyncedToPivotal(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "to test comments", "blah")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        commentOnJira = TrackerItemComment("this commentOnJira can be synced")
        jiraItem = next(jira.items())
        jiraItem.addComment(commentOnJira)
        jira.update(jiraItem)
        self.syncExistingItemFrom(jira, pivotal)
        updatedPivotalItem = next(pivotal.items())
        self.assertEqual(updatedPivotalItem.comments()[0], commentOnJira)
        pass
    
    def test_commentOnIssueInPivotalIsSyncedToJira(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_commentOnIssueInPivotalIsSyncedToJira", "blah")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        commentOnPivotal = TrackerItemComment("this commentOnPivotal can be synced")
        pivotalItem = next(pivotal.items())
        pivotalItem.addComment(commentOnPivotal)
        pivotal.update(pivotalItem)
        self.syncExistingItemFrom(pivotal, jira)
        updatedJiraItem = next(jira.items())
        self.assertEqual(updatedJiraItem.comments()[0], commentOnPivotal)
        pass
    
    def test_issueInJiraAndInPivotalAreSyncable(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_issueInJiraAndInPivotalAreSyncable", "a test description")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        jiraItem = next(jira.items())
        pivotalItem = next(pivotal.items())
        self.assertTrue(pivotalItem.canBeSyncedWith(jiraItem))
    
    def test_20000PlusCharacterCommentsAreNotSyned(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_20000PlusCharacterCommentsAreNotSyned", "blah")
        commentOnJira = TrackerItemComment(Testing.stringOfAsOfSize(20002))
        newJiraItem.addComment(commentOnJira)
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        pivotalItem = next(pivotal.items())
        self.assertEqual(len(pivotalItem.comments()), 0)
        
    def test_canSyncStatusToPivotalForExistingItems(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_canSyncStatusToPivotalForExistingItems", "a test description")
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        jiraItem = next(jira.items())
        status = TrackerItemStatus("accepted")
        jiraItem.withStatus(status)
        jira.update(jiraItem)
        self.syncExistingItemFrom(jira, pivotal)
        pivotalItem = next(pivotal.items())
        self.assertEqual(pivotalItem.status(),status)

    def test_canSyncReporterToPivotalForExistingItems(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_canSyncReporterToPivotalForExistingItems", "a test description")
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(JiraTrackerItem.withRequestor)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        self.syncExistingItemFrom(jira, toTracker=pivotal)
        pivotalItem = next(pivotal.items())
        self.assertEqual(pivotalItem.requestor(),user) 

    def test_doNotOverwriteJiraReporterWhenUnknown(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_doNotOverwriteJiraReporterWhenUnknown", "a test description")
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(JiraTrackerItem.withRequestor)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        jiraItem = self.tryToSyncUnknownUser(jira, pivotal)
        self.assertEqual(jiraItem.requestor(), user)
        
    def test_canSyncOwnerToPivotalForExistingItems(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_canSyncOwnerToPivotalForExistingItems", "a test description")
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(JiraTrackerItem.withOwner)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        self.syncExistingItemFrom(jira, toTracker=pivotal)
        pivotalItem = next(pivotal.items())
        self.assertEqual(pivotalItem.owner(),user)
    
    def test_doNotOverwriteJiraOwnerWhenUnknown(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_doNotOverwriteJiraOwnerWhenUnknown", "a test description")
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(JiraTrackerItem.withOwner)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        jiraItem = self.tryToSyncUnknownUser(jira, pivotal)
        self.assertEqual(jiraItem.owner(), user)

      
    def test_doNotOverwriteJiraReporterWhenUnassignedInPivotal(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_doNotOverwriteJiraReporterWhenUnassignedInPivotal", "a test description")
        newJiraItem.withRequestor(PivotalUser(Env().get("pivotal", "otherUser")))
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(JiraTrackerItem.withRequestor)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        updatePivotalAndSyncJiraItem = self.create_updatePivotalAndSyncJiraItem(PivotalTrackerItem.withRequestor)
        jiraItem = updatePivotalAndSyncJiraItem(jira, pivotal)
        self.assertEqual(jiraItem.requestor(), user)

    def test_doNotOverwriteJiraOwnerWhenUnassignedInPivotal(self):
        jira = self.jira_
        pivotal = self.pivotal_
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_doNotOverwriteJiraOwnerWhenUnassignedInPivotal", "a test description")
        newJiraItem.withOwner(PivotalUser(Env().get("pivotal", "otherUser")))
        getOtherUserAfterUpdatingJiraItem = self.create_getOtherUserAfterUpdatingJiraItem(JiraTrackerItem.withRequestor)
        user = getOtherUserAfterUpdatingJiraItem(jira, pivotal, newJiraItem)
        updatePivotalAndSyncJiraItem = self.create_updatePivotalAndSyncJiraItem(PivotalTrackerItem.withOwner)
        jiraItem = updatePivotalAndSyncJiraItem(jira, pivotal)
        self.assertEqual(jiraItem.owner(), user)
        
    def test_whenTicketNumberInCommentsOfOtherTickerTheRightSyncOccurs(self):
        jira = self.jira_
        pivotal = self.pivotal_
        desiredSummary = "test_whenTicketNumberInCommentsOfOtherTickerTheRightSyncOccurs-1"
        desiredDescription = "overwritten!"
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "to be overwritten", "also overwritten" )
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        jiraItem = next(jira.items())
        
        newJiraItem = jiraItemFactory(Env().get("jira", "project"), "test_whenTicketNumberInCommentsOfOtherTickerTheRightSyncOccurs-2", "don't overwrite" )
        newJiraItem.addComment(TrackerItemComment(jiraItem.Id()))
        self.syncNewItemToPivotal(newJiraItem, jira, pivotal)
        
        for item in jira.items():
            jiraItem = item
        
        jiraItem.withDescription(desiredDescription)
        jiraItem.withSummary(desiredSummary)
        jira.update(jiraItem)
        
        syncItem = TrackerSyncBy.syncingItem()
        for item in jira.items():
            syncItem(item, toTracker=pivotal)
        
        
        for item in pivotal.items():
            updatedPivotalItem = item
        
        self.assertEqual(updatedPivotalItem.summary(), desiredSummary)
        self.assertEqual(updatedPivotalItem.description(), desiredDescription)
        pass