From 0d6aebe8439327acdc5fa1264b4a08b715fba5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Boros?= Date: Sun, 13 Mar 2022 15:56:14 +0100 Subject: [PATCH] fix(clockify): fill summary if description exists * fix: summary is filled if description exists * fix: return single item entries if no tags given * chore(changelog): update changelog Signed-off-by: Gabor Boros --- CHANGELOG.md | 5 ++ internal/pkg/client/clockify/clockify.go | 6 ++ internal/pkg/client/clockify/clockify_test.go | 80 +++++++++++++++++++ internal/pkg/worklog/entry.go | 6 ++ 4 files changed, 97 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffc2558..106cee9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. ## [unreleased] +**Bug Fixes** + +- Summary is filled if description exists ([557e286](https://github.com/gabor-boros/minutes/commit/557e286110be54733511791083b3fa0f92b0d38e)) +- Return single item entries if no tags given ([405c405](https://github.com/gabor-boros/minutes/commit/405c405518b09228d455b32543b9486b6625d4fa)) + **Documentation** - Fix comment wording ([cb3b3bb](https://github.com/gabor-boros/minutes/commit/cb3b3bb9763bdb6c68d5e93d5f7f16de0605abfe)) diff --git a/internal/pkg/client/clockify/clockify.go b/internal/pkg/client/clockify/clockify.go index f6ee6c4..0db7330 100644 --- a/internal/pkg/client/clockify/clockify.go +++ b/internal/pkg/client/clockify/clockify.go @@ -107,6 +107,12 @@ func (c *clockifyClient) parseEntries(rawEntries interface{}, opts *client.Fetch UnbillableDuration: unbillableDuration, } + // If the entry's summary is empty, but we have notes, let's use notes for summary too + // See: https://github.com/gabor-boros/minutes/issues/38 + if worklogEntry.Summary == "" && worklogEntry.Notes != "" { + worklogEntry.Summary = worklogEntry.Notes + } + if utils.IsRegexSet(opts.TagsAsTasksRegex) && len(entry.Tags) > 0 { pageEntries := worklogEntry.SplitByTagsAsTasks(entry.Description, opts.TagsAsTasksRegex, entry.Tags) entries = append(entries, pageEntries...) diff --git a/internal/pkg/client/clockify/clockify_test.go b/internal/pkg/client/clockify/clockify_test.go index b375fb5..dd0bb41 100644 --- a/internal/pkg/client/clockify/clockify_test.go +++ b/internal/pkg/client/clockify/clockify_test.go @@ -379,3 +379,83 @@ func TestClockifyClient_FetchEntries_TagsAsTasks(t *testing.T) { require.Nil(t, err, "cannot fetch entries") require.ElementsMatch(t, expectedEntries, entries, "fetched entries are not matching") } + + +func TestClockifyClient_FetchEntries_TagsAsTasks_NoTags(t *testing.T) { + start := time.Date(2021, 10, 2, 0, 0, 0, 0, time.UTC) + end := time.Date(2021, 10, 2, 23, 59, 59, 0, time.UTC) + remainingCalls := 1 + + expectedEntries := worklog.Entries{ + { + Client: worklog.IDNameField{ + ID: "456", + Name: "My Awesome Company", + }, + Project: worklog.IDNameField{ + ID: "123", + Name: "TASK-1234", + }, + Task: worklog.IDNameField{}, + Summary: "Have a coffee with Tony", + Notes: "Have a coffee with Tony", + Start: start, + BillableDuration: end.Sub(start), + UnbillableDuration: 0, + }, + } + + mockServer := newMockServer(t, &mockServerOpts{ + Path: fmt.Sprintf(clockify.PathWorklog, "marvel-studios", "steve-rogers"), + Method: http.MethodGet, + StatusCode: http.StatusOK, + Token: "t-o-k-e-n", + TokenHeader: "X-Api-Key", + RemainingCalls: &remainingCalls, + ResponseData: &[]clockify.FetchEntry{ + { + Description: "Have a coffee with Tony", + Billable: true, + Project: clockify.Project{ + IDNameField: worklog.IDNameField{ + ID: "123", + Name: "TASK-1234", + }, + ClientID: "456", + ClientName: "My Awesome Company", + }, + TimeInterval: clockify.Interval{ + Start: start, + End: end, + }, + Task: worklog.IDNameField{}, + Tags: []worklog.IDNameField{}, + }, + }, + }) + defer mockServer.Close() + + clockifyClient, err := clockify.NewFetcher(&clockify.ClientOpts{ + BaseClientOpts: client.BaseClientOpts{ + Timeout: client.DefaultRequestTimeout, + }, + TokenAuth: client.TokenAuth{ + Header: "X-Api-Key", + Token: "t-o-k-e-n", + }, + BaseURL: mockServer.URL, + Workspace: "marvel-studios", + }) + + require.Nil(t, err) + + entries, err := clockifyClient.FetchEntries(context.Background(), &client.FetchOpts{ + User: "steve-rogers", + Start: start, + End: end, + TagsAsTasksRegex: regexp.MustCompile(`^TASK-\d+$`), + }) + + require.Nil(t, err, "cannot fetch entries") + require.ElementsMatch(t, expectedEntries, entries, "fetched entries are not matching") +} diff --git a/internal/pkg/worklog/entry.go b/internal/pkg/worklog/entry.go index d089785..63c73ed 100644 --- a/internal/pkg/worklog/entry.go +++ b/internal/pkg/worklog/entry.go @@ -94,7 +94,13 @@ func (e *Entry) SplitDuration(parts int) (splitBillableDuration time.Duration, s // SplitByTagsAsTasks splits the entry into pieces treating tags as tasks. // Not matching tags won't be treated as a new entry should be created, // therefore that tag will be skipped and the returned entries will lack that. +// If no tags are provided, the original entry will be returned as the only item +// of the `Entries` list. func (e *Entry) SplitByTagsAsTasks(summary string, regex *regexp.Regexp, tags []IDNameField) Entries { + if len(tags) == 0 { + return Entries{*e} + } + var tasks []IDNameField for _, tag := range tags { if taskName := regex.FindString(tag.Name); taskName != "" {