blob: 85ab9168762200e87d4065a9c9939163b49e1981 [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 Schraderd3fac192022-03-02 20:35:46 -080011 "github.com/frc971/971-Robot-Code/scouting/scraping"
Philipp Schradercbf5c6a2022-02-27 23:25:19 -080012 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/debug"
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080013 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/error_response"
Philipp Schraderd3fac192022-03-02 20:35:46 -080014 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/refresh_match_list"
15 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/refresh_match_list_response"
Philipp Schradercbf5c6a2022-02-27 23:25:19 -080016 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_matches"
17 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_matches_response"
Philipp Schraderacf96232022-03-01 22:03:30 -080018 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_data_scouting"
19 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_data_scouting_response"
Philipp Schraderd1c4bef2022-02-28 22:51:30 -080020 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_matches_for_team"
21 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_matches_for_team_response"
Alex Perry81f96ba2022-03-13 18:26:19 -070022 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_notes_for_team"
Milo Lin1d59f0c2022-06-22 20:30:58 -070023 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_shift_schedule"
24 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_shift_schedule_response"
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080025 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting"
Philipp Schrader30005e42022-03-06 13:53:58 -080026 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting_response"
Alex Perry81f96ba2022-03-13 18:26:19 -070027 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes"
Milo Lin1d59f0c2022-06-22 20:30:58 -070028 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_shift_schedule"
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080029 "github.com/frc971/971-Robot-Code/scouting/webserver/server"
30 flatbuffers "github.com/google/flatbuffers/go"
31)
32
33// Validates that an unhandled address results in a 404.
34func Test404(t *testing.T) {
Philipp Schrader8747f1b2022-02-23 23:56:22 -080035 db := MockDatabase{}
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080036 scoutingServer := server.NewScoutingServer()
Philipp Schraderd3fac192022-03-02 20:35:46 -080037 HandleRequests(&db, scrapeEmtpyMatchList, scoutingServer)
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080038 scoutingServer.Start(8080)
39 defer scoutingServer.Stop()
40
41 resp, err := http.Get("http://localhost:8080/requests/foo")
42 if err != nil {
43 t.Fatalf("Failed to get data: %v", err)
44 }
45 if resp.StatusCode != http.StatusNotFound {
46 t.Fatalf("Expected error code 404, but got %d instead", resp.Status)
47 }
48}
49
50// Validates that we can submit new data scouting data.
51func TestSubmitDataScoutingError(t *testing.T) {
Philipp Schrader8747f1b2022-02-23 23:56:22 -080052 db := MockDatabase{}
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080053 scoutingServer := server.NewScoutingServer()
Philipp Schraderd3fac192022-03-02 20:35:46 -080054 HandleRequests(&db, scrapeEmtpyMatchList, scoutingServer)
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080055 scoutingServer.Start(8080)
56 defer scoutingServer.Stop()
57
58 resp, err := http.Post("http://localhost:8080/requests/submit/data_scouting", "application/octet-stream", bytes.NewReader([]byte("")))
59 if err != nil {
60 t.Fatalf("Failed to send request: %v", err)
61 }
62 if resp.StatusCode != http.StatusBadRequest {
63 t.Fatal("Unexpected status code. Got", resp.Status)
64 }
65
66 responseBytes, err := io.ReadAll(resp.Body)
67 if err != nil {
68 t.Fatal("Failed to read response bytes:", err)
69 }
70 errorResponse := error_response.GetRootAsErrorResponse(responseBytes, 0)
71
72 errorMessage := string(errorResponse.ErrorMessage())
73 if errorMessage != "Failed to parse SubmitDataScouting: runtime error: index out of range [3] with length 0" {
74 t.Fatal("Got mismatched error message:", errorMessage)
75 }
76}
77
78// Validates that we can submit new data scouting data.
79func TestSubmitDataScouting(t *testing.T) {
Philipp Schrader8747f1b2022-02-23 23:56:22 -080080 db := MockDatabase{}
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080081 scoutingServer := server.NewScoutingServer()
Philipp Schraderd3fac192022-03-02 20:35:46 -080082 HandleRequests(&db, scrapeEmtpyMatchList, scoutingServer)
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080083 scoutingServer.Start(8080)
84 defer scoutingServer.Stop()
85
86 builder := flatbuffers.NewBuilder(1024)
87 builder.Finish((&submit_data_scouting.SubmitDataScoutingT{
Philipp Schraderfa45d742022-03-18 19:29:05 -070088 Team: 971,
89 Match: 1,
Philipp Schrader30b4a682022-04-16 14:36:17 -070090 SetNumber: 8,
Philipp Schrader4535b7e2022-04-08 20:27:00 -070091 CompLevel: "quals",
Philipp Schraderfa45d742022-03-18 19:29:05 -070092 StartingQuadrant: 2,
93 AutoBall1: true,
94 AutoBall2: false,
95 AutoBall3: false,
96 AutoBall4: false,
97 AutoBall5: false,
98 MissedShotsAuto: 9971,
99 UpperGoalAuto: 9971,
100 LowerGoalAuto: 9971,
101 MissedShotsTele: 9971,
102 UpperGoalTele: 9971,
103 LowerGoalTele: 9971,
104 DefenseRating: 9971,
105 DefenseReceivedRating: 4,
106 ClimbLevel: submit_data_scouting.ClimbLevelLow,
107 Comment: "this is a comment",
Philipp Schradercdb5cfc2022-02-20 14:57:07 -0800108 }).Pack(builder))
109
Philipp Schrader30005e42022-03-06 13:53:58 -0800110 response, err := debug.SubmitDataScouting("http://localhost:8080", builder.FinishedBytes())
Philipp Schradercdb5cfc2022-02-20 14:57:07 -0800111 if err != nil {
Philipp Schrader30005e42022-03-06 13:53:58 -0800112 t.Fatal("Failed to submit data scouting: ", err)
Philipp Schradercdb5cfc2022-02-20 14:57:07 -0800113 }
Philipp Schrader30005e42022-03-06 13:53:58 -0800114
115 // We get an empty response back. Validate that.
116 expected := submit_data_scouting_response.SubmitDataScoutingResponseT{}
117 if !reflect.DeepEqual(expected, *response) {
118 t.Fatal("Expected ", expected, ", but got:", *response)
Philipp Schradercdb5cfc2022-02-20 14:57:07 -0800119 }
Philipp Schradercdb5cfc2022-02-20 14:57:07 -0800120}
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800121
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800122// Validates that we can request the full match list.
123func TestRequestAllMatches(t *testing.T) {
124 db := MockDatabase{
125 matches: []db.Match{
126 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700127 MatchNumber: 1, SetNumber: 1, CompLevel: "qual",
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800128 R1: 5, R2: 42, R3: 600, B1: 971, B2: 400, B3: 200,
129 },
130 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700131 MatchNumber: 2, SetNumber: 1, CompLevel: "qual",
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800132 R1: 6, R2: 43, R3: 601, B1: 972, B2: 401, B3: 201,
133 },
134 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700135 MatchNumber: 3, SetNumber: 1, CompLevel: "qual",
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800136 R1: 7, R2: 44, R3: 602, B1: 973, B2: 402, B3: 202,
137 },
138 },
139 }
140 scoutingServer := server.NewScoutingServer()
Philipp Schraderd3fac192022-03-02 20:35:46 -0800141 HandleRequests(&db, scrapeEmtpyMatchList, scoutingServer)
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800142 scoutingServer.Start(8080)
143 defer scoutingServer.Stop()
144
145 builder := flatbuffers.NewBuilder(1024)
146 builder.Finish((&request_all_matches.RequestAllMatchesT{}).Pack(builder))
147
148 response, err := debug.RequestAllMatches("http://localhost:8080", builder.FinishedBytes())
149 if err != nil {
150 t.Fatal("Failed to request all matches: ", err)
151 }
152
153 expected := request_all_matches_response.RequestAllMatchesResponseT{
154 MatchList: []*request_all_matches_response.MatchT{
Philipp Schrader30b4a682022-04-16 14:36:17 -0700155 // MatchNumber, SetNumber, CompLevel
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800156 // R1, R2, R3, B1, B2, B3
157 {
158 1, 1, "qual",
159 5, 42, 600, 971, 400, 200,
160 },
161 {
162 2, 1, "qual",
163 6, 43, 601, 972, 401, 201,
164 },
165 {
166 3, 1, "qual",
167 7, 44, 602, 973, 402, 202,
168 },
169 },
170 }
171 if len(expected.MatchList) != len(response.MatchList) {
172 t.Fatal("Expected ", expected, ", but got ", *response)
173 }
174 for i, match := range expected.MatchList {
175 if !reflect.DeepEqual(*match, *response.MatchList[i]) {
176 t.Fatal("Expected for match", i, ":", *match, ", but got:", *response.MatchList[i])
177 }
178 }
Philipp Schrader30005e42022-03-06 13:53:58 -0800179
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800180}
181
Philipp Schraderd1c4bef2022-02-28 22:51:30 -0800182// Validates that we can request the full match list.
183func TestRequestMatchesForTeam(t *testing.T) {
184 db := MockDatabase{
185 matches: []db.Match{
186 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700187 MatchNumber: 1, SetNumber: 1, CompLevel: "qual",
Philipp Schraderd1c4bef2022-02-28 22:51:30 -0800188 R1: 5, R2: 42, R3: 600, B1: 971, B2: 400, B3: 200,
189 },
190 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700191 MatchNumber: 2, SetNumber: 1, CompLevel: "qual",
Philipp Schraderd1c4bef2022-02-28 22:51:30 -0800192 R1: 6, R2: 43, R3: 601, B1: 972, B2: 401, B3: 201,
193 },
194 },
195 }
196 scoutingServer := server.NewScoutingServer()
Philipp Schraderd3fac192022-03-02 20:35:46 -0800197 HandleRequests(&db, scrapeEmtpyMatchList, scoutingServer)
Philipp Schraderd1c4bef2022-02-28 22:51:30 -0800198 scoutingServer.Start(8080)
199 defer scoutingServer.Stop()
200
201 builder := flatbuffers.NewBuilder(1024)
202 builder.Finish((&request_matches_for_team.RequestMatchesForTeamT{
203 Team: 971,
204 }).Pack(builder))
205
206 response, err := debug.RequestMatchesForTeam("http://localhost:8080", builder.FinishedBytes())
207 if err != nil {
208 t.Fatal("Failed to request all matches: ", err)
209 }
210
211 expected := request_matches_for_team_response.RequestMatchesForTeamResponseT{
212 MatchList: []*request_matches_for_team_response.MatchT{
Philipp Schrader30b4a682022-04-16 14:36:17 -0700213 // MatchNumber, SetNumber, CompLevel
Philipp Schraderd1c4bef2022-02-28 22:51:30 -0800214 // R1, R2, R3, B1, B2, B3
215 {
216 1, 1, "qual",
217 5, 42, 600, 971, 400, 200,
218 },
219 },
220 }
221 if len(expected.MatchList) != len(response.MatchList) {
222 t.Fatal("Expected ", expected, ", but got ", *response)
223 }
224 for i, match := range expected.MatchList {
225 if !reflect.DeepEqual(*match, *response.MatchList[i]) {
226 t.Fatal("Expected for match", i, ":", *match, ", but got:", *response.MatchList[i])
227 }
228 }
229}
230
Philipp Schraderacf96232022-03-01 22:03:30 -0800231// Validates that we can request the stats.
232func TestRequestDataScouting(t *testing.T) {
233 db := MockDatabase{
234 stats: []db.Stats{
235 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700236 TeamNumber: 971, MatchNumber: 1, SetNumber: 2, CompLevel: "quals",
Philipp Schraderfee07e12022-03-17 22:19:47 -0700237 StartingQuadrant: 1,
238 AutoBallPickedUp: [5]bool{true, false, false, false, true},
239 ShotsMissed: 1, UpperGoalShots: 2, LowerGoalShots: 3,
Philipp Schraderacf96232022-03-01 22:03:30 -0800240 ShotsMissedAuto: 4, UpperGoalAuto: 5, LowerGoalAuto: 6,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700241 PlayedDefense: 7, DefenseReceivedScore: 3, Climbing: 2,
242 Comment: "a lovely comment", CollectedBy: "john",
Philipp Schraderacf96232022-03-01 22:03:30 -0800243 },
244 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700245 TeamNumber: 972, MatchNumber: 1, SetNumber: 4, CompLevel: "extra",
Philipp Schraderfee07e12022-03-17 22:19:47 -0700246 StartingQuadrant: 2,
247 AutoBallPickedUp: [5]bool{false, false, true, false, false},
248 ShotsMissed: 2, UpperGoalShots: 3, LowerGoalShots: 4,
Philipp Schraderacf96232022-03-01 22:03:30 -0800249 ShotsMissedAuto: 5, UpperGoalAuto: 6, LowerGoalAuto: 7,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700250 PlayedDefense: 8, DefenseReceivedScore: 1, Climbing: 4,
251 Comment: "another lovely comment", CollectedBy: "andrea",
Philipp Schraderacf96232022-03-01 22:03:30 -0800252 },
253 },
254 }
255 scoutingServer := server.NewScoutingServer()
Philipp Schraderd3fac192022-03-02 20:35:46 -0800256 HandleRequests(&db, scrapeEmtpyMatchList, scoutingServer)
Philipp Schraderacf96232022-03-01 22:03:30 -0800257 scoutingServer.Start(8080)
258 defer scoutingServer.Stop()
259
260 builder := flatbuffers.NewBuilder(1024)
261 builder.Finish((&request_data_scouting.RequestDataScoutingT{}).Pack(builder))
262
263 response, err := debug.RequestDataScouting("http://localhost:8080", builder.FinishedBytes())
264 if err != nil {
265 t.Fatal("Failed to request all matches: ", err)
266 }
267
268 expected := request_data_scouting_response.RequestDataScoutingResponseT{
269 StatsList: []*request_data_scouting_response.StatsT{
Philipp Schraderacf96232022-03-01 22:03:30 -0800270 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700271 Team: 971, Match: 1, SetNumber: 2, CompLevel: "quals",
Philipp Schrader36df73a2022-03-17 23:27:24 -0700272 MissedShotsAuto: 4, UpperGoalAuto: 5, LowerGoalAuto: 6,
273 MissedShotsTele: 1, UpperGoalTele: 2, LowerGoalTele: 3,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700274 DefenseRating: 7,
275 DefenseReceivedRating: 3,
276 CollectedBy: "john",
277 AutoBall1: true, AutoBall2: false, AutoBall3: false,
Philipp Schrader36df73a2022-03-17 23:27:24 -0700278 AutoBall4: false, AutoBall5: true,
279 StartingQuadrant: 1,
280 ClimbLevel: request_data_scouting_response.ClimbLevelFailedWithPlentyOfTime,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700281 Comment: "a lovely comment",
Philipp Schraderacf96232022-03-01 22:03:30 -0800282 },
283 {
Philipp Schrader30b4a682022-04-16 14:36:17 -0700284 Team: 972, Match: 1, SetNumber: 4, CompLevel: "extra",
Philipp Schrader36df73a2022-03-17 23:27:24 -0700285 MissedShotsAuto: 5, UpperGoalAuto: 6, LowerGoalAuto: 7,
286 MissedShotsTele: 2, UpperGoalTele: 3, LowerGoalTele: 4,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700287 DefenseRating: 8,
288 DefenseReceivedRating: 1,
289 CollectedBy: "andrea",
290 AutoBall1: false, AutoBall2: false, AutoBall3: true,
Philipp Schrader36df73a2022-03-17 23:27:24 -0700291 AutoBall4: false, AutoBall5: false,
292 StartingQuadrant: 2,
293 ClimbLevel: request_data_scouting_response.ClimbLevelMedium,
Philipp Schraderfa45d742022-03-18 19:29:05 -0700294 Comment: "another lovely comment",
Philipp Schraderacf96232022-03-01 22:03:30 -0800295 },
296 },
297 }
298 if len(expected.StatsList) != len(response.StatsList) {
299 t.Fatal("Expected ", expected, ", but got ", *response)
300 }
301 for i, match := range expected.StatsList {
302 if !reflect.DeepEqual(*match, *response.StatsList[i]) {
303 t.Fatal("Expected for stats", i, ":", *match, ", but got:", *response.StatsList[i])
304 }
305 }
306}
307
Alex Perry81f96ba2022-03-13 18:26:19 -0700308func TestSubmitNotes(t *testing.T) {
309 database := MockDatabase{}
310 scoutingServer := server.NewScoutingServer()
311 HandleRequests(&database, scrapeEmtpyMatchList, scoutingServer)
312 scoutingServer.Start(8080)
313 defer scoutingServer.Stop()
314
315 builder := flatbuffers.NewBuilder(1024)
316 builder.Finish((&submit_notes.SubmitNotesT{
Filip Kujawaf947cb42022-11-21 10:00:30 -0800317 Team: 971,
318 Notes: "Notes",
319 GoodDriving: true,
320 BadDriving: false,
321 SketchyClimb: true,
322 SolidClimb: false,
323 GoodDefense: true,
324 BadDefense: false,
Alex Perry81f96ba2022-03-13 18:26:19 -0700325 }).Pack(builder))
326
327 _, err := debug.SubmitNotes("http://localhost:8080", builder.FinishedBytes())
328 if err != nil {
329 t.Fatal("Failed to submit notes: ", err)
330 }
331
332 expected := []db.NotesData{
Filip Kujawaf947cb42022-11-21 10:00:30 -0800333 {
334 TeamNumber: 971,
335 Notes: "Notes",
336 GoodDriving: true,
337 BadDriving: false,
338 SketchyClimb: true,
339 SolidClimb: false,
340 GoodDefense: true,
341 BadDefense: false,
342 },
Alex Perry81f96ba2022-03-13 18:26:19 -0700343 }
344
345 if !reflect.DeepEqual(database.notes, expected) {
346 t.Fatal("Submitted notes did not match", expected, database.notes)
347 }
348}
349
350func TestRequestNotes(t *testing.T) {
351 database := MockDatabase{
352 notes: []db.NotesData{{
Filip Kujawaf947cb42022-11-21 10:00:30 -0800353 TeamNumber: 971,
354 Notes: "Notes",
355 GoodDriving: true,
356 BadDriving: false,
357 SketchyClimb: true,
358 SolidClimb: false,
359 GoodDefense: true,
360 BadDefense: false,
Alex Perry81f96ba2022-03-13 18:26:19 -0700361 }},
362 }
363 scoutingServer := server.NewScoutingServer()
364 HandleRequests(&database, scrapeEmtpyMatchList, scoutingServer)
365 scoutingServer.Start(8080)
366 defer scoutingServer.Stop()
367
368 builder := flatbuffers.NewBuilder(1024)
369 builder.Finish((&request_notes_for_team.RequestNotesForTeamT{
370 Team: 971,
371 }).Pack(builder))
372 response, err := debug.RequestNotes("http://localhost:8080", builder.FinishedBytes())
373 if err != nil {
374 t.Fatal("Failed to submit notes: ", err)
375 }
376
377 if response.Notes[0].Data != "Notes" {
378 t.Fatal("requested notes did not match", response)
379 }
380}
381
Milo Lin1d59f0c2022-06-22 20:30:58 -0700382func TestRequestShiftSchedule(t *testing.T) {
383 db := MockDatabase{
384 shiftSchedule: []db.Shift{
385 {
386 MatchNumber: 1,
387 R1scouter: "Bob",
388 R2scouter: "James",
389 R3scouter: "Robert",
390 B1scouter: "Alice",
391 B2scouter: "Mary",
392 B3scouter: "Patricia",
393 },
394 {
395 MatchNumber: 2,
396 R1scouter: "Liam",
397 R2scouter: "Noah",
398 R3scouter: "Oliver",
399 B1scouter: "Emma",
400 B2scouter: "Charlotte",
401 B3scouter: "Amelia",
402 },
403 },
404 }
405 scoutingServer := server.NewScoutingServer()
406 HandleRequests(&db, scrapeEmtpyMatchList, scoutingServer)
407 scoutingServer.Start(8080)
408 defer scoutingServer.Stop()
409
410 builder := flatbuffers.NewBuilder(1024)
411 builder.Finish((&request_shift_schedule.RequestShiftScheduleT{}).Pack(builder))
412
413 response, err := debug.RequestShiftSchedule("http://localhost:8080", builder.FinishedBytes())
414 if err != nil {
415 t.Fatal("Failed to request shift schedule: ", err)
416 }
417
418 expected := request_shift_schedule_response.RequestShiftScheduleResponseT{
419 ShiftSchedule: []*request_shift_schedule_response.MatchAssignmentT{
420 {
421 MatchNumber: 1,
422 R1scouter: "Bob",
423 R2scouter: "James",
424 R3scouter: "Robert",
425 B1scouter: "Alice",
426 B2scouter: "Mary",
427 B3scouter: "Patricia",
428 },
429 {
430 MatchNumber: 2,
431 R1scouter: "Liam",
432 R2scouter: "Noah",
433 R3scouter: "Oliver",
434 B1scouter: "Emma",
435 B2scouter: "Charlotte",
436 B3scouter: "Amelia",
437 },
438 },
439 }
440 if len(expected.ShiftSchedule) != len(response.ShiftSchedule) {
441 t.Fatal("Expected ", expected, ", but got ", *response)
442 }
443 for i, match := range expected.ShiftSchedule {
444 if !reflect.DeepEqual(*match, *response.ShiftSchedule[i]) {
445 t.Fatal("Expected for shift schedule", i, ":", *match, ", but got:", *response.ShiftSchedule[i])
446 }
447 }
448}
449
450func TestSubmitShiftSchedule(t *testing.T) {
451 database := MockDatabase{}
452 scoutingServer := server.NewScoutingServer()
453 HandleRequests(&database, scrapeEmtpyMatchList, scoutingServer)
454 scoutingServer.Start(8080)
455 defer scoutingServer.Stop()
456
457 builder := flatbuffers.NewBuilder(1024)
458 builder.Finish((&submit_shift_schedule.SubmitShiftScheduleT{
459 ShiftSchedule: []*submit_shift_schedule.MatchAssignmentT{
460 {MatchNumber: 1,
461 R1scouter: "Bob",
462 R2scouter: "James",
463 R3scouter: "Robert",
464 B1scouter: "Alice",
465 B2scouter: "Mary",
466 B3scouter: "Patricia"},
467 },
468 }).Pack(builder))
469
470 _, err := debug.SubmitShiftSchedule("http://localhost:8080", builder.FinishedBytes())
471 if err != nil {
472 t.Fatal("Failed to submit shift schedule: ", err)
473 }
474
475 expected := []db.Shift{
476 {MatchNumber: 1,
477 R1scouter: "Bob",
478 R2scouter: "James",
479 R3scouter: "Robert",
480 B1scouter: "Alice",
481 B2scouter: "Mary",
482 B3scouter: "Patricia"},
483 }
484 if !reflect.DeepEqual(expected, database.shiftSchedule) {
485 t.Fatal("Expected ", expected, ", but got:", database.shiftSchedule)
486 }
487}
488
Philipp Schraderd3fac192022-03-02 20:35:46 -0800489// Validates that we can download the schedule from The Blue Alliance.
490func TestRefreshMatchList(t *testing.T) {
491 scrapeMockSchedule := func(int32, string) ([]scraping.Match, error) {
492 return []scraping.Match{
493 {
494 CompLevel: "qual",
495 MatchNumber: 1,
Philipp Schrader45befdd2022-04-08 19:12:44 -0700496 SetNumber: 2,
Philipp Schraderd3fac192022-03-02 20:35:46 -0800497 Alliances: scraping.Alliances{
498 Red: scraping.Alliance{
499 TeamKeys: []string{
500 "100",
501 "200",
502 "300",
503 },
504 },
505 Blue: scraping.Alliance{
506 TeamKeys: []string{
507 "101",
508 "201",
509 "301",
510 },
511 },
512 },
513 WinningAlliance: "",
514 EventKey: "",
515 Time: 0,
516 PredictedTime: 0,
517 ActualTime: 0,
518 PostResultTime: 0,
519 ScoreBreakdowns: scraping.ScoreBreakdowns{},
520 },
521 }, nil
522 }
523
524 database := MockDatabase{}
525 scoutingServer := server.NewScoutingServer()
526 HandleRequests(&database, scrapeMockSchedule, scoutingServer)
527 scoutingServer.Start(8080)
528 defer scoutingServer.Stop()
529
530 builder := flatbuffers.NewBuilder(1024)
531 builder.Finish((&refresh_match_list.RefreshMatchListT{}).Pack(builder))
532
533 response, err := debug.RefreshMatchList("http://localhost:8080", builder.FinishedBytes())
534 if err != nil {
535 t.Fatal("Failed to request all matches: ", err)
536 }
537
538 // Validate the response.
539 expected := refresh_match_list_response.RefreshMatchListResponseT{}
540 if !reflect.DeepEqual(expected, *response) {
541 t.Fatal("Expected ", expected, ", but got ", *response)
542 }
543
544 // Make sure that the data made it into the database.
545 expectedMatches := []db.Match{
546 {
547 MatchNumber: 1,
Philipp Schrader30b4a682022-04-16 14:36:17 -0700548 SetNumber: 2,
Philipp Schraderd3fac192022-03-02 20:35:46 -0800549 CompLevel: "qual",
550 R1: 100,
551 R2: 200,
552 R3: 300,
553 B1: 101,
554 B2: 201,
555 B3: 301,
556 },
557 }
558 if !reflect.DeepEqual(expectedMatches, database.matches) {
559 t.Fatal("Expected ", expectedMatches, ", but got ", database.matches)
560 }
561}
562
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800563// A mocked database we can use for testing. Add functionality to this as
564// needed for your tests.
565
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800566type MockDatabase struct {
Milo Lin1d59f0c2022-06-22 20:30:58 -0700567 matches []db.Match
568 stats []db.Stats
569 notes []db.NotesData
570 shiftSchedule []db.Shift
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800571}
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800572
Philipp Schraderd3fac192022-03-02 20:35:46 -0800573func (database *MockDatabase) AddToMatch(match db.Match) error {
574 database.matches = append(database.matches, match)
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800575 return nil
576}
577
Philipp Schrader30005e42022-03-06 13:53:58 -0800578func (database *MockDatabase) AddToStats(stats db.Stats) error {
579 database.stats = append(database.stats, stats)
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800580 return nil
581}
582
583func (database *MockDatabase) ReturnMatches() ([]db.Match, error) {
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800584 return database.matches, nil
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800585}
586
587func (database *MockDatabase) ReturnStats() ([]db.Stats, error) {
Philipp Schraderacf96232022-03-01 22:03:30 -0800588 return database.stats, nil
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800589}
590
Philipp Schraderd1c4bef2022-02-28 22:51:30 -0800591func (database *MockDatabase) QueryMatches(requestedTeam int32) ([]db.Match, error) {
592 var matches []db.Match
593 for _, match := range database.matches {
594 for _, team := range []int32{match.R1, match.R2, match.R3, match.B1, match.B2, match.B3} {
595 if team == requestedTeam {
596 matches = append(matches, match)
597 break
598 }
599 }
600 }
601 return matches, nil
Philipp Schrader8747f1b2022-02-23 23:56:22 -0800602}
603
604func (database *MockDatabase) QueryStats(int) ([]db.Stats, error) {
605 return []db.Stats{}, nil
606}
Philipp Schraderd3fac192022-03-02 20:35:46 -0800607
Philipp Schradereecb8962022-06-01 21:02:42 -0700608func (database *MockDatabase) QueryNotes(requestedTeam int32) ([]string, error) {
Alex Perry81f96ba2022-03-13 18:26:19 -0700609 var results []string
610 for _, data := range database.notes {
611 if data.TeamNumber == requestedTeam {
Philipp Schradereecb8962022-06-01 21:02:42 -0700612 results = append(results, data.Notes)
Alex Perry81f96ba2022-03-13 18:26:19 -0700613 }
614 }
Philipp Schradereecb8962022-06-01 21:02:42 -0700615 return results, nil
Alex Perry81f96ba2022-03-13 18:26:19 -0700616}
617
Filip Kujawaf947cb42022-11-21 10:00:30 -0800618func (database *MockDatabase) AddNotes(data db.NotesData) error {
619 database.notes = append(database.notes, data)
Alex Perry81f96ba2022-03-13 18:26:19 -0700620 return nil
621}
622
Milo Lin1d59f0c2022-06-22 20:30:58 -0700623func (database *MockDatabase) AddToShift(data db.Shift) error {
624 database.shiftSchedule = append(database.shiftSchedule, data)
625 return nil
626}
627
628func (database *MockDatabase) ReturnAllShifts() ([]db.Shift, error) {
629 return database.shiftSchedule, nil
630}
631
632func (database *MockDatabase) QueryAllShifts(int) ([]db.Shift, error) {
633 return []db.Shift{}, nil
634}
635
Philipp Schraderd3fac192022-03-02 20:35:46 -0800636// Returns an empty match list from the fake The Blue Alliance scraping.
637func scrapeEmtpyMatchList(int32, string) ([]scraping.Match, error) {
638 return nil, nil
639}