Skip to content

Commit

Permalink
fix(clockify): fill summary if description exists
Browse files Browse the repository at this point in the history
* 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 <gabor.brs@gmail.com>
  • Loading branch information
gabor-boros committed Mar 14, 2022
1 parent 3c17e47 commit 0d6aebe
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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))
Expand Down
6 changes: 6 additions & 0 deletions internal/pkg/client/clockify/clockify.go
Expand Up @@ -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...)
Expand Down
80 changes: 80 additions & 0 deletions internal/pkg/client/clockify/clockify_test.go
Expand Up @@ -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")
}
6 changes: 6 additions & 0 deletions internal/pkg/worklog/entry.go
Expand Up @@ -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 != "" {
Expand Down

0 comments on commit 0d6aebe

Please sign in to comment.