6 "github.com/stretchr/testify/assert"
7 "github.com/stretchr/testify/mock"
17 func TestHandleSetChatSubject(t *testing.T) {
29 name: "sends chat subject to private chat members",
32 UserName: []byte{0x00, 0x01},
34 PrivateChats: map[uint32]*PrivateChat{
37 ClientConn: map[uint16]*ClientConn{
40 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
46 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
53 Clients: map[uint16]*ClientConn{
56 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
62 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
72 Type: []byte{0, 0x6a},
73 ID: []byte{0, 0, 0, 1},
74 ErrorCode: []byte{0, 0, 0, 0},
76 NewField(fieldChatID, []byte{0, 0, 0, 1}),
77 NewField(fieldChatSubject, []byte("Test Subject")),
83 clientID: &[]byte{0, 1},
86 Type: []byte{0, 0x77},
87 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
88 ErrorCode: []byte{0, 0, 0, 0},
90 NewField(fieldChatID, []byte{0, 0, 0, 1}),
91 NewField(fieldChatSubject, []byte("Test Subject")),
95 clientID: &[]byte{0, 2},
98 Type: []byte{0, 0x77},
99 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
100 ErrorCode: []byte{0, 0, 0, 0},
102 NewField(fieldChatID, []byte{0, 0, 0, 1}),
103 NewField(fieldChatSubject, []byte("Test Subject")),
110 for _, tt := range tests {
111 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
113 t.Run(tt.name, func(t *testing.T) {
114 got, err := HandleSetChatSubject(tt.args.cc, tt.args.t)
115 if (err != nil) != tt.wantErr {
116 t.Errorf("HandleSetChatSubject() error = %v, wantErr %v", err, tt.wantErr)
119 if !assert.Equal(t, tt.want, got) {
120 t.Errorf("HandleSetChatSubject() got = %v, want %v", got, tt.want)
126 func TestHandleLeaveChat(t *testing.T) {
138 name: "returns expected transactions",
143 PrivateChats: map[uint32]*PrivateChat{
145 ClientConn: map[uint16]*ClientConn{
148 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
154 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
161 Clients: map[uint16]*ClientConn{
164 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
170 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
177 t: NewTransaction(tranDeleteUser, nil, NewField(fieldChatID, []byte{0, 0, 0, 1})),
181 clientID: &[]byte{0, 1},
184 Type: []byte{0, 0x76},
185 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
186 ErrorCode: []byte{0, 0, 0, 0},
188 NewField(fieldChatID, []byte{0, 0, 0, 1}),
189 NewField(fieldUserID, []byte{0, 2}),
196 for _, tt := range tests {
198 t.Run(tt.name, func(t *testing.T) {
199 got, err := HandleLeaveChat(tt.args.cc, tt.args.t)
200 if (err != nil) != tt.wantErr {
201 t.Errorf("HandleLeaveChat() error = %v, wantErr %v", err, tt.wantErr)
204 if !assert.Equal(t, tt.want, got) {
205 t.Errorf("HandleLeaveChat() got = %v, want %v", got, tt.want)
211 func TestHandleGetUserNameList(t *testing.T) {
223 name: "replies with userlist transaction",
229 Clients: map[uint16]*ClientConn{
234 UserName: []byte{0, 4},
241 UserName: []byte{0, 4},
248 UserName: []byte{0, 4},
255 ID: []byte{0, 0, 0, 1},
261 clientID: &[]byte{1, 1},
265 ID: []byte{0, 0, 0, 1},
266 ErrorCode: []byte{0, 0, 0, 0},
269 fieldUsernameWithInfo,
270 []byte{00, 01, 00, 02, 00, 03, 00, 02, 00, 04},
273 fieldUsernameWithInfo,
274 []byte{00, 02, 00, 02, 00, 03, 00, 02, 00, 04},
282 for _, tt := range tests {
283 t.Run(tt.name, func(t *testing.T) {
284 got, err := HandleGetUserNameList(tt.args.cc, tt.args.t)
285 if (err != nil) != tt.wantErr {
286 t.Errorf("HandleGetUserNameList() error = %v, wantErr %v", err, tt.wantErr)
289 assert.Equal(t, tt.want, got)
294 func TestHandleChatSend(t *testing.T) {
306 name: "sends chat msg transaction to all clients",
310 Access: func() accessBitmap {
311 var bits accessBitmap
312 bits.Set(accessSendChat)
316 UserName: []byte{0x00, 0x01},
318 Clients: map[uint16]*ClientConn{
321 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
327 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
336 NewField(fieldData, []byte("hai")),
342 clientID: &[]byte{0, 1},
345 Type: []byte{0, 0x6a},
346 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
347 ErrorCode: []byte{0, 0, 0, 0},
349 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
353 clientID: &[]byte{0, 2},
356 Type: []byte{0, 0x6a},
357 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
358 ErrorCode: []byte{0, 0, 0, 0},
360 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
367 name: "treats Chat ID 00 00 00 00 as a public chat message",
371 Access: func() accessBitmap {
372 var bits accessBitmap
373 bits.Set(accessSendChat)
377 UserName: []byte{0x00, 0x01},
379 Clients: map[uint16]*ClientConn{
382 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
388 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
397 NewField(fieldData, []byte("hai")),
398 NewField(fieldChatID, []byte{0, 0, 0, 0}),
404 clientID: &[]byte{0, 1},
407 Type: []byte{0, 0x6a},
408 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
409 ErrorCode: []byte{0, 0, 0, 0},
411 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
415 clientID: &[]byte{0, 2},
418 Type: []byte{0, 0x6a},
419 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
420 ErrorCode: []byte{0, 0, 0, 0},
422 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
429 name: "when user does not have required permission",
433 Access: func() accessBitmap {
434 var bits accessBitmap
439 Accounts: map[string]*Account{},
443 tranChatSend, &[]byte{0, 1},
444 NewField(fieldData, []byte("hai")),
451 Type: []byte{0, 0x00},
452 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
453 ErrorCode: []byte{0, 0, 0, 1},
455 NewField(fieldError, []byte("You are not allowed to participate in chat.")),
462 name: "sends chat msg as emote if fieldChatOptions is set to 1",
466 Access: func() accessBitmap {
467 var bits accessBitmap
468 bits.Set(accessSendChat)
472 UserName: []byte("Testy McTest"),
474 Clients: map[uint16]*ClientConn{
477 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
483 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
492 NewField(fieldData, []byte("performed action")),
493 NewField(fieldChatOptions, []byte{0x00, 0x01}),
499 clientID: &[]byte{0, 1},
502 Type: []byte{0, 0x6a},
503 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
504 ErrorCode: []byte{0, 0, 0, 0},
506 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
510 clientID: &[]byte{0, 2},
513 Type: []byte{0, 0x6a},
514 ID: []byte{0xf0, 0xc5, 0x34, 0x1e},
515 ErrorCode: []byte{0, 0, 0, 0},
517 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
524 name: "does not send chat msg as emote if fieldChatOptions is set to 0",
528 Access: func() accessBitmap {
529 var bits accessBitmap
530 bits.Set(accessSendChat)
534 UserName: []byte("Testy McTest"),
536 Clients: map[uint16]*ClientConn{
539 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
545 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
554 NewField(fieldData, []byte("hello")),
555 NewField(fieldChatOptions, []byte{0x00, 0x00}),
561 clientID: &[]byte{0, 1},
564 Type: []byte{0, 0x6a},
565 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
566 ErrorCode: []byte{0, 0, 0, 0},
568 NewField(fieldData, []byte("\r Testy McTest: hello")),
572 clientID: &[]byte{0, 2},
575 Type: []byte{0, 0x6a},
576 ID: []byte{0xf0, 0xc5, 0x34, 0x1e},
577 ErrorCode: []byte{0, 0, 0, 0},
579 NewField(fieldData, []byte("\r Testy McTest: hello")),
586 name: "only sends chat msg to clients with accessReadChat permission",
590 Access: func() accessBitmap {
591 var bits accessBitmap
592 bits.Set(accessSendChat)
596 UserName: []byte{0x00, 0x01},
598 Clients: map[uint16]*ClientConn{
601 Access: func() accessBitmap {
602 var bits accessBitmap
603 bits.Set(accessReadChat)
610 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
619 NewField(fieldData, []byte("hai")),
625 clientID: &[]byte{0, 1},
628 Type: []byte{0, 0x6a},
629 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
630 ErrorCode: []byte{0, 0, 0, 0},
632 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
639 name: "only sends private chat msg to members of private chat",
643 Access: func() accessBitmap {
644 var bits accessBitmap
645 bits.Set(accessSendChat)
649 UserName: []byte{0x00, 0x01},
651 PrivateChats: map[uint32]*PrivateChat{
653 ClientConn: map[uint16]*ClientConn{
663 Clients: map[uint16]*ClientConn{
666 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
672 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
678 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
687 NewField(fieldData, []byte("hai")),
688 NewField(fieldChatID, []byte{0, 0, 0, 1}),
694 clientID: &[]byte{0, 1},
697 Type: []byte{0, 0x6a},
698 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
699 ErrorCode: []byte{0, 0, 0, 0},
701 NewField(fieldChatID, []byte{0, 0, 0, 1}),
702 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
706 clientID: &[]byte{0, 2},
709 Type: []byte{0, 0x6a},
710 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
711 ErrorCode: []byte{0, 0, 0, 0},
713 NewField(fieldChatID, []byte{0, 0, 0, 1}),
714 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
721 for _, tt := range tests {
722 t.Run(tt.name, func(t *testing.T) {
723 got, err := HandleChatSend(tt.args.cc, tt.args.t)
725 if (err != nil) != tt.wantErr {
726 t.Errorf("HandleChatSend() error = %v, wantErr %v", err, tt.wantErr)
729 tranAssertEqual(t, tt.want, got)
734 func TestHandleGetFileInfo(t *testing.T) {
735 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
744 wantRes []Transaction
748 name: "returns expected fields when a valid file is requested",
751 ID: &[]byte{0x00, 0x01},
755 FileRoot: func() string {
756 path, _ := os.Getwd()
757 return filepath.Join(path, "/test/config/Files")
763 tranGetFileInfo, nil,
764 NewField(fieldFileName, []byte("testfile.txt")),
765 NewField(fieldFilePath, []byte{0x00, 0x00}),
768 wantRes: []Transaction{
770 clientID: &[]byte{0, 1},
774 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
775 ErrorCode: []byte{0, 0, 0, 0},
777 NewField(fieldFileName, []byte("testfile.txt")),
778 NewField(fieldFileTypeString, []byte("Text File")),
779 NewField(fieldFileCreatorString, []byte("ttxt")),
780 NewField(fieldFileComment, []byte{}),
781 NewField(fieldFileType, []byte("TEXT")),
782 NewField(fieldFileCreateDate, make([]byte, 8)),
783 NewField(fieldFileModifyDate, make([]byte, 8)),
784 NewField(fieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}),
791 for _, tt := range tests {
792 t.Run(tt.name, func(t *testing.T) {
793 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
795 gotRes, err := HandleGetFileInfo(tt.args.cc, tt.args.t)
796 if (err != nil) != tt.wantErr {
797 t.Errorf("HandleGetFileInfo() error = %v, wantErr %v", err, tt.wantErr)
801 // Clear the fileWrapper timestamp fields to work around problems running the tests in multiple timezones
802 // TODO: revisit how to test this by mocking the stat calls
803 gotRes[0].Fields[5].Data = make([]byte, 8)
804 gotRes[0].Fields[6].Data = make([]byte, 8)
805 if !assert.Equal(t, tt.wantRes, gotRes) {
806 t.Errorf("HandleGetFileInfo() gotRes = %v, want %v", gotRes, tt.wantRes)
812 func TestHandleNewFolder(t *testing.T) {
820 wantRes []Transaction
824 name: "without required permission",
828 Access: func() accessBitmap {
829 var bits accessBitmap
839 wantRes: []Transaction{
843 Type: []byte{0, 0x00},
844 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
845 ErrorCode: []byte{0, 0, 0, 1},
847 NewField(fieldError, []byte("You are not allowed to create folders.")),
854 name: "when path is nested",
858 Access: func() accessBitmap {
859 var bits accessBitmap
860 bits.Set(accessCreateFolder)
869 FS: func() *MockFileStore {
870 mfs := &MockFileStore{}
871 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
872 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
878 tranNewFolder, &[]byte{0, 1},
879 NewField(fieldFileName, []byte("testFolder")),
880 NewField(fieldFilePath, []byte{
888 wantRes: []Transaction{
890 clientID: &[]byte{0, 1},
894 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
895 ErrorCode: []byte{0, 0, 0, 0},
901 name: "when path is not nested",
905 Access: func() accessBitmap {
906 var bits accessBitmap
907 bits.Set(accessCreateFolder)
916 FS: func() *MockFileStore {
917 mfs := &MockFileStore{}
918 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
919 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
925 tranNewFolder, &[]byte{0, 1},
926 NewField(fieldFileName, []byte("testFolder")),
929 wantRes: []Transaction{
931 clientID: &[]byte{0, 1},
935 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
936 ErrorCode: []byte{0, 0, 0, 0},
942 name: "when Write returns an err",
946 Access: func() accessBitmap {
947 var bits accessBitmap
948 bits.Set(accessCreateFolder)
957 FS: func() *MockFileStore {
958 mfs := &MockFileStore{}
959 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
960 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
966 tranNewFolder, &[]byte{0, 1},
967 NewField(fieldFileName, []byte("testFolder")),
968 NewField(fieldFilePath, []byte{
973 wantRes: []Transaction{},
977 name: "fieldFileName does not allow directory traversal",
981 Access: func() accessBitmap {
982 var bits accessBitmap
983 bits.Set(accessCreateFolder)
992 FS: func() *MockFileStore {
993 mfs := &MockFileStore{}
994 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
995 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
1001 tranNewFolder, &[]byte{0, 1},
1002 NewField(fieldFileName, []byte("../../testFolder")),
1005 wantRes: []Transaction{
1007 clientID: &[]byte{0, 1},
1011 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
1012 ErrorCode: []byte{0, 0, 0, 0},
1017 name: "fieldFilePath does not allow directory traversal",
1021 Access: func() accessBitmap {
1022 var bits accessBitmap
1023 bits.Set(accessCreateFolder)
1030 FileRoot: "/Files/",
1032 FS: func() *MockFileStore {
1033 mfs := &MockFileStore{}
1034 mfs.On("Mkdir", "/Files/foo/testFolder", fs.FileMode(0777)).Return(nil)
1035 mfs.On("Stat", "/Files/foo/testFolder").Return(nil, os.ErrNotExist)
1041 tranNewFolder, &[]byte{0, 1},
1042 NewField(fieldFileName, []byte("testFolder")),
1043 NewField(fieldFilePath, []byte{
1054 wantRes: []Transaction{
1056 clientID: &[]byte{0, 1},
1060 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
1061 ErrorCode: []byte{0, 0, 0, 0},
1066 for _, tt := range tests {
1067 t.Run(tt.name, func(t *testing.T) {
1069 gotRes, err := HandleNewFolder(tt.args.cc, tt.args.t)
1070 if (err != nil) != tt.wantErr {
1071 t.Errorf("HandleNewFolder() error = %v, wantErr %v", err, tt.wantErr)
1075 if !tranAssertEqual(t, tt.wantRes, gotRes) {
1076 t.Errorf("HandleNewFolder() gotRes = %v, want %v", gotRes, tt.wantRes)
1082 func TestHandleUploadFile(t *testing.T) {
1090 wantRes []Transaction
1094 name: "when request is valid and user has Upload Anywhere permission",
1099 fileTransfers: map[[4]byte]*FileTransfer{},
1101 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1103 transfers: map[int]map[[4]byte]*FileTransfer{
1107 Access: func() accessBitmap {
1108 var bits accessBitmap
1109 bits.Set(accessUploadFile)
1110 bits.Set(accessUploadAnywhere)
1116 tranUploadFile, &[]byte{0, 1},
1117 NewField(fieldFileName, []byte("testFile")),
1118 NewField(fieldFilePath, []byte{
1126 wantRes: []Transaction{
1131 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1132 ErrorCode: []byte{0, 0, 0, 0},
1134 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), // rand.Seed(1)
1141 name: "when user does not have required access",
1145 Access: func() accessBitmap {
1146 var bits accessBitmap
1152 tranUploadFile, &[]byte{0, 1},
1153 NewField(fieldFileName, []byte("testFile")),
1154 NewField(fieldFilePath, []byte{
1162 wantRes: []Transaction{
1166 Type: []byte{0, 0x00},
1167 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1168 ErrorCode: []byte{0, 0, 0, 1},
1170 NewField(fieldError, []byte("You are not allowed to upload files.")), // rand.Seed(1)
1177 for _, tt := range tests {
1178 t.Run(tt.name, func(t *testing.T) {
1180 gotRes, err := HandleUploadFile(tt.args.cc, tt.args.t)
1181 if (err != nil) != tt.wantErr {
1182 t.Errorf("HandleUploadFile() error = %v, wantErr %v", err, tt.wantErr)
1186 tranAssertEqual(t, tt.wantRes, gotRes)
1192 func TestHandleMakeAlias(t *testing.T) {
1200 wantRes []Transaction
1204 name: "with valid input and required permissions",
1207 logger: NewTestLogger(),
1209 Access: func() accessBitmap {
1210 var bits accessBitmap
1211 bits.Set(accessMakeAlias)
1217 FileRoot: func() string {
1218 path, _ := os.Getwd()
1219 return path + "/test/config/Files"
1222 Logger: NewTestLogger(),
1223 FS: func() *MockFileStore {
1224 mfs := &MockFileStore{}
1225 path, _ := os.Getwd()
1228 path+"/test/config/Files/foo/testFile",
1229 path+"/test/config/Files/bar/testFile",
1236 tranMakeFileAlias, &[]byte{0, 1},
1237 NewField(fieldFileName, []byte("testFile")),
1238 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1239 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1242 wantRes: []Transaction{
1247 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1248 ErrorCode: []byte{0, 0, 0, 0},
1249 Fields: []Field(nil),
1255 name: "when symlink returns an error",
1258 logger: NewTestLogger(),
1260 Access: func() accessBitmap {
1261 var bits accessBitmap
1262 bits.Set(accessMakeAlias)
1268 FileRoot: func() string {
1269 path, _ := os.Getwd()
1270 return path + "/test/config/Files"
1273 Logger: NewTestLogger(),
1274 FS: func() *MockFileStore {
1275 mfs := &MockFileStore{}
1276 path, _ := os.Getwd()
1279 path+"/test/config/Files/foo/testFile",
1280 path+"/test/config/Files/bar/testFile",
1281 ).Return(errors.New("ohno"))
1287 tranMakeFileAlias, &[]byte{0, 1},
1288 NewField(fieldFileName, []byte("testFile")),
1289 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1290 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1293 wantRes: []Transaction{
1297 Type: []byte{0, 0x00},
1298 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1299 ErrorCode: []byte{0, 0, 0, 1},
1301 NewField(fieldError, []byte("Error creating alias")),
1308 name: "when user does not have required permission",
1311 logger: NewTestLogger(),
1313 Access: func() accessBitmap {
1314 var bits accessBitmap
1320 FileRoot: func() string {
1321 path, _ := os.Getwd()
1322 return path + "/test/config/Files"
1328 tranMakeFileAlias, &[]byte{0, 1},
1329 NewField(fieldFileName, []byte("testFile")),
1330 NewField(fieldFilePath, []byte{
1336 NewField(fieldFileNewPath, []byte{
1344 wantRes: []Transaction{
1348 Type: []byte{0, 0x00},
1349 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1350 ErrorCode: []byte{0, 0, 0, 1},
1352 NewField(fieldError, []byte("You are not allowed to make aliases.")),
1359 for _, tt := range tests {
1360 t.Run(tt.name, func(t *testing.T) {
1361 gotRes, err := HandleMakeAlias(tt.args.cc, tt.args.t)
1362 if (err != nil) != tt.wantErr {
1363 t.Errorf("HandleMakeAlias(%v, %v)", tt.args.cc, tt.args.t)
1367 tranAssertEqual(t, tt.wantRes, gotRes)
1372 func TestHandleGetUser(t *testing.T) {
1380 wantRes []Transaction
1381 wantErr assert.ErrorAssertionFunc
1384 name: "when account is valid",
1388 Access: func() accessBitmap {
1389 var bits accessBitmap
1390 bits.Set(accessOpenUser)
1395 Accounts: map[string]*Account{
1399 Password: "password",
1400 Access: accessBitmap{},
1406 tranGetUser, &[]byte{0, 1},
1407 NewField(fieldUserLogin, []byte("guest")),
1410 wantRes: []Transaction{
1415 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1416 ErrorCode: []byte{0, 0, 0, 0},
1418 NewField(fieldUserName, []byte("Guest")),
1419 NewField(fieldUserLogin, negateString([]byte("guest"))),
1420 NewField(fieldUserPassword, []byte("password")),
1421 NewField(fieldUserAccess, []byte{0, 0, 0, 0, 0, 0, 0, 0}),
1425 wantErr: assert.NoError,
1428 name: "when user does not have required permission",
1432 Access: func() accessBitmap {
1433 var bits accessBitmap
1438 Accounts: map[string]*Account{},
1442 tranGetUser, &[]byte{0, 1},
1443 NewField(fieldUserLogin, []byte("nonExistentUser")),
1446 wantRes: []Transaction{
1450 Type: []byte{0, 0x00},
1451 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1452 ErrorCode: []byte{0, 0, 0, 1},
1454 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1458 wantErr: assert.NoError,
1461 name: "when account does not exist",
1465 Access: func() accessBitmap {
1466 var bits accessBitmap
1467 bits.Set(accessOpenUser)
1472 Accounts: map[string]*Account{},
1476 tranGetUser, &[]byte{0, 1},
1477 NewField(fieldUserLogin, []byte("nonExistentUser")),
1480 wantRes: []Transaction{
1484 Type: []byte{0, 0x00},
1485 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1486 ErrorCode: []byte{0, 0, 0, 1},
1488 NewField(fieldError, []byte("Account does not exist.")),
1492 wantErr: assert.NoError,
1495 for _, tt := range tests {
1496 t.Run(tt.name, func(t *testing.T) {
1497 gotRes, err := HandleGetUser(tt.args.cc, tt.args.t)
1498 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetUser(%v, %v)", tt.args.cc, tt.args.t)) {
1502 tranAssertEqual(t, tt.wantRes, gotRes)
1507 func TestHandleDeleteUser(t *testing.T) {
1515 wantRes []Transaction
1516 wantErr assert.ErrorAssertionFunc
1519 name: "when user dataFile",
1523 Access: func() accessBitmap {
1524 var bits accessBitmap
1525 bits.Set(accessDeleteUser)
1530 Accounts: map[string]*Account{
1533 Name: "Testy McTest",
1534 Password: "password",
1535 Access: accessBitmap{},
1538 FS: func() *MockFileStore {
1539 mfs := &MockFileStore{}
1540 mfs.On("Remove", "Users/testuser.yaml").Return(nil)
1546 tranDeleteUser, &[]byte{0, 1},
1547 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1550 wantRes: []Transaction{
1555 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1556 ErrorCode: []byte{0, 0, 0, 0},
1557 Fields: []Field(nil),
1560 wantErr: assert.NoError,
1563 name: "when user does not have required permission",
1567 Access: func() accessBitmap {
1568 var bits accessBitmap
1573 Accounts: map[string]*Account{},
1577 tranDeleteUser, &[]byte{0, 1},
1578 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1581 wantRes: []Transaction{
1585 Type: []byte{0, 0x00},
1586 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1587 ErrorCode: []byte{0, 0, 0, 1},
1589 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
1593 wantErr: assert.NoError,
1596 for _, tt := range tests {
1597 t.Run(tt.name, func(t *testing.T) {
1598 gotRes, err := HandleDeleteUser(tt.args.cc, tt.args.t)
1599 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteUser(%v, %v)", tt.args.cc, tt.args.t)) {
1603 tranAssertEqual(t, tt.wantRes, gotRes)
1608 func TestHandleGetMsgs(t *testing.T) {
1616 wantRes []Transaction
1617 wantErr assert.ErrorAssertionFunc
1620 name: "returns news data",
1624 Access: func() accessBitmap {
1625 var bits accessBitmap
1626 bits.Set(accessNewsReadArt)
1631 FlatNews: []byte("TEST"),
1635 tranGetMsgs, &[]byte{0, 1},
1638 wantRes: []Transaction{
1643 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1644 ErrorCode: []byte{0, 0, 0, 0},
1646 NewField(fieldData, []byte("TEST")),
1650 wantErr: assert.NoError,
1653 name: "when user does not have required permission",
1657 Access: func() accessBitmap {
1658 var bits accessBitmap
1663 Accounts: map[string]*Account{},
1667 tranGetMsgs, &[]byte{0, 1},
1670 wantRes: []Transaction{
1674 Type: []byte{0, 0x00},
1675 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1676 ErrorCode: []byte{0, 0, 0, 1},
1678 NewField(fieldError, []byte("You are not allowed to read news.")),
1682 wantErr: assert.NoError,
1685 for _, tt := range tests {
1686 t.Run(tt.name, func(t *testing.T) {
1687 gotRes, err := HandleGetMsgs(tt.args.cc, tt.args.t)
1688 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetMsgs(%v, %v)", tt.args.cc, tt.args.t)) {
1692 tranAssertEqual(t, tt.wantRes, gotRes)
1697 func TestHandleNewUser(t *testing.T) {
1705 wantRes []Transaction
1706 wantErr assert.ErrorAssertionFunc
1709 name: "when user does not have required permission",
1713 Access: func() accessBitmap {
1714 var bits accessBitmap
1719 Accounts: map[string]*Account{},
1723 tranNewUser, &[]byte{0, 1},
1726 wantRes: []Transaction{
1730 Type: []byte{0, 0x00},
1731 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1732 ErrorCode: []byte{0, 0, 0, 1},
1734 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
1738 wantErr: assert.NoError,
1741 name: "when user attempts to create account with greater access",
1745 Access: func() accessBitmap {
1746 var bits accessBitmap
1747 bits.Set(accessCreateUser)
1752 Accounts: map[string]*Account{},
1756 tranNewUser, &[]byte{0, 1},
1757 NewField(fieldUserLogin, []byte("userB")),
1761 var bits accessBitmap
1762 bits.Set(accessDisconUser)
1768 wantRes: []Transaction{
1772 Type: []byte{0, 0x00},
1773 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1774 ErrorCode: []byte{0, 0, 0, 1},
1776 NewField(fieldError, []byte("Cannot create account with more access than yourself.")),
1780 wantErr: assert.NoError,
1783 for _, tt := range tests {
1784 t.Run(tt.name, func(t *testing.T) {
1785 gotRes, err := HandleNewUser(tt.args.cc, tt.args.t)
1786 if !tt.wantErr(t, err, fmt.Sprintf("HandleNewUser(%v, %v)", tt.args.cc, tt.args.t)) {
1790 tranAssertEqual(t, tt.wantRes, gotRes)
1795 func TestHandleListUsers(t *testing.T) {
1803 wantRes []Transaction
1804 wantErr assert.ErrorAssertionFunc
1807 name: "when user does not have required permission",
1811 Access: func() accessBitmap {
1812 var bits accessBitmap
1817 Accounts: map[string]*Account{},
1821 tranNewUser, &[]byte{0, 1},
1824 wantRes: []Transaction{
1828 Type: []byte{0, 0x00},
1829 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1830 ErrorCode: []byte{0, 0, 0, 1},
1832 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1836 wantErr: assert.NoError,
1839 name: "when user has required permission",
1843 Access: func() accessBitmap {
1844 var bits accessBitmap
1845 bits.Set(accessOpenUser)
1850 Accounts: map[string]*Account{
1855 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
1861 tranGetClientInfoText, &[]byte{0, 1},
1862 NewField(fieldUserID, []byte{0, 1}),
1865 wantRes: []Transaction{
1870 ID: []byte{0, 0, 0, 0},
1871 ErrorCode: []byte{0, 0, 0, 0},
1873 NewField(fieldData, []byte{
1874 0x00, 0x04, 0x00, 0x66, 0x00, 0x05, 0x67, 0x75, 0x65, 0x73, 0x74, 0x00, 0x69, 0x00, 0x05, 0x98,
1875 0x8a, 0x9a, 0x8c, 0x8b, 0x00, 0x6e, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1876 0x00, 0x6a, 0x00, 0x01, 0x78,
1881 wantErr: assert.NoError,
1884 for _, tt := range tests {
1885 t.Run(tt.name, func(t *testing.T) {
1886 gotRes, err := HandleListUsers(tt.args.cc, tt.args.t)
1887 if !tt.wantErr(t, err, fmt.Sprintf("HandleListUsers(%v, %v)", tt.args.cc, tt.args.t)) {
1891 tranAssertEqual(t, tt.wantRes, gotRes)
1896 func TestHandleDownloadFile(t *testing.T) {
1904 wantRes []Transaction
1905 wantErr assert.ErrorAssertionFunc
1908 name: "when user does not have required permission",
1912 Access: func() accessBitmap {
1913 var bits accessBitmap
1919 t: NewTransaction(tranDownloadFile, &[]byte{0, 1}),
1921 wantRes: []Transaction{
1925 Type: []byte{0, 0x00},
1926 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1927 ErrorCode: []byte{0, 0, 0, 1},
1929 NewField(fieldError, []byte("You are not allowed to download files.")),
1933 wantErr: assert.NoError,
1936 name: "with a valid file",
1939 transfers: map[int]map[[4]byte]*FileTransfer{
1943 Access: func() accessBitmap {
1944 var bits accessBitmap
1945 bits.Set(accessDownloadFile)
1951 fileTransfers: map[[4]byte]*FileTransfer{},
1953 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1955 Accounts: map[string]*Account{},
1961 NewField(fieldFileName, []byte("testfile.txt")),
1962 NewField(fieldFilePath, []byte{0x0, 0x00}),
1965 wantRes: []Transaction{
1970 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1971 ErrorCode: []byte{0, 0, 0, 0},
1973 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
1974 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
1975 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x00, 0xa5}),
1976 NewField(fieldFileSize, []byte{0x00, 0x00, 0x00, 0x17}),
1980 wantErr: assert.NoError,
1983 name: "when client requests to resume 1k test file at offset 256",
1986 transfers: map[int]map[[4]byte]*FileTransfer{
1988 }, Account: &Account{
1989 Access: func() accessBitmap {
1990 var bits accessBitmap
1991 bits.Set(accessDownloadFile)
1998 // FS: func() *MockFileStore {
1999 // path, _ := os.Getwd()
2000 // testFile, err := os.Open(path + "/test/config/Files/testfile-1k")
2005 // mfi := &MockFileInfo{}
2006 // mfi.On("Mode").Return(fs.FileMode(0))
2007 // mfs := &MockFileStore{}
2008 // mfs.On("Stat", "/fakeRoot/Files/testfile.txt").Return(mfi, nil)
2009 // mfs.On("Open", "/fakeRoot/Files/testfile.txt").Return(testFile, nil)
2010 // mfs.On("Stat", "/fakeRoot/Files/.info_testfile.txt").Return(nil, errors.New("no"))
2011 // mfs.On("Stat", "/fakeRoot/Files/.rsrc_testfile.txt").Return(nil, errors.New("no"))
2015 fileTransfers: map[[4]byte]*FileTransfer{},
2017 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
2019 Accounts: map[string]*Account{},
2025 NewField(fieldFileName, []byte("testfile-1k")),
2026 NewField(fieldFilePath, []byte{0x00, 0x00}),
2028 fieldFileResumeData,
2030 frd := FileResumeData{
2034 ForkCount: [2]byte{0, 2},
2035 ForkInfoList: []ForkInfoList{
2037 Fork: [4]byte{0x44, 0x41, 0x54, 0x41}, // "DATA"
2038 DataSize: [4]byte{0, 0, 0x01, 0x00}, // request offset 256
2043 Fork: [4]byte{0x4d, 0x41, 0x43, 0x52}, // "MACR"
2044 DataSize: [4]byte{0, 0, 0, 0},
2050 b, _ := frd.BinaryMarshal()
2056 wantRes: []Transaction{
2061 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2062 ErrorCode: []byte{0, 0, 0, 0},
2064 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
2065 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
2066 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x03, 0x8d}),
2067 NewField(fieldFileSize, []byte{0x00, 0x00, 0x03, 0x00}),
2071 wantErr: assert.NoError,
2074 for _, tt := range tests {
2075 t.Run(tt.name, func(t *testing.T) {
2076 gotRes, err := HandleDownloadFile(tt.args.cc, tt.args.t)
2077 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadFile(%v, %v)", tt.args.cc, tt.args.t)) {
2081 tranAssertEqual(t, tt.wantRes, gotRes)
2086 func TestHandleUpdateUser(t *testing.T) {
2094 wantRes []Transaction
2095 wantErr assert.ErrorAssertionFunc
2098 name: "when action is create user without required permission",
2101 logger: NewTestLogger(),
2103 Logger: NewTestLogger(),
2106 Access: func() accessBitmap {
2107 var bits accessBitmap
2115 NewField(fieldData, []byte{
2116 0x00, 0x04, // field count
2118 0x00, 0x69, // fieldUserLogin = 105
2122 0x00, 0x6a, // fieldUserPassword = 106
2126 0x00, 0x66, // fieldUserName = 102
2130 0x00, 0x6e, // fieldUserAccess = 110
2132 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
2136 wantRes: []Transaction{
2140 Type: []byte{0, 0x00},
2141 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2142 ErrorCode: []byte{0, 0, 0, 1},
2144 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
2148 wantErr: assert.NoError,
2151 name: "when action is modify user without required permission",
2154 logger: NewTestLogger(),
2156 Logger: NewTestLogger(),
2157 Accounts: map[string]*Account{
2162 Access: func() accessBitmap {
2163 var bits accessBitmap
2171 NewField(fieldData, []byte{
2172 0x00, 0x04, // field count
2174 0x00, 0x69, // fieldUserLogin = 105
2178 0x00, 0x6a, // fieldUserPassword = 106
2182 0x00, 0x66, // fieldUserName = 102
2186 0x00, 0x6e, // fieldUserAccess = 110
2188 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
2192 wantRes: []Transaction{
2196 Type: []byte{0, 0x00},
2197 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2198 ErrorCode: []byte{0, 0, 0, 1},
2200 NewField(fieldError, []byte("You are not allowed to modify accounts.")),
2204 wantErr: assert.NoError,
2207 name: "when action is delete user without required permission",
2210 logger: NewTestLogger(),
2212 Accounts: map[string]*Account{
2217 Access: func() accessBitmap {
2218 var bits accessBitmap
2226 NewField(fieldData, []byte{
2234 wantRes: []Transaction{
2238 Type: []byte{0, 0x00},
2239 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2240 ErrorCode: []byte{0, 0, 0, 1},
2242 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
2246 wantErr: assert.NoError,
2249 for _, tt := range tests {
2250 t.Run(tt.name, func(t *testing.T) {
2251 gotRes, err := HandleUpdateUser(tt.args.cc, tt.args.t)
2252 if !tt.wantErr(t, err, fmt.Sprintf("HandleUpdateUser(%v, %v)", tt.args.cc, tt.args.t)) {
2256 tranAssertEqual(t, tt.wantRes, gotRes)
2261 func TestHandleDelNewsArt(t *testing.T) {
2269 wantRes []Transaction
2270 wantErr assert.ErrorAssertionFunc
2273 name: "without required permission",
2277 Access: func() accessBitmap {
2278 var bits accessBitmap
2288 wantRes: []Transaction{
2292 Type: []byte{0, 0x00},
2293 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2294 ErrorCode: []byte{0, 0, 0, 1},
2296 NewField(fieldError, []byte("You are not allowed to delete news articles.")),
2300 wantErr: assert.NoError,
2303 for _, tt := range tests {
2304 t.Run(tt.name, func(t *testing.T) {
2305 gotRes, err := HandleDelNewsArt(tt.args.cc, tt.args.t)
2306 if !tt.wantErr(t, err, fmt.Sprintf("HandleDelNewsArt(%v, %v)", tt.args.cc, tt.args.t)) {
2309 tranAssertEqual(t, tt.wantRes, gotRes)
2314 func TestHandleDisconnectUser(t *testing.T) {
2322 wantRes []Transaction
2323 wantErr assert.ErrorAssertionFunc
2326 name: "without required permission",
2330 Access: func() accessBitmap {
2331 var bits accessBitmap
2341 wantRes: []Transaction{
2345 Type: []byte{0, 0x00},
2346 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2347 ErrorCode: []byte{0, 0, 0, 1},
2349 NewField(fieldError, []byte("You are not allowed to disconnect users.")),
2353 wantErr: assert.NoError,
2356 name: "when target user has 'cannot be disconnected' priv",
2360 Clients: map[uint16]*ClientConn{
2364 Access: func() accessBitmap {
2365 var bits accessBitmap
2366 bits.Set(accessCannotBeDiscon)
2374 Access: func() accessBitmap {
2375 var bits accessBitmap
2376 bits.Set(accessDisconUser)
2384 NewField(fieldUserID, []byte{0, 1}),
2387 wantRes: []Transaction{
2391 Type: []byte{0, 0x00},
2392 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2393 ErrorCode: []byte{0, 0, 0, 1},
2395 NewField(fieldError, []byte("unnamed is not allowed to be disconnected.")),
2399 wantErr: assert.NoError,
2402 for _, tt := range tests {
2403 t.Run(tt.name, func(t *testing.T) {
2404 gotRes, err := HandleDisconnectUser(tt.args.cc, tt.args.t)
2405 if !tt.wantErr(t, err, fmt.Sprintf("HandleDisconnectUser(%v, %v)", tt.args.cc, tt.args.t)) {
2408 tranAssertEqual(t, tt.wantRes, gotRes)
2413 func TestHandleSendInstantMsg(t *testing.T) {
2421 wantRes []Transaction
2422 wantErr assert.ErrorAssertionFunc
2425 name: "without required permission",
2429 Access: func() accessBitmap {
2430 var bits accessBitmap
2440 wantRes: []Transaction{
2444 Type: []byte{0, 0x00},
2445 ID: []byte{0, 0, 0, 0},
2446 ErrorCode: []byte{0, 0, 0, 1},
2448 NewField(fieldError, []byte("You are not allowed to send private messages.")),
2452 wantErr: assert.NoError,
2455 name: "when client 1 sends a message to client 2",
2459 Access: func() accessBitmap {
2460 var bits accessBitmap
2461 bits.Set(accessSendPrivMsg)
2466 UserName: []byte("User1"),
2468 Clients: map[uint16]*ClientConn{
2470 AutoReply: []byte(nil),
2471 Flags: []byte{0, 0},
2479 NewField(fieldData, []byte("hai")),
2480 NewField(fieldUserID, []byte{0, 2}),
2483 wantRes: []Transaction{
2487 NewField(fieldData, []byte("hai")),
2488 NewField(fieldUserName, []byte("User1")),
2489 NewField(fieldUserID, []byte{0, 1}),
2490 NewField(fieldOptions, []byte{0, 1}),
2493 clientID: &[]byte{0, 1},
2497 ID: []byte{0, 0, 0, 0},
2498 ErrorCode: []byte{0, 0, 0, 0},
2499 Fields: []Field(nil),
2502 wantErr: assert.NoError,
2505 name: "when client 2 has autoreply enabled",
2509 Access: func() accessBitmap {
2510 var bits accessBitmap
2511 bits.Set(accessSendPrivMsg)
2516 UserName: []byte("User1"),
2518 Clients: map[uint16]*ClientConn{
2520 Flags: []byte{0, 0},
2522 UserName: []byte("User2"),
2523 AutoReply: []byte("autohai"),
2531 NewField(fieldData, []byte("hai")),
2532 NewField(fieldUserID, []byte{0, 2}),
2535 wantRes: []Transaction{
2539 NewField(fieldData, []byte("hai")),
2540 NewField(fieldUserName, []byte("User1")),
2541 NewField(fieldUserID, []byte{0, 1}),
2542 NewField(fieldOptions, []byte{0, 1}),
2547 NewField(fieldData, []byte("autohai")),
2548 NewField(fieldUserName, []byte("User2")),
2549 NewField(fieldUserID, []byte{0, 2}),
2550 NewField(fieldOptions, []byte{0, 1}),
2553 clientID: &[]byte{0, 1},
2557 ID: []byte{0, 0, 0, 0},
2558 ErrorCode: []byte{0, 0, 0, 0},
2559 Fields: []Field(nil),
2562 wantErr: assert.NoError,
2565 name: "when client 2 has refuse private messages enabled",
2569 Access: func() accessBitmap {
2570 var bits accessBitmap
2571 bits.Set(accessSendPrivMsg)
2576 UserName: []byte("User1"),
2578 Clients: map[uint16]*ClientConn{
2580 Flags: []byte{255, 255},
2582 UserName: []byte("User2"),
2590 NewField(fieldData, []byte("hai")),
2591 NewField(fieldUserID, []byte{0, 2}),
2594 wantRes: []Transaction{
2598 NewField(fieldData, []byte("User2 does not accept private messages.")),
2599 NewField(fieldUserName, []byte("User2")),
2600 NewField(fieldUserID, []byte{0, 2}),
2601 NewField(fieldOptions, []byte{0, 2}),
2604 clientID: &[]byte{0, 1},
2608 ID: []byte{0, 0, 0, 0},
2609 ErrorCode: []byte{0, 0, 0, 0},
2610 Fields: []Field(nil),
2613 wantErr: assert.NoError,
2616 for _, tt := range tests {
2617 t.Run(tt.name, func(t *testing.T) {
2618 gotRes, err := HandleSendInstantMsg(tt.args.cc, tt.args.t)
2619 if !tt.wantErr(t, err, fmt.Sprintf("HandleSendInstantMsg(%v, %v)", tt.args.cc, tt.args.t)) {
2623 tranAssertEqual(t, tt.wantRes, gotRes)
2628 func TestHandleDeleteFile(t *testing.T) {
2636 wantRes []Transaction
2637 wantErr assert.ErrorAssertionFunc
2640 name: "when user does not have required permission to delete a folder",
2644 Access: func() accessBitmap {
2645 var bits accessBitmap
2651 FileRoot: func() string {
2652 return "/fakeRoot/Files"
2655 FS: func() *MockFileStore {
2656 mfi := &MockFileInfo{}
2657 mfi.On("Mode").Return(fs.FileMode(0))
2658 mfi.On("Size").Return(int64(100))
2659 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2660 mfi.On("IsDir").Return(false)
2661 mfi.On("Name").Return("testfile")
2663 mfs := &MockFileStore{}
2664 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2665 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2666 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2670 Accounts: map[string]*Account{},
2674 tranDeleteFile, &[]byte{0, 1},
2675 NewField(fieldFileName, []byte("testfile")),
2676 NewField(fieldFilePath, []byte{
2684 wantRes: []Transaction{
2688 Type: []byte{0, 0x00},
2689 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2690 ErrorCode: []byte{0, 0, 0, 1},
2692 NewField(fieldError, []byte("You are not allowed to delete files.")),
2696 wantErr: assert.NoError,
2699 name: "deletes all associated metadata files",
2703 Access: func() accessBitmap {
2704 var bits accessBitmap
2705 bits.Set(accessDeleteFile)
2711 FileRoot: func() string {
2712 return "/fakeRoot/Files"
2715 FS: func() *MockFileStore {
2716 mfi := &MockFileInfo{}
2717 mfi.On("Mode").Return(fs.FileMode(0))
2718 mfi.On("Size").Return(int64(100))
2719 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2720 mfi.On("IsDir").Return(false)
2721 mfi.On("Name").Return("testfile")
2723 mfs := &MockFileStore{}
2724 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2725 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2726 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2728 mfs.On("RemoveAll", "/fakeRoot/Files/aaa/testfile").Return(nil)
2729 mfs.On("Remove", "/fakeRoot/Files/aaa/testfile.incomplete").Return(nil)
2730 mfs.On("Remove", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil)
2731 mfs.On("Remove", "/fakeRoot/Files/aaa/.info_testfile").Return(nil)
2735 Accounts: map[string]*Account{},
2739 tranDeleteFile, &[]byte{0, 1},
2740 NewField(fieldFileName, []byte("testfile")),
2741 NewField(fieldFilePath, []byte{
2749 wantRes: []Transaction{
2754 ID: []byte{0x0, 0x0, 0x0, 0x0},
2755 ErrorCode: []byte{0, 0, 0, 0},
2756 Fields: []Field(nil),
2759 wantErr: assert.NoError,
2762 for _, tt := range tests {
2763 t.Run(tt.name, func(t *testing.T) {
2764 gotRes, err := HandleDeleteFile(tt.args.cc, tt.args.t)
2765 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteFile(%v, %v)", tt.args.cc, tt.args.t)) {
2769 tranAssertEqual(t, tt.wantRes, gotRes)
2771 tt.args.cc.Server.FS.(*MockFileStore).AssertExpectations(t)
2776 func TestHandleGetFileNameList(t *testing.T) {
2784 wantRes []Transaction
2785 wantErr assert.ErrorAssertionFunc
2788 name: "when fieldFilePath is a drop box, but user does not have accessViewDropBoxes ",
2792 Access: func() accessBitmap {
2793 var bits accessBitmap
2800 FileRoot: func() string {
2801 path, _ := os.Getwd()
2802 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2808 tranGetFileNameList, &[]byte{0, 1},
2809 NewField(fieldFilePath, []byte{
2813 0x64, 0x72, 0x6f, 0x70, 0x20, 0x62, 0x6f, 0x78, // "drop box"
2817 wantRes: []Transaction{
2821 Type: []byte{0, 0x00},
2822 ID: []byte{0, 0, 0, 0},
2823 ErrorCode: []byte{0, 0, 0, 1},
2825 NewField(fieldError, []byte("You are not allowed to view drop boxes.")),
2829 wantErr: assert.NoError,
2832 name: "with file root",
2837 FileRoot: func() string {
2838 path, _ := os.Getwd()
2839 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2845 tranGetFileNameList, &[]byte{0, 1},
2846 NewField(fieldFilePath, []byte{
2852 wantRes: []Transaction{
2857 ID: []byte{0, 0, 0, 0},
2858 ErrorCode: []byte{0, 0, 0, 0},
2861 fieldFileNameWithInfo,
2863 fnwi := FileNameWithInfo{
2864 fileNameWithInfoHeader: fileNameWithInfoHeader{
2865 Type: [4]byte{0x54, 0x45, 0x58, 0x54},
2866 Creator: [4]byte{0x54, 0x54, 0x58, 0x54},
2867 FileSize: [4]byte{0, 0, 0x04, 0},
2869 NameScript: [2]byte{},
2870 NameSize: [2]byte{0, 0x0b},
2872 name: []byte("testfile-1k"),
2874 b, _ := fnwi.MarshalBinary()
2881 wantErr: assert.NoError,
2884 for _, tt := range tests {
2885 t.Run(tt.name, func(t *testing.T) {
2886 gotRes, err := HandleGetFileNameList(tt.args.cc, tt.args.t)
2887 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetFileNameList(%v, %v)", tt.args.cc, tt.args.t)) {
2891 tranAssertEqual(t, tt.wantRes, gotRes)
2896 func TestHandleGetClientInfoText(t *testing.T) {
2904 wantRes []Transaction
2905 wantErr assert.ErrorAssertionFunc
2908 name: "when user does not have required permission",
2912 Access: func() accessBitmap {
2913 var bits accessBitmap
2918 Accounts: map[string]*Account{},
2922 tranGetClientInfoText, &[]byte{0, 1},
2923 NewField(fieldUserID, []byte{0, 1}),
2926 wantRes: []Transaction{
2930 Type: []byte{0, 0x00},
2931 ID: []byte{0, 0, 0, 0},
2932 ErrorCode: []byte{0, 0, 0, 1},
2934 NewField(fieldError, []byte("You are not allowed to get client info.")),
2938 wantErr: assert.NoError,
2941 name: "with a valid user",
2944 UserName: []byte("Testy McTest"),
2945 RemoteAddr: "1.2.3.4:12345",
2947 Access: func() accessBitmap {
2948 var bits accessBitmap
2949 bits.Set(accessGetClientInfo)
2956 Accounts: map[string]*Account{},
2957 Clients: map[uint16]*ClientConn{
2959 UserName: []byte("Testy McTest"),
2960 RemoteAddr: "1.2.3.4:12345",
2962 Access: func() accessBitmap {
2963 var bits accessBitmap
2964 bits.Set(accessGetClientInfo)
2973 transfers: map[int]map[[4]byte]*FileTransfer{
2981 tranGetClientInfoText, &[]byte{0, 1},
2982 NewField(fieldUserID, []byte{0, 1}),
2985 wantRes: []Transaction{
2990 ID: []byte{0, 0, 0, 0},
2991 ErrorCode: []byte{0, 0, 0, 0},
2993 NewField(fieldData, []byte(
2994 strings.Replace(`Nickname: Testy McTest
2997 Address: 1.2.3.4:12345
2999 -------- File Downloads ---------
3003 ------- Folder Downloads --------
3007 --------- File Uploads ----------
3011 -------- Folder Uploads ---------
3015 ------- Waiting Downloads -------
3019 `, "\n", "\r", -1)),
3021 NewField(fieldUserName, []byte("Testy McTest")),
3025 wantErr: assert.NoError,
3028 for _, tt := range tests {
3029 t.Run(tt.name, func(t *testing.T) {
3030 gotRes, err := HandleGetClientInfoText(tt.args.cc, tt.args.t)
3031 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetClientInfoText(%v, %v)", tt.args.cc, tt.args.t)) {
3034 tranAssertEqual(t, tt.wantRes, gotRes)
3039 func TestHandleTranAgreed(t *testing.T) {
3047 wantRes []Transaction
3048 wantErr assert.ErrorAssertionFunc
3051 name: "normal request flow",
3055 Access: func() accessBitmap {
3056 var bits accessBitmap
3057 bits.Set(accessDisconUser)
3058 bits.Set(accessAnyName)
3062 Flags: []byte{0, 1},
3063 Version: []byte{0, 1},
3065 logger: NewTestLogger(),
3068 BannerFile: "banner.jpg",
3074 NewField(fieldUserName, []byte("username")),
3075 NewField(fieldUserIconID, []byte{0, 1}),
3076 NewField(fieldOptions, []byte{0, 0}),
3079 wantRes: []Transaction{
3081 clientID: &[]byte{0, 1},
3084 Type: []byte{0, 0x7a},
3085 ID: []byte{0, 0, 0, 0},
3086 ErrorCode: []byte{0, 0, 0, 0},
3088 NewField(fieldBannerType, []byte("JPEG")),
3092 clientID: &[]byte{0, 1},
3096 ID: []byte{0, 0, 0, 0},
3097 ErrorCode: []byte{0, 0, 0, 0},
3101 wantErr: assert.NoError,
3104 for _, tt := range tests {
3105 t.Run(tt.name, func(t *testing.T) {
3106 gotRes, err := HandleTranAgreed(tt.args.cc, tt.args.t)
3107 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranAgreed(%v, %v)", tt.args.cc, tt.args.t)) {
3110 tranAssertEqual(t, tt.wantRes, gotRes)
3115 func TestHandleSetClientUserInfo(t *testing.T) {
3123 wantRes []Transaction
3124 wantErr assert.ErrorAssertionFunc
3127 name: "when client does not have accessAnyName",
3131 Access: func() accessBitmap {
3132 var bits accessBitmap
3137 UserName: []byte("Guest"),
3138 Flags: []byte{0, 1},
3140 Clients: map[uint16]*ClientConn{
3148 tranSetClientUserInfo, nil,
3149 NewField(fieldUserIconID, []byte{0, 1}),
3150 NewField(fieldUserName, []byte("NOPE")),
3153 wantRes: []Transaction{
3155 clientID: &[]byte{0, 1},
3158 Type: []byte{0x01, 0x2d},
3159 ID: []byte{0, 0, 0, 0},
3160 ErrorCode: []byte{0, 0, 0, 0},
3162 NewField(fieldUserID, []byte{0, 1}),
3163 NewField(fieldUserIconID, []byte{0, 1}),
3164 NewField(fieldUserFlags, []byte{0, 1}),
3165 NewField(fieldUserName, []byte("Guest"))},
3168 wantErr: assert.NoError,
3171 for _, tt := range tests {
3172 t.Run(tt.name, func(t *testing.T) {
3173 gotRes, err := HandleSetClientUserInfo(tt.args.cc, tt.args.t)
3174 if !tt.wantErr(t, err, fmt.Sprintf("HandleSetClientUserInfo(%v, %v)", tt.args.cc, tt.args.t)) {
3178 tranAssertEqual(t, tt.wantRes, gotRes)
3183 func TestHandleDelNewsItem(t *testing.T) {
3191 wantRes []Transaction
3192 wantErr assert.ErrorAssertionFunc
3195 name: "when user does not have permission to delete a news category",
3199 Access: accessBitmap{},
3203 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3214 tranDelNewsItem, nil,
3215 NewField(fieldNewsPath,
3220 0x74, 0x65, 0x73, 0x74,
3225 wantRes: []Transaction{
3227 clientID: &[]byte{0, 1},
3230 Type: []byte{0, 0x00},
3231 ID: []byte{0, 0, 0, 0},
3232 ErrorCode: []byte{0, 0, 0, 1},
3234 NewField(fieldError, []byte("You are not allowed to delete news categories.")),
3238 wantErr: assert.NoError,
3241 name: "when user does not have permission to delete a news folder",
3245 Access: accessBitmap{},
3249 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3260 tranDelNewsItem, nil,
3261 NewField(fieldNewsPath,
3266 0x74, 0x65, 0x73, 0x74,
3271 wantRes: []Transaction{
3273 clientID: &[]byte{0, 1},
3276 Type: []byte{0, 0x00},
3277 ID: []byte{0, 0, 0, 0},
3278 ErrorCode: []byte{0, 0, 0, 1},
3280 NewField(fieldError, []byte("You are not allowed to delete news folders.")),
3284 wantErr: assert.NoError,
3287 name: "when user deletes a news folder",
3291 Access: func() accessBitmap {
3292 var bits accessBitmap
3293 bits.Set(accessNewsDeleteFldr)
3299 ConfigDir: "/fakeConfigRoot",
3300 FS: func() *MockFileStore {
3301 mfs := &MockFileStore{}
3302 mfs.On("WriteFile", "/fakeConfigRoot/ThreadedNews.yaml", mock.Anything, mock.Anything).Return(nil, os.ErrNotExist)
3305 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3316 tranDelNewsItem, nil,
3317 NewField(fieldNewsPath,
3322 0x74, 0x65, 0x73, 0x74,
3327 wantRes: []Transaction{
3329 clientID: &[]byte{0, 1},
3333 ID: []byte{0, 0, 0, 0},
3334 ErrorCode: []byte{0, 0, 0, 0},
3338 wantErr: assert.NoError,
3341 for _, tt := range tests {
3342 t.Run(tt.name, func(t *testing.T) {
3343 gotRes, err := HandleDelNewsItem(tt.args.cc, tt.args.t)
3344 if !tt.wantErr(t, err, fmt.Sprintf("HandleDelNewsItem(%v, %v)", tt.args.cc, tt.args.t)) {
3347 tranAssertEqual(t, tt.wantRes, gotRes)
3352 func TestHandleDownloadBanner(t *testing.T) {
3360 wantRes []Transaction
3361 wantErr assert.ErrorAssertionFunc
3364 name: "returns expected response",
3368 transfers: map[int]map[[4]byte]*FileTransfer{
3372 ConfigDir: "/config",
3374 BannerFile: "banner.jpg",
3376 fileTransfers: map[[4]byte]*FileTransfer{},
3377 FS: func() *MockFileStore {
3378 mfi := &MockFileInfo{}
3379 mfi.On("Size").Return(int64(100))
3381 mfs := &MockFileStore{}
3382 mfs.On("Stat", "/config/banner.jpg").Return(mfi, nil)
3387 t: NewTransaction(tranDownloadBanner, nil),
3389 wantRes: []Transaction{
3391 clientID: &[]byte{0, 1},
3395 ID: []byte{0, 0, 0, 0},
3396 ErrorCode: []byte{0, 0, 0, 0},
3398 NewField(fieldRefNum, []byte{1, 2, 3, 4}),
3399 NewField(fieldTransferSize, []byte{0, 0, 0, 0x64}),
3403 wantErr: assert.NoError,
3406 for _, tt := range tests {
3407 t.Run(tt.name, func(t *testing.T) {
3408 gotRes, err := HandleDownloadBanner(tt.args.cc, tt.args.t)
3409 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadBanner(%v, %v)", tt.args.cc, tt.args.t)) {
3413 tranAssertEqual(t, tt.wantRes, gotRes)
3418 func TestHandleTranOldPostNews(t *testing.T) {
3426 wantRes []Transaction
3427 wantErr assert.ErrorAssertionFunc
3430 name: "when user does not have required permission",
3434 Access: func() accessBitmap {
3435 var bits accessBitmap
3441 tranOldPostNews, &[]byte{0, 1},
3442 NewField(fieldData, []byte("hai")),
3445 wantRes: []Transaction{
3449 Type: []byte{0, 0x00},
3450 ID: []byte{0, 0, 0, 0},
3451 ErrorCode: []byte{0, 0, 0, 1},
3453 NewField(fieldError, []byte("You are not allowed to post news.")),
3457 wantErr: assert.NoError,
3460 name: "when user posts news update",
3464 Access: func() accessBitmap {
3465 var bits accessBitmap
3466 bits.Set(accessNewsPostArt)
3471 FS: func() *MockFileStore {
3472 mfs := &MockFileStore{}
3473 mfs.On("WriteFile", "/fakeConfigRoot/MessageBoard.txt", mock.Anything, mock.Anything).Return(nil, os.ErrNotExist)
3476 ConfigDir: "/fakeConfigRoot",
3481 tranOldPostNews, &[]byte{0, 1},
3482 NewField(fieldData, []byte("hai")),
3485 wantRes: []Transaction{
3490 ID: []byte{0, 0, 0, 0},
3491 ErrorCode: []byte{0, 0, 0, 0},
3494 wantErr: assert.NoError,
3497 for _, tt := range tests {
3498 t.Run(tt.name, func(t *testing.T) {
3499 gotRes, err := HandleTranOldPostNews(tt.args.cc, tt.args.t)
3500 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranOldPostNews(%v, %v)", tt.args.cc, tt.args.t)) {
3504 tranAssertEqual(t, tt.wantRes, gotRes)
3509 func TestHandleInviteNewChat(t *testing.T) {
3517 wantRes []Transaction
3518 wantErr assert.ErrorAssertionFunc
3521 name: "when user does not have required permission",
3525 Access: func() accessBitmap {
3526 var bits accessBitmap
3531 t: NewTransaction(tranInviteNewChat, &[]byte{0, 1}),
3533 wantRes: []Transaction{
3537 Type: []byte{0, 0x00},
3538 ID: []byte{0, 0, 0, 0},
3539 ErrorCode: []byte{0, 0, 0, 1},
3541 NewField(fieldError, []byte("You are not allowed to request private chat.")),
3545 wantErr: assert.NoError,
3548 name: "when userA invites userB to new private chat",
3553 Access: func() accessBitmap {
3554 var bits accessBitmap
3555 bits.Set(accessOpenChat)
3559 UserName: []byte("UserA"),
3561 Flags: []byte{0, 0},
3563 Clients: map[uint16]*ClientConn{
3566 UserName: []byte("UserB"),
3567 Flags: []byte{0, 0},
3570 PrivateChats: make(map[uint32]*PrivateChat),
3574 tranInviteNewChat, &[]byte{0, 1},
3575 NewField(fieldUserID, []byte{0, 2}),
3578 wantRes: []Transaction{
3580 clientID: &[]byte{0, 2},
3583 Type: []byte{0, 0x71},
3584 ID: []byte{0, 0, 0, 0},
3585 ErrorCode: []byte{0, 0, 0, 0},
3587 NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3588 NewField(fieldUserName, []byte("UserA")),
3589 NewField(fieldUserID, []byte{0, 1}),
3594 clientID: &[]byte{0, 1},
3598 ID: []byte{0, 0, 0, 0},
3599 ErrorCode: []byte{0, 0, 0, 0},
3601 NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3602 NewField(fieldUserName, []byte("UserA")),
3603 NewField(fieldUserID, []byte{0, 1}),
3604 NewField(fieldUserIconID, []byte{0, 1}),
3605 NewField(fieldUserFlags, []byte{0, 0}),
3609 wantErr: assert.NoError,
3612 name: "when userA invites userB to new private chat, but UserB has refuse private chat enabled",
3617 Access: func() accessBitmap {
3618 var bits accessBitmap
3619 bits.Set(accessOpenChat)
3623 UserName: []byte("UserA"),
3625 Flags: []byte{0, 0},
3627 Clients: map[uint16]*ClientConn{
3630 UserName: []byte("UserB"),
3631 Flags: []byte{255, 255},
3634 PrivateChats: make(map[uint32]*PrivateChat),
3638 tranInviteNewChat, &[]byte{0, 1},
3639 NewField(fieldUserID, []byte{0, 2}),
3642 wantRes: []Transaction{
3644 clientID: &[]byte{0, 1},
3647 Type: []byte{0, 0x68},
3648 ID: []byte{0, 0, 0, 0},
3649 ErrorCode: []byte{0, 0, 0, 0},
3651 NewField(fieldData, []byte("UserB does not accept private chats.")),
3652 NewField(fieldUserName, []byte("UserB")),
3653 NewField(fieldUserID, []byte{0, 2}),
3654 NewField(fieldOptions, []byte{0, 2}),
3658 clientID: &[]byte{0, 1},
3662 ID: []byte{0, 0, 0, 0},
3663 ErrorCode: []byte{0, 0, 0, 0},
3665 NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3666 NewField(fieldUserName, []byte("UserA")),
3667 NewField(fieldUserID, []byte{0, 1}),
3668 NewField(fieldUserIconID, []byte{0, 1}),
3669 NewField(fieldUserFlags, []byte{0, 0}),
3673 wantErr: assert.NoError,
3676 for _, tt := range tests {
3677 t.Run(tt.name, func(t *testing.T) {
3679 gotRes, err := HandleInviteNewChat(tt.args.cc, tt.args.t)
3680 if !tt.wantErr(t, err, fmt.Sprintf("HandleInviteNewChat(%v, %v)", tt.args.cc, tt.args.t)) {
3683 tranAssertEqual(t, tt.wantRes, gotRes)