Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c53f598
fix(jira): update epic collector to use new API endpoint and include …
GoSimplicity Aug 21, 2025
cda87db
Merge branch 'main' into main
GoSimplicity Aug 25, 2025
55fe451
fix(jira): enhance epic collector to dynamically select API endpoint …
GoSimplicity Aug 25, 2025
59dc06e
fix(jira): update epic collector to use correct API endpoint for JIRA…
GoSimplicity Aug 25, 2025
ecb4feb
Merge branch 'main' into main
GoSimplicity Aug 25, 2025
c3a54ae
fix(jira): refactor epic collector to streamline API endpoint selecti…
GoSimplicity Aug 25, 2025
74141bc
Merge branch 'main' into main
GoSimplicity Aug 27, 2025
9a6ff4a
fix(jira): fix type for Jira issue descriptions
GoSimplicity Aug 29, 2025
eb3f173
Merge branch 'main' into main
GoSimplicity Aug 29, 2025
01baebb
refactor(jira): update comment and worklog models to use FlexibleDesc…
GoSimplicity Aug 29, 2025
5c4060f
docs(jira): add ADF reference for FlexibleDescription type in issue m…
GoSimplicity Sep 1, 2025
5f8b3f9
Merge branch 'apache:main' into main
GoSimplicity Sep 5, 2025
d6d3764
refactor(migrations): enhance file meta migration to check column exi…
GoSimplicity Sep 5, 2025
9353974
Merge branch 'main' into main
GoSimplicity Sep 11, 2025
ffd06b4
Merge branch 'main' into main
GoSimplicity Sep 15, 2025
cc4e29f
Merge branch 'apache:main' into main
GoSimplicity Sep 23, 2025
71b27ba
feat(gitextractor): add support for excluding file extensions in comm…
GoSimplicity Sep 23, 2025
a0e2827
fix(ZenTao): add support for non-date string handling in UnmarshalJSO…
GoSimplicity Sep 23, 2025
ec8a3f9
Revert "feat(gitextractor): add support for excluding file extensions…
GoSimplicity Sep 23, 2025
f1f61e2
Merge branch 'main' into main
GoSimplicity Sep 23, 2025
8a2d490
Merge branch 'apache:main' into main
GoSimplicity Sep 24, 2025
786c46b
refactor(api): instantiate team and user objects directly in CreateTe…
GoSimplicity Sep 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions backend/core/models/common/iso8601time.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ func (jt *Iso8601Time) UnmarshalJSON(b []byte) error {
return nil
}
timeString = strings.Trim(timeString, `"`)

// Handle special cases for non-standard date representations
// Some systems may use text like "长期" (long-term) instead of actual dates
if isNonDateString(timeString) {
jt.Time = time.Time{}
return nil
}

t, err := ConvertStringToTime(timeString)
if err != nil {
return err
Expand All @@ -119,6 +127,34 @@ func (jt *Iso8601Time) UnmarshalJSON(b []byte) error {
return nil
}

// isNonDateString checks if a string represents a non-date value like "long-term"
func isNonDateString(s string) bool {
// Handle various representations of "long-term" in different systems
nonDateStrings := []string{
"长期", // Chinese for "long-term"
"\\u957f\\u671f", // Unicode escape sequence for "长期"
"\\\\u957f\\\\u671f", // Double-escaped Unicode sequence
"long-term", // English
"永久", // Chinese for "permanent"
"indefinite", // English
"unlimited", // English
}

for _, nonDate := range nonDateStrings {
if s == nonDate {
return true
}
}

// Also check if the string contains the Unicode escape pattern for "长期"
// This handles cases where escape sequences might be processed differently
if strings.Contains(s, "957f") && strings.Contains(s, "671f") {
return true
}

return false
}

// ToTime FIXME ...
func (jt *Iso8601Time) ToTime() time.Time {
return jt.Time
Expand Down
111 changes: 111 additions & 0 deletions backend/core/models/common/iso8601time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"database/sql/driver"
"fmt"
"reflect"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -162,6 +163,116 @@ func TestConvertStringToTime(t *testing.T) {
}
}

func TestIsNonDateString(t *testing.T) {
testCases := []struct {
name string
input string
output bool
}{
{
name: "ZenTao long-term in Chinese",
input: "长期",
output: true,
},
{
name: "ZenTao long-term in Unicode escape",
input: "\\u957f\\u671f",
output: true,
},
{
name: "ZenTao long-term in double-escaped Unicode",
input: "\\\\u957f\\\\u671f",
output: true,
},
{
name: "English long-term",
input: "long-term",
output: true,
},
{
name: "Chinese permanent",
input: "永久",
output: true,
},
{
name: "English indefinite",
input: "indefinite",
output: true,
},
{
name: "English unlimited",
input: "unlimited",
output: true,
},
{
name: "Valid date string",
input: "2023-03-01",
output: false,
},
{
name: "Valid datetime string",
input: "2023-03-01T12:30:00Z",
output: false,
},
{
name: "Random string",
input: "random",
output: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
output := isNonDateString(tc.input)
assert.Equal(t, tc.output, output, "Expected output to be %v, but got %v", tc.output, output)
})
}
}

func TestIso8601Time_UnmarshalJSON_NonDateStrings(t *testing.T) {
testCases := []struct {
name string
input string
shouldErr bool
}{
{
name: "ZenTao long-term in Chinese",
input: `"长期"`,
shouldErr: false,
},
{
name: "ZenTao long-term in Unicode escape",
input: `"\\u957f\\u671f"`,
shouldErr: false,
},
{
name: "English long-term",
input: `"long-term"`,
shouldErr: false,
},
{
name: "Valid date",
input: `"2023-03-01T12:30:00Z"`,
shouldErr: false,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var iso8601Time Iso8601Time
err := iso8601Time.UnmarshalJSON([]byte(tc.input))
if tc.shouldErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
// For non-date strings, the time should be zero
if isNonDateString(strings.Trim(tc.input, `"`)) {
assert.True(t, iso8601Time.Time.IsZero(), "Expected zero time for non-date string")
}
}
})
}
}

func TestConvertStringToTimeInLoc(t *testing.T) {
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
Expand Down
3 changes: 1 addition & 2 deletions backend/plugins/org/api/team.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,8 @@ func (h *Handlers) CreateTeam(input *plugin.ApiResourceInput) (*plugin.ApiResour
if err != nil {
return nil, err
}
var t *team
var items []interface{}
for _, tm := range t.toDomainLayer(tt) {
for _, tm := range (&team{}).toDomainLayer(tt) {
items = append(items, tm)
}
err = h.store.deleteAll(&crossdomain.Team{})
Expand Down
3 changes: 1 addition & 2 deletions backend/plugins/org/api/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,8 @@ func (h *Handlers) CreateUser(input *plugin.ApiResourceInput) (*plugin.ApiResour
if err != nil {
return nil, err
}
var u *user
var items []interface{}
users, teamUsers := u.toDomainLayer(uu)
users, teamUsers := (&user{}).toDomainLayer(uu)
for _, user := range users {
items = append(items, user)
}
Expand Down
Loading