blob: 6df15def9cc46d38571d53d33857e9377bbd55f8 [file] [log] [blame]
Philipp Schradercdb5cfc2022-02-20 14:57:07 -08001package requests
2
3import (
4 "bytes"
5 "io"
6 "net/http"
Philipp Schradercbf5c6a2022-02-27 23:25:19 -08007 "reflect"
Philipp Schradercdb5cfc2022-02-20 14:57:07 -08008 "testing"
9
Philipp Schrader8747f1b2022-02-23 23:56:22 -080010 "github.com/frc971/971-Robot-Code/scouting/db"
Philipp Schradercbf5c6a2022-02-27 23:25:19 -080011 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/debug"
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080012 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/error_response"
Emily Markova290147d2023-03-03 22:40:06 -080013 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_2023_data_scouting"
14 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_2023_data_scouting_response"
Filip Kujawaf882e022022-12-14 13:14:08 -080015 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_driver_rankings"
16 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_driver_rankings_response"
Philipp Schradercbf5c6a2022-02-27 23:25:19 -080017 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_matches"
18 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_matches_response"
Filip Kujawaf882e022022-12-14 13:14:08 -080019 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_notes"
20 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_notes_response"
Philipp Schraderacf96232022-03-01 22:03:30 -080021 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_data_scouting"
22 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_data_scouting_response"
Alex Perry81f96ba2022-03-13 18:26:19 -070023 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_notes_for_team"
Milo Lin1d59f0c2022-06-22 20:30:58 -070024 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_shift_schedule"
25 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_shift_schedule_response"
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080026 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting"
Philipp Schrader30005e42022-03-06 13:53:58 -080027 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting_response"
Filip Kujawa210a03b2022-11-24 14:41:11 -080028 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_driver_ranking"
Alex Perry81f96ba2022-03-13 18:26:19 -070029 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes"
Milo Lin1d59f0c2022-06-22 20:30:58 -070030 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_shift_schedule"
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080031 "github.com/frc971/971-Robot-Code/scouting/webserver/server"
32 flatbuffers "github.com/google/flatbuffers/go"
33)
34
35// Validates that an unhandled address results in a 404.
36func Test404(t *testing.T) {
Philipp Schrader8747f1b2022-02-23 23:56:22 -080037 db := MockDatabase{}
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080038 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -080039 HandleRequests(&db, scoutingServer)
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080040 scoutingServer.Start(8080)
41 defer scoutingServer.Stop()
42
43 resp, err := http.Get("http://localhost:8080/requests/foo")
44 if err != nil {
45 t.Fatalf("Failed to get data: %v", err)
46 }
47 if resp.StatusCode != http.StatusNotFound {
48 t.Fatalf("Expected error code 404, but got %d instead", resp.Status)
49 }
50}
51
52// Validates that we can submit new data scouting data.
53func TestSubmitDataScoutingError(t *testing.T) {
Philipp Schrader8747f1b2022-02-23 23:56:22 -080054 db := MockDatabase{}
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080055 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -080056 HandleRequests(&db, scoutingServer)
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080057 scoutingServer.Start(8080)
58 defer scoutingServer.Stop()
59
60 resp, err := http.Post("http://localhost:8080/requests/submit/data_scouting", "application/octet-stream", bytes.NewReader([]byte("")))
61 if err != nil {
62 t.Fatalf("Failed to send request: %v", err)
63 }
64 if resp.StatusCode != http.StatusBadRequest {
65 t.Fatal("Unexpected status code. Got", resp.Status)
66 }
67
68 responseBytes, err := io.ReadAll(resp.Body)
69 if err != nil {
70 t.Fatal("Failed to read response bytes:", err)
71 }
72 errorResponse := error_response.GetRootAsErrorResponse(responseBytes, 0)
73
74 errorMessage := string(errorResponse.ErrorMessage())
75 if errorMessage != "Failed to parse SubmitDataScouting: runtime error: index out of range [3] with length 0" {
76 t.Fatal("Got mismatched error message:", errorMessage)
77 }
78}
79
80// Validates that we can submit new data scouting data.
81func TestSubmitDataScouting(t *testing.T) {
Philipp Schrader8747f1b2022-02-23 23:56:22 -080082 db := MockDatabase{}
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080083 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -080084 HandleRequests(&db, scoutingServer)
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080085 scoutingServer.Start(8080)
86 defer scoutingServer.Stop()
87
88 builder := flatbuffers.NewBuilder(1024)
89 builder.Finish((&submit_data_scouting.SubmitDataScoutingT{
Philipp Schraderfa45d742022-03-18 19:29:05 -070090 Team: 971,
91 Match: 1,
Philipp Schrader30b4a682022-04-16 14:36:17 -070092 SetNumber: 8,
Philipp Schrader4535b7e2022-04-08 20:27:00 -070093 CompLevel: "quals",
Philipp Schraderfa45d742022-03-18 19:29:05 -070094 StartingQuadrant: 2,
95 AutoBall1: true,
96 AutoBall2: false,
97 AutoBall3: false,
98 AutoBall4: false,
99 AutoBall5: false,
100 MissedShotsAuto: 9971,
101 UpperGoalAuto: 9971,
102 LowerGoalAuto: 9971,
103 MissedShotsTele: 9971,
104 UpperGoalTele: 9971,
105 LowerGoalTele: 9971,
106 DefenseRating: 9971,
107 DefenseReceivedRating: 4,
108 ClimbLevel: submit_data_scouting.ClimbLevelLow,
109 Comment: "this is a comment",
Philipp Schradercdb5cfc2022-02-20 14:57:07 -0800110 }).Pack(builder))
111
Philipp Schrader30005e42022-03-06 13:53:58 -0800112 response, err := debug.SubmitDataScouting("http://localhost:8080", builder.FinishedBytes())
Philipp Schradercdb5cfc2022-02-20 14:57:07 -0800113 if err != nil {
Philipp Schrader30005e42022-03-06 13:53:58 -0800114 t.Fatal("Failed to submit data scouting: ", err)
Philipp Schradercdb5cfc2022-02-20 14:57:07 -0800115 }
Philipp Schrader30005e42022-03-06 13:53:58 -0800116
117 // We get an empty response back. Validate that.
118 expected := submit_data_scouting_response.SubmitDataScoutingResponseT{}
119 if !reflect.DeepEqual(expected, *response) {
120 t.Fatal("Expected ", expected, ", but got:", *response)
Philipp Schradercdb5cfc2022-02-20 14:57:07 -0800121 }
Philipp Schradercdb5cfc2022-02-20 14:57:07 -0800122}
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800123
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800124// Validates that we can request the full match list.
125func TestRequestAllMatches(t *testing.T) {
126 db := MockDatabase{
Emily Markovabf24c9e2023-02-08 20:31:11 -0800127 matches: []db.TeamMatch{
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800128 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800129 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800130 Alliance: "R", AlliancePosition: 1, TeamNumber: 5,
131 },
132 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800133 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800134 Alliance: "R", AlliancePosition: 2, TeamNumber: 42,
135 },
136 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800137 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800138 Alliance: "R", AlliancePosition: 3, TeamNumber: 600,
139 },
140 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800141 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800142 Alliance: "B", AlliancePosition: 1, TeamNumber: 971,
143 },
144 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800145 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800146 Alliance: "B", AlliancePosition: 2, TeamNumber: 400,
147 },
148 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800149 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800150 Alliance: "B", AlliancePosition: 3, TeamNumber: 200,
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800151 },
152 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800153 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800154 Alliance: "R", AlliancePosition: 1, TeamNumber: 6,
155 },
156 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800157 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800158 Alliance: "R", AlliancePosition: 2, TeamNumber: 43,
159 },
160 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800161 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800162 Alliance: "R", AlliancePosition: 3, TeamNumber: 601,
163 },
164 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800165 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800166 Alliance: "B", AlliancePosition: 1, TeamNumber: 972,
167 },
168 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800169 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800170 Alliance: "B", AlliancePosition: 2, TeamNumber: 401,
171 },
172 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800173 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800174 Alliance: "B", AlliancePosition: 3, TeamNumber: 201,
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800175 },
176 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800177 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800178 Alliance: "R", AlliancePosition: 1, TeamNumber: 7,
179 },
180 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800181 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800182 Alliance: "R", AlliancePosition: 2, TeamNumber: 44,
183 },
184 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800185 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800186 Alliance: "R", AlliancePosition: 3, TeamNumber: 602,
187 },
188 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800189 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800190 Alliance: "B", AlliancePosition: 1, TeamNumber: 973,
191 },
192 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800193 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800194 Alliance: "B", AlliancePosition: 2, TeamNumber: 402,
195 },
196 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800197 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800198 Alliance: "B", AlliancePosition: 3, TeamNumber: 202,
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800199 },
200 },
201 }
202 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800203 HandleRequests(&db, scoutingServer)
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800204 scoutingServer.Start(8080)
205 defer scoutingServer.Stop()
206
207 builder := flatbuffers.NewBuilder(1024)
208 builder.Finish((&request_all_matches.RequestAllMatchesT{}).Pack(builder))
209
210 response, err := debug.RequestAllMatches("http://localhost:8080", builder.FinishedBytes())
211 if err != nil {
212 t.Fatal("Failed to request all matches: ", err)
213 }
214
215 expected := request_all_matches_response.RequestAllMatchesResponseT{
216 MatchList: []*request_all_matches_response.MatchT{
Philipp Schrader30b4a682022-04-16 14:36:17 -0700217 // MatchNumber, SetNumber, CompLevel
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800218 // R1, R2, R3, B1, B2, B3
219 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800220 1, 1, "qm",
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800221 5, 42, 600, 971, 400, 200,
222 },
223 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800224 2, 1, "qm",
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800225 6, 43, 601, 972, 401, 201,
226 },
227 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800228 3, 1, "qm",
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800229 7, 44, 602, 973, 402, 202,
230 },
231 },
232 }
233 if len(expected.MatchList) != len(response.MatchList) {
234 t.Fatal("Expected ", expected, ", but got ", *response)
235 }
236 for i, match := range expected.MatchList {
237 if !reflect.DeepEqual(*match, *response.MatchList[i]) {
238 t.Fatal("Expected for match", i, ":", *match, ", but got:", *response.MatchList[i])
239 }
240 }
Philipp Schrader30005e42022-03-06 13:53:58 -0800241
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800242}
243
Philipp Schraderacf96232022-03-01 22:03:30 -0800244// Validates that we can request the stats.
245func TestRequestDataScouting(t *testing.T) {
246 db := MockDatabase{
247 stats: []db.Stats{
248 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700249 TeamNumber: 971, MatchNumber: 1, SetNumber: 2, CompLevel: "quals",
Philipp Schraderfee07e12022-03-17 22:19:47 -0700250 StartingQuadrant: 1,
251 AutoBallPickedUp: [5]bool{true, false, false, false, true},
252 ShotsMissed: 1, UpperGoalShots: 2, LowerGoalShots: 3,
Philipp Schraderacf96232022-03-01 22:03:30 -0800253 ShotsMissedAuto: 4, UpperGoalAuto: 5, LowerGoalAuto: 6,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700254 PlayedDefense: 7, DefenseReceivedScore: 3, Climbing: 2,
255 Comment: "a lovely comment", CollectedBy: "john",
Philipp Schraderacf96232022-03-01 22:03:30 -0800256 },
257 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700258 TeamNumber: 972, MatchNumber: 1, SetNumber: 4, CompLevel: "extra",
Philipp Schraderfee07e12022-03-17 22:19:47 -0700259 StartingQuadrant: 2,
260 AutoBallPickedUp: [5]bool{false, false, true, false, false},
261 ShotsMissed: 2, UpperGoalShots: 3, LowerGoalShots: 4,
Philipp Schraderacf96232022-03-01 22:03:30 -0800262 ShotsMissedAuto: 5, UpperGoalAuto: 6, LowerGoalAuto: 7,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700263 PlayedDefense: 8, DefenseReceivedScore: 1, Climbing: 4,
264 Comment: "another lovely comment", CollectedBy: "andrea",
Philipp Schraderacf96232022-03-01 22:03:30 -0800265 },
266 },
267 }
268 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800269 HandleRequests(&db, scoutingServer)
Philipp Schraderacf96232022-03-01 22:03:30 -0800270 scoutingServer.Start(8080)
271 defer scoutingServer.Stop()
272
273 builder := flatbuffers.NewBuilder(1024)
274 builder.Finish((&request_data_scouting.RequestDataScoutingT{}).Pack(builder))
275
276 response, err := debug.RequestDataScouting("http://localhost:8080", builder.FinishedBytes())
277 if err != nil {
278 t.Fatal("Failed to request all matches: ", err)
279 }
280
281 expected := request_data_scouting_response.RequestDataScoutingResponseT{
282 StatsList: []*request_data_scouting_response.StatsT{
Philipp Schraderacf96232022-03-01 22:03:30 -0800283 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700284 Team: 971, Match: 1, SetNumber: 2, CompLevel: "quals",
Philipp Schrader36df73a2022-03-17 23:27:24 -0700285 MissedShotsAuto: 4, UpperGoalAuto: 5, LowerGoalAuto: 6,
286 MissedShotsTele: 1, UpperGoalTele: 2, LowerGoalTele: 3,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700287 DefenseRating: 7,
288 DefenseReceivedRating: 3,
289 CollectedBy: "john",
290 AutoBall1: true, AutoBall2: false, AutoBall3: false,
Philipp Schrader36df73a2022-03-17 23:27:24 -0700291 AutoBall4: false, AutoBall5: true,
292 StartingQuadrant: 1,
293 ClimbLevel: request_data_scouting_response.ClimbLevelFailedWithPlentyOfTime,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700294 Comment: "a lovely comment",
Philipp Schraderacf96232022-03-01 22:03:30 -0800295 },
296 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700297 Team: 972, Match: 1, SetNumber: 4, CompLevel: "extra",
Philipp Schrader36df73a2022-03-17 23:27:24 -0700298 MissedShotsAuto: 5, UpperGoalAuto: 6, LowerGoalAuto: 7,
299 MissedShotsTele: 2, UpperGoalTele: 3, LowerGoalTele: 4,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700300 DefenseRating: 8,
301 DefenseReceivedRating: 1,
302 CollectedBy: "andrea",
303 AutoBall1: false, AutoBall2: false, AutoBall3: true,
Philipp Schrader36df73a2022-03-17 23:27:24 -0700304 AutoBall4: false, AutoBall5: false,
305 StartingQuadrant: 2,
306 ClimbLevel: request_data_scouting_response.ClimbLevelMedium,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700307 Comment: "another lovely comment",
Philipp Schraderacf96232022-03-01 22:03:30 -0800308 },
309 },
310 }
311 if len(expected.StatsList) != len(response.StatsList) {
312 t.Fatal("Expected ", expected, ", but got ", *response)
313 }
314 for i, match := range expected.StatsList {
315 if !reflect.DeepEqual(*match, *response.StatsList[i]) {
316 t.Fatal("Expected for stats", i, ":", *match, ", but got:", *response.StatsList[i])
317 }
318 }
319}
320
Emily Markova290147d2023-03-03 22:40:06 -0800321// Validates that we can request the 2023 stats.
322func TestRequest2023DataScouting(t *testing.T) {
323 db := MockDatabase{
324 stats2023: []db.Stats2023{
325 {
326 TeamNumber: "3634", MatchNumber: 1, SetNumber: 2,
327 CompLevel: "quals", StartingQuadrant: 3, LowCubesAuto: 10,
328 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 0,
329 LowConesAuto: 1, MiddleConesAuto: 2, HighConesAuto: 1,
330 ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
331 HighCubes: 2, CubesDropped: 1, LowCones: 1,
332 MiddleCones: 2, HighCones: 0, ConesDropped: 1,
333 AvgCycle: 34, CollectedBy: "isaac",
334 },
335 {
336 TeamNumber: "2343", MatchNumber: 1, SetNumber: 2,
337 CompLevel: "quals", StartingQuadrant: 1, LowCubesAuto: 0,
338 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 2,
339 LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
340 ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
341 HighCubes: 1, CubesDropped: 0, LowCones: 0,
342 MiddleCones: 2, HighCones: 1, ConesDropped: 1,
343 AvgCycle: 53, CollectedBy: "unknown",
344 },
345 },
346 }
347 scoutingServer := server.NewScoutingServer()
348 HandleRequests(&db, scoutingServer)
349 scoutingServer.Start(8080)
350 defer scoutingServer.Stop()
351
352 builder := flatbuffers.NewBuilder(1024)
353 builder.Finish((&request_2023_data_scouting.Request2023DataScoutingT{}).Pack(builder))
354
355 response, err := debug.Request2023DataScouting("http://localhost:8080", builder.FinishedBytes())
356 if err != nil {
357 t.Fatal("Failed to request all matches: ", err)
358 }
359
360 expected := request_2023_data_scouting_response.Request2023DataScoutingResponseT{
361 StatsList: []*request_2023_data_scouting_response.Stats2023T{
362 {
363 TeamNumber: "3634", MatchNumber: 1, SetNumber: 2,
364 CompLevel: "quals", StartingQuadrant: 3, LowCubesAuto: 10,
365 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 0,
366 LowConesAuto: 1, MiddleConesAuto: 2, HighConesAuto: 1,
367 ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
368 HighCubes: 2, CubesDropped: 1, LowCones: 1,
369 MiddleCones: 2, HighCones: 0, ConesDropped: 1,
370 AvgCycle: 34, CollectedBy: "isaac",
371 },
372 {
373 TeamNumber: "2343", MatchNumber: 1, SetNumber: 2,
374 CompLevel: "quals", StartingQuadrant: 1, LowCubesAuto: 0,
375 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 2,
376 LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
377 ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
378 HighCubes: 1, CubesDropped: 0, LowCones: 0,
379 MiddleCones: 2, HighCones: 1, ConesDropped: 1,
380 AvgCycle: 53, CollectedBy: "unknown",
381 },
382 },
383 }
384 if len(expected.StatsList) != len(response.StatsList) {
385 t.Fatal("Expected ", expected, ", but got ", *response)
386 }
387 for i, match := range expected.StatsList {
388 if !reflect.DeepEqual(*match, *response.StatsList[i]) {
389 t.Fatal("Expected for stats", i, ":", *match, ", but got:", *response.StatsList[i])
390 }
391 }
392}
393
Alex Perry81f96ba2022-03-13 18:26:19 -0700394func TestSubmitNotes(t *testing.T) {
395 database := MockDatabase{}
396 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800397 HandleRequests(&database, scoutingServer)
Alex Perry81f96ba2022-03-13 18:26:19 -0700398 scoutingServer.Start(8080)
399 defer scoutingServer.Stop()
400
401 builder := flatbuffers.NewBuilder(1024)
402 builder.Finish((&submit_notes.SubmitNotesT{
Filip Kujawaf947cb42022-11-21 10:00:30 -0800403 Team: 971,
404 Notes: "Notes",
405 GoodDriving: true,
406 BadDriving: false,
407 SketchyClimb: true,
408 SolidClimb: false,
409 GoodDefense: true,
410 BadDefense: false,
Alex Perry81f96ba2022-03-13 18:26:19 -0700411 }).Pack(builder))
412
413 _, err := debug.SubmitNotes("http://localhost:8080", builder.FinishedBytes())
414 if err != nil {
415 t.Fatal("Failed to submit notes: ", err)
416 }
417
418 expected := []db.NotesData{
Filip Kujawaf947cb42022-11-21 10:00:30 -0800419 {
420 TeamNumber: 971,
421 Notes: "Notes",
422 GoodDriving: true,
423 BadDriving: false,
424 SketchyClimb: true,
425 SolidClimb: false,
426 GoodDefense: true,
427 BadDefense: false,
428 },
Alex Perry81f96ba2022-03-13 18:26:19 -0700429 }
430
431 if !reflect.DeepEqual(database.notes, expected) {
432 t.Fatal("Submitted notes did not match", expected, database.notes)
433 }
434}
435
436func TestRequestNotes(t *testing.T) {
437 database := MockDatabase{
438 notes: []db.NotesData{{
Filip Kujawaf947cb42022-11-21 10:00:30 -0800439 TeamNumber: 971,
440 Notes: "Notes",
441 GoodDriving: true,
442 BadDriving: false,
443 SketchyClimb: true,
444 SolidClimb: false,
445 GoodDefense: true,
446 BadDefense: false,
Alex Perry81f96ba2022-03-13 18:26:19 -0700447 }},
448 }
449 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800450 HandleRequests(&database, scoutingServer)
Alex Perry81f96ba2022-03-13 18:26:19 -0700451 scoutingServer.Start(8080)
452 defer scoutingServer.Stop()
453
454 builder := flatbuffers.NewBuilder(1024)
455 builder.Finish((&request_notes_for_team.RequestNotesForTeamT{
456 Team: 971,
457 }).Pack(builder))
458 response, err := debug.RequestNotes("http://localhost:8080", builder.FinishedBytes())
459 if err != nil {
460 t.Fatal("Failed to submit notes: ", err)
461 }
462
463 if response.Notes[0].Data != "Notes" {
464 t.Fatal("requested notes did not match", response)
465 }
466}
467
Milo Lin1d59f0c2022-06-22 20:30:58 -0700468func TestRequestShiftSchedule(t *testing.T) {
469 db := MockDatabase{
470 shiftSchedule: []db.Shift{
471 {
472 MatchNumber: 1,
473 R1scouter: "Bob",
474 R2scouter: "James",
475 R3scouter: "Robert",
476 B1scouter: "Alice",
477 B2scouter: "Mary",
478 B3scouter: "Patricia",
479 },
480 {
481 MatchNumber: 2,
482 R1scouter: "Liam",
483 R2scouter: "Noah",
484 R3scouter: "Oliver",
485 B1scouter: "Emma",
486 B2scouter: "Charlotte",
487 B3scouter: "Amelia",
488 },
489 },
490 }
491 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800492 HandleRequests(&db, scoutingServer)
Milo Lin1d59f0c2022-06-22 20:30:58 -0700493 scoutingServer.Start(8080)
494 defer scoutingServer.Stop()
495
496 builder := flatbuffers.NewBuilder(1024)
497 builder.Finish((&request_shift_schedule.RequestShiftScheduleT{}).Pack(builder))
498
499 response, err := debug.RequestShiftSchedule("http://localhost:8080", builder.FinishedBytes())
500 if err != nil {
501 t.Fatal("Failed to request shift schedule: ", err)
502 }
503
504 expected := request_shift_schedule_response.RequestShiftScheduleResponseT{
505 ShiftSchedule: []*request_shift_schedule_response.MatchAssignmentT{
506 {
507 MatchNumber: 1,
508 R1scouter: "Bob",
509 R2scouter: "James",
510 R3scouter: "Robert",
511 B1scouter: "Alice",
512 B2scouter: "Mary",
513 B3scouter: "Patricia",
514 },
515 {
516 MatchNumber: 2,
517 R1scouter: "Liam",
518 R2scouter: "Noah",
519 R3scouter: "Oliver",
520 B1scouter: "Emma",
521 B2scouter: "Charlotte",
522 B3scouter: "Amelia",
523 },
524 },
525 }
526 if len(expected.ShiftSchedule) != len(response.ShiftSchedule) {
527 t.Fatal("Expected ", expected, ", but got ", *response)
528 }
529 for i, match := range expected.ShiftSchedule {
530 if !reflect.DeepEqual(*match, *response.ShiftSchedule[i]) {
531 t.Fatal("Expected for shift schedule", i, ":", *match, ", but got:", *response.ShiftSchedule[i])
532 }
533 }
534}
535
536func TestSubmitShiftSchedule(t *testing.T) {
537 database := MockDatabase{}
538 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800539 HandleRequests(&database, scoutingServer)
Milo Lin1d59f0c2022-06-22 20:30:58 -0700540 scoutingServer.Start(8080)
541 defer scoutingServer.Stop()
542
543 builder := flatbuffers.NewBuilder(1024)
544 builder.Finish((&submit_shift_schedule.SubmitShiftScheduleT{
545 ShiftSchedule: []*submit_shift_schedule.MatchAssignmentT{
546 {MatchNumber: 1,
547 R1scouter: "Bob",
548 R2scouter: "James",
549 R3scouter: "Robert",
550 B1scouter: "Alice",
551 B2scouter: "Mary",
552 B3scouter: "Patricia"},
553 },
554 }).Pack(builder))
555
556 _, err := debug.SubmitShiftSchedule("http://localhost:8080", builder.FinishedBytes())
557 if err != nil {
558 t.Fatal("Failed to submit shift schedule: ", err)
559 }
560
561 expected := []db.Shift{
562 {MatchNumber: 1,
563 R1scouter: "Bob",
564 R2scouter: "James",
565 R3scouter: "Robert",
566 B1scouter: "Alice",
567 B2scouter: "Mary",
568 B3scouter: "Patricia"},
569 }
570 if !reflect.DeepEqual(expected, database.shiftSchedule) {
571 t.Fatal("Expected ", expected, ", but got:", database.shiftSchedule)
572 }
573}
574
Filip Kujawa210a03b2022-11-24 14:41:11 -0800575func TestSubmitDriverRanking(t *testing.T) {
576 database := MockDatabase{}
577 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800578 HandleRequests(&database, scoutingServer)
Filip Kujawa210a03b2022-11-24 14:41:11 -0800579 scoutingServer.Start(8080)
580 defer scoutingServer.Stop()
581
582 builder := flatbuffers.NewBuilder(1024)
583 builder.Finish((&submit_driver_ranking.SubmitDriverRankingT{
584 MatchNumber: 36,
585 Rank1: 1234,
586 Rank2: 1235,
587 Rank3: 1236,
588 }).Pack(builder))
589
590 _, err := debug.SubmitDriverRanking("http://localhost:8080", builder.FinishedBytes())
591 if err != nil {
592 t.Fatal("Failed to submit driver ranking: ", err)
593 }
594
595 expected := []db.DriverRankingData{
596 {MatchNumber: 36, Rank1: 1234, Rank2: 1235, Rank3: 1236},
597 }
598
599 if !reflect.DeepEqual(database.driver_ranking, expected) {
600 t.Fatal("Submitted notes did not match", expected, database.notes)
601 }
602}
603
Filip Kujawaf882e022022-12-14 13:14:08 -0800604// Validates that we can request the driver rankings.
605func TestRequestDriverRankings(t *testing.T) {
606 db := MockDatabase{
607 driver_ranking: []db.DriverRankingData{
608 {
609 MatchNumber: 36,
610 Rank1: 1234,
611 Rank2: 1235,
612 Rank3: 1236,
613 },
614 {
615 MatchNumber: 36,
616 Rank1: 101,
617 Rank2: 202,
618 Rank3: 303,
619 },
620 },
621 }
622 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800623 HandleRequests(&db, scoutingServer)
Filip Kujawaf882e022022-12-14 13:14:08 -0800624 scoutingServer.Start(8080)
625 defer scoutingServer.Stop()
626
627 builder := flatbuffers.NewBuilder(1024)
628 builder.Finish((&request_all_driver_rankings.RequestAllDriverRankingsT{}).Pack(builder))
629
630 response, err := debug.RequestAllDriverRankings("http://localhost:8080", builder.FinishedBytes())
631 if err != nil {
632 t.Fatal("Failed to request all driver rankings: ", err)
633 }
634
635 expected := request_all_driver_rankings_response.RequestAllDriverRankingsResponseT{
636 DriverRankingList: []*request_all_driver_rankings_response.RankingT{
637 {
638 MatchNumber: 36,
639 Rank1: 1234,
640 Rank2: 1235,
641 Rank3: 1236,
642 },
643 {
644 MatchNumber: 36,
645 Rank1: 101,
646 Rank2: 202,
647 Rank3: 303,
648 },
649 },
650 }
651 if len(expected.DriverRankingList) != len(response.DriverRankingList) {
652 t.Fatal("Expected ", expected, ", but got ", *response)
653 }
654 for i, match := range expected.DriverRankingList {
655 if !reflect.DeepEqual(*match, *response.DriverRankingList[i]) {
656 t.Fatal("Expected for driver ranking", i, ":", *match, ", but got:", *response.DriverRankingList[i])
657 }
658 }
659}
660
661// Validates that we can request all notes.
662func TestRequestAllNotes(t *testing.T) {
663 db := MockDatabase{
664 notes: []db.NotesData{
665 {
666 TeamNumber: 971,
667 Notes: "Notes",
668 GoodDriving: true,
669 BadDriving: false,
670 SketchyClimb: true,
671 SolidClimb: false,
672 GoodDefense: true,
673 BadDefense: false,
674 },
675 {
676 TeamNumber: 972,
677 Notes: "More Notes",
678 GoodDriving: false,
679 BadDriving: false,
680 SketchyClimb: false,
681 SolidClimb: true,
682 GoodDefense: false,
683 BadDefense: true,
684 },
685 },
686 }
687 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800688 HandleRequests(&db, scoutingServer)
Filip Kujawaf882e022022-12-14 13:14:08 -0800689 scoutingServer.Start(8080)
690 defer scoutingServer.Stop()
691
692 builder := flatbuffers.NewBuilder(1024)
693 builder.Finish((&request_all_notes.RequestAllNotesT{}).Pack(builder))
694
695 response, err := debug.RequestAllNotes("http://localhost:8080", builder.FinishedBytes())
696 if err != nil {
697 t.Fatal("Failed to request all notes: ", err)
698 }
699
700 expected := request_all_notes_response.RequestAllNotesResponseT{
701 NoteList: []*request_all_notes_response.NoteT{
702 {
703 Team: 971,
704 Notes: "Notes",
705 GoodDriving: true,
706 BadDriving: false,
707 SketchyClimb: true,
708 SolidClimb: false,
709 GoodDefense: true,
710 BadDefense: false,
711 },
712 {
713 Team: 972,
714 Notes: "More Notes",
715 GoodDriving: false,
716 BadDriving: false,
717 SketchyClimb: false,
718 SolidClimb: true,
719 GoodDefense: false,
720 BadDefense: true,
721 },
722 },
723 }
724 if len(expected.NoteList) != len(response.NoteList) {
725 t.Fatal("Expected ", expected, ", but got ", *response)
726 }
727 for i, note := range expected.NoteList {
728 if !reflect.DeepEqual(*note, *response.NoteList[i]) {
729 t.Fatal("Expected for note", i, ":", *note, ", but got:", *response.NoteList[i])
730 }
731 }
732}
733
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800734// A mocked database we can use for testing. Add functionality to this as
735// needed for your tests.
736
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800737type MockDatabase struct {
Emily Markovabf24c9e2023-02-08 20:31:11 -0800738 matches []db.TeamMatch
Filip Kujawa210a03b2022-11-24 14:41:11 -0800739 stats []db.Stats
740 notes []db.NotesData
741 shiftSchedule []db.Shift
742 driver_ranking []db.DriverRankingData
Emily Markova290147d2023-03-03 22:40:06 -0800743 stats2023 []db.Stats2023
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800744}
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800745
Emily Markovabf24c9e2023-02-08 20:31:11 -0800746func (database *MockDatabase) AddToMatch(match db.TeamMatch) error {
Philipp Schraderd3fac192022-03-02 20:35:46 -0800747 database.matches = append(database.matches, match)
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800748 return nil
749}
750
Philipp Schrader30005e42022-03-06 13:53:58 -0800751func (database *MockDatabase) AddToStats(stats db.Stats) error {
752 database.stats = append(database.stats, stats)
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800753 return nil
754}
755
Emily Markova290147d2023-03-03 22:40:06 -0800756func (database *MockDatabase) AddToStats2023(stats2023 db.Stats2023) error {
757 database.stats2023 = append(database.stats2023, stats2023)
758 return nil
759}
Emily Markovabf24c9e2023-02-08 20:31:11 -0800760func (database *MockDatabase) ReturnMatches() ([]db.TeamMatch, error) {
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800761 return database.matches, nil
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800762}
763
764func (database *MockDatabase) ReturnStats() ([]db.Stats, error) {
Philipp Schraderacf96232022-03-01 22:03:30 -0800765 return database.stats, nil
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800766}
767
Emily Markova290147d2023-03-03 22:40:06 -0800768func (database *MockDatabase) ReturnStats2023() ([]db.Stats2023, error) {
769 return database.stats2023, nil
770}
771
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800772func (database *MockDatabase) QueryStats(int) ([]db.Stats, error) {
773 return []db.Stats{}, nil
774}
Philipp Schraderd3fac192022-03-02 20:35:46 -0800775
Philipp Schradereecb8962022-06-01 21:02:42 -0700776func (database *MockDatabase) QueryNotes(requestedTeam int32) ([]string, error) {
Alex Perry81f96ba2022-03-13 18:26:19 -0700777 var results []string
778 for _, data := range database.notes {
779 if data.TeamNumber == requestedTeam {
Philipp Schradereecb8962022-06-01 21:02:42 -0700780 results = append(results, data.Notes)
Alex Perry81f96ba2022-03-13 18:26:19 -0700781 }
782 }
Philipp Schradereecb8962022-06-01 21:02:42 -0700783 return results, nil
Alex Perry81f96ba2022-03-13 18:26:19 -0700784}
785
Filip Kujawaf947cb42022-11-21 10:00:30 -0800786func (database *MockDatabase) AddNotes(data db.NotesData) error {
787 database.notes = append(database.notes, data)
Alex Perry81f96ba2022-03-13 18:26:19 -0700788 return nil
789}
790
Filip Kujawaf882e022022-12-14 13:14:08 -0800791func (database *MockDatabase) ReturnAllNotes() ([]db.NotesData, error) {
792 return database.notes, nil
793}
794
Milo Lin1d59f0c2022-06-22 20:30:58 -0700795func (database *MockDatabase) AddToShift(data db.Shift) error {
796 database.shiftSchedule = append(database.shiftSchedule, data)
797 return nil
798}
799
800func (database *MockDatabase) ReturnAllShifts() ([]db.Shift, error) {
801 return database.shiftSchedule, nil
802}
803
804func (database *MockDatabase) QueryAllShifts(int) ([]db.Shift, error) {
805 return []db.Shift{}, nil
806}
807
Filip Kujawa210a03b2022-11-24 14:41:11 -0800808func (database *MockDatabase) AddDriverRanking(data db.DriverRankingData) error {
809 database.driver_ranking = append(database.driver_ranking, data)
810 return nil
811}
812
Filip Kujawaf882e022022-12-14 13:14:08 -0800813func (database *MockDatabase) ReturnAllDriverRankings() ([]db.DriverRankingData, error) {
814 return database.driver_ranking, nil
815}