]> git.r.bdr.sh - rbdr/mobius/blame - hotline/transaction_handlers_test.go
Fix issue with HL 1.5+ user flag unset
[rbdr/mobius] / hotline / transaction_handlers_test.go
CommitLineData
6988a057
JH
1package hotline
2
3import (
4 "github.com/stretchr/testify/assert"
00d1ef67 5 "io/fs"
6988a057 6 "math/rand"
00d1ef67 7 "os"
6988a057
JH
8 "testing"
9)
10
11func TestHandleSetChatSubject(t *testing.T) {
12 type args struct {
13 cc *ClientConn
14 t *Transaction
15 }
16 tests := []struct {
17 name string
18 args args
19 want []Transaction
20 wantErr bool
21 }{
22 {
23 name: "sends chat subject to private chat members",
24 args: args{
25 cc: &ClientConn{
72dd37f1 26 UserName: []byte{0x00, 0x01},
6988a057
JH
27 Server: &Server{
28 PrivateChats: map[uint32]*PrivateChat{
29 uint32(1): {
30 Subject: "unset",
31 ClientConn: map[uint16]*ClientConn{
32 uint16(1): {
33 Account: &Account{
34 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
35 },
36 ID: &[]byte{0, 1},
37 },
38 uint16(2): {
39 Account: &Account{
40 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
41 },
42 ID: &[]byte{0, 2},
43 },
44 },
45 },
46 },
47 Clients: map[uint16]*ClientConn{
48 uint16(1): {
49 Account: &Account{
50 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
51 },
52 ID: &[]byte{0, 1},
53 },
54 uint16(2): {
55 Account: &Account{
56 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
57 },
58 ID: &[]byte{0, 2},
59 },
60 },
61 },
62 },
63 t: &Transaction{
64 Flags: 0x00,
65 IsReply: 0x00,
66 Type: []byte{0, 0x6a},
67 ID: []byte{0, 0, 0, 1},
68 ErrorCode: []byte{0, 0, 0, 0},
69 Fields: []Field{
70 NewField(fieldChatID, []byte{0, 0, 0, 1}),
71 NewField(fieldChatSubject, []byte("Test Subject")),
72 },
73 },
74 },
75 want: []Transaction{
76 {
77 clientID: &[]byte{0, 1},
78 Flags: 0x00,
79 IsReply: 0x00,
80 Type: []byte{0, 0x77},
81 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
82 ErrorCode: []byte{0, 0, 0, 0},
83 Fields: []Field{
84 NewField(fieldChatID, []byte{0, 0, 0, 1}),
85 NewField(fieldChatSubject, []byte("Test Subject")),
86 },
87 },
88 {
89 clientID: &[]byte{0, 2},
90 Flags: 0x00,
91 IsReply: 0x00,
92 Type: []byte{0, 0x77},
93 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
94 ErrorCode: []byte{0, 0, 0, 0},
95 Fields: []Field{
96 NewField(fieldChatID, []byte{0, 0, 0, 1}),
97 NewField(fieldChatSubject, []byte("Test Subject")),
98 },
99 },
100 },
101 wantErr: false,
102 },
103 }
104 for _, tt := range tests {
105 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
106
107 t.Run(tt.name, func(t *testing.T) {
108 got, err := HandleSetChatSubject(tt.args.cc, tt.args.t)
109 if (err != nil) != tt.wantErr {
110 t.Errorf("HandleSetChatSubject() error = %v, wantErr %v", err, tt.wantErr)
111 return
112 }
113 if !assert.Equal(t, tt.want, got) {
114 t.Errorf("HandleSetChatSubject() got = %v, want %v", got, tt.want)
115 }
116 })
117 }
118}
119
120func TestHandleLeaveChat(t *testing.T) {
121 type args struct {
122 cc *ClientConn
123 t *Transaction
124 }
125 tests := []struct {
126 name string
127 args args
128 want []Transaction
129 wantErr bool
130 }{
131 {
132 name: "returns expected transactions",
133 args: args{
134 cc: &ClientConn{
135 ID: &[]byte{0, 2},
136 Server: &Server{
137 PrivateChats: map[uint32]*PrivateChat{
138 uint32(1): {
139 ClientConn: map[uint16]*ClientConn{
140 uint16(1): {
141 Account: &Account{
142 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
143 },
144 ID: &[]byte{0, 1},
145 },
146 uint16(2): {
147 Account: &Account{
148 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
149 },
150 ID: &[]byte{0, 2},
151 },
152 },
153 },
154 },
155 Clients: map[uint16]*ClientConn{
156 uint16(1): {
157 Account: &Account{
158 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
159 },
160 ID: &[]byte{0, 1},
161 },
162 uint16(2): {
163 Account: &Account{
164 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
165 },
166 ID: &[]byte{0, 2},
167 },
168 },
169 },
170 },
5c34f875 171 t: NewTransaction(tranDeleteUser, nil, NewField(fieldChatID, []byte{0, 0, 0, 1})),
6988a057
JH
172 },
173 want: []Transaction{
174 {
175 clientID: &[]byte{0, 1},
176 Flags: 0x00,
177 IsReply: 0x00,
178 Type: []byte{0, 0x76},
179 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
180 ErrorCode: []byte{0, 0, 0, 0},
181 Fields: []Field{
182 NewField(fieldChatID, []byte{0, 0, 0, 1}),
183 NewField(fieldUserID, []byte{0, 2}),
184 },
185 },
186 },
187 wantErr: false,
188 },
189 }
190 for _, tt := range tests {
191 rand.Seed(1)
192 t.Run(tt.name, func(t *testing.T) {
193 got, err := HandleLeaveChat(tt.args.cc, tt.args.t)
194 if (err != nil) != tt.wantErr {
195 t.Errorf("HandleLeaveChat() error = %v, wantErr %v", err, tt.wantErr)
196 return
197 }
198 if !assert.Equal(t, tt.want, got) {
199 t.Errorf("HandleLeaveChat() got = %v, want %v", got, tt.want)
200 }
201 })
202 }
203}
204
6988a057
JH
205func TestHandleGetUserNameList(t *testing.T) {
206 type args struct {
207 cc *ClientConn
208 t *Transaction
209 }
210 tests := []struct {
211 name string
212 args args
213 want []Transaction
214 wantErr bool
215 }{
216 {
217 name: "replies with userlist transaction",
218 args: args{
219 cc: &ClientConn{
220
221 ID: &[]byte{1, 1},
222 Server: &Server{
223 Clients: map[uint16]*ClientConn{
224 uint16(1): {
225 ID: &[]byte{0, 1},
226 Icon: &[]byte{0, 2},
227 Flags: &[]byte{0, 3},
72dd37f1 228 UserName: []byte{0, 4},
bd1ce113 229 Agreed: true,
6988a057 230 },
c7e932c0
JH
231 uint16(2): {
232 ID: &[]byte{0, 2},
233 Icon: &[]byte{0, 2},
234 Flags: &[]byte{0, 3},
235 UserName: []byte{0, 4},
bd1ce113
JH
236 Agreed: true,
237 },
238 uint16(3): {
239 ID: &[]byte{0, 3},
240 Icon: &[]byte{0, 2},
241 Flags: &[]byte{0, 3},
242 UserName: []byte{0, 4},
243 Agreed: false,
c7e932c0 244 },
6988a057
JH
245 },
246 },
247 },
248 t: &Transaction{
249 ID: []byte{0, 0, 0, 1},
250 Type: []byte{0, 1},
251 },
252 },
253 want: []Transaction{
254 {
255 clientID: &[]byte{1, 1},
256 Flags: 0x00,
257 IsReply: 0x01,
258 Type: []byte{0, 1},
259 ID: []byte{0, 0, 0, 1},
260 ErrorCode: []byte{0, 0, 0, 0},
261 Fields: []Field{
262 NewField(
263 fieldUsernameWithInfo,
264 []byte{00, 01, 00, 02, 00, 03, 00, 02, 00, 04},
265 ),
c7e932c0
JH
266 NewField(
267 fieldUsernameWithInfo,
268 []byte{00, 02, 00, 02, 00, 03, 00, 02, 00, 04},
269 ),
6988a057
JH
270 },
271 },
272 },
273 wantErr: false,
274 },
275 }
276 for _, tt := range tests {
277 t.Run(tt.name, func(t *testing.T) {
278 got, err := HandleGetUserNameList(tt.args.cc, tt.args.t)
279 if (err != nil) != tt.wantErr {
280 t.Errorf("HandleGetUserNameList() error = %v, wantErr %v", err, tt.wantErr)
281 return
282 }
bd1ce113 283 assert.Equal(t, tt.want, got)
6988a057
JH
284 })
285 }
286}
287
288func TestHandleChatSend(t *testing.T) {
289 type args struct {
290 cc *ClientConn
291 t *Transaction
292 }
293 tests := []struct {
294 name string
295 args args
296 want []Transaction
297 wantErr bool
298 }{
299 {
300 name: "sends chat msg transaction to all clients",
301 args: args{
302 cc: &ClientConn{
72dd37f1 303 UserName: []byte{0x00, 0x01},
6988a057
JH
304 Server: &Server{
305 Clients: map[uint16]*ClientConn{
306 uint16(1): {
307 Account: &Account{
308 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
309 },
310 ID: &[]byte{0, 1},
311 },
312 uint16(2): {
313 Account: &Account{
314 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
315 },
316 ID: &[]byte{0, 2},
317 },
318 },
319 },
320 },
321 t: &Transaction{
322 Fields: []Field{
323 NewField(fieldData, []byte("hai")),
324 },
325 },
326 },
327 want: []Transaction{
328 {
329 clientID: &[]byte{0, 1},
330 Flags: 0x00,
331 IsReply: 0x00,
332 Type: []byte{0, 0x6a},
333 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
334 ErrorCode: []byte{0, 0, 0, 0},
335 Fields: []Field{
336 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
337 },
338 },
339 {
340 clientID: &[]byte{0, 2},
341 Flags: 0x00,
342 IsReply: 0x00,
343 Type: []byte{0, 0x6a},
344 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
345 ErrorCode: []byte{0, 0, 0, 0},
346 Fields: []Field{
347 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
348 },
349 },
350 },
351 wantErr: false,
352 },
72dd37f1
JH
353 {
354 name: "sends chat msg as emote if fieldChatOptions is set",
355 args: args{
356 cc: &ClientConn{
357 UserName: []byte("Testy McTest"),
358 Server: &Server{
359 Clients: map[uint16]*ClientConn{
360 uint16(1): {
361 Account: &Account{
362 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
363 },
364 ID: &[]byte{0, 1},
365 },
366 uint16(2): {
367 Account: &Account{
368 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
369 },
370 ID: &[]byte{0, 2},
371 },
372 },
373 },
374 },
375 t: &Transaction{
376 Fields: []Field{
377 NewField(fieldData, []byte("performed action")),
378 NewField(fieldChatOptions, []byte{0x00, 0x01}),
379 },
380 },
381 },
382 want: []Transaction{
383 {
384 clientID: &[]byte{0, 1},
385 Flags: 0x00,
386 IsReply: 0x00,
387 Type: []byte{0, 0x6a},
388 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
389 ErrorCode: []byte{0, 0, 0, 0},
390 Fields: []Field{
391 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
392 },
393 },
394 {
395 clientID: &[]byte{0, 2},
396 Flags: 0x00,
397 IsReply: 0x00,
398 Type: []byte{0, 0x6a},
399 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
400 ErrorCode: []byte{0, 0, 0, 0},
401 Fields: []Field{
402 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
403 },
404 },
405 },
406 wantErr: false,
407 },
6988a057
JH
408 {
409 name: "only sends chat msg to clients with accessReadChat permission",
410 args: args{
411 cc: &ClientConn{
72dd37f1 412 UserName: []byte{0x00, 0x01},
6988a057
JH
413 Server: &Server{
414 Clients: map[uint16]*ClientConn{
415 uint16(1): {
416 Account: &Account{
417 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
418 },
419 ID: &[]byte{0, 1},
420 },
421 uint16(2): {
422 Account: &Account{
423 Access: &[]byte{0, 0, 0, 0, 0, 0, 0, 0},
424 },
425 ID: &[]byte{0, 2},
426 },
427 },
428 },
429 },
430 t: &Transaction{
431 Fields: []Field{
432 NewField(fieldData, []byte("hai")),
433 },
434 },
435 },
436 want: []Transaction{
437 {
438 clientID: &[]byte{0, 1},
439 Flags: 0x00,
440 IsReply: 0x00,
441 Type: []byte{0, 0x6a},
442 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
443 ErrorCode: []byte{0, 0, 0, 0},
444 Fields: []Field{
445 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
446 },
447 },
448 },
449 wantErr: false,
450 },
451 }
452 for _, tt := range tests {
453 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
454 t.Run(tt.name, func(t *testing.T) {
455 got, err := HandleChatSend(tt.args.cc, tt.args.t)
456
457 if (err != nil) != tt.wantErr {
458 t.Errorf("HandleChatSend() error = %v, wantErr %v", err, tt.wantErr)
459 return
460 }
461 if !assert.Equal(t, tt.want, got) {
462 t.Errorf("HandleChatSend() got = %v, want %v", got, tt.want)
463 }
464 })
465 }
466}
72dd37f1
JH
467
468func TestHandleGetFileInfo(t *testing.T) {
469 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
470
471 type args struct {
472 cc *ClientConn
473 t *Transaction
474 }
475 tests := []struct {
476 name string
477 args args
478 wantRes []Transaction
479 wantErr bool
480 }{
481 {
482 name: "returns expected fields when a valid file is requested",
483 args: args{
484 cc: &ClientConn{
485 ID: &[]byte{0x00, 0x01},
486 Server: &Server{
487 Config: &Config{
29f329ae
JH
488 FileRoot: func() string {
489 path, _ := os.Getwd()
490 return path + "/test/config/Files"
491 }(),
72dd37f1
JH
492 },
493 },
494 },
495 t: NewTransaction(
496 tranGetFileInfo, nil,
497 NewField(fieldFileName, []byte("testfile.txt")),
498 NewField(fieldFilePath, []byte{0x00, 0x00}),
72dd37f1
JH
499 ),
500 },
501 wantRes: []Transaction{
502 {
503 clientID: &[]byte{0, 1},
504 Flags: 0x00,
505 IsReply: 0x01,
506 Type: []byte{0, 0xce},
507 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
508 ErrorCode: []byte{0, 0, 0, 0},
509 Fields: []Field{
510 NewField(fieldFileName, []byte("testfile.txt")),
511 NewField(fieldFileTypeString, []byte("TEXT")),
2728d12b 512 NewField(fieldFileCreatorString, []byte("ttxt")),
5218c782 513 NewField(fieldFileComment, []byte{}),
72dd37f1 514 NewField(fieldFileType, []byte("TEXT")),
29f329ae
JH
515 NewField(fieldFileCreateDate, make([]byte, 8)),
516 NewField(fieldFileModifyDate, make([]byte, 8)),
72dd37f1
JH
517 NewField(fieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}),
518 },
519 },
520 },
521 wantErr: false,
522 },
523 }
524 for _, tt := range tests {
525 t.Run(tt.name, func(t *testing.T) {
526 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
527
528 gotRes, err := HandleGetFileInfo(tt.args.cc, tt.args.t)
529 if (err != nil) != tt.wantErr {
530 t.Errorf("HandleGetFileInfo() error = %v, wantErr %v", err, tt.wantErr)
531 return
532 }
29f329ae
JH
533
534 // Clear the file timestamp fields to work around problems running the tests in multiple timezones
535 // TODO: revisit how to test this by mocking the stat calls
536 gotRes[0].Fields[5].Data = make([]byte, 8)
537 gotRes[0].Fields[6].Data = make([]byte, 8)
00d1ef67 538 if !assert.Equal(t, tt.wantRes, gotRes) {
72dd37f1
JH
539 t.Errorf("HandleGetFileInfo() gotRes = %v, want %v", gotRes, tt.wantRes)
540 }
541 })
542 }
543}
00d1ef67
JH
544
545func TestHandleNewFolder(t *testing.T) {
546 type args struct {
547 cc *ClientConn
548 t *Transaction
549 }
550 tests := []struct {
551 setup func()
552 name string
553 args args
554 wantRes []Transaction
555 wantErr bool
556 }{
557 {
558 name: "when path is nested",
559 args: args{
560 cc: &ClientConn{
561 ID: &[]byte{0, 1},
562 Server: &Server{
563 Config: &Config{
564 FileRoot: "/Files/",
565 },
566 },
567 },
568 t: NewTransaction(
569 tranNewFolder, &[]byte{0, 1},
570 NewField(fieldFileName, []byte("testFolder")),
571 NewField(fieldFilePath, []byte{
572 0x00, 0x01,
573 0x00, 0x00,
574 0x03,
575 0x61, 0x61, 0x61,
576 }),
577 ),
578 },
579 setup: func() {
580 mfs := MockFileStore{}
581 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
582 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
583 FS = mfs
584 },
585 wantRes: []Transaction{
586 {
587 clientID: &[]byte{0, 1},
588 Flags: 0x00,
589 IsReply: 0x01,
590 Type: []byte{0, 0xcd},
591 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
592 ErrorCode: []byte{0, 0, 0, 0},
593 },
594 },
595 wantErr: false,
596 },
597 {
598 name: "when path is not nested",
599 args: args{
600 cc: &ClientConn{
601 ID: &[]byte{0, 1},
602 Server: &Server{
603 Config: &Config{
604 FileRoot: "/Files",
605 },
606 },
607 },
608 t: NewTransaction(
609 tranNewFolder, &[]byte{0, 1},
610 NewField(fieldFileName, []byte("testFolder")),
611 ),
612 },
613 setup: func() {
614 mfs := MockFileStore{}
615 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
616 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
617 FS = mfs
618 },
619 wantRes: []Transaction{
620 {
621 clientID: &[]byte{0, 1},
622 Flags: 0x00,
623 IsReply: 0x01,
624 Type: []byte{0, 0xcd},
625 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
626 ErrorCode: []byte{0, 0, 0, 0},
627 },
628 },
629 wantErr: false,
630 },
631 {
632 name: "when UnmarshalBinary returns an err",
633 args: args{
634 cc: &ClientConn{
635 ID: &[]byte{0, 1},
636 Server: &Server{
637 Config: &Config{
638 FileRoot: "/Files/",
639 },
640 },
641 },
642 t: NewTransaction(
643 tranNewFolder, &[]byte{0, 1},
644 NewField(fieldFileName, []byte("testFolder")),
645 NewField(fieldFilePath, []byte{
646 0x00,
647 }),
648 ),
649 },
650 setup: func() {
651 mfs := MockFileStore{}
652 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
653 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
654 FS = mfs
655 },
656 wantRes: []Transaction{},
657 wantErr: true,
658 },
659 {
660 name: "fieldFileName does not allow directory traversal",
661 args: args{
662 cc: &ClientConn{
663 ID: &[]byte{0, 1},
664 Server: &Server{
665 Config: &Config{
666 FileRoot: "/Files/",
667 },
668 },
669 },
670 t: NewTransaction(
671 tranNewFolder, &[]byte{0, 1},
672 NewField(fieldFileName, []byte("../../testFolder")),
00d1ef67
JH
673 ),
674 },
675 setup: func() {
676 mfs := MockFileStore{}
677 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
678 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
679 FS = mfs
680 },
681 wantRes: []Transaction{
682 {
683 clientID: &[]byte{0, 1},
684 Flags: 0x00,
685 IsReply: 0x01,
686 Type: []byte{0, 0xcd},
687 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
688 ErrorCode: []byte{0, 0, 0, 0},
689 },
92a7e455 690 }, wantErr: false,
00d1ef67
JH
691 },
692 {
693 name: "fieldFilePath does not allow directory traversal",
694 args: args{
695 cc: &ClientConn{
696 ID: &[]byte{0, 1},
697 Server: &Server{
698 Config: &Config{
699 FileRoot: "/Files/",
700 },
701 },
702 },
703 t: NewTransaction(
704 tranNewFolder, &[]byte{0, 1},
705 NewField(fieldFileName, []byte("testFolder")),
706 NewField(fieldFilePath, []byte{
707 0x00, 0x02,
708 0x00, 0x00,
709 0x03,
710 0x2e, 0x2e, 0x2f,
711 0x00, 0x00,
712 0x03,
713 0x66, 0x6f, 0x6f,
714 }),
715 ),
716 },
717 setup: func() {
718 mfs := MockFileStore{}
719 mfs.On("Mkdir", "/Files/foo/testFolder", fs.FileMode(0777)).Return(nil)
720 mfs.On("Stat", "/Files/foo/testFolder").Return(nil, os.ErrNotExist)
721 FS = mfs
722 },
723 wantRes: []Transaction{
724 {
725 clientID: &[]byte{0, 1},
726 Flags: 0x00,
727 IsReply: 0x01,
728 Type: []byte{0, 0xcd},
729 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
730 ErrorCode: []byte{0, 0, 0, 0},
731 },
92a7e455 732 }, wantErr: false,
00d1ef67
JH
733 },
734 }
735 for _, tt := range tests {
736 t.Run(tt.name, func(t *testing.T) {
737 tt.setup()
738
739 gotRes, err := HandleNewFolder(tt.args.cc, tt.args.t)
740 if (err != nil) != tt.wantErr {
741 t.Errorf("HandleNewFolder() error = %v, wantErr %v", err, tt.wantErr)
742 return
743 }
744 if !tranAssertEqual(t, tt.wantRes, gotRes) {
745 t.Errorf("HandleNewFolder() gotRes = %v, want %v", gotRes, tt.wantRes)
746 }
747 })
748 }
749}
750
92a7e455
JH
751func TestHandleUploadFile(t *testing.T) {
752 type args struct {
753 cc *ClientConn
754 t *Transaction
755 }
756 tests := []struct {
757 name string
758 args args
759 wantRes []Transaction
760 wantErr bool
761 }{
762 {
763 name: "when request is valid",
764 args: args{
765 cc: &ClientConn{
766 Server: &Server{
767 FileTransfers: map[uint32]*FileTransfer{},
768 },
769 Account: &Account{
770 Access: func() *[]byte {
771 var bits accessBitmap
772 bits.Set(accessUploadFile)
773 access := bits[:]
774 return &access
775 }(),
776 },
777 },
778 t: NewTransaction(
779 tranUploadFile, &[]byte{0, 1},
780 NewField(fieldFileName, []byte("testFile")),
781 NewField(fieldFilePath, []byte{
782 0x00, 0x01,
783 0x00, 0x00,
784 0x03,
785 0x2e, 0x2e, 0x2f,
786 }),
787 ),
788 },
789 wantRes: []Transaction{
790 {
791 Flags: 0x00,
792 IsReply: 0x01,
793 Type: []byte{0, 0xcb},
794 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
795 ErrorCode: []byte{0, 0, 0, 0},
796 Fields: []Field{
797 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), // rand.Seed(1)
798 },
799 },
800 },
801 wantErr: false,
802 },
803 {
804 name: "when user does not have required access",
805 args: args{
806 cc: &ClientConn{
807 Account: &Account{
808 Access: func() *[]byte {
809 var bits accessBitmap
810 access := bits[:]
811 return &access
812 }(),
813 },
814 Server: &Server{
815 FileTransfers: map[uint32]*FileTransfer{},
816 },
817 },
818 t: NewTransaction(
819 tranUploadFile, &[]byte{0, 1},
820 NewField(fieldFileName, []byte("testFile")),
821 NewField(fieldFilePath, []byte{
822 0x00, 0x01,
823 0x00, 0x00,
824 0x03,
825 0x2e, 0x2e, 0x2f,
826 }),
827 ),
828 },
829 wantRes: []Transaction{
830 {
831 Flags: 0x00,
832 IsReply: 0x01,
833 Type: []byte{0, 0x00},
834 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
835 ErrorCode: []byte{0, 0, 0, 1},
836 Fields: []Field{
837 NewField(fieldError, []byte("You are not allowed to upload files.")), // rand.Seed(1)
838 },
839 },
840 },
841 wantErr: false,
842 },
843 }
844 for _, tt := range tests {
845 t.Run(tt.name, func(t *testing.T) {
846 rand.Seed(1)
847 gotRes, err := HandleUploadFile(tt.args.cc, tt.args.t)
848 if (err != nil) != tt.wantErr {
849 t.Errorf("HandleUploadFile() error = %v, wantErr %v", err, tt.wantErr)
850 return
851 }
852 if !tranAssertEqual(t, tt.wantRes, gotRes) {
853 t.Errorf("HandleUploadFile() gotRes = %v, want %v", gotRes, tt.wantRes)
854 }
855 })
856 }
857}