blob: d81b659389f7ec46048ac433bc86f5485cfc83a9 [file] [log] [blame]
Philipp Schradercdb5cfc2022-02-20 14:57:07 -08001package requests
2
3import (
Philipp Schradercdb5cfc2022-02-20 14:57:07 -08004 "net/http"
Philipp Schradercbf5c6a2022-02-27 23:25:19 -08005 "reflect"
Philipp Schradercdb5cfc2022-02-20 14:57:07 -08006 "testing"
7
Philipp Schrader8747f1b2022-02-23 23:56:22 -08008 "github.com/frc971/971-Robot-Code/scouting/db"
Philipp Schradercbf5c6a2022-02-27 23:25:19 -08009 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/debug"
Filip Kujawac1ded372023-05-27 14:33:43 -070010 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/delete_2023_data_scouting"
Emily Markova290147d2023-03-03 22:40:06 -080011 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_2023_data_scouting"
12 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_2023_data_scouting_response"
Filip Kujawaf882e022022-12-14 13:14:08 -080013 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_driver_rankings"
14 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_driver_rankings_response"
Philipp Schradercbf5c6a2022-02-27 23:25:19 -080015 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_matches"
16 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_matches_response"
Filip Kujawaf882e022022-12-14 13:14:08 -080017 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_notes"
18 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_notes_response"
Emily Markova8e39f452023-12-23 12:17:30 -080019 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_pit_images"
20 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_pit_images_response"
Alex Perry81f96ba2022-03-13 18:26:19 -070021 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_notes_for_team"
Emily Markovafaecfe12023-07-01 12:40:03 -070022 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_pit_images"
23 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_pit_images_response"
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"
Emily Markova1abe9782023-03-11 19:45:38 -080026 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_actions"
Filip Kujawa210a03b2022-11-24 14:41:11 -080027 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_driver_ranking"
Alex Perry81f96ba2022-03-13 18:26:19 -070028 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes"
Emily Markovafaecfe12023-07-01 12:40:03 -070029 "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_pit_image"
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
Philipp Schradercbf5c6a2022-02-27 23:25:19 -080052// Validates that we can request the full match list.
53func TestRequestAllMatches(t *testing.T) {
54 db := MockDatabase{
Emily Markovabf24c9e2023-02-08 20:31:11 -080055 matches: []db.TeamMatch{
Philipp Schradercbf5c6a2022-02-27 23:25:19 -080056 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080057 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070058 Alliance: "R", AlliancePosition: 1, TeamNumber: "5",
Emily Markovabf24c9e2023-02-08 20:31:11 -080059 },
60 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080061 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070062 Alliance: "R", AlliancePosition: 2, TeamNumber: "42",
Emily Markovabf24c9e2023-02-08 20:31:11 -080063 },
64 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080065 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070066 Alliance: "R", AlliancePosition: 3, TeamNumber: "600",
Emily Markovabf24c9e2023-02-08 20:31:11 -080067 },
68 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080069 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070070 Alliance: "B", AlliancePosition: 1, TeamNumber: "971",
Emily Markovabf24c9e2023-02-08 20:31:11 -080071 },
72 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080073 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070074 Alliance: "B", AlliancePosition: 2, TeamNumber: "400",
Emily Markovabf24c9e2023-02-08 20:31:11 -080075 },
76 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080077 MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070078 Alliance: "B", AlliancePosition: 3, TeamNumber: "200",
Philipp Schradercbf5c6a2022-02-27 23:25:19 -080079 },
80 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080081 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070082 Alliance: "R", AlliancePosition: 1, TeamNumber: "6",
Emily Markovabf24c9e2023-02-08 20:31:11 -080083 },
84 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080085 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070086 Alliance: "R", AlliancePosition: 2, TeamNumber: "43",
Emily Markovabf24c9e2023-02-08 20:31:11 -080087 },
88 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080089 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070090 Alliance: "R", AlliancePosition: 3, TeamNumber: "601",
Emily Markovabf24c9e2023-02-08 20:31:11 -080091 },
92 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080093 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070094 Alliance: "B", AlliancePosition: 1, TeamNumber: "972",
Emily Markovabf24c9e2023-02-08 20:31:11 -080095 },
96 {
Emily Markovaabcac6e2023-02-18 17:50:03 -080097 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -070098 Alliance: "B", AlliancePosition: 2, TeamNumber: "401",
Emily Markovabf24c9e2023-02-08 20:31:11 -080099 },
100 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800101 MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -0700102 Alliance: "B", AlliancePosition: 3, TeamNumber: "201",
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800103 },
104 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800105 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -0700106 Alliance: "R", AlliancePosition: 1, TeamNumber: "7",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800107 },
108 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800109 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -0700110 Alliance: "R", AlliancePosition: 2, TeamNumber: "44",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800111 },
112 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800113 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -0700114 Alliance: "R", AlliancePosition: 3, TeamNumber: "602",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800115 },
116 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800117 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -0700118 Alliance: "B", AlliancePosition: 1, TeamNumber: "973",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800119 },
120 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800121 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -0700122 Alliance: "B", AlliancePosition: 2, TeamNumber: "402",
Emily Markovabf24c9e2023-02-08 20:31:11 -0800123 },
124 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800125 MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
Emily Markovab8551572023-03-22 19:49:39 -0700126 Alliance: "B", AlliancePosition: 3, TeamNumber: "202",
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800127 },
128 },
Philipp Schrader0f7b6362023-03-11 14:02:48 -0800129 // Pretend that we have some data scouting data.
130 stats2023: []db.Stats2023{
131 {
132 TeamNumber: "5", MatchNumber: 1, SetNumber: 1,
133 CompLevel: "qm", StartingQuadrant: 3, LowCubesAuto: 10,
134 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 0,
135 LowConesAuto: 1, MiddleConesAuto: 2, HighConesAuto: 1,
136 ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
137 HighCubes: 2, CubesDropped: 1, LowCones: 1,
Filip Kujawa7a045e72023-04-13 08:41:09 -0700138 MiddleCones: 2, HighCones: 0, ConesDropped: 1, SuperchargedPieces: 0,
Filip Kujawa0b4b1e52023-04-15 14:05:40 -0700139 AvgCycle: 34, Mobility: false, DockedAuto: true, EngagedAuto: true,
Emily Markova63c63f62023-03-29 20:57:35 -0700140 BalanceAttemptAuto: false, Docked: false, Engaged: false,
141 BalanceAttempt: false, CollectedBy: "alex",
Philipp Schrader0f7b6362023-03-11 14:02:48 -0800142 },
143 {
144 TeamNumber: "973", MatchNumber: 3, SetNumber: 1,
145 CompLevel: "qm", StartingQuadrant: 1, LowCubesAuto: 0,
146 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 2,
147 LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
148 ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
149 HighCubes: 1, CubesDropped: 0, LowCones: 0,
Filip Kujawa7a045e72023-04-13 08:41:09 -0700150 MiddleCones: 2, HighCones: 1, ConesDropped: 1, SuperchargedPieces: 0,
Filip Kujawa0b4b1e52023-04-15 14:05:40 -0700151 AvgCycle: 53, Mobility: true, DockedAuto: true, EngagedAuto: false,
Emily Markova63c63f62023-03-29 20:57:35 -0700152 BalanceAttemptAuto: false, Docked: false, Engaged: false,
153 BalanceAttempt: true, CollectedBy: "bob",
Philipp Schrader0f7b6362023-03-11 14:02:48 -0800154 },
155 },
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800156 }
157 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800158 HandleRequests(&db, scoutingServer)
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800159 scoutingServer.Start(8080)
160 defer scoutingServer.Stop()
161
162 builder := flatbuffers.NewBuilder(1024)
163 builder.Finish((&request_all_matches.RequestAllMatchesT{}).Pack(builder))
164
165 response, err := debug.RequestAllMatches("http://localhost:8080", builder.FinishedBytes())
166 if err != nil {
167 t.Fatal("Failed to request all matches: ", err)
168 }
169
170 expected := request_all_matches_response.RequestAllMatchesResponseT{
171 MatchList: []*request_all_matches_response.MatchT{
Philipp Schrader30b4a682022-04-16 14:36:17 -0700172 // MatchNumber, SetNumber, CompLevel
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800173 // R1, R2, R3, B1, B2, B3
174 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800175 1, 1, "qm",
Emily Markovab8551572023-03-22 19:49:39 -0700176 "5", "42", "600", "971", "400", "200",
Philipp Schrader0f7b6362023-03-11 14:02:48 -0800177 &request_all_matches_response.ScoutedLevelT{
178 // The R1 team has already been data
179 // scouted.
180 true, false, false, false, false, false,
181 },
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800182 },
183 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800184 2, 1, "qm",
Emily Markovab8551572023-03-22 19:49:39 -0700185 "6", "43", "601", "972", "401", "201",
Philipp Schrader0f7b6362023-03-11 14:02:48 -0800186 &request_all_matches_response.ScoutedLevelT{
187 false, false, false, false, false, false,
188 },
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800189 },
190 {
Emily Markovaabcac6e2023-02-18 17:50:03 -0800191 3, 1, "qm",
Emily Markovab8551572023-03-22 19:49:39 -0700192 "7", "44", "602", "973", "402", "202",
Philipp Schrader0f7b6362023-03-11 14:02:48 -0800193 &request_all_matches_response.ScoutedLevelT{
194 // The B1 team has already been data
195 // scouted.
196 false, false, false, true, false, false,
197 },
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800198 },
199 },
200 }
201 if len(expected.MatchList) != len(response.MatchList) {
202 t.Fatal("Expected ", expected, ", but got ", *response)
203 }
204 for i, match := range expected.MatchList {
205 if !reflect.DeepEqual(*match, *response.MatchList[i]) {
206 t.Fatal("Expected for match", i, ":", *match, ", but got:", *response.MatchList[i])
207 }
208 }
Philipp Schrader30005e42022-03-06 13:53:58 -0800209
Philipp Schradercbf5c6a2022-02-27 23:25:19 -0800210}
211
Emily Markova290147d2023-03-03 22:40:06 -0800212// Validates that we can request the 2023 stats.
213func TestRequest2023DataScouting(t *testing.T) {
214 db := MockDatabase{
215 stats2023: []db.Stats2023{
216 {
217 TeamNumber: "3634", MatchNumber: 1, SetNumber: 2,
218 CompLevel: "quals", StartingQuadrant: 3, LowCubesAuto: 10,
219 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 0,
220 LowConesAuto: 1, MiddleConesAuto: 2, HighConesAuto: 1,
221 ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
222 HighCubes: 2, CubesDropped: 1, LowCones: 1,
Filip Kujawa7a045e72023-04-13 08:41:09 -0700223 MiddleCones: 2, HighCones: 0, ConesDropped: 1, SuperchargedPieces: 0,
Filip Kujawa0b4b1e52023-04-15 14:05:40 -0700224 AvgCycle: 34, Mobility: false, DockedAuto: true, EngagedAuto: false,
Emily Markova63c63f62023-03-29 20:57:35 -0700225 BalanceAttemptAuto: false, Docked: false, Engaged: false,
226 BalanceAttempt: true, CollectedBy: "isaac",
Emily Markova290147d2023-03-03 22:40:06 -0800227 },
228 {
229 TeamNumber: "2343", MatchNumber: 1, SetNumber: 2,
230 CompLevel: "quals", StartingQuadrant: 1, LowCubesAuto: 0,
231 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 2,
232 LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
233 ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
234 HighCubes: 1, CubesDropped: 0, LowCones: 0,
Filip Kujawa7a045e72023-04-13 08:41:09 -0700235 MiddleCones: 2, HighCones: 1, ConesDropped: 1, SuperchargedPieces: 0,
Filip Kujawa0b4b1e52023-04-15 14:05:40 -0700236 AvgCycle: 53, Mobility: false, DockedAuto: false, EngagedAuto: false,
Emily Markova63c63f62023-03-29 20:57:35 -0700237 BalanceAttemptAuto: true, Docked: false, Engaged: false,
238 BalanceAttempt: true, CollectedBy: "unknown",
Emily Markova290147d2023-03-03 22:40:06 -0800239 },
240 },
241 }
242 scoutingServer := server.NewScoutingServer()
243 HandleRequests(&db, scoutingServer)
244 scoutingServer.Start(8080)
245 defer scoutingServer.Stop()
246
247 builder := flatbuffers.NewBuilder(1024)
248 builder.Finish((&request_2023_data_scouting.Request2023DataScoutingT{}).Pack(builder))
249
250 response, err := debug.Request2023DataScouting("http://localhost:8080", builder.FinishedBytes())
251 if err != nil {
252 t.Fatal("Failed to request all matches: ", err)
253 }
254
255 expected := request_2023_data_scouting_response.Request2023DataScoutingResponseT{
256 StatsList: []*request_2023_data_scouting_response.Stats2023T{
257 {
258 TeamNumber: "3634", MatchNumber: 1, SetNumber: 2,
259 CompLevel: "quals", StartingQuadrant: 3, LowCubesAuto: 10,
260 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 0,
261 LowConesAuto: 1, MiddleConesAuto: 2, HighConesAuto: 1,
262 ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
263 HighCubes: 2, CubesDropped: 1, LowCones: 1,
Filip Kujawa7a045e72023-04-13 08:41:09 -0700264 MiddleCones: 2, HighCones: 0, ConesDropped: 1, SuperchargedPieces: 0,
Filip Kujawa0b4b1e52023-04-15 14:05:40 -0700265 AvgCycle: 34, Mobility: false, DockedAuto: true, EngagedAuto: false,
Emily Markova63c63f62023-03-29 20:57:35 -0700266 BalanceAttemptAuto: false, Docked: false, Engaged: false,
267 BalanceAttempt: true, CollectedBy: "isaac",
Emily Markova290147d2023-03-03 22:40:06 -0800268 },
269 {
270 TeamNumber: "2343", MatchNumber: 1, SetNumber: 2,
271 CompLevel: "quals", StartingQuadrant: 1, LowCubesAuto: 0,
272 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 2,
273 LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
274 ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
275 HighCubes: 1, CubesDropped: 0, LowCones: 0,
Filip Kujawa7a045e72023-04-13 08:41:09 -0700276 MiddleCones: 2, HighCones: 1, ConesDropped: 1, SuperchargedPieces: 0,
Filip Kujawa0b4b1e52023-04-15 14:05:40 -0700277 AvgCycle: 53, Mobility: false, DockedAuto: false, EngagedAuto: false,
Emily Markova63c63f62023-03-29 20:57:35 -0700278 BalanceAttemptAuto: true, Docked: false, Engaged: false,
279 BalanceAttempt: true, CollectedBy: "unknown",
Emily Markova290147d2023-03-03 22:40:06 -0800280 },
281 },
282 }
283 if len(expected.StatsList) != len(response.StatsList) {
284 t.Fatal("Expected ", expected, ", but got ", *response)
285 }
286 for i, match := range expected.StatsList {
287 if !reflect.DeepEqual(*match, *response.StatsList[i]) {
288 t.Fatal("Expected for stats", i, ":", *match, ", but got:", *response.StatsList[i])
289 }
290 }
291}
292
Emily Markova1abe9782023-03-11 19:45:38 -0800293// Validates that we can request the 2023 stats.
294func TestConvertActionsToStat(t *testing.T) {
295 builder := flatbuffers.NewBuilder(1024)
296 builder.Finish((&submit_actions.SubmitActionsT{
297 TeamNumber: "4244",
298 MatchNumber: 3,
299 SetNumber: 1,
300 CompLevel: "quals",
Emily Markova1abe9782023-03-11 19:45:38 -0800301 ActionsList: []*submit_actions.ActionT{
302 {
303 ActionTaken: &submit_actions.ActionTypeT{
304 Type: submit_actions.ActionTypeStartMatchAction,
305 Value: &submit_actions.StartMatchActionT{
306 Position: 1,
307 },
308 },
309 Timestamp: 0,
310 },
311 {
312 ActionTaken: &submit_actions.ActionTypeT{
313 Type: submit_actions.ActionTypePickupObjectAction,
314 Value: &submit_actions.PickupObjectActionT{
315 ObjectType: submit_actions.ObjectTypekCube,
316 Auto: true,
317 },
318 },
319 Timestamp: 400,
320 },
321 {
322 ActionTaken: &submit_actions.ActionTypeT{
323 Type: submit_actions.ActionTypePickupObjectAction,
324 Value: &submit_actions.PickupObjectActionT{
325 ObjectType: submit_actions.ObjectTypekCube,
326 Auto: true,
327 },
328 },
329 Timestamp: 800,
330 },
331 {
332 ActionTaken: &submit_actions.ActionTypeT{
333 Type: submit_actions.ActionTypePlaceObjectAction,
334 Value: &submit_actions.PlaceObjectActionT{
335 ObjectType: submit_actions.ObjectTypekCube,
336 ScoreLevel: submit_actions.ScoreLevelkLow,
337 Auto: true,
338 },
339 },
340 Timestamp: 2000,
341 },
342 {
343 ActionTaken: &submit_actions.ActionTypeT{
Filip Kujawa0b4b1e52023-04-15 14:05:40 -0700344 Type: submit_actions.ActionTypeMobilityAction,
345 Value: &submit_actions.MobilityActionT{
346 Mobility: true,
347 },
348 },
349 Timestamp: 2200,
350 },
351 {
352 ActionTaken: &submit_actions.ActionTypeT{
Emily Markova46a69bf2023-03-22 20:45:52 -0700353 Type: submit_actions.ActionTypeAutoBalanceAction,
354 Value: &submit_actions.AutoBalanceActionT{
Emily Markova63c63f62023-03-29 20:57:35 -0700355 Docked: true,
356 Engaged: true,
357 BalanceAttempt: false,
Emily Markova46a69bf2023-03-22 20:45:52 -0700358 },
359 },
360 Timestamp: 2400,
361 },
362 {
363 ActionTaken: &submit_actions.ActionTypeT{
Emily Markova1abe9782023-03-11 19:45:38 -0800364 Type: submit_actions.ActionTypePickupObjectAction,
365 Value: &submit_actions.PickupObjectActionT{
366 ObjectType: submit_actions.ObjectTypekCone,
367 Auto: false,
368 },
369 },
370 Timestamp: 2800,
371 },
372 {
373 ActionTaken: &submit_actions.ActionTypeT{
374 Type: submit_actions.ActionTypePlaceObjectAction,
375 Value: &submit_actions.PlaceObjectActionT{
376 ObjectType: submit_actions.ObjectTypekCone,
377 ScoreLevel: submit_actions.ScoreLevelkHigh,
378 Auto: false,
379 },
380 },
381 Timestamp: 3100,
382 },
Emily Markova46a69bf2023-03-22 20:45:52 -0700383 {
384 ActionTaken: &submit_actions.ActionTypeT{
Filip Kujawa7a045e72023-04-13 08:41:09 -0700385 Type: submit_actions.ActionTypePickupObjectAction,
386 Value: &submit_actions.PickupObjectActionT{
387 ObjectType: submit_actions.ObjectTypekCube,
388 Auto: false,
389 },
390 },
391 Timestamp: 3500,
392 },
393 {
394 ActionTaken: &submit_actions.ActionTypeT{
395 Type: submit_actions.ActionTypePlaceObjectAction,
396 Value: &submit_actions.PlaceObjectActionT{
397 ObjectType: submit_actions.ObjectTypekCube,
398 ScoreLevel: submit_actions.ScoreLevelkSupercharged,
399 Auto: false,
400 },
401 },
402 Timestamp: 3900,
403 },
404 {
405 ActionTaken: &submit_actions.ActionTypeT{
Emily Markova46a69bf2023-03-22 20:45:52 -0700406 Type: submit_actions.ActionTypeEndMatchAction,
407 Value: &submit_actions.EndMatchActionT{
Emily Markova63c63f62023-03-29 20:57:35 -0700408 Docked: true,
409 Engaged: false,
410 BalanceAttempt: true,
Emily Markova46a69bf2023-03-22 20:45:52 -0700411 },
412 },
Filip Kujawa7a045e72023-04-13 08:41:09 -0700413 Timestamp: 4200,
Emily Markova46a69bf2023-03-22 20:45:52 -0700414 },
Emily Markova1abe9782023-03-11 19:45:38 -0800415 },
Philipp Schrader4b489222023-04-15 16:40:16 -0700416 PreScouting: false,
Emily Markova1abe9782023-03-11 19:45:38 -0800417 }).Pack(builder))
418
419 submitActions := submit_actions.GetRootAsSubmitActions(builder.FinishedBytes(), 0)
420 response, err := ConvertActionsToStat(submitActions)
421
422 if err != nil {
423 t.Fatal("Failed to convert actions to stats: ", err)
424 }
425
426 expected := db.Stats2023{
Philipp Schrader4b489222023-04-15 16:40:16 -0700427 PreScouting: false,
428 TeamNumber: "4244", MatchNumber: 3, SetNumber: 1,
Emily Markova1abe9782023-03-11 19:45:38 -0800429 CompLevel: "quals", StartingQuadrant: 1, LowCubesAuto: 1,
430 MiddleCubesAuto: 0, HighCubesAuto: 0, CubesDroppedAuto: 1,
431 LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
432 ConesDroppedAuto: 0, LowCubes: 0, MiddleCubes: 0,
433 HighCubes: 0, CubesDropped: 0, LowCones: 0,
Filip Kujawa7a045e72023-04-13 08:41:09 -0700434 MiddleCones: 0, HighCones: 1, ConesDropped: 0, SuperchargedPieces: 1,
Filip Kujawa0b4b1e52023-04-15 14:05:40 -0700435 AvgCycle: 950, Mobility: true, DockedAuto: true, EngagedAuto: true,
Emily Markova63c63f62023-03-29 20:57:35 -0700436 BalanceAttemptAuto: false, Docked: true, Engaged: false,
Philipp Schradere11114f2023-04-15 17:04:25 -0700437 BalanceAttempt: true, CollectedBy: "",
Emily Markova1abe9782023-03-11 19:45:38 -0800438 }
439
440 if expected != response {
441 t.Fatal("Expected ", expected, ", but got ", response)
442 }
443}
444
Alex Perry81f96ba2022-03-13 18:26:19 -0700445func TestSubmitNotes(t *testing.T) {
446 database := MockDatabase{}
447 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800448 HandleRequests(&database, scoutingServer)
Alex Perry81f96ba2022-03-13 18:26:19 -0700449 scoutingServer.Start(8080)
450 defer scoutingServer.Stop()
451
452 builder := flatbuffers.NewBuilder(1024)
453 builder.Finish((&submit_notes.SubmitNotesT{
Emily Markovae68b7632023-12-30 14:17:55 -0800454 Team: "971",
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800455 Notes: "Notes",
456 GoodDriving: true,
457 BadDriving: false,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700458 SolidPlacing: true,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800459 SketchyPlacing: false,
460 GoodDefense: true,
461 BadDefense: false,
462 EasilyDefended: true,
Alex Perry81f96ba2022-03-13 18:26:19 -0700463 }).Pack(builder))
464
465 _, err := debug.SubmitNotes("http://localhost:8080", builder.FinishedBytes())
466 if err != nil {
467 t.Fatal("Failed to submit notes: ", err)
468 }
469
470 expected := []db.NotesData{
Filip Kujawaf947cb42022-11-21 10:00:30 -0800471 {
Emily Markovae68b7632023-12-30 14:17:55 -0800472 TeamNumber: "971",
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800473 Notes: "Notes",
474 GoodDriving: true,
475 BadDriving: false,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700476 SolidPlacing: true,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800477 SketchyPlacing: false,
478 GoodDefense: true,
479 BadDefense: false,
480 EasilyDefended: true,
Filip Kujawaf947cb42022-11-21 10:00:30 -0800481 },
Alex Perry81f96ba2022-03-13 18:26:19 -0700482 }
483
484 if !reflect.DeepEqual(database.notes, expected) {
485 t.Fatal("Submitted notes did not match", expected, database.notes)
486 }
487}
488
489func TestRequestNotes(t *testing.T) {
490 database := MockDatabase{
491 notes: []db.NotesData{{
Emily Markovae68b7632023-12-30 14:17:55 -0800492 TeamNumber: "971A",
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800493 Notes: "Notes",
494 GoodDriving: true,
495 BadDriving: false,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700496 SolidPlacing: true,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800497 SketchyPlacing: false,
498 GoodDefense: true,
499 BadDefense: false,
500 EasilyDefended: true,
Alex Perry81f96ba2022-03-13 18:26:19 -0700501 }},
502 }
503 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800504 HandleRequests(&database, scoutingServer)
Alex Perry81f96ba2022-03-13 18:26:19 -0700505 scoutingServer.Start(8080)
506 defer scoutingServer.Stop()
507
508 builder := flatbuffers.NewBuilder(1024)
509 builder.Finish((&request_notes_for_team.RequestNotesForTeamT{
Emily Markovae68b7632023-12-30 14:17:55 -0800510 Team: "971A",
Alex Perry81f96ba2022-03-13 18:26:19 -0700511 }).Pack(builder))
512 response, err := debug.RequestNotes("http://localhost:8080", builder.FinishedBytes())
513 if err != nil {
514 t.Fatal("Failed to submit notes: ", err)
515 }
516
517 if response.Notes[0].Data != "Notes" {
518 t.Fatal("requested notes did not match", response)
519 }
520}
521
Emily Markovafaecfe12023-07-01 12:40:03 -0700522func TestSubmitPitImage(t *testing.T) {
523 database := MockDatabase{}
524 scoutingServer := server.NewScoutingServer()
525 HandleRequests(&database, scoutingServer)
526 scoutingServer.Start(8080)
527 defer scoutingServer.Stop()
528
529 builder := flatbuffers.NewBuilder(1024)
530 builder.Finish((&submit_pit_image.SubmitPitImageT{
531 TeamNumber: "483A", ImagePath: "483Arobot.jpg",
532 ImageData: []byte{12, 43, 54, 34, 98},
533 }).Pack(builder))
534
535 _, err := debug.SubmitPitImage("http://localhost:8080", builder.FinishedBytes())
536 if err != nil {
537 t.Fatal("Failed to submit pit image: ", err)
538 }
539
540 expected := []db.PitImage{
541 {
542 TeamNumber: "483A", CheckSum: "177d9dc52bc25f391232e82521259c378964c068832a9178d73448ba4ac5e0b1",
543 ImagePath: "483Arobot.jpg", ImageData: []byte{12, 43, 54, 34, 98},
544 },
545 }
546
547 if !reflect.DeepEqual(database.images, expected) {
548 t.Fatal("Submitted image did not match", expected, database.images)
549 }
550}
551
552func TestRequestPitImages(t *testing.T) {
553 db := MockDatabase{
554 images: []db.PitImage{
555 {
556 TeamNumber: "932", ImagePath: "pitimage.jpg",
557 ImageData: []byte{3, 34, 44, 65}, CheckSum: "abcdf",
558 },
559 {
560 TeamNumber: "234", ImagePath: "234robot.png",
561 ImageData: []byte{64, 54, 21, 21, 76, 32}, CheckSum: "egrfd",
562 },
563 {
564 TeamNumber: "93A", ImagePath: "abcd.jpg",
565 ImageData: []byte{92, 94, 10, 30, 57, 32, 32}, CheckSum: "rgegfd",
566 },
567 },
568 }
569
570 scoutingServer := server.NewScoutingServer()
571 HandleRequests(&db, scoutingServer)
572 scoutingServer.Start(8080)
573 defer scoutingServer.Stop()
574
575 builder := flatbuffers.NewBuilder(1024)
576 builder.Finish((&request_pit_images.RequestPitImagesT{"932"}).Pack(builder))
577
578 response, err := debug.RequestPitImages("http://localhost:8080", builder.FinishedBytes())
579 if err != nil {
580 t.Fatal("Failed to request pit images: ", err)
581 }
582
583 expected := request_pit_images_response.RequestPitImagesResponseT{
584 PitImageList: []*request_pit_images_response.PitImageT{
585 {
586 TeamNumber: "932", ImagePath: "pitimage.jpg", CheckSum: "abcdf",
587 },
588 },
589 }
590
591 if len(expected.PitImageList) != len(response.PitImageList) {
592 t.Fatal("Expected ", expected, ", but got ", *response)
593 }
594
595 for i, pit_image := range expected.PitImageList {
596 if !reflect.DeepEqual(*pit_image, *response.PitImageList[i]) {
597 t.Fatal("Expected for pit image", i, ":", *pit_image, ", but got:", *response.PitImageList[i])
598 }
599 }
600}
601
Emily Markova8e39f452023-12-23 12:17:30 -0800602func TestRequestAllPitImages(t *testing.T) {
603 db := MockDatabase{
604 images: []db.PitImage{
605 {
606 TeamNumber: "32", ImagePath: "pitimage.jpg",
607 ImageData: []byte{3, 43, 44, 32}, CheckSum: "cdhrj",
608 },
609 {
610 TeamNumber: "231", ImagePath: "232robot.png",
611 ImageData: []byte{64, 54, 54, 21, 76, 32}, CheckSum: "rgre",
612 },
613 {
614 TeamNumber: "90", ImagePath: "abcd.jpg",
615 ImageData: []byte{92, 94, 10, 30, 57, 32, 32}, CheckSum: "erfer",
616 },
617 },
618 }
619
620 scoutingServer := server.NewScoutingServer()
621 HandleRequests(&db, scoutingServer)
622 scoutingServer.Start(8080)
623 defer scoutingServer.Stop()
624
625 builder := flatbuffers.NewBuilder(1024)
626 builder.Finish((&request_all_pit_images.RequestAllPitImagesT{}).Pack(builder))
627
628 response, err := debug.RequestAllPitImages("http://localhost:8080", builder.FinishedBytes())
629 if err != nil {
630 t.Fatal("Failed to request pit images: ", err)
631 }
632
633 expected := request_all_pit_images_response.RequestAllPitImagesResponseT{
634 PitImageList: []*request_all_pit_images_response.PitImageT{
635 {
636 TeamNumber: "32", ImagePath: "pitimage.jpg", CheckSum: "cdhrj",
637 },
638 {
639 TeamNumber: "231", ImagePath: "232robot.png", CheckSum: "rgre",
640 },
641 {
642 TeamNumber: "90", ImagePath: "abcd.jpg", CheckSum: "erfer",
643 },
644 },
645 }
646
647 if len(expected.PitImageList) != len(response.PitImageList) {
648 t.Fatal("Expected ", expected, ", but got ", *response)
649 }
650
651 for i, pit_image := range expected.PitImageList {
652 if !reflect.DeepEqual(*pit_image, *response.PitImageList[i]) {
653 t.Fatal("Expected for pit image", i, ":", *pit_image, ", but got:", *response.PitImageList[i])
654 }
655 }
656}
657
Milo Lin1d59f0c2022-06-22 20:30:58 -0700658func TestRequestShiftSchedule(t *testing.T) {
659 db := MockDatabase{
660 shiftSchedule: []db.Shift{
661 {
662 MatchNumber: 1,
663 R1scouter: "Bob",
664 R2scouter: "James",
665 R3scouter: "Robert",
666 B1scouter: "Alice",
667 B2scouter: "Mary",
668 B3scouter: "Patricia",
669 },
670 {
671 MatchNumber: 2,
672 R1scouter: "Liam",
673 R2scouter: "Noah",
674 R3scouter: "Oliver",
675 B1scouter: "Emma",
676 B2scouter: "Charlotte",
677 B3scouter: "Amelia",
678 },
679 },
680 }
681 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800682 HandleRequests(&db, scoutingServer)
Milo Lin1d59f0c2022-06-22 20:30:58 -0700683 scoutingServer.Start(8080)
684 defer scoutingServer.Stop()
685
686 builder := flatbuffers.NewBuilder(1024)
687 builder.Finish((&request_shift_schedule.RequestShiftScheduleT{}).Pack(builder))
688
689 response, err := debug.RequestShiftSchedule("http://localhost:8080", builder.FinishedBytes())
690 if err != nil {
691 t.Fatal("Failed to request shift schedule: ", err)
692 }
693
694 expected := request_shift_schedule_response.RequestShiftScheduleResponseT{
695 ShiftSchedule: []*request_shift_schedule_response.MatchAssignmentT{
696 {
697 MatchNumber: 1,
Philipp Schrader2ff455b2023-05-03 22:11:50 -0700698 R1Scouter: "Bob",
699 R2Scouter: "James",
700 R3Scouter: "Robert",
701 B1Scouter: "Alice",
702 B2Scouter: "Mary",
703 B3Scouter: "Patricia",
Milo Lin1d59f0c2022-06-22 20:30:58 -0700704 },
705 {
706 MatchNumber: 2,
Philipp Schrader2ff455b2023-05-03 22:11:50 -0700707 R1Scouter: "Liam",
708 R2Scouter: "Noah",
709 R3Scouter: "Oliver",
710 B1Scouter: "Emma",
711 B2Scouter: "Charlotte",
712 B3Scouter: "Amelia",
Milo Lin1d59f0c2022-06-22 20:30:58 -0700713 },
714 },
715 }
716 if len(expected.ShiftSchedule) != len(response.ShiftSchedule) {
717 t.Fatal("Expected ", expected, ", but got ", *response)
718 }
719 for i, match := range expected.ShiftSchedule {
720 if !reflect.DeepEqual(*match, *response.ShiftSchedule[i]) {
721 t.Fatal("Expected for shift schedule", i, ":", *match, ", but got:", *response.ShiftSchedule[i])
722 }
723 }
724}
725
726func TestSubmitShiftSchedule(t *testing.T) {
727 database := MockDatabase{}
728 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800729 HandleRequests(&database, scoutingServer)
Milo Lin1d59f0c2022-06-22 20:30:58 -0700730 scoutingServer.Start(8080)
731 defer scoutingServer.Stop()
732
733 builder := flatbuffers.NewBuilder(1024)
734 builder.Finish((&submit_shift_schedule.SubmitShiftScheduleT{
735 ShiftSchedule: []*submit_shift_schedule.MatchAssignmentT{
736 {MatchNumber: 1,
Philipp Schrader2ff455b2023-05-03 22:11:50 -0700737 R1Scouter: "Bob",
738 R2Scouter: "James",
739 R3Scouter: "Robert",
740 B1Scouter: "Alice",
741 B2Scouter: "Mary",
742 B3Scouter: "Patricia"},
Milo Lin1d59f0c2022-06-22 20:30:58 -0700743 },
744 }).Pack(builder))
745
746 _, err := debug.SubmitShiftSchedule("http://localhost:8080", builder.FinishedBytes())
747 if err != nil {
748 t.Fatal("Failed to submit shift schedule: ", err)
749 }
750
751 expected := []db.Shift{
752 {MatchNumber: 1,
753 R1scouter: "Bob",
754 R2scouter: "James",
755 R3scouter: "Robert",
756 B1scouter: "Alice",
757 B2scouter: "Mary",
758 B3scouter: "Patricia"},
759 }
760 if !reflect.DeepEqual(expected, database.shiftSchedule) {
761 t.Fatal("Expected ", expected, ", but got:", database.shiftSchedule)
762 }
763}
764
Filip Kujawa210a03b2022-11-24 14:41:11 -0800765func TestSubmitDriverRanking(t *testing.T) {
766 database := MockDatabase{}
767 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800768 HandleRequests(&database, scoutingServer)
Filip Kujawa210a03b2022-11-24 14:41:11 -0800769 scoutingServer.Start(8080)
770 defer scoutingServer.Stop()
771
772 builder := flatbuffers.NewBuilder(1024)
773 builder.Finish((&submit_driver_ranking.SubmitDriverRankingT{
774 MatchNumber: 36,
Emily Markovae68b7632023-12-30 14:17:55 -0800775 Rank1: "1234",
776 Rank2: "1235",
777 Rank3: "1236",
Filip Kujawa210a03b2022-11-24 14:41:11 -0800778 }).Pack(builder))
779
780 _, err := debug.SubmitDriverRanking("http://localhost:8080", builder.FinishedBytes())
781 if err != nil {
782 t.Fatal("Failed to submit driver ranking: ", err)
783 }
784
785 expected := []db.DriverRankingData{
Emily Markovae68b7632023-12-30 14:17:55 -0800786 {MatchNumber: 36, Rank1: "1234", Rank2: "1235", Rank3: "1236"},
Filip Kujawa210a03b2022-11-24 14:41:11 -0800787 }
788
789 if !reflect.DeepEqual(database.driver_ranking, expected) {
790 t.Fatal("Submitted notes did not match", expected, database.notes)
791 }
792}
793
Filip Kujawaf882e022022-12-14 13:14:08 -0800794// Validates that we can request the driver rankings.
795func TestRequestDriverRankings(t *testing.T) {
796 db := MockDatabase{
797 driver_ranking: []db.DriverRankingData{
798 {
799 MatchNumber: 36,
Emily Markovae68b7632023-12-30 14:17:55 -0800800 Rank1: "1234",
801 Rank2: "1235",
802 Rank3: "1236",
Filip Kujawaf882e022022-12-14 13:14:08 -0800803 },
804 {
805 MatchNumber: 36,
Emily Markovae68b7632023-12-30 14:17:55 -0800806 Rank1: "101",
807 Rank2: "202",
808 Rank3: "303",
Filip Kujawaf882e022022-12-14 13:14:08 -0800809 },
810 },
811 }
812 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800813 HandleRequests(&db, scoutingServer)
Filip Kujawaf882e022022-12-14 13:14:08 -0800814 scoutingServer.Start(8080)
815 defer scoutingServer.Stop()
816
817 builder := flatbuffers.NewBuilder(1024)
818 builder.Finish((&request_all_driver_rankings.RequestAllDriverRankingsT{}).Pack(builder))
819
820 response, err := debug.RequestAllDriverRankings("http://localhost:8080", builder.FinishedBytes())
821 if err != nil {
822 t.Fatal("Failed to request all driver rankings: ", err)
823 }
824
825 expected := request_all_driver_rankings_response.RequestAllDriverRankingsResponseT{
826 DriverRankingList: []*request_all_driver_rankings_response.RankingT{
827 {
828 MatchNumber: 36,
Emily Markovae68b7632023-12-30 14:17:55 -0800829 Rank1: "1234",
830 Rank2: "1235",
831 Rank3: "1236",
Filip Kujawaf882e022022-12-14 13:14:08 -0800832 },
833 {
834 MatchNumber: 36,
Emily Markovae68b7632023-12-30 14:17:55 -0800835 Rank1: "101",
836 Rank2: "202",
837 Rank3: "303",
Filip Kujawaf882e022022-12-14 13:14:08 -0800838 },
839 },
840 }
841 if len(expected.DriverRankingList) != len(response.DriverRankingList) {
842 t.Fatal("Expected ", expected, ", but got ", *response)
843 }
844 for i, match := range expected.DriverRankingList {
845 if !reflect.DeepEqual(*match, *response.DriverRankingList[i]) {
846 t.Fatal("Expected for driver ranking", i, ":", *match, ", but got:", *response.DriverRankingList[i])
847 }
848 }
849}
850
851// Validates that we can request all notes.
852func TestRequestAllNotes(t *testing.T) {
853 db := MockDatabase{
854 notes: []db.NotesData{
855 {
Emily Markovae68b7632023-12-30 14:17:55 -0800856 TeamNumber: "971",
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800857 Notes: "Notes",
858 GoodDriving: true,
859 BadDriving: false,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700860 SolidPlacing: true,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800861 SketchyPlacing: false,
862 GoodDefense: true,
863 BadDefense: false,
864 EasilyDefended: false,
Filip Kujawaf882e022022-12-14 13:14:08 -0800865 },
866 {
Emily Markovae68b7632023-12-30 14:17:55 -0800867 TeamNumber: "972",
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800868 Notes: "More Notes",
869 GoodDriving: false,
870 BadDriving: false,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700871 SolidPlacing: false,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800872 SketchyPlacing: true,
873 GoodDefense: false,
874 BadDefense: true,
875 EasilyDefended: false,
Filip Kujawaf882e022022-12-14 13:14:08 -0800876 },
877 },
878 }
879 scoutingServer := server.NewScoutingServer()
Philipp Schrader43c730b2023-02-26 20:27:44 -0800880 HandleRequests(&db, scoutingServer)
Filip Kujawaf882e022022-12-14 13:14:08 -0800881 scoutingServer.Start(8080)
882 defer scoutingServer.Stop()
883
884 builder := flatbuffers.NewBuilder(1024)
885 builder.Finish((&request_all_notes.RequestAllNotesT{}).Pack(builder))
886
887 response, err := debug.RequestAllNotes("http://localhost:8080", builder.FinishedBytes())
888 if err != nil {
889 t.Fatal("Failed to request all notes: ", err)
890 }
891
892 expected := request_all_notes_response.RequestAllNotesResponseT{
893 NoteList: []*request_all_notes_response.NoteT{
894 {
Emily Markovae68b7632023-12-30 14:17:55 -0800895 Team: "971",
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800896 Notes: "Notes",
897 GoodDriving: true,
898 BadDriving: false,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700899 SolidPlacing: true,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800900 SketchyPlacing: false,
901 GoodDefense: true,
902 BadDefense: false,
903 EasilyDefended: false,
Filip Kujawaf882e022022-12-14 13:14:08 -0800904 },
905 {
Emily Markovae68b7632023-12-30 14:17:55 -0800906 Team: "972",
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800907 Notes: "More Notes",
908 GoodDriving: false,
909 BadDriving: false,
Filip Kujawa11dc4c92023-04-13 08:55:43 -0700910 SolidPlacing: false,
Filip Kujawa7ddd5652023-03-07 19:56:15 -0800911 SketchyPlacing: true,
912 GoodDefense: false,
913 BadDefense: true,
914 EasilyDefended: false,
Filip Kujawaf882e022022-12-14 13:14:08 -0800915 },
916 },
917 }
918 if len(expected.NoteList) != len(response.NoteList) {
919 t.Fatal("Expected ", expected, ", but got ", *response)
920 }
921 for i, note := range expected.NoteList {
922 if !reflect.DeepEqual(*note, *response.NoteList[i]) {
923 t.Fatal("Expected for note", i, ":", *note, ", but got:", *response.NoteList[i])
924 }
925 }
926}
927
Sabina Leaver9b4eb312023-02-20 19:58:17 -0800928func packAction(action *submit_actions.ActionT) []byte {
929 builder := flatbuffers.NewBuilder(50 * 1024)
930 builder.Finish((action).Pack(builder))
931 return (builder.FinishedBytes())
932}
933
934func TestAddingActions(t *testing.T) {
935 database := MockDatabase{}
936 scoutingServer := server.NewScoutingServer()
937 HandleRequests(&database, scoutingServer)
938 scoutingServer.Start(8080)
939 defer scoutingServer.Stop()
940
941 builder := flatbuffers.NewBuilder(1024)
942 builder.Finish((&submit_actions.SubmitActionsT{
943 TeamNumber: "1234",
944 MatchNumber: 4,
945 SetNumber: 1,
946 CompLevel: "qual",
947 ActionsList: []*submit_actions.ActionT{
948 {
949 ActionTaken: &submit_actions.ActionTypeT{
950 Type: submit_actions.ActionTypePickupObjectAction,
951 Value: &submit_actions.PickupObjectActionT{
952 ObjectType: submit_actions.ObjectTypekCube,
953 Auto: true,
954 },
955 },
956 Timestamp: 2400,
957 },
958 {
959 ActionTaken: &submit_actions.ActionTypeT{
960 Type: submit_actions.ActionTypePlaceObjectAction,
961 Value: &submit_actions.PlaceObjectActionT{
962 ObjectType: submit_actions.ObjectTypekCube,
963 ScoreLevel: submit_actions.ScoreLevelkLow,
964 Auto: false,
965 },
966 },
967 Timestamp: 1009,
968 },
969 },
Philipp Schrader4b489222023-04-15 16:40:16 -0700970 PreScouting: true,
Sabina Leaver9b4eb312023-02-20 19:58:17 -0800971 }).Pack(builder))
972
973 _, err := debug.SubmitActions("http://localhost:8080", builder.FinishedBytes())
974 if err != nil {
975 t.Fatal("Failed to submit actions: ", err)
976 }
977
978 // Make sure that the data made it into the database.
979 // TODO: Add this back when we figure out how to add the serialized action into the database.
980
981 /* expectedActionsT := []*submit_actions.ActionT{
982 {
983 ActionTaken: &submit_actions.ActionTypeT{
984 Type: submit_actions.ActionTypePickupObjectAction,
985 Value: &submit_actions.PickupObjectActionT{
986 ObjectType: submit_actions.ObjectTypekCube,
987 Auto: true,
988 },
989 },
990 Timestamp: 2400,
991 },
992 {
993 ActionTaken: &submit_actions.ActionTypeT{
994 Type: submit_actions.ActionTypePlaceObjectAction,
995 Value: &submit_actions.PlaceObjectActionT{
996 ObjectType: submit_actions.ObjectTypekCube,
997 ScoreLevel: submit_actions.ScoreLevelkLow,
998 Auto: false,
999 },
1000 },
1001 Timestamp: 1009,
1002 },
1003 } */
1004
1005 expectedActions := []db.Action{
1006 {
Philipp Schrader4b489222023-04-15 16:40:16 -07001007 PreScouting: true,
Sabina Leaver9b4eb312023-02-20 19:58:17 -08001008 TeamNumber: "1234",
1009 MatchNumber: 4,
1010 SetNumber: 1,
1011 CompLevel: "qual",
1012 CollectedBy: "debug_cli",
1013 CompletedAction: []byte{},
Philipp Schrader670a1c82023-05-17 19:42:43 -07001014 Timestamp: 2400,
Sabina Leaver9b4eb312023-02-20 19:58:17 -08001015 },
1016 {
Philipp Schrader4b489222023-04-15 16:40:16 -07001017 PreScouting: true,
Sabina Leaver9b4eb312023-02-20 19:58:17 -08001018 TeamNumber: "1234",
1019 MatchNumber: 4,
1020 SetNumber: 1,
1021 CompLevel: "qual",
1022 CollectedBy: "debug_cli",
1023 CompletedAction: []byte{},
Philipp Schrader670a1c82023-05-17 19:42:43 -07001024 Timestamp: 1009,
Sabina Leaver9b4eb312023-02-20 19:58:17 -08001025 },
1026 }
1027
Philipp Schradere11114f2023-04-15 17:04:25 -07001028 expectedStats := []db.Stats2023{
1029 db.Stats2023{
1030 PreScouting: true,
1031 TeamNumber: "1234", MatchNumber: 4, SetNumber: 1,
1032 CompLevel: "qual", StartingQuadrant: 0, LowCubesAuto: 0,
1033 MiddleCubesAuto: 0, HighCubesAuto: 0, CubesDroppedAuto: 0,
1034 LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
1035 ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 0,
1036 HighCubes: 0, CubesDropped: 0, LowCones: 0,
1037 MiddleCones: 0, HighCones: 0, ConesDropped: 0, SuperchargedPieces: 0,
1038 AvgCycle: 0, Mobility: false, DockedAuto: false, EngagedAuto: false,
1039 BalanceAttemptAuto: false, Docked: false, Engaged: false,
1040 BalanceAttempt: false, CollectedBy: "debug_cli",
1041 },
1042 }
1043
Sabina Leaver9b4eb312023-02-20 19:58:17 -08001044 if !reflect.DeepEqual(expectedActions, database.actions) {
1045 t.Fatal("Expected ", expectedActions, ", but got:", database.actions)
1046 }
Philipp Schradere11114f2023-04-15 17:04:25 -07001047 if !reflect.DeepEqual(expectedStats, database.stats2023) {
1048 t.Fatal("Expected ", expectedStats, ", but got:", database.stats2023)
1049 }
Sabina Leaver9b4eb312023-02-20 19:58:17 -08001050}
1051
Filip Kujawac1ded372023-05-27 14:33:43 -07001052// Validates that we can delete stats.
1053func TestDeleteFromStats(t *testing.T) {
1054 database := MockDatabase{
1055 stats2023: []db.Stats2023{
1056 {
1057 TeamNumber: "3634", MatchNumber: 1, SetNumber: 2,
1058 CompLevel: "quals", StartingQuadrant: 3, LowCubesAuto: 10,
1059 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 0,
1060 LowConesAuto: 1, MiddleConesAuto: 2, HighConesAuto: 1,
1061 ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
1062 HighCubes: 2, CubesDropped: 1, LowCones: 1,
1063 MiddleCones: 2, HighCones: 0, ConesDropped: 1, SuperchargedPieces: 0,
1064 AvgCycle: 34, Mobility: false, DockedAuto: true, EngagedAuto: false,
1065 BalanceAttemptAuto: false, Docked: false, Engaged: false,
1066 BalanceAttempt: true, CollectedBy: "isaac",
1067 },
1068 {
1069 TeamNumber: "2343", MatchNumber: 1, SetNumber: 2,
1070 CompLevel: "quals", StartingQuadrant: 1, LowCubesAuto: 0,
1071 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 2,
1072 LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
1073 ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
1074 HighCubes: 1, CubesDropped: 0, LowCones: 0,
1075 MiddleCones: 2, HighCones: 1, ConesDropped: 1, SuperchargedPieces: 0,
1076 AvgCycle: 53, Mobility: false, DockedAuto: false, EngagedAuto: false,
1077 BalanceAttemptAuto: true, Docked: false, Engaged: false,
1078 BalanceAttempt: true, CollectedBy: "unknown",
1079 },
1080 },
1081 actions: []db.Action{
1082 {
1083 PreScouting: true,
1084 TeamNumber: "3634",
1085 MatchNumber: 1,
1086 SetNumber: 2,
1087 CompLevel: "quals",
1088 CollectedBy: "debug_cli",
1089 CompletedAction: []byte{},
1090 Timestamp: 2400,
1091 },
1092 {
1093 PreScouting: true,
1094 TeamNumber: "2343",
1095 MatchNumber: 1,
1096 SetNumber: 2,
1097 CompLevel: "quals",
1098 CollectedBy: "debug_cli",
1099 CompletedAction: []byte{},
1100 Timestamp: 1009,
1101 },
1102 },
1103 }
1104 scoutingServer := server.NewScoutingServer()
1105 HandleRequests(&database, scoutingServer)
1106 scoutingServer.Start(8080)
1107 defer scoutingServer.Stop()
1108
1109 builder := flatbuffers.NewBuilder(1024)
1110 builder.Finish((&delete_2023_data_scouting.Delete2023DataScoutingT{
1111 CompLevel: "quals",
1112 MatchNumber: 1,
1113 SetNumber: 2,
1114 TeamNumber: "2343",
1115 }).Pack(builder))
1116
1117 _, err := debug.Delete2023DataScouting("http://localhost:8080", builder.FinishedBytes())
1118 if err != nil {
1119 t.Fatal("Failed to delete from data scouting ", err)
1120 }
1121
1122 expectedActions := []db.Action{
1123 {
1124 PreScouting: true,
1125 TeamNumber: "3634",
1126 MatchNumber: 1,
1127 SetNumber: 2,
1128 CompLevel: "quals",
1129 CollectedBy: "debug_cli",
1130 CompletedAction: []byte{},
1131 Timestamp: 2400,
1132 },
1133 }
1134
1135 expectedStats := []db.Stats2023{
1136 {
1137 TeamNumber: "3634", MatchNumber: 1, SetNumber: 2,
1138 CompLevel: "quals", StartingQuadrant: 3, LowCubesAuto: 10,
1139 MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 0,
1140 LowConesAuto: 1, MiddleConesAuto: 2, HighConesAuto: 1,
1141 ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
1142 HighCubes: 2, CubesDropped: 1, LowCones: 1,
1143 MiddleCones: 2, HighCones: 0, ConesDropped: 1, SuperchargedPieces: 0,
1144 AvgCycle: 34, Mobility: false, DockedAuto: true, EngagedAuto: false,
1145 BalanceAttemptAuto: false, Docked: false, Engaged: false,
1146 BalanceAttempt: true, CollectedBy: "isaac",
1147 },
1148 }
1149
1150 if !reflect.DeepEqual(expectedActions, database.actions) {
1151 t.Fatal("Expected ", expectedActions, ", but got:", database.actions)
1152 }
1153 if !reflect.DeepEqual(expectedStats, database.stats2023) {
1154 t.Fatal("Expected ", expectedStats, ", but got:", database.stats2023)
1155 }
1156}
1157
Philipp Schrader8747f1b2022-02-23 23:56:22 -08001158// A mocked database we can use for testing. Add functionality to this as
1159// needed for your tests.
1160
Philipp Schradercbf5c6a2022-02-27 23:25:19 -08001161type MockDatabase struct {
Emily Markovabf24c9e2023-02-08 20:31:11 -08001162 matches []db.TeamMatch
Filip Kujawa210a03b2022-11-24 14:41:11 -08001163 notes []db.NotesData
1164 shiftSchedule []db.Shift
1165 driver_ranking []db.DriverRankingData
Emily Markova290147d2023-03-03 22:40:06 -08001166 stats2023 []db.Stats2023
Sabina Leaver9b4eb312023-02-20 19:58:17 -08001167 actions []db.Action
Emily Markovafaecfe12023-07-01 12:40:03 -07001168 images []db.PitImage
Philipp Schradercbf5c6a2022-02-27 23:25:19 -08001169}
Philipp Schrader8747f1b2022-02-23 23:56:22 -08001170
Emily Markovabf24c9e2023-02-08 20:31:11 -08001171func (database *MockDatabase) AddToMatch(match db.TeamMatch) error {
Philipp Schraderd3fac192022-03-02 20:35:46 -08001172 database.matches = append(database.matches, match)
Philipp Schrader8747f1b2022-02-23 23:56:22 -08001173 return nil
1174}
1175
Emily Markova290147d2023-03-03 22:40:06 -08001176func (database *MockDatabase) AddToStats2023(stats2023 db.Stats2023) error {
1177 database.stats2023 = append(database.stats2023, stats2023)
1178 return nil
1179}
Emily Markovabf24c9e2023-02-08 20:31:11 -08001180func (database *MockDatabase) ReturnMatches() ([]db.TeamMatch, error) {
Philipp Schradercbf5c6a2022-02-27 23:25:19 -08001181 return database.matches, nil
Philipp Schrader8747f1b2022-02-23 23:56:22 -08001182}
1183
Emily Markova290147d2023-03-03 22:40:06 -08001184func (database *MockDatabase) ReturnStats2023() ([]db.Stats2023, error) {
1185 return database.stats2023, nil
1186}
1187
Filip Kujawaf3f9def2023-04-20 13:46:46 -07001188func (database *MockDatabase) ReturnStats2023ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]db.Stats2023, error) {
Philipp Schrader0f7b6362023-03-11 14:02:48 -08001189 var results []db.Stats2023
1190 for _, stats := range database.stats2023 {
Filip Kujawaf3f9def2023-04-20 13:46:46 -07001191 if stats.TeamNumber == teamNumber && stats.MatchNumber == matchNumber && stats.SetNumber == setNumber && stats.CompLevel == compLevel && stats.PreScouting == preScouting {
Philipp Schrader0f7b6362023-03-11 14:02:48 -08001192 results = append(results, stats)
1193 }
1194 }
1195 return results, nil
1196}
1197
Emily Markovae68b7632023-12-30 14:17:55 -08001198func (database *MockDatabase) QueryNotes(requestedTeam string) ([]string, error) {
Alex Perry81f96ba2022-03-13 18:26:19 -07001199 var results []string
1200 for _, data := range database.notes {
1201 if data.TeamNumber == requestedTeam {
Philipp Schradereecb8962022-06-01 21:02:42 -07001202 results = append(results, data.Notes)
Alex Perry81f96ba2022-03-13 18:26:19 -07001203 }
1204 }
Philipp Schradereecb8962022-06-01 21:02:42 -07001205 return results, nil
Alex Perry81f96ba2022-03-13 18:26:19 -07001206}
1207
Filip Kujawaf947cb42022-11-21 10:00:30 -08001208func (database *MockDatabase) AddNotes(data db.NotesData) error {
1209 database.notes = append(database.notes, data)
Alex Perry81f96ba2022-03-13 18:26:19 -07001210 return nil
1211}
1212
Filip Kujawaf882e022022-12-14 13:14:08 -08001213func (database *MockDatabase) ReturnAllNotes() ([]db.NotesData, error) {
1214 return database.notes, nil
1215}
1216
Milo Lin1d59f0c2022-06-22 20:30:58 -07001217func (database *MockDatabase) AddToShift(data db.Shift) error {
1218 database.shiftSchedule = append(database.shiftSchedule, data)
1219 return nil
1220}
1221
1222func (database *MockDatabase) ReturnAllShifts() ([]db.Shift, error) {
1223 return database.shiftSchedule, nil
1224}
1225
1226func (database *MockDatabase) QueryAllShifts(int) ([]db.Shift, error) {
1227 return []db.Shift{}, nil
1228}
1229
Emily Markovafaecfe12023-07-01 12:40:03 -07001230func (database *MockDatabase) QueryPitImages(requestedTeam string) ([]db.RequestedPitImage, error) {
1231 var results []db.RequestedPitImage
1232 for _, data := range database.images {
1233 if data.TeamNumber == requestedTeam {
1234 results = append(results, db.RequestedPitImage{
1235 TeamNumber: data.TeamNumber,
1236 ImagePath: data.ImagePath,
1237 CheckSum: data.CheckSum,
1238 })
1239 }
1240 }
1241 return results, nil
1242}
1243
Filip Kujawa210a03b2022-11-24 14:41:11 -08001244func (database *MockDatabase) AddDriverRanking(data db.DriverRankingData) error {
1245 database.driver_ranking = append(database.driver_ranking, data)
1246 return nil
1247}
1248
Filip Kujawaf882e022022-12-14 13:14:08 -08001249func (database *MockDatabase) ReturnAllDriverRankings() ([]db.DriverRankingData, error) {
1250 return database.driver_ranking, nil
1251}
Sabina Leaver9b4eb312023-02-20 19:58:17 -08001252
1253func (database *MockDatabase) AddAction(action db.Action) error {
1254 database.actions = append(database.actions, action)
1255 return nil
1256}
1257
Emily Markovafaecfe12023-07-01 12:40:03 -07001258func (database *MockDatabase) AddPitImage(pitImage db.PitImage) error {
1259 database.images = append(database.images, pitImage)
1260 return nil
1261}
1262
Sabina Leaver9b4eb312023-02-20 19:58:17 -08001263func (database *MockDatabase) ReturnActions() ([]db.Action, error) {
1264 return database.actions, nil
1265}
Filip Kujawac1ded372023-05-27 14:33:43 -07001266
Emily Markova8e39f452023-12-23 12:17:30 -08001267func (database *MockDatabase) ReturnPitImages() ([]db.PitImage, error) {
1268 return database.images, nil
1269}
1270
Filip Kujawac1ded372023-05-27 14:33:43 -07001271func (database *MockDatabase) DeleteFromStats(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
1272 for i, stat := range database.stats2023 {
1273 if stat.CompLevel == compLevel_ &&
1274 stat.MatchNumber == matchNumber_ &&
1275 stat.SetNumber == setNumber_ &&
1276 stat.TeamNumber == teamNumber_ {
1277 // Match found, remove the element from the array.
1278 database.stats2023 = append(database.stats2023[:i], database.stats2023[i+1:]...)
1279 }
1280 }
1281 return nil
1282}
1283
1284func (database *MockDatabase) DeleteFromActions(compLevel_ string, matchNumber_ int32, setNumber_ int32, teamNumber_ string) error {
1285 for i, action := range database.actions {
1286 if action.CompLevel == compLevel_ &&
1287 action.MatchNumber == matchNumber_ &&
1288 action.SetNumber == setNumber_ &&
1289 action.TeamNumber == teamNumber_ {
1290 // Match found, remove the element from the array.
1291 database.actions = append(database.actions[:i], database.actions[i+1:]...)
1292 }
1293 }
1294 return nil
1295}