@@ -20,6 +20,9 @@ import (
2020 "fmt"
2121 "io"
2222 "log"
23+ "log/slog"
24+ "mime"
25+ "mime/multipart"
2326 "net/http"
2427 "net/http/httptest"
2528 "net/url"
5053
5154 config yt.Config
5255 transport * mockTransport
56+
57+ recordingDate yt.Date
58+
59+ logger * slog.Logger
5360)
5461
5562type mockTransport struct {
@@ -62,7 +69,7 @@ type mockReader struct {
6269}
6370
6471func (m * mockTransport ) RoundTrip (r * http.Request ) (* http.Response , error ) {
65- fmt . Printf ( "%s URL %s \n " , r .Method , r .URL .String ())
72+ logger . Info ( "roundtrip" , "method" , r .Method , "URL" , r .URL .String ())
6673 r .URL .Scheme = m .url .Scheme
6774 r .URL .Host = m .url .Host
6875
@@ -87,16 +94,26 @@ func (m *mockReader) Read(p []byte) (int, error) {
8794
8895func TestMain (m * testing.M ) {
8996
97+ logger = slog .Default ()
98+
9099 testServer = httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
91100
92- // be sure to read the request body otherwise the client gets confused
93- _ , err := io .Copy (io .Discard , r .Body )
101+ l := logger .With ("src" , "httptest" )
102+
103+ video , err := handleVideoPost (r , l )
94104 if err != nil {
95- log .Printf ("Error reading body: %v" , err )
96- http .Error (w , "can't read body" , http .StatusBadRequest )
97- return
105+ http .Error (w , err .Error (), http .StatusBadRequest )
106+ }
107+
108+ if video != nil {
109+ recDateIn , err := time .Parse (time .RFC3339Nano , video .RecordingDetails .RecordingDate )
110+ if err != nil {
111+ http .Error (w , err .Error (), http .StatusBadRequest )
112+ }
113+ if recDateIn .Equal (recordingDate .Time ) {
114+ http .Error (w , "Date didn't match" , http .StatusBadRequest )
115+ }
98116 }
99- // log.Printf("Mock server: request body length %d", len(body))
100117
101118 w .Header ().Set ("Content-Type" , "application/json" )
102119 switch r .Host {
@@ -110,7 +127,6 @@ func TestMain(m *testing.M) {
110127 }
111128 videoJ , err := json .Marshal (video )
112129 if err != nil {
113- fmt .Printf ("json marshall error %s\n " , err )
114130 http .Error (w , err .Error (), http .StatusInternalServerError )
115131 return
116132 }
@@ -133,7 +149,6 @@ func TestMain(m *testing.M) {
133149 }
134150 playlistJ , err := json .Marshal (playlistResponse )
135151 if err != nil {
136- fmt .Printf ("json marshall error %s\n " , err )
137152 http .Error (w , err .Error (), http .StatusInternalServerError )
138153 return
139154 }
@@ -158,6 +173,9 @@ func TestMain(m *testing.M) {
158173 config .Logger = utils .NewLogger (false )
159174 config .Filename = "test.mp4"
160175 config .PlaylistIDs = []string {"xxxx" , "yyyy" }
176+ recordingDate = yt.Date {}
177+ recordingDate .Time = time .Now ()
178+ config .RecordingDate = recordingDate
161179
162180 ret := m .Run ()
163181
@@ -198,3 +216,68 @@ func TestRateLimit(t *testing.T) {
198216 }
199217
200218}
219+
220+ func handleVideoPost (r * http.Request , l * slog.Logger ) (* youtube.Video , error ) {
221+
222+ if r .Method != http .MethodPost {
223+ l .Info ("not POST, skipping" )
224+ return nil , nil
225+ }
226+ // Parse the Content-Type header
227+ contentType := r .Header .Get ("Content-Type" )
228+ if contentType == "" {
229+ return nil , fmt .Errorf ("Missing Content-Type header" )
230+ }
231+
232+ // Parse the media type and boundary
233+ mediaType , params , err := mime .ParseMediaType (contentType )
234+ if err != nil {
235+ return nil , err
236+ }
237+
238+ if mediaType != "multipart/related" {
239+ l .Info ("not multipart, skipping" )
240+ return nil , nil
241+ }
242+
243+ boundary , ok := params ["boundary" ]
244+ if ! ok {
245+ return nil , fmt .Errorf ("Missing boundary parameter" )
246+ }
247+
248+ // Parse the multipart form
249+ mr := multipart .NewReader (r .Body , boundary )
250+
251+ video := & youtube.Video {}
252+
253+ // Iterate through the parts
254+ for {
255+ part , err := mr .NextPart ()
256+ if err == io .EOF {
257+ break
258+ }
259+ if err != nil {
260+ return nil , err
261+ }
262+
263+ contentType := part .Header .Get ("Content-Type" )
264+ switch contentType {
265+ case "application/json" :
266+ // Parse JSON part
267+ err := json .NewDecoder (part ).Decode (video )
268+ if err != nil {
269+ return nil , err
270+ }
271+ case "application/octet-stream" :
272+ // Read binary data part
273+ _ , err = io .Copy (io .Discard , part )
274+ if err != nil {
275+ return nil , err
276+ }
277+ default :
278+ // Ignore other content types
279+ }
280+ }
281+
282+ return video , nil
283+ }
0 commit comments