@@ -102,6 +102,11 @@ func TestBuildFeed_WithVehicles(t *testing.T) {
102102
103103 require .NotNil (t , bus2 )
104104 assert .Nil (t , bus2 .Vehicle .Trip , "bus-2 has no trip, Trip should be nil" )
105+
106+ // E012: header timestamp must be >= max entity timestamp.
107+ // 1752566500 is the larger of the two vehicle timestamps above (bus-2).
108+ assert .GreaterOrEqual (t , feed .Header .GetTimestamp (), uint64 (1752566500 ),
109+ "header timestamp must be >= max entity timestamp (E012)" )
105110}
106111
107112func TestGetFeed_Protobuf (t * testing.T ) {
@@ -231,6 +236,36 @@ func TestHandlePostLocation_Validation(t *testing.T) {
231236 loc : LocationReport {VehicleID : "bus-1" , Latitude : 1 , Longitude : 2 , Timestamp : time .Now ().Unix () + 600 },
232237 want : "timestamp must be within 5 minutes of server time" ,
233238 },
239+ {
240+ name : "bearing negative" ,
241+ loc : LocationReport {VehicleID : "bus-1" , Latitude : 1 , Longitude : 2 , Bearing : - 1 , Timestamp : time .Now ().Unix ()},
242+ want : "bearing must be between 0 and 360 (inclusive)" ,
243+ },
244+ {
245+ name : "bearing too high" ,
246+ loc : LocationReport {VehicleID : "bus-1" , Latitude : 1 , Longitude : 2 , Bearing : 361 , Timestamp : time .Now ().Unix ()},
247+ want : "bearing must be between 0 and 360 (inclusive)" ,
248+ },
249+ {
250+ name : "speed negative" ,
251+ loc : LocationReport {VehicleID : "bus-1" , Latitude : 1 , Longitude : 2 , Speed : - 5 , Timestamp : time .Now ().Unix ()},
252+ want : "speed must be non-negative" ,
253+ },
254+ {
255+ name : "bearing just below zero" ,
256+ loc : LocationReport {VehicleID : "bus-1" , Latitude : 1 , Longitude : 2 , Bearing : - 0.001 , Timestamp : time .Now ().Unix ()},
257+ want : "bearing must be between 0 and 360 (inclusive)" ,
258+ },
259+ {
260+ name : "bearing just above 360" ,
261+ loc : LocationReport {VehicleID : "bus-1" , Latitude : 1 , Longitude : 2 , Bearing : 360.001 , Timestamp : time .Now ().Unix ()},
262+ want : "bearing must be between 0 and 360 (inclusive)" ,
263+ },
264+ {
265+ name : "speed just below zero" ,
266+ loc : LocationReport {VehicleID : "bus-1" , Latitude : 1 , Longitude : 2 , Speed : - 0.001 , Timestamp : time .Now ().Unix ()},
267+ want : "speed must be non-negative" ,
268+ },
234269 }
235270
236271 for _ , tc := range tests {
@@ -669,3 +704,37 @@ func TestHandlePostLocation_RateLimitDifferentVehiclesAreIndependent(t *testing.
669704 assert .Equal (t , http .StatusTooManyRequests , postLocationWithClaims (handler , locA , claimsA ).Code )
670705 assert .Equal (t , http .StatusTooManyRequests , postLocationWithClaims (handler , locB , claimsB ).Code )
671706}
707+
708+ func TestHandlePostLocation_BearingSpeedBoundaries (t * testing.T ) {
709+ tracker := NewTracker (5 * time .Minute )
710+ defer tracker .Stop ()
711+
712+ tests := []struct {
713+ name string
714+ sub string
715+ loc LocationReport
716+ }{
717+ {"bearing exactly 0 (north)" , "driver-bearing-0" , LocationReport {
718+ VehicleID : "bus-1" , Latitude : 1 , Longitude : 2 ,
719+ Bearing : 0 , Timestamp : time .Now ().Unix ()}},
720+ {"bearing exactly 360" , "driver-bearing-360" , LocationReport {
721+ VehicleID : "bus-2" , Latitude : 1 , Longitude : 2 ,
722+ Bearing : 360 , Timestamp : time .Now ().Unix ()}},
723+ {"bearing 359.99" , "driver-bearing-359" , LocationReport {
724+ VehicleID : "bus-3" , Latitude : 1 , Longitude : 2 ,
725+ Bearing : 359.99 , Timestamp : time .Now ().Unix ()}},
726+ {"speed exactly 0 (stationary)" , "driver-speed-0" , LocationReport {
727+ VehicleID : "bus-4" , Latitude : 1 , Longitude : 2 ,
728+ Speed : 0 , Timestamp : time .Now ().Unix ()}},
729+ }
730+
731+ for _ , tc := range tests {
732+ t .Run (tc .name , func (t * testing.T ) {
733+ mStore := & mockStore {}
734+ handler := handlePostLocation (mStore , tracker , NewVehicleRateLimiter ())
735+ w := postLocationWithClaims (handler , tc .loc , jwt.MapClaims {"sub" : tc .sub })
736+ assert .Equal (t , http .StatusCreated , w .Code , "boundary value should be accepted" )
737+ assert .True (t , mStore .saved , "boundary value should have been saved" )
738+ })
739+ }
740+ }
0 commit comments