Skip to content

Commit 62aecd8

Browse files
committed
test(import): cover complete Gemini Apps zone boundaries
1 parent 101e00e commit 62aecd8

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

internal/importer/gemini_apps_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,9 @@ func TestImportGeminiAppsWholeHourZonePersistsCorrectTimestamp(t *testing.T) {
259259
stored, err := d.GetSessionFull(context.Background(), page.Sessions[0].ID)
260260
require.NoError(t, err)
261261
require.NotNil(t, stored.StartedAt)
262+
require.NotNil(t, stored.EndedAt)
262263
assert.Equal(t, "2025-01-02T07:04:05Z", *stored.StartedAt)
264+
assert.Equal(t, *stored.StartedAt, *stored.EndedAt)
263265
messages, err := d.GetAllMessages(context.Background(), page.Sessions[0].ID)
264266
require.NoError(t, err)
265267
require.Len(t, messages, 1)

internal/parser/gemini_apps_takeout_test.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"path/filepath"
66
"strings"
77
"testing"
8+
"time"
89

910
"github.com/stretchr/testify/assert"
1011
"github.com/stretchr/testify/require"
@@ -163,6 +164,32 @@ func TestParseGeminiAppsEquivalentNumericZonesKeepStableIdentity(t *testing.T) {
163164
assert.Equal(t, ids["prompt"], padded["prompt"])
164165
}
165166

167+
func TestRESPEC2HeadGMT8Reproduction(t *testing.T) {
168+
path := filepath.Join(t.TempDir(), "activity.html")
169+
fixture := geminiAppsSingleCellHTML(
170+
"", "My Activity History", "Prompted",
171+
"Jan 2, 2025, 3:04:05 PM GMT+8", "<p>prompt</p>",
172+
)
173+
require.NoError(t, os.WriteFile(path, []byte(fixture), 0o644))
174+
175+
provider, ok := NewProvider(AgentGeminiApps, ProviderConfig{})
176+
require.True(t, ok)
177+
exporter := provider.(GeminiAppsExportParser)
178+
var result ParseResult
179+
_, err := exporter.ParseGeminiAppsExport(path, func(got ParseResult) error {
180+
result = got
181+
return nil
182+
})
183+
require.NoError(t, err)
184+
require.Len(t, result.Messages, 1)
185+
186+
sessionTimestamp := result.Session.StartedAt.UTC().Format(time.RFC3339)
187+
messageTimestamp := result.Messages[0].Timestamp.UTC().Format(time.RFC3339)
188+
t.Logf("session=%s message=%s messages=%d id=%s", sessionTimestamp, messageTimestamp, len(result.Messages), result.Session.ID)
189+
assert.Equal(t, "2025-01-02T07:04:05Z", sessionTimestamp)
190+
assert.Equal(t, sessionTimestamp, messageTimestamp)
191+
}
192+
166193
func TestParseGeminiAppsRejectsNotPromptedActivityLabel(t *testing.T) {
167194
fixture := strings.ReplaceAll(
168195
sanitizedGeminiAppsHTML,
@@ -1165,10 +1192,22 @@ func TestParseGeminiAppsTimestampUsesExplicitZones(t *testing.T) {
11651192
}{
11661193
{"edt", "Jan 2, 2025, 3:04:05 PM EDT", "2025-01-02T19:04:05Z"},
11671194
{"pst", "Jan 2, 2025, 3:04:05 PM PST", "2025-01-02T23:04:05Z"},
1195+
{"utc", "Jan 2, 2025, 3:04:05 PM UTC", "2025-01-02T15:04:05Z"},
1196+
{"gmt", "Jan 2, 2025, 3:04:05 PM GMT", "2025-01-02T15:04:05Z"},
1197+
{"est", "Jan 2, 2025, 3:04:05 PM EST", "2025-01-02T20:04:05Z"},
1198+
{"cst", "Jan 2, 2025, 3:04:05 PM CST", "2025-01-02T21:04:05Z"},
1199+
{"cdt", "Jan 2, 2025, 3:04:05 PM CDT", "2025-01-02T20:04:05Z"},
1200+
{"mst", "Jan 2, 2025, 3:04:05 PM MST", "2025-01-02T22:04:05Z"},
1201+
{"mdt", "Jan 2, 2025, 3:04:05 PM MDT", "2025-01-02T21:04:05Z"},
1202+
{"pdt", "Jan 2, 2025, 3:04:05 PM PDT", "2025-01-02T22:04:05Z"},
11681203
{"whole-hour", "Jan 2, 2025, 3:04:05 PM GMT+8", "2025-01-02T07:04:05Z"},
11691204
{"whole-hour-padded", "Jan 2, 2025, 3:04:05 PM GMT+08:00", "2025-01-02T07:04:05Z"},
1205+
{"whole-hour-two-digit", "Jan 2, 2025, 3:04:05 PM GMT+08", "2025-01-02T07:04:05Z"},
1206+
{"whole-hour-lowercase", "Jan 2, 2025, 3:04:05 PM gmt+8", "2025-01-02T07:04:05Z"},
1207+
{"whole-hour-mixed-case", "Jan 2, 2025, 3:04:05 PM GmT+8", "2025-01-02T07:04:05Z"},
11701208
{"whole-hour-negative", "Jan 2, 2025, 3:04:05 PM GMT-8", "2025-01-02T23:04:05Z"},
11711209
{"numeric", "Jan 2, 2025, 3:04:05 PM GMT+05:30", "2025-01-02T09:34:05Z"},
1210+
{"numeric-max", "Jan 2, 2025, 3:04:05 PM GMT+23:59", "2025-01-01T15:05:05Z"},
11721211
{"negative-zero", "Jan 2, 2025, 3:04:05 PM GMT-00:30", "2025-01-02T15:34:05Z"},
11731212
}
11741213
for _, tt := range tests {
@@ -1182,7 +1221,7 @@ func TestParseGeminiAppsTimestampUsesExplicitZones(t *testing.T) {
11821221
}
11831222

11841223
for _, zone := range []string{
1185-
"GMT+8:3", "GMT+8junk", "GMT+8:30junk", "GMT+24", "GMT+8:60", "XYZ",
1224+
"GMT+8:3", "GMT+8junk", "GMT+8:30junk", "GMT+24", "GMT+8:60", "GMT+8,", "XYZ",
11861225
} {
11871226
t.Run("reject-"+zone, func(t *testing.T) {
11881227
match := geminiAppsTimestampRE.FindStringSubmatch(
@@ -1191,6 +1230,7 @@ func TestParseGeminiAppsTimestampUsesExplicitZones(t *testing.T) {
11911230
require.Len(t, match, 2)
11921231
_, err := parseGeminiAppsTimestamp(match[0], match[1])
11931232
assert.ErrorContains(t, err, "unsupported")
1233+
assert.ErrorContains(t, err, strings.ToUpper(zone))
11941234
})
11951235
}
11961236
}

0 commit comments

Comments
 (0)