Update time parser to handle OneDrive format (#1013)

## Description

OneDrive format uses '-' in place of ':'. Purge command needs to be able to clear folders with this format as well.

## Type of change

<!--- Please check the type of change your PR introduces: --->
- [ ] 🌻 Feature
- [x] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Test
- [ ] 💻 CI/Deployment
- [ ] 🐹 Trivial/Minor

## Issue(s)

* closes #1012

## Test Plan

<!-- How will this be tested prior to merging.-->
- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
This commit is contained in:
ashmrtn 2022-09-30 15:38:43 -07:00 committed by GitHub
parent dd7b84871f
commit b612718723
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 39 deletions

View File

@ -9,9 +9,10 @@ import (
const (
// the clipped format occurs when m365 removes the :00 second suffix
ClippedSimpleTimeFormat = "02-Jan-2006_15:04"
LegacyTimeFormat = time.RFC3339
SimpleDateTimeFormat = "02-Jan-2006_15:04:05"
ClippedSimpleTimeFormat = "02-Jan-2006_15:04"
ClippedSimpleTimeFormatOneDrive = "02-Jan-2006_15-04"
LegacyTimeFormat = time.RFC3339
SimpleDateTimeFormat = "02-Jan-2006_15:04:05"
// SimpleDateTimeFormatOneDrive is similar to `SimpleDateTimeFormat`
// but uses `-` instead of `:` which is a reserved character in
// OneDrive
@ -21,11 +22,13 @@ const (
)
var (
clippedSimpleTimeRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}:\d{2}).*`)
legacyTimeRE = regexp.MustCompile(
clippedSimpleTimeRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}:\d{2}).*`)
clippedSimpleTimeOneDriveRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}-\d{2}).*`)
legacyTimeRE = regexp.MustCompile(
`.*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}?([Zz]|[a-zA-Z]{2}|([\+|\-]([01]\d|2[0-3])))).*`)
simpleDateTimeRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}:\d{2}:\d{2}).*`)
standardTimeRE = regexp.MustCompile(
simpleDateTimeRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}:\d{2}:\d{2}).*`)
simpleDateTimeOneDriveRE = regexp.MustCompile(`.*(\d{2}-[a-zA-Z]{3}-\d{4}_\d{2}-\d{2}-\d{2}).*`)
standardTimeRE = regexp.MustCompile(
`.*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?([Zz]|[a-zA-Z]{2}|([\+|\-]([01]\d|2[0-3])))).*`)
tabularOutputTimeRE = regexp.MustCompile(`.*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}([Zz]|[a-zA-Z]{2})).*`)
)
@ -33,10 +36,22 @@ var (
var (
// clipped formats must appear last, else they take priority over the regular Simple format.
formats = []string{
StandardTimeFormat, SimpleDateTimeFormat, LegacyTimeFormat, TabularOutputTimeFormat, ClippedSimpleTimeFormat,
StandardTimeFormat,
SimpleDateTimeFormat,
SimpleDateTimeFormatOneDrive,
LegacyTimeFormat,
TabularOutputTimeFormat,
ClippedSimpleTimeFormat,
ClippedSimpleTimeFormatOneDrive,
}
regexes = []*regexp.Regexp{
standardTimeRE, simpleDateTimeRE, legacyTimeRE, tabularOutputTimeRE, clippedSimpleTimeRE,
standardTimeRE,
simpleDateTimeRE,
simpleDateTimeOneDriveRE,
legacyTimeRE,
tabularOutputTimeRE,
clippedSimpleTimeRE,
clippedSimpleTimeOneDriveRE,
}
)
@ -48,29 +63,34 @@ func FormatNow(fmt string) string {
return time.Now().UTC().Format(fmt)
}
// FormatTimeWith produces the a datetime with the given format.
func FormatTimeWith(t time.Time, fmt string) string {
return t.UTC().Format(fmt)
}
// FormatTime produces the standard format for corso time values.
// Always formats into the UTC timezone.
func FormatTime(t time.Time) string {
return t.UTC().Format(StandardTimeFormat)
return FormatTimeWith(t, StandardTimeFormat)
}
// FormatSimpleDateTime produces a simple datetime of the format
// "02-Jan-2006_15:04:05"
func FormatSimpleDateTime(t time.Time) string {
return t.UTC().Format(SimpleDateTimeFormat)
return FormatTimeWith(t, SimpleDateTimeFormat)
}
// FormatTabularDisplayTime produces the standard format for displaying
// a timestamp as part of user-readable cli output.
// "2016-01-02T15:04:05Z"
func FormatTabularDisplayTime(t time.Time) string {
return t.UTC().Format(TabularOutputTimeFormat)
return FormatTimeWith(t, TabularOutputTimeFormat)
}
// FormatLegacyTime produces standard format for string values
// that are placed in SingleValueExtendedProperty tags
func FormatLegacyTime(t time.Time) string {
return t.UTC().Format(LegacyTimeFormat)
return FormatTimeWith(t, LegacyTimeFormat)
}
// ParseTime makes a best attempt to produce a time value from

View File

@ -57,15 +57,11 @@ func (suite *CommonTimeUnitSuite) TestParseTime() {
}
func (suite *CommonTimeUnitSuite) TestExtractTime() {
clipSimpleTime := func(t string) string {
return t[:len(t)-3]
}
comparable := func(t *testing.T, tt time.Time, clipped bool) time.Time {
comparable := func(t *testing.T, tt time.Time, clippedFormat string) time.Time {
ts := common.FormatLegacyTime(tt.UTC())
if clipped {
ts = tt.UTC().Format(common.ClippedSimpleTimeFormat)
if len(clippedFormat) > 0 {
ts = tt.UTC().Format(clippedFormat)
}
c, err := common.ParseTime(ts)
@ -95,16 +91,15 @@ func (suite *CommonTimeUnitSuite) TestExtractTime() {
type timeFormatter func(time.Time) string
var (
clippedF = func(t time.Time) string {
return clipSimpleTime(common.FormatSimpleDateTime(t))
}
legacyF = common.FormatLegacyTime
simpleF = common.FormatSimpleDateTime
stdF = common.FormatTime
tabularF = common.FormatTabularDisplayTime
formatters = []timeFormatter{legacyF, simpleF, stdF, tabularF, clippedF}
)
formats := []string{
common.ClippedSimpleTimeFormat,
common.ClippedSimpleTimeFormatOneDrive,
common.LegacyTimeFormat,
common.SimpleDateTimeFormat,
common.SimpleDateTimeFormatOneDrive,
common.StandardTimeFormat,
common.TabularOutputTimeFormat,
}
type presuf struct {
prefix string
@ -119,23 +114,29 @@ func (suite *CommonTimeUnitSuite) TestExtractTime() {
}
type testable struct {
input string
expect time.Time
clipped bool
input string
clippedFormat string
expect time.Time
}
table := []testable{}
// test matrix: for each input, in each format, with each prefix/suffix, run the test.
for _, in := range inputs {
for i, f := range formatters {
v := f(in)
for _, f := range formats {
clippedFormat := f
if f != common.ClippedSimpleTimeFormat && f != common.ClippedSimpleTimeFormatOneDrive {
clippedFormat = ""
}
v := common.FormatTimeWith(in, f)
for _, ps := range pss {
table = append(table, testable{
input: ps.prefix + v + ps.suffix,
expect: comparable(suite.T(), in, i == 4),
clipped: i == 4,
input: ps.prefix + v + ps.suffix,
expect: comparable(suite.T(), in, clippedFormat),
clippedFormat: clippedFormat,
})
}
}
@ -145,7 +146,7 @@ func (suite *CommonTimeUnitSuite) TestExtractTime() {
suite.T().Run(test.input, func(t *testing.T) {
result, err := common.ExtractTime(test.input)
require.NoError(t, err)
assert.Equal(t, test.expect, comparable(t, result, test.clipped))
assert.Equal(t, test.expect, comparable(t, result, test.clippedFormat))
})
}
}