def test_sync_single_toggl_already_inserted_in_redmine(self):
        redmine = RedmineHelper("url", None, False)
        redmine.get = Mock()
        redmine.put = Mock()
        redmine.update = Mock()
        toggl = TogglHelper("url", None)
        toggl.get = Mock()

        toggl.get.return_value = [
            TogglEntry(
                None,
                3600,
                "2016-01-01T01:01:01",
                17,
                "#987 hard work",
                self.redmine_config,
            )
        ]

        redmine.get.return_value = [
            RedmineTimeEntry(
                222,
                "2016-05-01T04:02:22",
                "john doe",
                1,
                "2016-01-01",
                "987",
                "#987 hard work [toggl#17]",
            )
        ]

        s = Synchronizer(MagicMock(), redmine, toggl, None, raise_errors=True)
        s.start(1)
        redmine.update.assert_not_called()
        redmine.put.assert_not_called()
    def test_start_one_day_single(self):
        redmine = RedmineHelper("url", None, False)
        toggl = TogglHelper("url", None)

        toggl.get = MagicMock()
        toggl.get.return_value = [
            TogglEntry(None, 3600, "2016-03-02T01:01:01", 777, "test #333",
                       self.redmine_config)
        ]

        redmine.get = MagicMock()
        redmine.get.return_value = [
            RedmineTimeEntry(
                777,
                "2016-01-01T01:02:03",
                "john doe",
                1.0,
                "2016-03-02",
                333,
                "test #333 [toggl#777]",
            )
        ]
        redmine.update = MagicMock()

        s = Synchronizer(Mock(), redmine, toggl, None, raise_errors=True)
        s.start(1)

        toggl.get.assert_called_once_with(1)
        redmine.get.assert_called_once_with('333')
        redmine.update.assert_not_called()
    def test_sync_single_toggl_no_redmine(self):
        config = MagicMock()
        redmine = RedmineHelper("url", None, False)
        redmine.get = Mock()
        redmine.put = Mock()
        toggl = TogglHelper("url", None)
        toggl.get = Mock()

        toggl.get.return_value = [
            TogglEntry(
                None,
                3600,
                "2016-01-01T01:01:01",
                17,
                "#987 hard work",
                self.redmine_config,
            )
        ]

        redmine.get.return_value = []

        s = Synchronizer(config, redmine, toggl, None, raise_errors=True)
        s.start(1)

        toggl.get.assert_called_once_with(1)

        redmine.put.assert_called_once_with(
            issueId="987",
            spentOn="2016-01-01",
            hours=1.0,
            comment="#987 hard work [toggl#17]",
        )
    def test_sync_skipping_entries_under_1min(self):
        config = MagicMock()
        jira = JiraHelper(None, None, None, False)
        jira.get = Mock()
        jira.jira_api = Mock()
        # jira.put = Mock()
        jira.jira_api.add_worklog = Mock()
        toggl = TogglHelper("url", None)
        toggl.get = Mock()

        toggl.get.return_value = [
            TogglEntry(
                None,
                29,  # time rounds to under 60 sec
                "2016-01-01T01:01:01",
                17,
                "SLUG-987 hard work",
                self.jira_config,
            )
        ]

        jira.get.return_value = []

        s = Synchronizer(config, jira, toggl, None, raise_errors=True)
        s.start(1)

        toggl.get.assert_called_once_with(1)
        jira.jira_api.add_worklog.assert_not_called()
    def test_start_one_day_single(self):
        jira = JiraHelper(None, None, None, False)
        toggl = TogglHelper("url", None)
        toggl.get = Mock()

        toggl.get.return_value = [
            TogglEntry(None, 3600, "2016-03-02T01:01:01", 777, "test SLUG-333",
                       self.jira_config)
        ]

        jira.get = Mock()
        jira.get.return_value = [
            JiraTimeEntry(
                777,
                "2016-01-01T01:02:03",
                "john doe",
                3600,
                "2016-03-02T01:01:01",
                "SLUG-333",
                "test SLUG-333 [toggl#777]",
            )
        ]
        jira.update = MagicMock()

        s = Synchronizer(Mock(), jira, toggl, None, raise_errors=True)
        s.start(1)

        toggl.get.assert_called_once_with(1)
        jira.get.assert_called_once_with('SLUG-333')
        jira.update.assert_not_called()
    def test_sync_single_toggl_update_to_under_1min_clears_worklog(self):
        jira = JiraHelper(None, None, None, False)
        jira.get = Mock()
        jira.delete = Mock()
        toggl = TogglHelper("url", None)
        toggl.get = Mock()

        toggl.get.return_value = [
            TogglEntry(
                None,
                29,  # time rounds to under 60 sec
                "2016-01-01T01:01:01",
                17,
                "SLUG-987 hard work",
                self.jira_config,
            )
        ]

        jira.get.return_value = [
            JiraTimeEntry(
                222,
                "2016-05-01T04:02:22",
                "john doe",
                1000,
                "2016-01-01T01:01:01",
                "SLUG-987",
                "SLUG-987 hard work [toggl#17]",
            )
        ]

        s = Synchronizer(MagicMock(), jira, toggl, None, raise_errors=True)
        s.start(1)

        jira.delete.assert_called_once_with(222, "SLUG-987")
    def test_sync_single_toggl_already_inserted_in_jira(self):
        jira = JiraHelper(None, None, None, False)
        jira.get = Mock()
        jira.put = Mock()
        jira.update = Mock()
        toggl = TogglHelper("url", None)
        toggl.get = Mock()

        toggl.get.return_value = [
            TogglEntry(
                None,
                3600,
                "2016-01-01T01:01:01",
                17,
                "SLUG-987 hard work",
                self.jira_config,
            )
        ]

        jira.get.return_value = [
            JiraTimeEntry(
                222,
                "2016-05-01T04:02:22",
                "john doe",
                3600,
                "2016-01-01T01:01:01",
                "SLUG-987",
                "SLUG-987 hard work [toggl#17]",
            )
        ]

        s = Synchronizer(MagicMock(), jira, toggl, None, raise_errors=True)
        s.start(1)
        jira.update.assert_not_called()
        jira.put.assert_not_called()
    def test_sync_single_toggl_no_jira(self):
        config = MagicMock()
        jira = JiraHelper(None, None, None, False)
        jira.get = Mock()
        jira.put = Mock()
        toggl = TogglHelper("url", None)
        toggl.get = Mock()

        toggl.get.return_value = [
            TogglEntry(
                None,
                3600,
                "2016-01-01T01:01:01",
                17,
                "SLUG-987 hard work",
                self.jira_config,
            )
        ]

        jira.get.return_value = []

        s = Synchronizer(config, jira, toggl, None, raise_errors=True)
        s.start(1)

        toggl.get.assert_called_once_with(1)

        jira.put.assert_called_once_with(
            issueId="SLUG-987",
            started="2016-01-01T01:01:01",
            seconds=3600,
            comment="SLUG-987 hard work [toggl#17]",
        )
    def test_start_one_day_empty(self):
        redmine = RedmineHelper("url", None, False)
        toggl = TogglHelper("url", None)
        toggl.get = MagicMock()

        s = Synchronizer(Mock(), redmine, toggl, None, raise_errors=True)
        s.start(1)

        toggl.get.assert_called_once_with(1)
Example #10
0
    def __append_redmine_summary(self, allEntries):
        redmineEntries = TogglHelper.filter_valid_entries(allEntries)

        if len(redmineEntries) > 0:
            self.append("---")
            self.append("**Redmine summary**")

            redmineIssuesSums = {}

            for e in redmineEntries:
                if e.taskId not in redmineIssuesSums:
                    redmineIssuesSums[e.taskId] = 0

                redmineIssuesSums[e.taskId] += e.duration

            longestTasks = sorted(redmineIssuesSums,
                                  key=lambda id: -redmineIssuesSums[id])[:3]

            self.append("You spent most time on:")

            for id in longestTasks:
                self.append("- #{}: {} h".format(
                    id, TogglEntry.secondsToHours(redmineIssuesSums[id])))

            self.append("")
Example #11
0
    def appendEntries(self, allEntries):
        self.append("Found entries in toggl: **{}** (filtered: **{}**)".format(
            len(allEntries),
            len(TogglHelper.filter_valid_entries(allEntries))))

        self.__append_summary(allEntries)
        self.append("")

        self.__append_redmine_summary(allEntries)
    def test_ignore_negative_duration(self):
        """
        Synchronizer should ignore entries with negative durations (pending entries).

		From toggl docs:
           duration: time entry duration in seconds. If the time entry is currently running, the duration attribute contains a negative value, denoting the start
           of the time entry in seconds since epoch (Jan 1 1970). The correct duration can be calculated as current_time + duration, where current_time is the current
           time in seconds since epoch. (integer, required)
        """

        redmine = RedmineHelper("url", None, False)
        redmine.get = Mock()
        redmine.put = Mock()
        toggl = TogglHelper("url", None)
        toggl.get = Mock()

        toggl.get.return_value = [
            TogglEntry(None, 3600, "2016-01-01T01:01:01", 777, "test #333",
                       self.redmine_config),
            TogglEntry(
                None,
                -3600,
                "2016-01-01T01:01:01",
                778,
                "test #334",
                self.redmine_config,
            ),
        ]

        redmine.get.return_value = []

        s = Synchronizer(Mock(), redmine, toggl, None, raise_errors=True)
        s.start(1)

        toggl.get.assert_called_once_with(1)
        redmine.get.assert_called_once_with("333")

        redmine.put.assert_called_once_with(
            issueId="333",
            spentOn="2016-01-01",
            hours=1.0,
            comment="test #333 [toggl#777]",
        )
    def test_sync_single_toggl_modified_entry(self):
        redmine = RedmineHelper("url", None, False)
        redmine.get = Mock()
        redmine.update = Mock()
        toggl = TogglHelper("url", None)
        toggl.get = Mock()

        toggl.get.return_value = [
            TogglEntry(
                None,
                2 * 3600,
                "2016-01-01T01:01:01",
                17,
                "#987 hard work",
                self.redmine_config,
            )
        ]

        redmine.get.return_value = [
            RedmineTimeEntry(
                222,
                "2016-05-01T04:02:22",
                "john doe",
                1,
                "2016-01-01",
                "987",
                "#987 hard work [toggl#17]",
            )
        ]

        s = Synchronizer(MagicMock(), redmine, toggl, None, raise_errors=True)
        s.start(1)

        redmine.update.assert_called_once_with(
            id=222,
            issueId="987",
            spentOn="2016-01-01",
            hours=2.0,
            comment="#987 hard work [toggl#17]",
        )
    def test_sync_single_toggl_modified_entry(self):
        jira = JiraHelper(None, None, None, False)
        jira.get = Mock()
        jira.update = Mock()
        toggl = TogglHelper("url", None)
        toggl.get = Mock()

        toggl.get.return_value = [
            TogglEntry(
                None,
                2 * 3600,
                "2016-01-01T01:01:01",
                17,
                "SLUG-987 hard work",
                self.jira_config,
            )
        ]

        jira.get.return_value = [
            JiraTimeEntry(
                222,
                "2016-05-01T04:02:22",
                "john doe",
                1,
                "2016-01-01T01:01:01",
                "SLUG-987",
                "SLUG-987 hard work [toggl#17]",
            )
        ]

        s = Synchronizer(MagicMock(), jira, toggl, None, raise_errors=True)
        s.start(1)

        jira.update.assert_called_once_with(
            id=222,
            issueId="SLUG-987",
            started="2016-01-01T01:01:01",
            seconds=2 * 3600,
            comment="SLUG-987 hard work [toggl#17]",
        )
Example #15
0
        sys.exit(0)

    config = Config.fromFile()

    # print("Found api key pairs: {}".format(len(config.entries)))

    mattermost = None

    if config.mattermost:
        runner = RequestsRunner.fromConfig(config.mattermost)
        mattermost = MattermostNotifier(runner, args.simulation)

    for config_entry in config.entries:
        print("Synchronization for {} ...".format(config_entry.label))
        print("---")
        toggl = TogglHelper(config.toggl, config_entry)
        api_helper = ApiHelperFactory(config_entry).create()
        if not api_helper:
            print(
                "Can't interpret config to destination API - entry: {}".format(
                    config_entry.label))
            continue

        if mattermost != None:
            mattermost.append("TogglSync v{} for {}".format(
                version.VERSION, config_entry.label))
            mattermost.append("---")
            mattermost.append("")

        sync = Synchronizer(config,
                            api_helper,