From 7f700e748b7b458ce03647ecfaa4fb9b947852d8 Mon Sep 17 00:00:00 2001 From: cappy-dev Date: Sat, 8 Aug 2026 05:31:37 +0000 Subject: [PATCH] fix: serialize team_name in StatboticsTeamEvent.toJson StatboticsTeamEvent.fromJson decodes team_name, but toJson left it out, so a record cached through toJson and reloaded through fromJson lost the nickname. The on-device last-good cache round-trips through these two methods, and team_name is the one event-scoped name source (/teams ignores its event parameter), so the loss was silent. Add the field to toJson and two round-trip regression tests. On behalf of @project516 --- CHANGELOG.md | 9 ++++++ lib/src/statbotics_models.dart | 1 + pubspec.yaml | 2 +- test/statbotics_client_test.dart | 52 ++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56ffade..b4b3ed2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.3.1 + +- `StatboticsTeamEvent.toJson` now serializes `team_name`, so the + round-trip `toJson` advertises through `fromJson` actually preserves the + nickname. Previously the field was decoded but left out of `toJson`, so a + cached record came back from the on-device last-good cache with an empty + `teamName` even though `/team_events` had carried one. Only `team_name` was at + risk; every other field already round-tripped. + ## 0.3.0 - `StatboticsTeamEvent.teamName` exposes the nickname `/team_events` already diff --git a/lib/src/statbotics_models.dart b/lib/src/statbotics_models.dart index ec4cc78..c28b404 100644 --- a/lib/src/statbotics_models.dart +++ b/lib/src/statbotics_models.dart @@ -286,6 +286,7 @@ class StatboticsTeamEvent { 'team': team, 'event': event, 'event_name': eventName, + 'team_name': teamName, 'year': year, 'wins': wins, 'losses': losses, diff --git a/pubspec.yaml b/pubspec.yaml index 96444e0..5247b49 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: statbotics_client description: A typed Dart client for the Statbotics API v3 (FRC EPA statistics, events, matches). Pure Dart, no Flutter dependency. -version: 0.3.0 +version: 0.3.1 repository: https://github.com/Project516/statbotics_client topics: diff --git a/test/statbotics_client_test.dart b/test/statbotics_client_test.dart index 015246c..c91cdd2 100644 --- a/test/statbotics_client_test.dart +++ b/test/statbotics_client_test.dart @@ -178,6 +178,58 @@ void main() { expect(te.teamName, isEmpty); }); + test('StatboticsTeamEvent.toJson round-trips team_name', () { + // toJson advertised a round-trip for the on-device last-good cache, but + // omitted team_name, so a cached StatboticsTeamEvent came back with an + // empty nickname. The cache key Statbotics itself does not store is the + // one event-scoped name source (/teams ignores its event param), so the + // loss was silent. + final original = StatboticsTeamEvent.fromJson({ + 'team': 3847, + 'event': '2026txhou', + 'event_name': 'Houston', + 'team_name': 'Spectrum', + 'year': 2026, + 'wins': 1, + 'losses': 0, + 'ties': 0, + 'rank': 7, + 'num_teams': 42, + 'epa': { + 'total_points': {'mean': 41.2, 'sd': 2.9}, + 'auto_points': {'mean': 9.5}, + }, + }); + final restored = StatboticsTeamEvent.fromJson(original.toJson()); + expect(restored.teamName, 'Spectrum'); + expect(restored.team, 3847); + expect(restored.event, '2026txhou'); + expect(restored.eventName, 'Houston'); + expect(restored.year, 2026); + expect(restored.wins, 1); + expect(restored.losses, 0); + expect(restored.ties, 0); + expect(restored.rank, 7); + expect(restored.numTeams, 42); + expect(restored.epa.totalPointsMean, closeTo(41.2, 0.01)); + expect(restored.epa.autoPointsMean, closeTo(9.5, 0.01)); + }); + + test('StatboticsTeamEvent.toJson round-trips an empty team_name', () { + final original = StatboticsTeamEvent.fromJson({ + 'team': 111, + 'event': '2026x', + 'event_name': 'X', + 'year': 2026, + 'wins': 0, + 'losses': 0, + 'ties': 0, + 'epa': {}, + }); + final restored = StatboticsTeamEvent.fromJson(original.toJson()); + expect(restored.teamName, isEmpty); + }); + test('StatboticsTeamEvent.record omits ties when zero', () { final te = StatboticsTeamEvent.fromJson({ 'team': 1234,