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",
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: "only sends chat msg to clients with accessReadChat permission",
528 Access: func() accessBitmap {
529 var bits accessBitmap
530 bits.Set(accessSendChat)
534 UserName: []byte{0x00, 0x01},
536 Clients: map[uint16]*ClientConn{
539 Access: func() accessBitmap {
540 var bits accessBitmap
541 bits.Set(accessReadChat)
548 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
557 NewField(fieldData, []byte("hai")),
563 clientID: &[]byte{0, 1},
566 Type: []byte{0, 0x6a},
567 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
568 ErrorCode: []byte{0, 0, 0, 0},
570 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
577 name: "only sends private chat msg to members of private chat",
581 Access: func() accessBitmap {
582 var bits accessBitmap
583 bits.Set(accessSendChat)
587 UserName: []byte{0x00, 0x01},
589 PrivateChats: map[uint32]*PrivateChat{
591 ClientConn: map[uint16]*ClientConn{
601 Clients: map[uint16]*ClientConn{
604 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
610 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
616 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
625 NewField(fieldData, []byte("hai")),
626 NewField(fieldChatID, []byte{0, 0, 0, 1}),
632 clientID: &[]byte{0, 1},
635 Type: []byte{0, 0x6a},
636 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
637 ErrorCode: []byte{0, 0, 0, 0},
639 NewField(fieldChatID, []byte{0, 0, 0, 1}),
640 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
644 clientID: &[]byte{0, 2},
647 Type: []byte{0, 0x6a},
648 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
649 ErrorCode: []byte{0, 0, 0, 0},
651 NewField(fieldChatID, []byte{0, 0, 0, 1}),
652 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
659 for _, tt := range tests {
660 t.Run(tt.name, func(t *testing.T) {
661 got, err := HandleChatSend(tt.args.cc, tt.args.t)
663 if (err != nil) != tt.wantErr {
664 t.Errorf("HandleChatSend() error = %v, wantErr %v", err, tt.wantErr)
667 tranAssertEqual(t, tt.want, got)
672 func TestHandleGetFileInfo(t *testing.T) {
673 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
682 wantRes []Transaction
686 name: "returns expected fields when a valid file is requested",
689 ID: &[]byte{0x00, 0x01},
693 FileRoot: func() string {
694 path, _ := os.Getwd()
695 return filepath.Join(path, "/test/config/Files")
701 tranGetFileInfo, nil,
702 NewField(fieldFileName, []byte("testfile.txt")),
703 NewField(fieldFilePath, []byte{0x00, 0x00}),
706 wantRes: []Transaction{
708 clientID: &[]byte{0, 1},
711 Type: []byte{0, 0xce},
712 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
713 ErrorCode: []byte{0, 0, 0, 0},
715 NewField(fieldFileName, []byte("testfile.txt")),
716 NewField(fieldFileTypeString, []byte("Text File")),
717 NewField(fieldFileCreatorString, []byte("ttxt")),
718 NewField(fieldFileComment, []byte{}),
719 NewField(fieldFileType, []byte("TEXT")),
720 NewField(fieldFileCreateDate, make([]byte, 8)),
721 NewField(fieldFileModifyDate, make([]byte, 8)),
722 NewField(fieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}),
729 for _, tt := range tests {
730 t.Run(tt.name, func(t *testing.T) {
731 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
733 gotRes, err := HandleGetFileInfo(tt.args.cc, tt.args.t)
734 if (err != nil) != tt.wantErr {
735 t.Errorf("HandleGetFileInfo() error = %v, wantErr %v", err, tt.wantErr)
739 // Clear the fileWrapper timestamp fields to work around problems running the tests in multiple timezones
740 // TODO: revisit how to test this by mocking the stat calls
741 gotRes[0].Fields[5].Data = make([]byte, 8)
742 gotRes[0].Fields[6].Data = make([]byte, 8)
743 if !assert.Equal(t, tt.wantRes, gotRes) {
744 t.Errorf("HandleGetFileInfo() gotRes = %v, want %v", gotRes, tt.wantRes)
750 func TestHandleNewFolder(t *testing.T) {
758 wantRes []Transaction
762 name: "without required permission",
766 Access: func() accessBitmap {
767 var bits accessBitmap
777 wantRes: []Transaction{
781 Type: []byte{0, 0x00},
782 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
783 ErrorCode: []byte{0, 0, 0, 1},
785 NewField(fieldError, []byte("You are not allowed to create folders.")),
792 name: "when path is nested",
796 Access: func() accessBitmap {
797 var bits accessBitmap
798 bits.Set(accessCreateFolder)
807 FS: func() *MockFileStore {
808 mfs := &MockFileStore{}
809 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
810 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
816 tranNewFolder, &[]byte{0, 1},
817 NewField(fieldFileName, []byte("testFolder")),
818 NewField(fieldFilePath, []byte{
826 wantRes: []Transaction{
828 clientID: &[]byte{0, 1},
831 Type: []byte{0, 0xcd},
832 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
833 ErrorCode: []byte{0, 0, 0, 0},
839 name: "when path is not nested",
843 Access: func() accessBitmap {
844 var bits accessBitmap
845 bits.Set(accessCreateFolder)
854 FS: func() *MockFileStore {
855 mfs := &MockFileStore{}
856 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
857 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
863 tranNewFolder, &[]byte{0, 1},
864 NewField(fieldFileName, []byte("testFolder")),
867 wantRes: []Transaction{
869 clientID: &[]byte{0, 1},
872 Type: []byte{0, 0xcd},
873 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
874 ErrorCode: []byte{0, 0, 0, 0},
880 name: "when Write returns an err",
884 Access: func() accessBitmap {
885 var bits accessBitmap
886 bits.Set(accessCreateFolder)
895 FS: func() *MockFileStore {
896 mfs := &MockFileStore{}
897 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
898 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
904 tranNewFolder, &[]byte{0, 1},
905 NewField(fieldFileName, []byte("testFolder")),
906 NewField(fieldFilePath, []byte{
911 wantRes: []Transaction{},
915 name: "fieldFileName does not allow directory traversal",
919 Access: func() accessBitmap {
920 var bits accessBitmap
921 bits.Set(accessCreateFolder)
930 FS: func() *MockFileStore {
931 mfs := &MockFileStore{}
932 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
933 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
939 tranNewFolder, &[]byte{0, 1},
940 NewField(fieldFileName, []byte("../../testFolder")),
943 wantRes: []Transaction{
945 clientID: &[]byte{0, 1},
948 Type: []byte{0, 0xcd},
949 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
950 ErrorCode: []byte{0, 0, 0, 0},
955 name: "fieldFilePath does not allow directory traversal",
959 Access: func() accessBitmap {
960 var bits accessBitmap
961 bits.Set(accessCreateFolder)
970 FS: func() *MockFileStore {
971 mfs := &MockFileStore{}
972 mfs.On("Mkdir", "/Files/foo/testFolder", fs.FileMode(0777)).Return(nil)
973 mfs.On("Stat", "/Files/foo/testFolder").Return(nil, os.ErrNotExist)
979 tranNewFolder, &[]byte{0, 1},
980 NewField(fieldFileName, []byte("testFolder")),
981 NewField(fieldFilePath, []byte{
992 wantRes: []Transaction{
994 clientID: &[]byte{0, 1},
997 Type: []byte{0, 0xcd},
998 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
999 ErrorCode: []byte{0, 0, 0, 0},
1004 for _, tt := range tests {
1005 t.Run(tt.name, func(t *testing.T) {
1007 gotRes, err := HandleNewFolder(tt.args.cc, tt.args.t)
1008 if (err != nil) != tt.wantErr {
1009 t.Errorf("HandleNewFolder() error = %v, wantErr %v", err, tt.wantErr)
1013 if !tranAssertEqual(t, tt.wantRes, gotRes) {
1014 t.Errorf("HandleNewFolder() gotRes = %v, want %v", gotRes, tt.wantRes)
1020 func TestHandleUploadFile(t *testing.T) {
1028 wantRes []Transaction
1032 name: "when request is valid and user has Upload Anywhere permission",
1037 fileTransfers: map[[4]byte]*FileTransfer{},
1039 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1041 transfers: map[int]map[[4]byte]*FileTransfer{
1045 Access: func() accessBitmap {
1046 var bits accessBitmap
1047 bits.Set(accessUploadFile)
1048 bits.Set(accessUploadAnywhere)
1054 tranUploadFile, &[]byte{0, 1},
1055 NewField(fieldFileName, []byte("testFile")),
1056 NewField(fieldFilePath, []byte{
1064 wantRes: []Transaction{
1068 Type: []byte{0, 0xcb},
1069 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1070 ErrorCode: []byte{0, 0, 0, 0},
1072 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), // rand.Seed(1)
1079 name: "when user does not have required access",
1083 Access: func() accessBitmap {
1084 var bits accessBitmap
1090 tranUploadFile, &[]byte{0, 1},
1091 NewField(fieldFileName, []byte("testFile")),
1092 NewField(fieldFilePath, []byte{
1100 wantRes: []Transaction{
1104 Type: []byte{0, 0x00},
1105 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1106 ErrorCode: []byte{0, 0, 0, 1},
1108 NewField(fieldError, []byte("You are not allowed to upload files.")), // rand.Seed(1)
1115 for _, tt := range tests {
1116 t.Run(tt.name, func(t *testing.T) {
1118 gotRes, err := HandleUploadFile(tt.args.cc, tt.args.t)
1119 if (err != nil) != tt.wantErr {
1120 t.Errorf("HandleUploadFile() error = %v, wantErr %v", err, tt.wantErr)
1124 tranAssertEqual(t, tt.wantRes, gotRes)
1130 func TestHandleMakeAlias(t *testing.T) {
1138 wantRes []Transaction
1142 name: "with valid input and required permissions",
1145 logger: NewTestLogger(),
1147 Access: func() accessBitmap {
1148 var bits accessBitmap
1149 bits.Set(accessMakeAlias)
1155 FileRoot: func() string {
1156 path, _ := os.Getwd()
1157 return path + "/test/config/Files"
1160 Logger: NewTestLogger(),
1161 FS: func() *MockFileStore {
1162 mfs := &MockFileStore{}
1163 path, _ := os.Getwd()
1166 path+"/test/config/Files/foo/testFile",
1167 path+"/test/config/Files/bar/testFile",
1174 tranMakeFileAlias, &[]byte{0, 1},
1175 NewField(fieldFileName, []byte("testFile")),
1176 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1177 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1180 wantRes: []Transaction{
1184 Type: []byte{0, 0xd1},
1185 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1186 ErrorCode: []byte{0, 0, 0, 0},
1187 Fields: []Field(nil),
1193 name: "when symlink returns an error",
1196 logger: NewTestLogger(),
1198 Access: func() accessBitmap {
1199 var bits accessBitmap
1200 bits.Set(accessMakeAlias)
1206 FileRoot: func() string {
1207 path, _ := os.Getwd()
1208 return path + "/test/config/Files"
1211 Logger: NewTestLogger(),
1212 FS: func() *MockFileStore {
1213 mfs := &MockFileStore{}
1214 path, _ := os.Getwd()
1217 path+"/test/config/Files/foo/testFile",
1218 path+"/test/config/Files/bar/testFile",
1219 ).Return(errors.New("ohno"))
1225 tranMakeFileAlias, &[]byte{0, 1},
1226 NewField(fieldFileName, []byte("testFile")),
1227 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1228 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1231 wantRes: []Transaction{
1235 Type: []byte{0, 0x00},
1236 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1237 ErrorCode: []byte{0, 0, 0, 1},
1239 NewField(fieldError, []byte("Error creating alias")),
1246 name: "when user does not have required permission",
1249 logger: NewTestLogger(),
1251 Access: func() accessBitmap {
1252 var bits accessBitmap
1258 FileRoot: func() string {
1259 path, _ := os.Getwd()
1260 return path + "/test/config/Files"
1266 tranMakeFileAlias, &[]byte{0, 1},
1267 NewField(fieldFileName, []byte("testFile")),
1268 NewField(fieldFilePath, []byte{
1274 NewField(fieldFileNewPath, []byte{
1282 wantRes: []Transaction{
1286 Type: []byte{0, 0x00},
1287 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1288 ErrorCode: []byte{0, 0, 0, 1},
1290 NewField(fieldError, []byte("You are not allowed to make aliases.")),
1297 for _, tt := range tests {
1298 t.Run(tt.name, func(t *testing.T) {
1299 gotRes, err := HandleMakeAlias(tt.args.cc, tt.args.t)
1300 if (err != nil) != tt.wantErr {
1301 t.Errorf("HandleMakeAlias(%v, %v)", tt.args.cc, tt.args.t)
1305 tranAssertEqual(t, tt.wantRes, gotRes)
1310 func TestHandleGetUser(t *testing.T) {
1318 wantRes []Transaction
1319 wantErr assert.ErrorAssertionFunc
1322 name: "when account is valid",
1326 Access: func() accessBitmap {
1327 var bits accessBitmap
1328 bits.Set(accessOpenUser)
1333 Accounts: map[string]*Account{
1337 Password: "password",
1338 Access: accessBitmap{},
1344 tranGetUser, &[]byte{0, 1},
1345 NewField(fieldUserLogin, []byte("guest")),
1348 wantRes: []Transaction{
1352 Type: []byte{0x01, 0x60},
1353 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1354 ErrorCode: []byte{0, 0, 0, 0},
1356 NewField(fieldUserName, []byte("Guest")),
1357 NewField(fieldUserLogin, negateString([]byte("guest"))),
1358 NewField(fieldUserPassword, []byte("password")),
1359 NewField(fieldUserAccess, []byte{0, 0, 0, 0, 0, 0, 0, 0}),
1363 wantErr: assert.NoError,
1366 name: "when user does not have required permission",
1370 Access: func() accessBitmap {
1371 var bits accessBitmap
1376 Accounts: map[string]*Account{},
1380 tranGetUser, &[]byte{0, 1},
1381 NewField(fieldUserLogin, []byte("nonExistentUser")),
1384 wantRes: []Transaction{
1388 Type: []byte{0, 0x00},
1389 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1390 ErrorCode: []byte{0, 0, 0, 1},
1392 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1396 wantErr: assert.NoError,
1399 name: "when account does not exist",
1403 Access: func() accessBitmap {
1404 var bits accessBitmap
1405 bits.Set(accessOpenUser)
1410 Accounts: map[string]*Account{},
1414 tranGetUser, &[]byte{0, 1},
1415 NewField(fieldUserLogin, []byte("nonExistentUser")),
1418 wantRes: []Transaction{
1422 Type: []byte{0, 0x00},
1423 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1424 ErrorCode: []byte{0, 0, 0, 1},
1426 NewField(fieldError, []byte("Account does not exist.")),
1430 wantErr: assert.NoError,
1433 for _, tt := range tests {
1434 t.Run(tt.name, func(t *testing.T) {
1435 gotRes, err := HandleGetUser(tt.args.cc, tt.args.t)
1436 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetUser(%v, %v)", tt.args.cc, tt.args.t)) {
1440 tranAssertEqual(t, tt.wantRes, gotRes)
1445 func TestHandleDeleteUser(t *testing.T) {
1453 wantRes []Transaction
1454 wantErr assert.ErrorAssertionFunc
1457 name: "when user dataFile",
1461 Access: func() accessBitmap {
1462 var bits accessBitmap
1463 bits.Set(accessDeleteUser)
1468 Accounts: map[string]*Account{
1471 Name: "Testy McTest",
1472 Password: "password",
1473 Access: accessBitmap{},
1476 FS: func() *MockFileStore {
1477 mfs := &MockFileStore{}
1478 mfs.On("Remove", "Users/testuser.yaml").Return(nil)
1484 tranDeleteUser, &[]byte{0, 1},
1485 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1488 wantRes: []Transaction{
1492 Type: []byte{0x1, 0x5f},
1493 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1494 ErrorCode: []byte{0, 0, 0, 0},
1495 Fields: []Field(nil),
1498 wantErr: assert.NoError,
1501 name: "when user does not have required permission",
1505 Access: func() accessBitmap {
1506 var bits accessBitmap
1511 Accounts: map[string]*Account{},
1515 tranDeleteUser, &[]byte{0, 1},
1516 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1519 wantRes: []Transaction{
1523 Type: []byte{0, 0x00},
1524 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1525 ErrorCode: []byte{0, 0, 0, 1},
1527 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
1531 wantErr: assert.NoError,
1534 for _, tt := range tests {
1535 t.Run(tt.name, func(t *testing.T) {
1536 gotRes, err := HandleDeleteUser(tt.args.cc, tt.args.t)
1537 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteUser(%v, %v)", tt.args.cc, tt.args.t)) {
1541 tranAssertEqual(t, tt.wantRes, gotRes)
1546 func TestHandleGetMsgs(t *testing.T) {
1554 wantRes []Transaction
1555 wantErr assert.ErrorAssertionFunc
1558 name: "returns news data",
1562 Access: func() accessBitmap {
1563 var bits accessBitmap
1564 bits.Set(accessNewsReadArt)
1569 FlatNews: []byte("TEST"),
1573 tranGetMsgs, &[]byte{0, 1},
1576 wantRes: []Transaction{
1580 Type: []byte{0, 0x65},
1581 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1582 ErrorCode: []byte{0, 0, 0, 0},
1584 NewField(fieldData, []byte("TEST")),
1588 wantErr: assert.NoError,
1591 name: "when user does not have required permission",
1595 Access: func() accessBitmap {
1596 var bits accessBitmap
1601 Accounts: map[string]*Account{},
1605 tranGetMsgs, &[]byte{0, 1},
1608 wantRes: []Transaction{
1612 Type: []byte{0, 0x00},
1613 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1614 ErrorCode: []byte{0, 0, 0, 1},
1616 NewField(fieldError, []byte("You are not allowed to read news.")),
1620 wantErr: assert.NoError,
1623 for _, tt := range tests {
1624 t.Run(tt.name, func(t *testing.T) {
1625 gotRes, err := HandleGetMsgs(tt.args.cc, tt.args.t)
1626 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetMsgs(%v, %v)", tt.args.cc, tt.args.t)) {
1630 tranAssertEqual(t, tt.wantRes, gotRes)
1635 func TestHandleNewUser(t *testing.T) {
1643 wantRes []Transaction
1644 wantErr assert.ErrorAssertionFunc
1647 name: "when user does not have required permission",
1651 Access: func() accessBitmap {
1652 var bits accessBitmap
1657 Accounts: map[string]*Account{},
1661 tranNewUser, &[]byte{0, 1},
1664 wantRes: []Transaction{
1668 Type: []byte{0, 0x00},
1669 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1670 ErrorCode: []byte{0, 0, 0, 1},
1672 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
1676 wantErr: assert.NoError,
1679 name: "when user attempts to create account with greater access",
1683 Access: func() accessBitmap {
1684 var bits accessBitmap
1685 bits.Set(accessCreateUser)
1690 Accounts: map[string]*Account{},
1694 tranNewUser, &[]byte{0, 1},
1695 NewField(fieldUserLogin, []byte("userB")),
1699 var bits accessBitmap
1700 bits.Set(accessDisconUser)
1706 wantRes: []Transaction{
1710 Type: []byte{0, 0x00},
1711 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1712 ErrorCode: []byte{0, 0, 0, 1},
1714 NewField(fieldError, []byte("Cannot create account with more access than yourself.")),
1718 wantErr: assert.NoError,
1721 for _, tt := range tests {
1722 t.Run(tt.name, func(t *testing.T) {
1723 gotRes, err := HandleNewUser(tt.args.cc, tt.args.t)
1724 if !tt.wantErr(t, err, fmt.Sprintf("HandleNewUser(%v, %v)", tt.args.cc, tt.args.t)) {
1728 tranAssertEqual(t, tt.wantRes, gotRes)
1733 func TestHandleListUsers(t *testing.T) {
1741 wantRes []Transaction
1742 wantErr assert.ErrorAssertionFunc
1745 name: "when user does not have required permission",
1749 Access: func() accessBitmap {
1750 var bits accessBitmap
1755 Accounts: map[string]*Account{},
1759 tranNewUser, &[]byte{0, 1},
1762 wantRes: []Transaction{
1766 Type: []byte{0, 0x00},
1767 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1768 ErrorCode: []byte{0, 0, 0, 1},
1770 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1774 wantErr: assert.NoError,
1777 name: "when user has required permission",
1781 Access: func() accessBitmap {
1782 var bits accessBitmap
1783 bits.Set(accessOpenUser)
1788 Accounts: map[string]*Account{
1793 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
1799 tranGetClientInfoText, &[]byte{0, 1},
1800 NewField(fieldUserID, []byte{0, 1}),
1803 wantRes: []Transaction{
1807 Type: []byte{0x01, 0x2f},
1808 ID: []byte{0, 0, 0, 0},
1809 ErrorCode: []byte{0, 0, 0, 0},
1811 NewField(fieldData, []byte{
1812 0x00, 0x04, 0x00, 0x66, 0x00, 0x05, 0x67, 0x75, 0x65, 0x73, 0x74, 0x00, 0x69, 0x00, 0x05, 0x98,
1813 0x8a, 0x9a, 0x8c, 0x8b, 0x00, 0x6e, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1814 0x00, 0x6a, 0x00, 0x01, 0x78,
1819 wantErr: assert.NoError,
1822 for _, tt := range tests {
1823 t.Run(tt.name, func(t *testing.T) {
1824 gotRes, err := HandleListUsers(tt.args.cc, tt.args.t)
1825 if !tt.wantErr(t, err, fmt.Sprintf("HandleListUsers(%v, %v)", tt.args.cc, tt.args.t)) {
1829 tranAssertEqual(t, tt.wantRes, gotRes)
1834 func TestHandleDownloadFile(t *testing.T) {
1842 wantRes []Transaction
1843 wantErr assert.ErrorAssertionFunc
1846 name: "when user does not have required permission",
1850 Access: func() accessBitmap {
1851 var bits accessBitmap
1857 t: NewTransaction(tranDownloadFile, &[]byte{0, 1}),
1859 wantRes: []Transaction{
1863 Type: []byte{0, 0x00},
1864 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1865 ErrorCode: []byte{0, 0, 0, 1},
1867 NewField(fieldError, []byte("You are not allowed to download files.")),
1871 wantErr: assert.NoError,
1874 name: "with a valid file",
1877 transfers: map[int]map[[4]byte]*FileTransfer{
1881 Access: func() accessBitmap {
1882 var bits accessBitmap
1883 bits.Set(accessDownloadFile)
1889 fileTransfers: map[[4]byte]*FileTransfer{},
1891 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1893 Accounts: map[string]*Account{},
1899 NewField(fieldFileName, []byte("testfile.txt")),
1900 NewField(fieldFilePath, []byte{0x0, 0x00}),
1903 wantRes: []Transaction{
1907 Type: []byte{0, 0x2},
1908 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1909 ErrorCode: []byte{0, 0, 0, 0},
1911 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
1912 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
1913 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x00, 0xa5}),
1914 NewField(fieldFileSize, []byte{0x00, 0x00, 0x00, 0x17}),
1918 wantErr: assert.NoError,
1921 name: "when client requests to resume 1k test file at offset 256",
1924 transfers: map[int]map[[4]byte]*FileTransfer{
1926 }, Account: &Account{
1927 Access: func() accessBitmap {
1928 var bits accessBitmap
1929 bits.Set(accessDownloadFile)
1936 // FS: func() *MockFileStore {
1937 // path, _ := os.Getwd()
1938 // testFile, err := os.Open(path + "/test/config/Files/testfile-1k")
1943 // mfi := &MockFileInfo{}
1944 // mfi.On("Mode").Return(fs.FileMode(0))
1945 // mfs := &MockFileStore{}
1946 // mfs.On("Stat", "/fakeRoot/Files/testfile.txt").Return(mfi, nil)
1947 // mfs.On("Open", "/fakeRoot/Files/testfile.txt").Return(testFile, nil)
1948 // mfs.On("Stat", "/fakeRoot/Files/.info_testfile.txt").Return(nil, errors.New("no"))
1949 // mfs.On("Stat", "/fakeRoot/Files/.rsrc_testfile.txt").Return(nil, errors.New("no"))
1953 fileTransfers: map[[4]byte]*FileTransfer{},
1955 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1957 Accounts: map[string]*Account{},
1963 NewField(fieldFileName, []byte("testfile-1k")),
1964 NewField(fieldFilePath, []byte{0x00, 0x00}),
1966 fieldFileResumeData,
1968 frd := FileResumeData{
1972 ForkCount: [2]byte{0, 2},
1973 ForkInfoList: []ForkInfoList{
1975 Fork: [4]byte{0x44, 0x41, 0x54, 0x41}, // "DATA"
1976 DataSize: [4]byte{0, 0, 0x01, 0x00}, // request offset 256
1981 Fork: [4]byte{0x4d, 0x41, 0x43, 0x52}, // "MACR"
1982 DataSize: [4]byte{0, 0, 0, 0},
1988 b, _ := frd.BinaryMarshal()
1994 wantRes: []Transaction{
1998 Type: []byte{0, 0x2},
1999 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2000 ErrorCode: []byte{0, 0, 0, 0},
2002 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
2003 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
2004 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x03, 0x8d}),
2005 NewField(fieldFileSize, []byte{0x00, 0x00, 0x03, 0x00}),
2009 wantErr: assert.NoError,
2012 for _, tt := range tests {
2013 t.Run(tt.name, func(t *testing.T) {
2014 gotRes, err := HandleDownloadFile(tt.args.cc, tt.args.t)
2015 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadFile(%v, %v)", tt.args.cc, tt.args.t)) {
2019 tranAssertEqual(t, tt.wantRes, gotRes)
2024 func TestHandleUpdateUser(t *testing.T) {
2032 wantRes []Transaction
2033 wantErr assert.ErrorAssertionFunc
2036 name: "when action is create user without required permission",
2039 logger: NewTestLogger(),
2041 Logger: NewTestLogger(),
2044 Access: func() accessBitmap {
2045 var bits accessBitmap
2053 NewField(fieldData, []byte{
2054 0x00, 0x04, // field count
2056 0x00, 0x69, // fieldUserLogin = 105
2060 0x00, 0x6a, // fieldUserPassword = 106
2064 0x00, 0x66, // fieldUserName = 102
2068 0x00, 0x6e, // fieldUserAccess = 110
2070 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
2074 wantRes: []Transaction{
2078 Type: []byte{0, 0x00},
2079 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2080 ErrorCode: []byte{0, 0, 0, 1},
2082 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
2086 wantErr: assert.NoError,
2089 name: "when action is modify user without required permission",
2092 logger: NewTestLogger(),
2094 Logger: NewTestLogger(),
2095 Accounts: map[string]*Account{
2100 Access: func() accessBitmap {
2101 var bits accessBitmap
2109 NewField(fieldData, []byte{
2110 0x00, 0x04, // field count
2112 0x00, 0x69, // fieldUserLogin = 105
2116 0x00, 0x6a, // fieldUserPassword = 106
2120 0x00, 0x66, // fieldUserName = 102
2124 0x00, 0x6e, // fieldUserAccess = 110
2126 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
2130 wantRes: []Transaction{
2134 Type: []byte{0, 0x00},
2135 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2136 ErrorCode: []byte{0, 0, 0, 1},
2138 NewField(fieldError, []byte("You are not allowed to modify accounts.")),
2142 wantErr: assert.NoError,
2145 name: "when action is delete user without required permission",
2148 logger: NewTestLogger(),
2150 Accounts: map[string]*Account{
2155 Access: func() accessBitmap {
2156 var bits accessBitmap
2164 NewField(fieldData, []byte{
2172 wantRes: []Transaction{
2176 Type: []byte{0, 0x00},
2177 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2178 ErrorCode: []byte{0, 0, 0, 1},
2180 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
2184 wantErr: assert.NoError,
2187 for _, tt := range tests {
2188 t.Run(tt.name, func(t *testing.T) {
2189 gotRes, err := HandleUpdateUser(tt.args.cc, tt.args.t)
2190 if !tt.wantErr(t, err, fmt.Sprintf("HandleUpdateUser(%v, %v)", tt.args.cc, tt.args.t)) {
2194 tranAssertEqual(t, tt.wantRes, gotRes)
2199 func TestHandleDelNewsArt(t *testing.T) {
2207 wantRes []Transaction
2208 wantErr assert.ErrorAssertionFunc
2211 name: "without required permission",
2215 Access: func() accessBitmap {
2216 var bits accessBitmap
2226 wantRes: []Transaction{
2230 Type: []byte{0, 0x00},
2231 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2232 ErrorCode: []byte{0, 0, 0, 1},
2234 NewField(fieldError, []byte("You are not allowed to delete news articles.")),
2238 wantErr: assert.NoError,
2241 for _, tt := range tests {
2242 t.Run(tt.name, func(t *testing.T) {
2243 gotRes, err := HandleDelNewsArt(tt.args.cc, tt.args.t)
2244 if !tt.wantErr(t, err, fmt.Sprintf("HandleDelNewsArt(%v, %v)", tt.args.cc, tt.args.t)) {
2247 tranAssertEqual(t, tt.wantRes, gotRes)
2252 func TestHandleDisconnectUser(t *testing.T) {
2260 wantRes []Transaction
2261 wantErr assert.ErrorAssertionFunc
2264 name: "without required permission",
2268 Access: func() accessBitmap {
2269 var bits accessBitmap
2279 wantRes: []Transaction{
2283 Type: []byte{0, 0x00},
2284 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2285 ErrorCode: []byte{0, 0, 0, 1},
2287 NewField(fieldError, []byte("You are not allowed to disconnect users.")),
2291 wantErr: assert.NoError,
2294 name: "when target user has 'cannot be disconnected' priv",
2298 Clients: map[uint16]*ClientConn{
2302 Access: func() accessBitmap {
2303 var bits accessBitmap
2304 bits.Set(accessCannotBeDiscon)
2312 Access: func() accessBitmap {
2313 var bits accessBitmap
2314 bits.Set(accessDisconUser)
2322 NewField(fieldUserID, []byte{0, 1}),
2325 wantRes: []Transaction{
2329 Type: []byte{0, 0x00},
2330 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2331 ErrorCode: []byte{0, 0, 0, 1},
2333 NewField(fieldError, []byte("unnamed is not allowed to be disconnected.")),
2337 wantErr: assert.NoError,
2340 for _, tt := range tests {
2341 t.Run(tt.name, func(t *testing.T) {
2342 gotRes, err := HandleDisconnectUser(tt.args.cc, tt.args.t)
2343 if !tt.wantErr(t, err, fmt.Sprintf("HandleDisconnectUser(%v, %v)", tt.args.cc, tt.args.t)) {
2346 tranAssertEqual(t, tt.wantRes, gotRes)
2351 func TestHandleSendInstantMsg(t *testing.T) {
2359 wantRes []Transaction
2360 wantErr assert.ErrorAssertionFunc
2363 name: "without required permission",
2367 Access: func() accessBitmap {
2368 var bits accessBitmap
2378 wantRes: []Transaction{
2382 Type: []byte{0, 0x00},
2383 ID: []byte{0, 0, 0, 0},
2384 ErrorCode: []byte{0, 0, 0, 1},
2386 NewField(fieldError, []byte("You are not allowed to send private messages.")),
2390 wantErr: assert.NoError,
2393 name: "when client 1 sends a message to client 2",
2397 Access: func() accessBitmap {
2398 var bits accessBitmap
2399 bits.Set(accessSendPrivMsg)
2404 UserName: []byte("User1"),
2406 Clients: map[uint16]*ClientConn{
2408 AutoReply: []byte(nil),
2409 Flags: []byte{0, 0},
2417 NewField(fieldData, []byte("hai")),
2418 NewField(fieldUserID, []byte{0, 2}),
2421 wantRes: []Transaction{
2425 NewField(fieldData, []byte("hai")),
2426 NewField(fieldUserName, []byte("User1")),
2427 NewField(fieldUserID, []byte{0, 1}),
2428 NewField(fieldOptions, []byte{0, 1}),
2431 clientID: &[]byte{0, 1},
2434 Type: []byte{0x0, 0x6c},
2435 ID: []byte{0, 0, 0, 0},
2436 ErrorCode: []byte{0, 0, 0, 0},
2437 Fields: []Field(nil),
2440 wantErr: assert.NoError,
2443 name: "when client 2 has autoreply enabled",
2447 Access: func() accessBitmap {
2448 var bits accessBitmap
2449 bits.Set(accessSendPrivMsg)
2454 UserName: []byte("User1"),
2456 Clients: map[uint16]*ClientConn{
2458 Flags: []byte{0, 0},
2460 UserName: []byte("User2"),
2461 AutoReply: []byte("autohai"),
2469 NewField(fieldData, []byte("hai")),
2470 NewField(fieldUserID, []byte{0, 2}),
2473 wantRes: []Transaction{
2477 NewField(fieldData, []byte("hai")),
2478 NewField(fieldUserName, []byte("User1")),
2479 NewField(fieldUserID, []byte{0, 1}),
2480 NewField(fieldOptions, []byte{0, 1}),
2485 NewField(fieldData, []byte("autohai")),
2486 NewField(fieldUserName, []byte("User2")),
2487 NewField(fieldUserID, []byte{0, 2}),
2488 NewField(fieldOptions, []byte{0, 1}),
2491 clientID: &[]byte{0, 1},
2494 Type: []byte{0x0, 0x6c},
2495 ID: []byte{0, 0, 0, 0},
2496 ErrorCode: []byte{0, 0, 0, 0},
2497 Fields: []Field(nil),
2500 wantErr: assert.NoError,
2503 name: "when client 2 has refuse private messages enabled",
2507 Access: func() accessBitmap {
2508 var bits accessBitmap
2509 bits.Set(accessSendPrivMsg)
2514 UserName: []byte("User1"),
2516 Clients: map[uint16]*ClientConn{
2518 Flags: []byte{255, 255},
2520 UserName: []byte("User2"),
2528 NewField(fieldData, []byte("hai")),
2529 NewField(fieldUserID, []byte{0, 2}),
2532 wantRes: []Transaction{
2536 NewField(fieldData, []byte("User2 does not accept private messages.")),
2537 NewField(fieldUserName, []byte("User2")),
2538 NewField(fieldUserID, []byte{0, 2}),
2539 NewField(fieldOptions, []byte{0, 2}),
2542 clientID: &[]byte{0, 1},
2545 Type: []byte{0x0, 0x6c},
2546 ID: []byte{0, 0, 0, 0},
2547 ErrorCode: []byte{0, 0, 0, 0},
2548 Fields: []Field(nil),
2551 wantErr: assert.NoError,
2554 for _, tt := range tests {
2555 t.Run(tt.name, func(t *testing.T) {
2556 gotRes, err := HandleSendInstantMsg(tt.args.cc, tt.args.t)
2557 if !tt.wantErr(t, err, fmt.Sprintf("HandleSendInstantMsg(%v, %v)", tt.args.cc, tt.args.t)) {
2561 tranAssertEqual(t, tt.wantRes, gotRes)
2566 func TestHandleDeleteFile(t *testing.T) {
2574 wantRes []Transaction
2575 wantErr assert.ErrorAssertionFunc
2578 name: "when user does not have required permission to delete a folder",
2582 Access: func() accessBitmap {
2583 var bits accessBitmap
2589 FileRoot: func() string {
2590 return "/fakeRoot/Files"
2593 FS: func() *MockFileStore {
2594 mfi := &MockFileInfo{}
2595 mfi.On("Mode").Return(fs.FileMode(0))
2596 mfi.On("Size").Return(int64(100))
2597 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2598 mfi.On("IsDir").Return(false)
2599 mfi.On("Name").Return("testfile")
2601 mfs := &MockFileStore{}
2602 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2603 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2604 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2608 Accounts: map[string]*Account{},
2612 tranDeleteFile, &[]byte{0, 1},
2613 NewField(fieldFileName, []byte("testfile")),
2614 NewField(fieldFilePath, []byte{
2622 wantRes: []Transaction{
2626 Type: []byte{0, 0x00},
2627 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2628 ErrorCode: []byte{0, 0, 0, 1},
2630 NewField(fieldError, []byte("You are not allowed to delete files.")),
2634 wantErr: assert.NoError,
2637 name: "deletes all associated metadata files",
2641 Access: func() accessBitmap {
2642 var bits accessBitmap
2643 bits.Set(accessDeleteFile)
2649 FileRoot: func() string {
2650 return "/fakeRoot/Files"
2653 FS: func() *MockFileStore {
2654 mfi := &MockFileInfo{}
2655 mfi.On("Mode").Return(fs.FileMode(0))
2656 mfi.On("Size").Return(int64(100))
2657 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2658 mfi.On("IsDir").Return(false)
2659 mfi.On("Name").Return("testfile")
2661 mfs := &MockFileStore{}
2662 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2663 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2664 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2666 mfs.On("RemoveAll", "/fakeRoot/Files/aaa/testfile").Return(nil)
2667 mfs.On("Remove", "/fakeRoot/Files/aaa/testfile.incomplete").Return(nil)
2668 mfs.On("Remove", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil)
2669 mfs.On("Remove", "/fakeRoot/Files/aaa/.info_testfile").Return(nil)
2673 Accounts: map[string]*Account{},
2677 tranDeleteFile, &[]byte{0, 1},
2678 NewField(fieldFileName, []byte("testfile")),
2679 NewField(fieldFilePath, []byte{
2687 wantRes: []Transaction{
2691 Type: []byte{0x0, 0xcc},
2692 ID: []byte{0x0, 0x0, 0x0, 0x0},
2693 ErrorCode: []byte{0, 0, 0, 0},
2694 Fields: []Field(nil),
2697 wantErr: assert.NoError,
2700 for _, tt := range tests {
2701 t.Run(tt.name, func(t *testing.T) {
2702 gotRes, err := HandleDeleteFile(tt.args.cc, tt.args.t)
2703 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteFile(%v, %v)", tt.args.cc, tt.args.t)) {
2707 tranAssertEqual(t, tt.wantRes, gotRes)
2709 tt.args.cc.Server.FS.(*MockFileStore).AssertExpectations(t)
2714 func TestHandleGetFileNameList(t *testing.T) {
2722 wantRes []Transaction
2723 wantErr assert.ErrorAssertionFunc
2726 name: "when fieldFilePath is a drop box, but user does not have accessViewDropBoxes ",
2730 Access: func() accessBitmap {
2731 var bits accessBitmap
2738 FileRoot: func() string {
2739 path, _ := os.Getwd()
2740 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2746 tranGetFileNameList, &[]byte{0, 1},
2747 NewField(fieldFilePath, []byte{
2751 0x64, 0x72, 0x6f, 0x70, 0x20, 0x62, 0x6f, 0x78, // "drop box"
2755 wantRes: []Transaction{
2759 Type: []byte{0, 0x00},
2760 ID: []byte{0, 0, 0, 0},
2761 ErrorCode: []byte{0, 0, 0, 1},
2763 NewField(fieldError, []byte("You are not allowed to view drop boxes.")),
2767 wantErr: assert.NoError,
2770 name: "with file root",
2775 FileRoot: func() string {
2776 path, _ := os.Getwd()
2777 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2783 tranGetFileNameList, &[]byte{0, 1},
2784 NewField(fieldFilePath, []byte{
2790 wantRes: []Transaction{
2794 Type: []byte{0, 0xc8},
2795 ID: []byte{0, 0, 0, 0},
2796 ErrorCode: []byte{0, 0, 0, 0},
2799 fieldFileNameWithInfo,
2801 fnwi := FileNameWithInfo{
2802 fileNameWithInfoHeader: fileNameWithInfoHeader{
2803 Type: [4]byte{0x54, 0x45, 0x58, 0x54},
2804 Creator: [4]byte{0x54, 0x54, 0x58, 0x54},
2805 FileSize: [4]byte{0, 0, 0x04, 0},
2807 NameScript: [2]byte{},
2808 NameSize: [2]byte{0, 0x0b},
2810 name: []byte("testfile-1k"),
2812 b, _ := fnwi.MarshalBinary()
2819 wantErr: assert.NoError,
2822 for _, tt := range tests {
2823 t.Run(tt.name, func(t *testing.T) {
2824 gotRes, err := HandleGetFileNameList(tt.args.cc, tt.args.t)
2825 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetFileNameList(%v, %v)", tt.args.cc, tt.args.t)) {
2829 tranAssertEqual(t, tt.wantRes, gotRes)
2834 func TestHandleGetClientInfoText(t *testing.T) {
2842 wantRes []Transaction
2843 wantErr assert.ErrorAssertionFunc
2846 name: "when user does not have required permission",
2850 Access: func() accessBitmap {
2851 var bits accessBitmap
2856 Accounts: map[string]*Account{},
2860 tranGetClientInfoText, &[]byte{0, 1},
2861 NewField(fieldUserID, []byte{0, 1}),
2864 wantRes: []Transaction{
2868 Type: []byte{0, 0x00},
2869 ID: []byte{0, 0, 0, 0},
2870 ErrorCode: []byte{0, 0, 0, 1},
2872 NewField(fieldError, []byte("You are not allowed to get client info.")),
2876 wantErr: assert.NoError,
2879 name: "with a valid user",
2882 UserName: []byte("Testy McTest"),
2883 RemoteAddr: "1.2.3.4:12345",
2885 Access: func() accessBitmap {
2886 var bits accessBitmap
2887 bits.Set(accessGetClientInfo)
2894 Accounts: map[string]*Account{},
2895 Clients: map[uint16]*ClientConn{
2897 UserName: []byte("Testy McTest"),
2898 RemoteAddr: "1.2.3.4:12345",
2900 Access: func() accessBitmap {
2901 var bits accessBitmap
2902 bits.Set(accessGetClientInfo)
2911 transfers: map[int]map[[4]byte]*FileTransfer{
2919 tranGetClientInfoText, &[]byte{0, 1},
2920 NewField(fieldUserID, []byte{0, 1}),
2923 wantRes: []Transaction{
2927 Type: []byte{0x1, 0x2f},
2928 ID: []byte{0, 0, 0, 0},
2929 ErrorCode: []byte{0, 0, 0, 0},
2931 NewField(fieldData, []byte(
2932 strings.Replace(`Nickname: Testy McTest
2935 Address: 1.2.3.4:12345
2937 -------- File Downloads ---------
2941 ------- Folder Downloads --------
2945 --------- File Uploads ----------
2949 -------- Folder Uploads ---------
2953 ------- Waiting Downloads -------
2957 `, "\n", "\r", -1)),
2959 NewField(fieldUserName, []byte("Testy McTest")),
2963 wantErr: assert.NoError,
2966 for _, tt := range tests {
2967 t.Run(tt.name, func(t *testing.T) {
2968 gotRes, err := HandleGetClientInfoText(tt.args.cc, tt.args.t)
2969 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetClientInfoText(%v, %v)", tt.args.cc, tt.args.t)) {
2972 tranAssertEqual(t, tt.wantRes, gotRes)
2977 func TestHandleTranAgreed(t *testing.T) {
2985 wantRes []Transaction
2986 wantErr assert.ErrorAssertionFunc
2989 name: "normal request flow",
2993 Access: func() accessBitmap {
2994 var bits accessBitmap
2995 bits.Set(accessDisconUser)
2996 bits.Set(accessAnyName)
3000 Flags: []byte{0, 1},
3001 Version: []byte{0, 1},
3003 logger: NewTestLogger(),
3006 BannerFile: "banner.jpg",
3012 NewField(fieldUserName, []byte("username")),
3013 NewField(fieldUserIconID, []byte{0, 1}),
3014 NewField(fieldOptions, []byte{0, 0}),
3017 wantRes: []Transaction{
3019 clientID: &[]byte{0, 1},
3022 Type: []byte{0, 0x7a},
3023 ID: []byte{0, 0, 0, 0},
3024 ErrorCode: []byte{0, 0, 0, 0},
3026 NewField(fieldBannerType, []byte("JPEG")),
3030 clientID: &[]byte{0, 1},
3033 Type: []byte{0, 0x79},
3034 ID: []byte{0, 0, 0, 0},
3035 ErrorCode: []byte{0, 0, 0, 0},
3039 wantErr: assert.NoError,
3042 for _, tt := range tests {
3043 t.Run(tt.name, func(t *testing.T) {
3044 gotRes, err := HandleTranAgreed(tt.args.cc, tt.args.t)
3045 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranAgreed(%v, %v)", tt.args.cc, tt.args.t)) {
3048 tranAssertEqual(t, tt.wantRes, gotRes)
3053 func TestHandleSetClientUserInfo(t *testing.T) {
3061 wantRes []Transaction
3062 wantErr assert.ErrorAssertionFunc
3065 name: "when client does not have accessAnyName",
3069 Access: func() accessBitmap {
3070 var bits accessBitmap
3075 UserName: []byte("Guest"),
3076 Flags: []byte{0, 1},
3078 Clients: map[uint16]*ClientConn{
3086 tranSetClientUserInfo, nil,
3087 NewField(fieldUserIconID, []byte{0, 1}),
3088 NewField(fieldUserName, []byte("NOPE")),
3091 wantRes: []Transaction{
3093 clientID: &[]byte{0, 1},
3096 Type: []byte{0x01, 0x2d},
3097 ID: []byte{0, 0, 0, 0},
3098 ErrorCode: []byte{0, 0, 0, 0},
3100 NewField(fieldUserID, []byte{0, 1}),
3101 NewField(fieldUserIconID, []byte{0, 1}),
3102 NewField(fieldUserFlags, []byte{0, 1}),
3103 NewField(fieldUserName, []byte("Guest"))},
3106 wantErr: assert.NoError,
3109 for _, tt := range tests {
3110 t.Run(tt.name, func(t *testing.T) {
3111 gotRes, err := HandleSetClientUserInfo(tt.args.cc, tt.args.t)
3112 if !tt.wantErr(t, err, fmt.Sprintf("HandleSetClientUserInfo(%v, %v)", tt.args.cc, tt.args.t)) {
3116 tranAssertEqual(t, tt.wantRes, gotRes)
3121 func TestHandleDelNewsItem(t *testing.T) {
3129 wantRes []Transaction
3130 wantErr assert.ErrorAssertionFunc
3133 name: "when user does not have permission to delete a news category",
3137 Access: accessBitmap{},
3141 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3152 tranDelNewsItem, nil,
3153 NewField(fieldNewsPath,
3158 0x74, 0x65, 0x73, 0x74,
3163 wantRes: []Transaction{
3165 clientID: &[]byte{0, 1},
3168 Type: []byte{0, 0x00},
3169 ID: []byte{0, 0, 0, 0},
3170 ErrorCode: []byte{0, 0, 0, 1},
3172 NewField(fieldError, []byte("You are not allowed to delete news categories.")),
3176 wantErr: assert.NoError,
3179 name: "when user does not have permission to delete a news folder",
3183 Access: accessBitmap{},
3187 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3198 tranDelNewsItem, nil,
3199 NewField(fieldNewsPath,
3204 0x74, 0x65, 0x73, 0x74,
3209 wantRes: []Transaction{
3211 clientID: &[]byte{0, 1},
3214 Type: []byte{0, 0x00},
3215 ID: []byte{0, 0, 0, 0},
3216 ErrorCode: []byte{0, 0, 0, 1},
3218 NewField(fieldError, []byte("You are not allowed to delete news folders.")),
3222 wantErr: assert.NoError,
3225 name: "when user deletes a news folder",
3229 Access: func() accessBitmap {
3230 var bits accessBitmap
3231 bits.Set(accessNewsDeleteFldr)
3237 ConfigDir: "/fakeConfigRoot",
3238 FS: func() *MockFileStore {
3239 mfs := &MockFileStore{}
3240 mfs.On("WriteFile", "/fakeConfigRoot/ThreadedNews.yaml", mock.Anything, mock.Anything).Return(nil, os.ErrNotExist)
3243 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3254 tranDelNewsItem, nil,
3255 NewField(fieldNewsPath,
3260 0x74, 0x65, 0x73, 0x74,
3265 wantRes: []Transaction{
3267 clientID: &[]byte{0, 1},
3270 Type: []byte{0x01, 0x7c},
3271 ID: []byte{0, 0, 0, 0},
3272 ErrorCode: []byte{0, 0, 0, 0},
3276 wantErr: assert.NoError,
3279 for _, tt := range tests {
3280 t.Run(tt.name, func(t *testing.T) {
3281 gotRes, err := HandleDelNewsItem(tt.args.cc, tt.args.t)
3282 if !tt.wantErr(t, err, fmt.Sprintf("HandleDelNewsItem(%v, %v)", tt.args.cc, tt.args.t)) {
3285 tranAssertEqual(t, tt.wantRes, gotRes)
3290 func TestHandleDownloadBanner(t *testing.T) {
3298 wantRes []Transaction
3299 wantErr assert.ErrorAssertionFunc
3302 name: "returns expected response",
3306 transfers: map[int]map[[4]byte]*FileTransfer{
3310 ConfigDir: "/config",
3312 BannerFile: "banner.jpg",
3314 fileTransfers: map[[4]byte]*FileTransfer{},
3315 FS: func() *MockFileStore {
3316 mfi := &MockFileInfo{}
3317 mfi.On("Size").Return(int64(100))
3319 mfs := &MockFileStore{}
3320 mfs.On("Stat", "/config/banner.jpg").Return(mfi, nil)
3325 t: NewTransaction(tranDownloadBanner, nil),
3327 wantRes: []Transaction{
3329 clientID: &[]byte{0, 1},
3332 Type: []byte{0x00, 0xd4},
3333 ID: []byte{0, 0, 0, 0},
3334 ErrorCode: []byte{0, 0, 0, 0},
3336 NewField(fieldRefNum, []byte{1, 2, 3, 4}),
3337 NewField(fieldTransferSize, []byte{0, 0, 0, 0x64}),
3341 wantErr: assert.NoError,
3344 for _, tt := range tests {
3345 t.Run(tt.name, func(t *testing.T) {
3346 gotRes, err := HandleDownloadBanner(tt.args.cc, tt.args.t)
3347 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadBanner(%v, %v)", tt.args.cc, tt.args.t)) {
3351 tranAssertEqual(t, tt.wantRes, gotRes)
3356 func TestHandleTranOldPostNews(t *testing.T) {
3364 wantRes []Transaction
3365 wantErr assert.ErrorAssertionFunc
3368 name: "when user does not have required permission",
3372 Access: func() accessBitmap {
3373 var bits accessBitmap
3379 tranOldPostNews, &[]byte{0, 1},
3380 NewField(fieldData, []byte("hai")),
3383 wantRes: []Transaction{
3387 Type: []byte{0, 0x00},
3388 ID: []byte{0, 0, 0, 0},
3389 ErrorCode: []byte{0, 0, 0, 1},
3391 NewField(fieldError, []byte("You are not allowed to post news.")),
3395 wantErr: assert.NoError,
3398 name: "when user posts news update",
3402 Access: func() accessBitmap {
3403 var bits accessBitmap
3404 bits.Set(accessNewsPostArt)
3409 FS: func() *MockFileStore {
3410 mfs := &MockFileStore{}
3411 mfs.On("WriteFile", "/fakeConfigRoot/MessageBoard.txt", mock.Anything, mock.Anything).Return(nil, os.ErrNotExist)
3414 ConfigDir: "/fakeConfigRoot",
3419 tranOldPostNews, &[]byte{0, 1},
3420 NewField(fieldData, []byte("hai")),
3423 wantRes: []Transaction{
3427 Type: []byte{0, 0x67},
3428 ID: []byte{0, 0, 0, 0},
3429 ErrorCode: []byte{0, 0, 0, 0},
3432 wantErr: assert.NoError,
3435 for _, tt := range tests {
3436 t.Run(tt.name, func(t *testing.T) {
3437 gotRes, err := HandleTranOldPostNews(tt.args.cc, tt.args.t)
3438 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranOldPostNews(%v, %v)", tt.args.cc, tt.args.t)) {
3442 tranAssertEqual(t, tt.wantRes, gotRes)
3447 func TestHandleInviteNewChat(t *testing.T) {
3455 wantRes []Transaction
3456 wantErr assert.ErrorAssertionFunc
3459 name: "when user does not have required permission",
3463 Access: func() accessBitmap {
3464 var bits accessBitmap
3469 t: NewTransaction(tranInviteNewChat, &[]byte{0, 1}),
3471 wantRes: []Transaction{
3475 Type: []byte{0, 0x00},
3476 ID: []byte{0, 0, 0, 0},
3477 ErrorCode: []byte{0, 0, 0, 1},
3479 NewField(fieldError, []byte("You are not allowed to request private chat.")),
3483 wantErr: assert.NoError,
3486 name: "when userA invites userB to new private chat",
3491 Access: func() accessBitmap {
3492 var bits accessBitmap
3493 bits.Set(accessOpenChat)
3497 UserName: []byte("UserA"),
3499 Flags: []byte{0, 0},
3501 Clients: map[uint16]*ClientConn{
3504 UserName: []byte("UserB"),
3505 Flags: []byte{0, 0},
3508 PrivateChats: make(map[uint32]*PrivateChat),
3512 tranInviteNewChat, &[]byte{0, 1},
3513 NewField(fieldUserID, []byte{0, 2}),
3516 wantRes: []Transaction{
3518 clientID: &[]byte{0, 2},
3521 Type: []byte{0, 0x71},
3522 ID: []byte{0, 0, 0, 0},
3523 ErrorCode: []byte{0, 0, 0, 0},
3525 NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3526 NewField(fieldUserName, []byte("UserA")),
3527 NewField(fieldUserID, []byte{0, 1}),
3532 clientID: &[]byte{0, 1},
3535 Type: []byte{0, 0x70},
3536 ID: []byte{0, 0, 0, 0},
3537 ErrorCode: []byte{0, 0, 0, 0},
3539 NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3540 NewField(fieldUserName, []byte("UserA")),
3541 NewField(fieldUserID, []byte{0, 1}),
3542 NewField(fieldUserIconID, []byte{0, 1}),
3543 NewField(fieldUserFlags, []byte{0, 0}),
3547 wantErr: assert.NoError,
3550 name: "when userA invites userB to new private chat, but UserB has refuse private chat enabled",
3555 Access: func() accessBitmap {
3556 var bits accessBitmap
3557 bits.Set(accessOpenChat)
3561 UserName: []byte("UserA"),
3563 Flags: []byte{0, 0},
3565 Clients: map[uint16]*ClientConn{
3568 UserName: []byte("UserB"),
3569 Flags: []byte{255, 255},
3572 PrivateChats: make(map[uint32]*PrivateChat),
3576 tranInviteNewChat, &[]byte{0, 1},
3577 NewField(fieldUserID, []byte{0, 2}),
3580 wantRes: []Transaction{
3582 clientID: &[]byte{0, 1},
3585 Type: []byte{0, 0x68},
3586 ID: []byte{0, 0, 0, 0},
3587 ErrorCode: []byte{0, 0, 0, 0},
3589 NewField(fieldData, []byte("UserB does not accept private chats.")),
3590 NewField(fieldUserName, []byte("UserB")),
3591 NewField(fieldUserID, []byte{0, 2}),
3592 NewField(fieldOptions, []byte{0, 2}),
3596 clientID: &[]byte{0, 1},
3599 Type: []byte{0, 0x70},
3600 ID: []byte{0, 0, 0, 0},
3601 ErrorCode: []byte{0, 0, 0, 0},
3603 NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3604 NewField(fieldUserName, []byte("UserA")),
3605 NewField(fieldUserID, []byte{0, 1}),
3606 NewField(fieldUserIconID, []byte{0, 1}),
3607 NewField(fieldUserFlags, []byte{0, 0}),
3611 wantErr: assert.NoError,
3614 for _, tt := range tests {
3615 t.Run(tt.name, func(t *testing.T) {
3617 gotRes, err := HandleInviteNewChat(tt.args.cc, tt.args.t)
3618 if !tt.wantErr(t, err, fmt.Sprintf("HandleInviteNewChat(%v, %v)", tt.args.cc, tt.args.t)) {
3621 tranAssertEqual(t, tt.wantRes, gotRes)