4 "github.com/stretchr/testify/assert"
12 func TestHandleSetChatSubject(t *testing.T) {
24 name: "sends chat subject to private chat members",
27 UserName: []byte{0x00, 0x01},
29 PrivateChats: map[uint32]*PrivateChat{
32 ClientConn: map[uint16]*ClientConn{
35 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
41 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
48 Clients: map[uint16]*ClientConn{
51 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
57 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
67 Type: []byte{0, 0x6a},
68 ID: []byte{0, 0, 0, 1},
69 ErrorCode: []byte{0, 0, 0, 0},
71 NewField(fieldChatID, []byte{0, 0, 0, 1}),
72 NewField(fieldChatSubject, []byte("Test Subject")),
78 clientID: &[]byte{0, 1},
81 Type: []byte{0, 0x77},
82 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
83 ErrorCode: []byte{0, 0, 0, 0},
85 NewField(fieldChatID, []byte{0, 0, 0, 1}),
86 NewField(fieldChatSubject, []byte("Test Subject")),
90 clientID: &[]byte{0, 2},
93 Type: []byte{0, 0x77},
94 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
95 ErrorCode: []byte{0, 0, 0, 0},
97 NewField(fieldChatID, []byte{0, 0, 0, 1}),
98 NewField(fieldChatSubject, []byte("Test Subject")),
105 for _, tt := range tests {
106 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
108 t.Run(tt.name, func(t *testing.T) {
109 got, err := HandleSetChatSubject(tt.args.cc, tt.args.t)
110 if (err != nil) != tt.wantErr {
111 t.Errorf("HandleSetChatSubject() error = %v, wantErr %v", err, tt.wantErr)
114 if !assert.Equal(t, tt.want, got) {
115 t.Errorf("HandleSetChatSubject() got = %v, want %v", got, tt.want)
121 func TestHandleLeaveChat(t *testing.T) {
133 name: "returns expected transactions",
138 PrivateChats: map[uint32]*PrivateChat{
140 ClientConn: map[uint16]*ClientConn{
143 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
149 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
156 Clients: map[uint16]*ClientConn{
159 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
165 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
172 t: NewTransaction(tranDeleteUser, nil, NewField(fieldChatID, []byte{0, 0, 0, 1})),
176 clientID: &[]byte{0, 1},
179 Type: []byte{0, 0x76},
180 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
181 ErrorCode: []byte{0, 0, 0, 0},
183 NewField(fieldChatID, []byte{0, 0, 0, 1}),
184 NewField(fieldUserID, []byte{0, 2}),
191 for _, tt := range tests {
193 t.Run(tt.name, func(t *testing.T) {
194 got, err := HandleLeaveChat(tt.args.cc, tt.args.t)
195 if (err != nil) != tt.wantErr {
196 t.Errorf("HandleLeaveChat() error = %v, wantErr %v", err, tt.wantErr)
199 if !assert.Equal(t, tt.want, got) {
200 t.Errorf("HandleLeaveChat() got = %v, want %v", got, tt.want)
206 func TestHandleGetUserNameList(t *testing.T) {
218 name: "replies with userlist transaction",
224 Clients: map[uint16]*ClientConn{
228 Flags: &[]byte{0, 3},
229 UserName: []byte{0, 4},
235 ID: []byte{0, 0, 0, 1},
241 clientID: &[]byte{1, 1},
245 ID: []byte{0, 0, 0, 1},
246 ErrorCode: []byte{0, 0, 0, 0},
249 fieldUsernameWithInfo,
250 []byte{00, 01, 00, 02, 00, 03, 00, 02, 00, 04},
258 for _, tt := range tests {
259 t.Run(tt.name, func(t *testing.T) {
260 got, err := HandleGetUserNameList(tt.args.cc, tt.args.t)
261 if (err != nil) != tt.wantErr {
262 t.Errorf("HandleGetUserNameList() error = %v, wantErr %v", err, tt.wantErr)
265 if !reflect.DeepEqual(got, tt.want) {
266 t.Errorf("HandleGetUserNameList() got = %v, want %v", got, tt.want)
272 func TestHandleChatSend(t *testing.T) {
284 name: "sends chat msg transaction to all clients",
287 UserName: []byte{0x00, 0x01},
289 Clients: map[uint16]*ClientConn{
292 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
298 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
307 NewField(fieldData, []byte("hai")),
313 clientID: &[]byte{0, 1},
316 Type: []byte{0, 0x6a},
317 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
318 ErrorCode: []byte{0, 0, 0, 0},
320 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
324 clientID: &[]byte{0, 2},
327 Type: []byte{0, 0x6a},
328 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
329 ErrorCode: []byte{0, 0, 0, 0},
331 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
338 name: "sends chat msg as emote if fieldChatOptions is set",
341 UserName: []byte("Testy McTest"),
343 Clients: map[uint16]*ClientConn{
346 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
352 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
361 NewField(fieldData, []byte("performed action")),
362 NewField(fieldChatOptions, []byte{0x00, 0x01}),
368 clientID: &[]byte{0, 1},
371 Type: []byte{0, 0x6a},
372 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
373 ErrorCode: []byte{0, 0, 0, 0},
375 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
379 clientID: &[]byte{0, 2},
382 Type: []byte{0, 0x6a},
383 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
384 ErrorCode: []byte{0, 0, 0, 0},
386 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
393 name: "only sends chat msg to clients with accessReadChat permission",
396 UserName: []byte{0x00, 0x01},
398 Clients: map[uint16]*ClientConn{
401 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
407 Access: &[]byte{0, 0, 0, 0, 0, 0, 0, 0},
416 NewField(fieldData, []byte("hai")),
422 clientID: &[]byte{0, 1},
425 Type: []byte{0, 0x6a},
426 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
427 ErrorCode: []byte{0, 0, 0, 0},
429 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
436 for _, tt := range tests {
437 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
438 t.Run(tt.name, func(t *testing.T) {
439 got, err := HandleChatSend(tt.args.cc, tt.args.t)
441 if (err != nil) != tt.wantErr {
442 t.Errorf("HandleChatSend() error = %v, wantErr %v", err, tt.wantErr)
445 if !assert.Equal(t, tt.want, got) {
446 t.Errorf("HandleChatSend() got = %v, want %v", got, tt.want)
452 func TestHandleGetFileInfo(t *testing.T) {
453 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
462 wantRes []Transaction
466 name: "returns expected fields when a valid file is requested",
469 ID: &[]byte{0x00, 0x01},
472 FileRoot: "./test/config/Files/",
477 tranGetFileInfo, nil,
478 NewField(fieldFileName, []byte("testfile.txt")),
479 NewField(fieldFilePath, []byte{0x00, 0x00}),
480 //NewField(fieldFilePath, []byte{
484 // 0x74, 0x65, 0x73, 0x74,
487 // 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
491 // 0x46, 0x69, 0x6c, 0x65, 73},
495 wantRes: []Transaction{
497 clientID: &[]byte{0, 1},
500 Type: []byte{0, 0xce},
501 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
502 ErrorCode: []byte{0, 0, 0, 0},
504 NewField(fieldFileName, []byte("testfile.txt")),
505 NewField(fieldFileTypeString, []byte("TEXT")),
506 NewField(fieldFileCreatorString, []byte("TTXT")),
507 NewField(fieldFileComment, []byte("TODO")),
508 NewField(fieldFileType, []byte("TEXT")),
509 NewField(fieldFileCreateDate, []byte{0x07, 0x70, 0x00, 0x00, 0xba, 0x74, 0x24, 0x73}),
510 NewField(fieldFileModifyDate, []byte{0x07, 0x70, 0x00, 0x00, 0xba, 0x74, 0x24, 0x73}),
511 NewField(fieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}),
518 for _, tt := range tests {
519 t.Run(tt.name, func(t *testing.T) {
520 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
522 gotRes, err := HandleGetFileInfo(tt.args.cc, tt.args.t)
523 if (err != nil) != tt.wantErr {
524 t.Errorf("HandleGetFileInfo() error = %v, wantErr %v", err, tt.wantErr)
527 if !assert.Equal(t, tt.wantRes, gotRes) {
528 t.Errorf("HandleGetFileInfo() gotRes = %v, want %v", gotRes, tt.wantRes)
534 func TestHandleNewFolder(t *testing.T) {
543 wantRes []Transaction
547 name: "when path is nested",
558 tranNewFolder, &[]byte{0, 1},
559 NewField(fieldFileName, []byte("testFolder")),
560 NewField(fieldFilePath, []byte{
569 mfs := MockFileStore{}
570 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
571 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
574 wantRes: []Transaction{
576 clientID: &[]byte{0, 1},
579 Type: []byte{0, 0xcd},
580 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
581 ErrorCode: []byte{0, 0, 0, 0},
587 name: "when path is not nested",
598 tranNewFolder, &[]byte{0, 1},
599 NewField(fieldFileName, []byte("testFolder")),
603 mfs := MockFileStore{}
604 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
605 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
608 wantRes: []Transaction{
610 clientID: &[]byte{0, 1},
613 Type: []byte{0, 0xcd},
614 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
615 ErrorCode: []byte{0, 0, 0, 0},
621 name: "when UnmarshalBinary returns an err",
632 tranNewFolder, &[]byte{0, 1},
633 NewField(fieldFileName, []byte("testFolder")),
634 NewField(fieldFilePath, []byte{
640 mfs := MockFileStore{}
641 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
642 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
645 wantRes: []Transaction{},
649 name: "fieldFileName does not allow directory traversal",
660 tranNewFolder, &[]byte{0, 1},
661 NewField(fieldFileName, []byte("../../testFolder")),
666 mfs := MockFileStore{}
667 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
668 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
671 wantRes: []Transaction{
673 clientID: &[]byte{0, 1},
676 Type: []byte{0, 0xcd},
677 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
678 ErrorCode: []byte{0, 0, 0, 0},
683 name: "fieldFilePath does not allow directory traversal",
694 tranNewFolder, &[]byte{0, 1},
695 NewField(fieldFileName, []byte("testFolder")),
696 NewField(fieldFilePath, []byte{
708 mfs := MockFileStore{}
709 mfs.On("Mkdir", "/Files/foo/testFolder", fs.FileMode(0777)).Return(nil)
710 mfs.On("Stat", "/Files/foo/testFolder").Return(nil, os.ErrNotExist)
713 wantRes: []Transaction{
715 clientID: &[]byte{0, 1},
718 Type: []byte{0, 0xcd},
719 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
720 ErrorCode: []byte{0, 0, 0, 0},
725 for _, tt := range tests {
726 t.Run(tt.name, func(t *testing.T) {
729 gotRes, err := HandleNewFolder(tt.args.cc, tt.args.t)
730 if (err != nil) != tt.wantErr {
731 t.Errorf("HandleNewFolder() error = %v, wantErr %v", err, tt.wantErr)
734 if !tranAssertEqual(t, tt.wantRes, gotRes) {
735 t.Errorf("HandleNewFolder() gotRes = %v, want %v", gotRes, tt.wantRes)