6 "github.com/stretchr/testify/assert"
16 func TestHandleSetChatSubject(t *testing.T) {
28 name: "sends chat subject to private chat members",
31 UserName: []byte{0x00, 0x01},
33 PrivateChats: map[uint32]*PrivateChat{
36 ClientConn: map[uint16]*ClientConn{
39 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
45 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
52 Clients: map[uint16]*ClientConn{
55 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
61 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
71 Type: []byte{0, 0x6a},
72 ID: []byte{0, 0, 0, 1},
73 ErrorCode: []byte{0, 0, 0, 0},
75 NewField(fieldChatID, []byte{0, 0, 0, 1}),
76 NewField(fieldChatSubject, []byte("Test Subject")),
82 clientID: &[]byte{0, 1},
85 Type: []byte{0, 0x77},
86 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
87 ErrorCode: []byte{0, 0, 0, 0},
89 NewField(fieldChatID, []byte{0, 0, 0, 1}),
90 NewField(fieldChatSubject, []byte("Test Subject")),
94 clientID: &[]byte{0, 2},
97 Type: []byte{0, 0x77},
98 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
99 ErrorCode: []byte{0, 0, 0, 0},
101 NewField(fieldChatID, []byte{0, 0, 0, 1}),
102 NewField(fieldChatSubject, []byte("Test Subject")),
109 for _, tt := range tests {
110 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
112 t.Run(tt.name, func(t *testing.T) {
113 got, err := HandleSetChatSubject(tt.args.cc, tt.args.t)
114 if (err != nil) != tt.wantErr {
115 t.Errorf("HandleSetChatSubject() error = %v, wantErr %v", err, tt.wantErr)
118 if !assert.Equal(t, tt.want, got) {
119 t.Errorf("HandleSetChatSubject() got = %v, want %v", got, tt.want)
125 func TestHandleLeaveChat(t *testing.T) {
137 name: "returns expected transactions",
142 PrivateChats: map[uint32]*PrivateChat{
144 ClientConn: map[uint16]*ClientConn{
147 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
153 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
160 Clients: map[uint16]*ClientConn{
163 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
169 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
176 t: NewTransaction(tranDeleteUser, nil, NewField(fieldChatID, []byte{0, 0, 0, 1})),
180 clientID: &[]byte{0, 1},
183 Type: []byte{0, 0x76},
184 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
185 ErrorCode: []byte{0, 0, 0, 0},
187 NewField(fieldChatID, []byte{0, 0, 0, 1}),
188 NewField(fieldUserID, []byte{0, 2}),
195 for _, tt := range tests {
197 t.Run(tt.name, func(t *testing.T) {
198 got, err := HandleLeaveChat(tt.args.cc, tt.args.t)
199 if (err != nil) != tt.wantErr {
200 t.Errorf("HandleLeaveChat() error = %v, wantErr %v", err, tt.wantErr)
203 if !assert.Equal(t, tt.want, got) {
204 t.Errorf("HandleLeaveChat() got = %v, want %v", got, tt.want)
210 func TestHandleGetUserNameList(t *testing.T) {
222 name: "replies with userlist transaction",
228 Clients: map[uint16]*ClientConn{
232 Flags: &[]byte{0, 3},
233 UserName: []byte{0, 4},
239 Flags: &[]byte{0, 3},
240 UserName: []byte{0, 4},
246 Flags: &[]byte{0, 3},
247 UserName: []byte{0, 4},
254 ID: []byte{0, 0, 0, 1},
260 clientID: &[]byte{1, 1},
264 ID: []byte{0, 0, 0, 1},
265 ErrorCode: []byte{0, 0, 0, 0},
268 fieldUsernameWithInfo,
269 []byte{00, 01, 00, 02, 00, 03, 00, 02, 00, 04},
272 fieldUsernameWithInfo,
273 []byte{00, 02, 00, 02, 00, 03, 00, 02, 00, 04},
281 for _, tt := range tests {
282 t.Run(tt.name, func(t *testing.T) {
283 got, err := HandleGetUserNameList(tt.args.cc, tt.args.t)
284 if (err != nil) != tt.wantErr {
285 t.Errorf("HandleGetUserNameList() error = %v, wantErr %v", err, tt.wantErr)
288 assert.Equal(t, tt.want, got)
293 func TestHandleChatSend(t *testing.T) {
305 name: "sends chat msg transaction to all clients",
309 Access: func() *[]byte {
310 var bits accessBitmap
311 bits.Set(accessSendChat)
316 UserName: []byte{0x00, 0x01},
318 Clients: map[uint16]*ClientConn{
321 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
327 Access: &[]byte{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: "when user does not have required permission",
371 Access: func() *[]byte {
372 var bits accessBitmap
378 Accounts: map[string]*Account{},
382 tranChatSend, &[]byte{0, 1},
383 NewField(fieldData, []byte("hai")),
390 Type: []byte{0, 0x00},
391 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
392 ErrorCode: []byte{0, 0, 0, 1},
394 NewField(fieldError, []byte("You are not allowed to participate in chat.")),
401 name: "sends chat msg as emote if fieldChatOptions is set",
405 Access: func() *[]byte {
406 var bits accessBitmap
407 bits.Set(accessSendChat)
412 UserName: []byte("Testy McTest"),
414 Clients: map[uint16]*ClientConn{
417 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
423 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
432 NewField(fieldData, []byte("performed action")),
433 NewField(fieldChatOptions, []byte{0x00, 0x01}),
439 clientID: &[]byte{0, 1},
442 Type: []byte{0, 0x6a},
443 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
444 ErrorCode: []byte{0, 0, 0, 0},
446 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
450 clientID: &[]byte{0, 2},
453 Type: []byte{0, 0x6a},
454 ID: []byte{0xf0, 0xc5, 0x34, 0x1e},
455 ErrorCode: []byte{0, 0, 0, 0},
457 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
464 name: "only sends chat msg to clients with accessReadChat permission",
468 Access: func() *[]byte {
469 var bits accessBitmap
470 bits.Set(accessSendChat)
475 UserName: []byte{0x00, 0x01},
477 Clients: map[uint16]*ClientConn{
480 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
486 Access: &[]byte{0, 0, 0, 0, 0, 0, 0, 0},
495 NewField(fieldData, []byte("hai")),
501 clientID: &[]byte{0, 1},
504 Type: []byte{0, 0x6a},
505 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
506 ErrorCode: []byte{0, 0, 0, 0},
508 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
515 name: "only sends private chat msg to members of private chat",
519 Access: func() *[]byte {
520 var bits accessBitmap
521 bits.Set(accessSendChat)
526 UserName: []byte{0x00, 0x01},
528 PrivateChats: map[uint32]*PrivateChat{
530 ClientConn: map[uint16]*ClientConn{
540 Clients: map[uint16]*ClientConn{
543 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
549 Access: &[]byte{0, 0, 0, 0, 0, 0, 0, 0},
555 Access: &[]byte{0, 0, 0, 0, 0, 0, 0, 0},
564 NewField(fieldData, []byte("hai")),
565 NewField(fieldChatID, []byte{0, 0, 0, 1}),
571 clientID: &[]byte{0, 1},
574 Type: []byte{0, 0x6a},
575 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
576 ErrorCode: []byte{0, 0, 0, 0},
578 NewField(fieldChatID, []byte{0, 0, 0, 1}),
579 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
583 clientID: &[]byte{0, 2},
586 Type: []byte{0, 0x6a},
587 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
588 ErrorCode: []byte{0, 0, 0, 0},
590 NewField(fieldChatID, []byte{0, 0, 0, 1}),
591 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
598 for _, tt := range tests {
599 t.Run(tt.name, func(t *testing.T) {
600 got, err := HandleChatSend(tt.args.cc, tt.args.t)
602 if (err != nil) != tt.wantErr {
603 t.Errorf("HandleChatSend() error = %v, wantErr %v", err, tt.wantErr)
606 tranAssertEqual(t, tt.want, got)
611 func TestHandleGetFileInfo(t *testing.T) {
612 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
621 wantRes []Transaction
625 name: "returns expected fields when a valid file is requested",
628 ID: &[]byte{0x00, 0x01},
632 FileRoot: func() string {
633 path, _ := os.Getwd()
634 return filepath.Join(path, "/test/config/Files")
640 tranGetFileInfo, nil,
641 NewField(fieldFileName, []byte("testfile.txt")),
642 NewField(fieldFilePath, []byte{0x00, 0x00}),
645 wantRes: []Transaction{
647 clientID: &[]byte{0, 1},
650 Type: []byte{0, 0xce},
651 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
652 ErrorCode: []byte{0, 0, 0, 0},
654 NewField(fieldFileName, []byte("testfile.txt")),
655 NewField(fieldFileTypeString, []byte("Text File")),
656 NewField(fieldFileCreatorString, []byte("ttxt")),
657 NewField(fieldFileComment, []byte{}),
658 NewField(fieldFileType, []byte("TEXT")),
659 NewField(fieldFileCreateDate, make([]byte, 8)),
660 NewField(fieldFileModifyDate, make([]byte, 8)),
661 NewField(fieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}),
668 for _, tt := range tests {
669 t.Run(tt.name, func(t *testing.T) {
670 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
672 gotRes, err := HandleGetFileInfo(tt.args.cc, tt.args.t)
673 if (err != nil) != tt.wantErr {
674 t.Errorf("HandleGetFileInfo() error = %v, wantErr %v", err, tt.wantErr)
678 // Clear the fileWrapper timestamp fields to work around problems running the tests in multiple timezones
679 // TODO: revisit how to test this by mocking the stat calls
680 gotRes[0].Fields[5].Data = make([]byte, 8)
681 gotRes[0].Fields[6].Data = make([]byte, 8)
682 if !assert.Equal(t, tt.wantRes, gotRes) {
683 t.Errorf("HandleGetFileInfo() gotRes = %v, want %v", gotRes, tt.wantRes)
689 func TestHandleNewFolder(t *testing.T) {
697 wantRes []Transaction
701 name: "without required permission",
705 Access: func() *[]byte {
706 var bits accessBitmap
717 wantRes: []Transaction{
721 Type: []byte{0, 0x00},
722 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
723 ErrorCode: []byte{0, 0, 0, 1},
725 NewField(fieldError, []byte("You are not allowed to create folders.")),
732 name: "when path is nested",
736 Access: func() *[]byte {
737 var bits accessBitmap
738 bits.Set(accessCreateFolder)
748 FS: func() *MockFileStore {
749 mfs := &MockFileStore{}
750 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
751 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
757 tranNewFolder, &[]byte{0, 1},
758 NewField(fieldFileName, []byte("testFolder")),
759 NewField(fieldFilePath, []byte{
767 wantRes: []Transaction{
769 clientID: &[]byte{0, 1},
772 Type: []byte{0, 0xcd},
773 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
774 ErrorCode: []byte{0, 0, 0, 0},
780 name: "when path is not nested",
784 Access: func() *[]byte {
785 var bits accessBitmap
786 bits.Set(accessCreateFolder)
796 FS: func() *MockFileStore {
797 mfs := &MockFileStore{}
798 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
799 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
805 tranNewFolder, &[]byte{0, 1},
806 NewField(fieldFileName, []byte("testFolder")),
809 wantRes: []Transaction{
811 clientID: &[]byte{0, 1},
814 Type: []byte{0, 0xcd},
815 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
816 ErrorCode: []byte{0, 0, 0, 0},
822 name: "when UnmarshalBinary returns an err",
826 Access: func() *[]byte {
827 var bits accessBitmap
828 bits.Set(accessCreateFolder)
838 FS: func() *MockFileStore {
839 mfs := &MockFileStore{}
840 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
841 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
847 tranNewFolder, &[]byte{0, 1},
848 NewField(fieldFileName, []byte("testFolder")),
849 NewField(fieldFilePath, []byte{
854 wantRes: []Transaction{},
858 name: "fieldFileName does not allow directory traversal",
862 Access: func() *[]byte {
863 var bits accessBitmap
864 bits.Set(accessCreateFolder)
874 FS: func() *MockFileStore {
875 mfs := &MockFileStore{}
876 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
877 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
883 tranNewFolder, &[]byte{0, 1},
884 NewField(fieldFileName, []byte("../../testFolder")),
887 wantRes: []Transaction{
889 clientID: &[]byte{0, 1},
892 Type: []byte{0, 0xcd},
893 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
894 ErrorCode: []byte{0, 0, 0, 0},
899 name: "fieldFilePath does not allow directory traversal",
903 Access: func() *[]byte {
904 var bits accessBitmap
905 bits.Set(accessCreateFolder)
915 FS: func() *MockFileStore {
916 mfs := &MockFileStore{}
917 mfs.On("Mkdir", "/Files/foo/testFolder", fs.FileMode(0777)).Return(nil)
918 mfs.On("Stat", "/Files/foo/testFolder").Return(nil, os.ErrNotExist)
924 tranNewFolder, &[]byte{0, 1},
925 NewField(fieldFileName, []byte("testFolder")),
926 NewField(fieldFilePath, []byte{
937 wantRes: []Transaction{
939 clientID: &[]byte{0, 1},
942 Type: []byte{0, 0xcd},
943 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
944 ErrorCode: []byte{0, 0, 0, 0},
949 for _, tt := range tests {
950 t.Run(tt.name, func(t *testing.T) {
952 gotRes, err := HandleNewFolder(tt.args.cc, tt.args.t)
953 if (err != nil) != tt.wantErr {
954 t.Errorf("HandleNewFolder() error = %v, wantErr %v", err, tt.wantErr)
958 if !tranAssertEqual(t, tt.wantRes, gotRes) {
959 t.Errorf("HandleNewFolder() gotRes = %v, want %v", gotRes, tt.wantRes)
965 func TestHandleUploadFile(t *testing.T) {
973 wantRes []Transaction
977 name: "when request is valid and user has Upload Anywhere permission",
982 fileTransfers: map[[4]byte]*FileTransfer{},
984 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
986 transfers: map[int]map[[4]byte]*FileTransfer{
990 Access: func() *[]byte {
991 var bits accessBitmap
992 bits.Set(accessUploadFile)
993 bits.Set(accessUploadAnywhere)
1000 tranUploadFile, &[]byte{0, 1},
1001 NewField(fieldFileName, []byte("testFile")),
1002 NewField(fieldFilePath, []byte{
1010 wantRes: []Transaction{
1014 Type: []byte{0, 0xcb},
1015 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1016 ErrorCode: []byte{0, 0, 0, 0},
1018 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), // rand.Seed(1)
1025 name: "when user does not have required access",
1029 Access: func() *[]byte {
1030 var bits accessBitmap
1037 tranUploadFile, &[]byte{0, 1},
1038 NewField(fieldFileName, []byte("testFile")),
1039 NewField(fieldFilePath, []byte{
1047 wantRes: []Transaction{
1051 Type: []byte{0, 0x00},
1052 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1053 ErrorCode: []byte{0, 0, 0, 1},
1055 NewField(fieldError, []byte("You are not allowed to upload files.")), // rand.Seed(1)
1062 for _, tt := range tests {
1063 t.Run(tt.name, func(t *testing.T) {
1065 gotRes, err := HandleUploadFile(tt.args.cc, tt.args.t)
1066 if (err != nil) != tt.wantErr {
1067 t.Errorf("HandleUploadFile() error = %v, wantErr %v", err, tt.wantErr)
1071 tranAssertEqual(t, tt.wantRes, gotRes)
1077 func TestHandleMakeAlias(t *testing.T) {
1085 wantRes []Transaction
1089 name: "with valid input and required permissions",
1092 logger: NewTestLogger(),
1094 Access: func() *[]byte {
1095 var bits accessBitmap
1096 bits.Set(accessMakeAlias)
1103 FileRoot: func() string {
1104 path, _ := os.Getwd()
1105 return path + "/test/config/Files"
1108 Logger: NewTestLogger(),
1109 FS: func() *MockFileStore {
1110 mfs := &MockFileStore{}
1111 path, _ := os.Getwd()
1114 path+"/test/config/Files/foo/testFile",
1115 path+"/test/config/Files/bar/testFile",
1122 tranMakeFileAlias, &[]byte{0, 1},
1123 NewField(fieldFileName, []byte("testFile")),
1124 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1125 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1128 wantRes: []Transaction{
1132 Type: []byte{0, 0xd1},
1133 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1134 ErrorCode: []byte{0, 0, 0, 0},
1135 Fields: []Field(nil),
1141 name: "when symlink returns an error",
1144 logger: NewTestLogger(),
1146 Access: func() *[]byte {
1147 var bits accessBitmap
1148 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",
1168 ).Return(errors.New("ohno"))
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, 0x00},
1185 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1186 ErrorCode: []byte{0, 0, 0, 1},
1188 NewField(fieldError, []byte("Error creating alias")),
1195 name: "when user does not have required permission",
1198 logger: NewTestLogger(),
1200 Access: func() *[]byte {
1201 var bits accessBitmap
1208 FileRoot: func() string {
1209 path, _ := os.Getwd()
1210 return path + "/test/config/Files"
1216 tranMakeFileAlias, &[]byte{0, 1},
1217 NewField(fieldFileName, []byte("testFile")),
1218 NewField(fieldFilePath, []byte{
1224 NewField(fieldFileNewPath, []byte{
1232 wantRes: []Transaction{
1236 Type: []byte{0, 0x00},
1237 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1238 ErrorCode: []byte{0, 0, 0, 1},
1240 NewField(fieldError, []byte("You are not allowed to make aliases.")),
1247 for _, tt := range tests {
1248 t.Run(tt.name, func(t *testing.T) {
1249 gotRes, err := HandleMakeAlias(tt.args.cc, tt.args.t)
1250 if (err != nil) != tt.wantErr {
1251 t.Errorf("HandleMakeAlias(%v, %v)", tt.args.cc, tt.args.t)
1255 tranAssertEqual(t, tt.wantRes, gotRes)
1260 func TestHandleGetUser(t *testing.T) {
1268 wantRes []Transaction
1269 wantErr assert.ErrorAssertionFunc
1272 name: "when account is valid",
1276 Access: func() *[]byte {
1277 var bits accessBitmap
1278 bits.Set(accessOpenUser)
1284 Accounts: map[string]*Account{
1288 Password: "password",
1295 tranGetUser, &[]byte{0, 1},
1296 NewField(fieldUserLogin, []byte("guest")),
1299 wantRes: []Transaction{
1303 Type: []byte{0x01, 0x60},
1304 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1305 ErrorCode: []byte{0, 0, 0, 0},
1307 NewField(fieldUserName, []byte("Guest")),
1308 NewField(fieldUserLogin, negateString([]byte("guest"))),
1309 NewField(fieldUserPassword, []byte("password")),
1310 NewField(fieldUserAccess, []byte{1}),
1314 wantErr: assert.NoError,
1317 name: "when user does not have required permission",
1321 Access: func() *[]byte {
1322 var bits accessBitmap
1328 Accounts: map[string]*Account{},
1332 tranGetUser, &[]byte{0, 1},
1333 NewField(fieldUserLogin, []byte("nonExistentUser")),
1336 wantRes: []Transaction{
1340 Type: []byte{0, 0x00},
1341 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1342 ErrorCode: []byte{0, 0, 0, 1},
1344 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1348 wantErr: assert.NoError,
1351 name: "when account does not exist",
1355 Access: func() *[]byte {
1356 var bits accessBitmap
1357 bits.Set(accessOpenUser)
1363 Accounts: map[string]*Account{},
1367 tranGetUser, &[]byte{0, 1},
1368 NewField(fieldUserLogin, []byte("nonExistentUser")),
1371 wantRes: []Transaction{
1375 Type: []byte{0, 0x00},
1376 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1377 ErrorCode: []byte{0, 0, 0, 1},
1379 NewField(fieldError, []byte("Account does not exist.")),
1383 wantErr: assert.NoError,
1386 for _, tt := range tests {
1387 t.Run(tt.name, func(t *testing.T) {
1388 gotRes, err := HandleGetUser(tt.args.cc, tt.args.t)
1389 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetUser(%v, %v)", tt.args.cc, tt.args.t)) {
1393 tranAssertEqual(t, tt.wantRes, gotRes)
1398 func TestHandleDeleteUser(t *testing.T) {
1406 wantRes []Transaction
1407 wantErr assert.ErrorAssertionFunc
1410 name: "when user dataFile",
1414 Access: func() *[]byte {
1415 var bits accessBitmap
1416 bits.Set(accessDeleteUser)
1422 Accounts: map[string]*Account{
1425 Name: "Testy McTest",
1426 Password: "password",
1430 FS: func() *MockFileStore {
1431 mfs := &MockFileStore{}
1432 mfs.On("Remove", "Users/testuser.yaml").Return(nil)
1438 tranDeleteUser, &[]byte{0, 1},
1439 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1442 wantRes: []Transaction{
1446 Type: []byte{0x1, 0x5f},
1447 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1448 ErrorCode: []byte{0, 0, 0, 0},
1449 Fields: []Field(nil),
1452 wantErr: assert.NoError,
1455 name: "when user does not have required permission",
1459 Access: func() *[]byte {
1460 var bits accessBitmap
1466 Accounts: map[string]*Account{},
1470 tranDeleteUser, &[]byte{0, 1},
1471 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1474 wantRes: []Transaction{
1478 Type: []byte{0, 0x00},
1479 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1480 ErrorCode: []byte{0, 0, 0, 1},
1482 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
1486 wantErr: assert.NoError,
1489 for _, tt := range tests {
1490 t.Run(tt.name, func(t *testing.T) {
1491 gotRes, err := HandleDeleteUser(tt.args.cc, tt.args.t)
1492 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteUser(%v, %v)", tt.args.cc, tt.args.t)) {
1496 tranAssertEqual(t, tt.wantRes, gotRes)
1501 func TestHandleGetMsgs(t *testing.T) {
1509 wantRes []Transaction
1510 wantErr assert.ErrorAssertionFunc
1513 name: "returns news data",
1517 Access: func() *[]byte {
1518 var bits accessBitmap
1519 bits.Set(accessNewsReadArt)
1525 FlatNews: []byte("TEST"),
1529 tranGetMsgs, &[]byte{0, 1},
1532 wantRes: []Transaction{
1536 Type: []byte{0, 0x65},
1537 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1538 ErrorCode: []byte{0, 0, 0, 0},
1540 NewField(fieldData, []byte("TEST")),
1544 wantErr: assert.NoError,
1547 name: "when user does not have required permission",
1551 Access: func() *[]byte {
1552 var bits accessBitmap
1558 Accounts: map[string]*Account{},
1562 tranGetMsgs, &[]byte{0, 1},
1565 wantRes: []Transaction{
1569 Type: []byte{0, 0x00},
1570 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1571 ErrorCode: []byte{0, 0, 0, 1},
1573 NewField(fieldError, []byte("You are not allowed to read news.")),
1577 wantErr: assert.NoError,
1580 for _, tt := range tests {
1581 t.Run(tt.name, func(t *testing.T) {
1582 gotRes, err := HandleGetMsgs(tt.args.cc, tt.args.t)
1583 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetMsgs(%v, %v)", tt.args.cc, tt.args.t)) {
1587 tranAssertEqual(t, tt.wantRes, gotRes)
1592 func TestHandleNewUser(t *testing.T) {
1600 wantRes []Transaction
1601 wantErr assert.ErrorAssertionFunc
1604 name: "when user does not have required permission",
1608 Access: func() *[]byte {
1609 var bits accessBitmap
1615 Accounts: map[string]*Account{},
1619 tranNewUser, &[]byte{0, 1},
1622 wantRes: []Transaction{
1626 Type: []byte{0, 0x00},
1627 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1628 ErrorCode: []byte{0, 0, 0, 1},
1630 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
1634 wantErr: assert.NoError,
1637 for _, tt := range tests {
1638 t.Run(tt.name, func(t *testing.T) {
1639 gotRes, err := HandleNewUser(tt.args.cc, tt.args.t)
1640 if !tt.wantErr(t, err, fmt.Sprintf("HandleNewUser(%v, %v)", tt.args.cc, tt.args.t)) {
1644 tranAssertEqual(t, tt.wantRes, gotRes)
1649 func TestHandleListUsers(t *testing.T) {
1657 wantRes []Transaction
1658 wantErr assert.ErrorAssertionFunc
1661 name: "when user does not have required permission",
1665 Access: func() *[]byte {
1666 var bits accessBitmap
1672 Accounts: map[string]*Account{},
1676 tranNewUser, &[]byte{0, 1},
1679 wantRes: []Transaction{
1683 Type: []byte{0, 0x00},
1684 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1685 ErrorCode: []byte{0, 0, 0, 1},
1687 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1691 wantErr: assert.NoError,
1694 name: "when user has required permission",
1698 Access: func() *[]byte {
1699 var bits accessBitmap
1700 bits.Set(accessOpenUser)
1706 Accounts: map[string]*Account{
1711 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
1717 tranGetClientInfoText, &[]byte{0, 1},
1718 NewField(fieldUserID, []byte{0, 1}),
1721 wantRes: []Transaction{
1725 Type: []byte{0x01, 0x2f},
1726 ID: []byte{0, 0, 0, 0},
1727 ErrorCode: []byte{0, 0, 0, 0},
1729 NewField(fieldData, []byte{
1730 0x00, 0x04, 0x00, 0x66, 0x00, 0x05, 0x67, 0x75, 0x65, 0x73, 0x74, 0x00, 0x69, 0x00, 0x05, 0x98,
1731 0x8a, 0x9a, 0x8c, 0x8b, 0x00, 0x6e, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1732 0x00, 0x6a, 0x00, 0x01, 0x78,
1737 wantErr: assert.NoError,
1740 for _, tt := range tests {
1741 t.Run(tt.name, func(t *testing.T) {
1742 gotRes, err := HandleListUsers(tt.args.cc, tt.args.t)
1743 if !tt.wantErr(t, err, fmt.Sprintf("HandleListUsers(%v, %v)", tt.args.cc, tt.args.t)) {
1747 tranAssertEqual(t, tt.wantRes, gotRes)
1752 func TestHandleDownloadFile(t *testing.T) {
1760 wantRes []Transaction
1761 wantErr assert.ErrorAssertionFunc
1764 name: "when user does not have required permission",
1768 Access: func() *[]byte {
1769 var bits accessBitmap
1776 t: NewTransaction(tranDownloadFile, &[]byte{0, 1}),
1778 wantRes: []Transaction{
1782 Type: []byte{0, 0x00},
1783 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1784 ErrorCode: []byte{0, 0, 0, 1},
1786 NewField(fieldError, []byte("You are not allowed to download files.")),
1790 wantErr: assert.NoError,
1793 name: "with a valid file",
1796 transfers: map[int]map[[4]byte]*FileTransfer{
1800 Access: func() *[]byte {
1801 var bits accessBitmap
1802 bits.Set(accessDownloadFile)
1809 fileTransfers: map[[4]byte]*FileTransfer{},
1811 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1813 Accounts: map[string]*Account{},
1819 NewField(fieldFileName, []byte("testfile.txt")),
1820 NewField(fieldFilePath, []byte{0x0, 0x00}),
1823 wantRes: []Transaction{
1827 Type: []byte{0, 0x2},
1828 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1829 ErrorCode: []byte{0, 0, 0, 0},
1831 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
1832 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
1833 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x00, 0xa5}),
1834 NewField(fieldFileSize, []byte{0x00, 0x00, 0x00, 0x17}),
1838 wantErr: assert.NoError,
1841 name: "when client requests to resume 1k test file at offset 256",
1844 transfers: map[int]map[[4]byte]*FileTransfer{
1846 }, Account: &Account{
1847 Access: func() *[]byte {
1848 var bits accessBitmap
1849 bits.Set(accessDownloadFile)
1857 // FS: func() *MockFileStore {
1858 // path, _ := os.Getwd()
1859 // testFile, err := os.Open(path + "/test/config/Files/testfile-1k")
1864 // mfi := &MockFileInfo{}
1865 // mfi.On("Mode").Return(fs.FileMode(0))
1866 // mfs := &MockFileStore{}
1867 // mfs.On("Stat", "/fakeRoot/Files/testfile.txt").Return(mfi, nil)
1868 // mfs.On("Open", "/fakeRoot/Files/testfile.txt").Return(testFile, nil)
1869 // mfs.On("Stat", "/fakeRoot/Files/.info_testfile.txt").Return(nil, errors.New("no"))
1870 // mfs.On("Stat", "/fakeRoot/Files/.rsrc_testfile.txt").Return(nil, errors.New("no"))
1874 fileTransfers: map[[4]byte]*FileTransfer{},
1876 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1878 Accounts: map[string]*Account{},
1884 NewField(fieldFileName, []byte("testfile-1k")),
1885 NewField(fieldFilePath, []byte{0x00, 0x00}),
1887 fieldFileResumeData,
1889 frd := FileResumeData{
1893 ForkCount: [2]byte{0, 2},
1894 ForkInfoList: []ForkInfoList{
1896 Fork: [4]byte{0x44, 0x41, 0x54, 0x41}, // "DATA"
1897 DataSize: [4]byte{0, 0, 0x01, 0x00}, // request offset 256
1902 Fork: [4]byte{0x4d, 0x41, 0x43, 0x52}, // "MACR"
1903 DataSize: [4]byte{0, 0, 0, 0},
1909 b, _ := frd.BinaryMarshal()
1915 wantRes: []Transaction{
1919 Type: []byte{0, 0x2},
1920 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1921 ErrorCode: []byte{0, 0, 0, 0},
1923 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
1924 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
1925 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x03, 0x8d}),
1926 NewField(fieldFileSize, []byte{0x00, 0x00, 0x03, 0x00}),
1930 wantErr: assert.NoError,
1933 for _, tt := range tests {
1934 t.Run(tt.name, func(t *testing.T) {
1935 gotRes, err := HandleDownloadFile(tt.args.cc, tt.args.t)
1936 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadFile(%v, %v)", tt.args.cc, tt.args.t)) {
1940 tranAssertEqual(t, tt.wantRes, gotRes)
1945 func TestHandleUpdateUser(t *testing.T) {
1953 wantRes []Transaction
1954 wantErr assert.ErrorAssertionFunc
1957 name: "when action is create user without required permission",
1960 logger: NewTestLogger(),
1962 Logger: NewTestLogger(),
1965 Access: func() *[]byte {
1966 var bits accessBitmap
1975 NewField(fieldData, []byte{
1976 0x00, 0x04, // field count
1978 0x00, 0x69, // fieldUserLogin = 105
1982 0x00, 0x6a, // fieldUserPassword = 106
1986 0x00, 0x66, // fieldUserName = 102
1990 0x00, 0x6e, // fieldUserAccess = 110
1992 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
1996 wantRes: []Transaction{
2000 Type: []byte{0, 0x00},
2001 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2002 ErrorCode: []byte{0, 0, 0, 1},
2004 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
2008 wantErr: assert.NoError,
2011 name: "when action is modify user without required permission",
2014 logger: NewTestLogger(),
2016 Logger: NewTestLogger(),
2017 Accounts: map[string]*Account{
2022 Access: func() *[]byte {
2023 var bits accessBitmap
2032 NewField(fieldData, []byte{
2033 0x00, 0x04, // field count
2035 0x00, 0x69, // fieldUserLogin = 105
2039 0x00, 0x6a, // fieldUserPassword = 106
2043 0x00, 0x66, // fieldUserName = 102
2047 0x00, 0x6e, // fieldUserAccess = 110
2049 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
2053 wantRes: []Transaction{
2057 Type: []byte{0, 0x00},
2058 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2059 ErrorCode: []byte{0, 0, 0, 1},
2061 NewField(fieldError, []byte("You are not allowed to modify accounts.")),
2065 wantErr: assert.NoError,
2068 name: "when action is delete user without required permission",
2071 logger: NewTestLogger(),
2073 Accounts: map[string]*Account{
2078 Access: func() *[]byte {
2079 var bits accessBitmap
2088 NewField(fieldData, []byte{
2096 wantRes: []Transaction{
2100 Type: []byte{0, 0x00},
2101 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2102 ErrorCode: []byte{0, 0, 0, 1},
2104 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
2108 wantErr: assert.NoError,
2111 for _, tt := range tests {
2112 t.Run(tt.name, func(t *testing.T) {
2113 gotRes, err := HandleUpdateUser(tt.args.cc, tt.args.t)
2114 if !tt.wantErr(t, err, fmt.Sprintf("HandleUpdateUser(%v, %v)", tt.args.cc, tt.args.t)) {
2118 tranAssertEqual(t, tt.wantRes, gotRes)
2123 func TestHandleDelNewsArt(t *testing.T) {
2131 wantRes []Transaction
2132 wantErr assert.ErrorAssertionFunc
2135 name: "without required permission",
2139 Access: func() *[]byte {
2140 var bits accessBitmap
2151 wantRes: []Transaction{
2155 Type: []byte{0, 0x00},
2156 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2157 ErrorCode: []byte{0, 0, 0, 1},
2159 NewField(fieldError, []byte("You are not allowed to delete news articles.")),
2163 wantErr: assert.NoError,
2166 for _, tt := range tests {
2167 t.Run(tt.name, func(t *testing.T) {
2168 gotRes, err := HandleDelNewsArt(tt.args.cc, tt.args.t)
2169 if !tt.wantErr(t, err, fmt.Sprintf("HandleDelNewsArt(%v, %v)", tt.args.cc, tt.args.t)) {
2172 tranAssertEqual(t, tt.wantRes, gotRes)
2177 func TestHandleDisconnectUser(t *testing.T) {
2185 wantRes []Transaction
2186 wantErr assert.ErrorAssertionFunc
2189 name: "without required permission",
2193 Access: func() *[]byte {
2194 var bits accessBitmap
2205 wantRes: []Transaction{
2209 Type: []byte{0, 0x00},
2210 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2211 ErrorCode: []byte{0, 0, 0, 1},
2213 NewField(fieldError, []byte("You are not allowed to disconnect users.")),
2217 wantErr: assert.NoError,
2220 name: "when target user has 'cannot be disconnected' priv",
2224 Clients: map[uint16]*ClientConn{
2228 Access: func() *[]byte {
2229 var bits accessBitmap
2230 bits.Set(accessCannotBeDiscon)
2239 Access: func() *[]byte {
2240 var bits accessBitmap
2241 bits.Set(accessDisconUser)
2250 NewField(fieldUserID, []byte{0, 1}),
2253 wantRes: []Transaction{
2257 Type: []byte{0, 0x00},
2258 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2259 ErrorCode: []byte{0, 0, 0, 1},
2261 NewField(fieldError, []byte("unnamed is not allowed to be disconnected.")),
2265 wantErr: assert.NoError,
2268 for _, tt := range tests {
2269 t.Run(tt.name, func(t *testing.T) {
2270 gotRes, err := HandleDisconnectUser(tt.args.cc, tt.args.t)
2271 if !tt.wantErr(t, err, fmt.Sprintf("HandleDisconnectUser(%v, %v)", tt.args.cc, tt.args.t)) {
2274 tranAssertEqual(t, tt.wantRes, gotRes)
2279 func TestHandleSendInstantMsg(t *testing.T) {
2287 wantRes []Transaction
2288 wantErr assert.ErrorAssertionFunc
2291 name: "when client 1 sends a message to client 2",
2295 UserName: []byte("User1"),
2297 Clients: map[uint16]*ClientConn{
2299 AutoReply: []byte(nil),
2307 NewField(fieldData, []byte("hai")),
2308 NewField(fieldUserID, []byte{0, 2}),
2311 wantRes: []Transaction{
2315 NewField(fieldData, []byte("hai")),
2316 NewField(fieldUserName, []byte("User1")),
2317 NewField(fieldUserID, []byte{0, 1}),
2318 NewField(fieldOptions, []byte{0, 1}),
2321 clientID: &[]byte{0, 1},
2324 Type: []byte{0x0, 0x6c},
2325 ID: []byte{0, 0, 0, 0},
2326 ErrorCode: []byte{0, 0, 0, 0},
2327 Fields: []Field(nil),
2330 wantErr: assert.NoError,
2333 name: "when client 2 has autoreply enabled",
2337 UserName: []byte("User1"),
2339 Clients: map[uint16]*ClientConn{
2342 UserName: []byte("User2"),
2343 AutoReply: []byte("autohai"),
2351 NewField(fieldData, []byte("hai")),
2352 NewField(fieldUserID, []byte{0, 2}),
2355 wantRes: []Transaction{
2359 NewField(fieldData, []byte("hai")),
2360 NewField(fieldUserName, []byte("User1")),
2361 NewField(fieldUserID, []byte{0, 1}),
2362 NewField(fieldOptions, []byte{0, 1}),
2367 NewField(fieldData, []byte("autohai")),
2368 NewField(fieldUserName, []byte("User2")),
2369 NewField(fieldUserID, []byte{0, 2}),
2370 NewField(fieldOptions, []byte{0, 1}),
2373 clientID: &[]byte{0, 1},
2376 Type: []byte{0x0, 0x6c},
2377 ID: []byte{0, 0, 0, 0},
2378 ErrorCode: []byte{0, 0, 0, 0},
2379 Fields: []Field(nil),
2382 wantErr: assert.NoError,
2385 for _, tt := range tests {
2386 t.Run(tt.name, func(t *testing.T) {
2387 gotRes, err := HandleSendInstantMsg(tt.args.cc, tt.args.t)
2388 if !tt.wantErr(t, err, fmt.Sprintf("HandleSendInstantMsg(%v, %v)", tt.args.cc, tt.args.t)) {
2392 tranAssertEqual(t, tt.wantRes, gotRes)
2397 func TestHandleDeleteFile(t *testing.T) {
2405 wantRes []Transaction
2406 wantErr assert.ErrorAssertionFunc
2409 name: "when user does not have required permission to delete a folder",
2413 Access: func() *[]byte {
2414 var bits accessBitmap
2421 FileRoot: func() string {
2422 return "/fakeRoot/Files"
2425 FS: func() *MockFileStore {
2426 mfi := &MockFileInfo{}
2427 mfi.On("Mode").Return(fs.FileMode(0))
2428 mfi.On("Size").Return(int64(100))
2429 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2430 mfi.On("IsDir").Return(false)
2431 mfi.On("Name").Return("testfile")
2433 mfs := &MockFileStore{}
2434 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2435 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2436 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2440 Accounts: map[string]*Account{},
2444 tranDeleteFile, &[]byte{0, 1},
2445 NewField(fieldFileName, []byte("testfile")),
2446 NewField(fieldFilePath, []byte{
2454 wantRes: []Transaction{
2458 Type: []byte{0, 0x00},
2459 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2460 ErrorCode: []byte{0, 0, 0, 1},
2462 NewField(fieldError, []byte("You are not allowed to delete files.")),
2466 wantErr: assert.NoError,
2469 name: "deletes all associated metadata files",
2473 Access: func() *[]byte {
2474 var bits accessBitmap
2475 bits.Set(accessDeleteFile)
2482 FileRoot: func() string {
2483 return "/fakeRoot/Files"
2486 FS: func() *MockFileStore {
2487 mfi := &MockFileInfo{}
2488 mfi.On("Mode").Return(fs.FileMode(0))
2489 mfi.On("Size").Return(int64(100))
2490 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2491 mfi.On("IsDir").Return(false)
2492 mfi.On("Name").Return("testfile")
2494 mfs := &MockFileStore{}
2495 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2496 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2497 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2499 mfs.On("RemoveAll", "/fakeRoot/Files/aaa/testfile").Return(nil)
2500 mfs.On("Remove", "/fakeRoot/Files/aaa/testfile.incomplete").Return(nil)
2501 mfs.On("Remove", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil)
2502 mfs.On("Remove", "/fakeRoot/Files/aaa/.info_testfile").Return(nil)
2506 Accounts: map[string]*Account{},
2510 tranDeleteFile, &[]byte{0, 1},
2511 NewField(fieldFileName, []byte("testfile")),
2512 NewField(fieldFilePath, []byte{
2520 wantRes: []Transaction{
2524 Type: []byte{0x0, 0xcc},
2525 ID: []byte{0x0, 0x0, 0x0, 0x0},
2526 ErrorCode: []byte{0, 0, 0, 0},
2527 Fields: []Field(nil),
2530 wantErr: assert.NoError,
2533 for _, tt := range tests {
2534 t.Run(tt.name, func(t *testing.T) {
2535 gotRes, err := HandleDeleteFile(tt.args.cc, tt.args.t)
2536 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteFile(%v, %v)", tt.args.cc, tt.args.t)) {
2540 tranAssertEqual(t, tt.wantRes, gotRes)
2542 tt.args.cc.Server.FS.(*MockFileStore).AssertExpectations(t)
2547 func TestHandleGetFileNameList(t *testing.T) {
2555 wantRes []Transaction
2556 wantErr assert.ErrorAssertionFunc
2559 name: "when fieldFilePath is a drop box, but user does not have accessViewDropBoxes ",
2563 Access: func() *[]byte {
2564 var bits accessBitmap
2572 FileRoot: func() string {
2573 path, _ := os.Getwd()
2574 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2580 tranGetFileNameList, &[]byte{0, 1},
2581 NewField(fieldFilePath, []byte{
2585 0x64, 0x72, 0x6f, 0x70, 0x20, 0x62, 0x6f, 0x78, // "drop box"
2589 wantRes: []Transaction{
2593 Type: []byte{0, 0x00},
2594 ID: []byte{0, 0, 0, 0},
2595 ErrorCode: []byte{0, 0, 0, 1},
2597 NewField(fieldError, []byte("You are not allowed to view drop boxes.")),
2601 wantErr: assert.NoError,
2604 name: "with file root",
2609 FileRoot: func() string {
2610 path, _ := os.Getwd()
2611 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2617 tranGetFileNameList, &[]byte{0, 1},
2618 NewField(fieldFilePath, []byte{
2624 wantRes: []Transaction{
2628 Type: []byte{0, 0xc8},
2629 ID: []byte{0, 0, 0, 0},
2630 ErrorCode: []byte{0, 0, 0, 0},
2633 fieldFileNameWithInfo,
2635 fnwi := FileNameWithInfo{
2636 fileNameWithInfoHeader: fileNameWithInfoHeader{
2637 Type: [4]byte{0x54, 0x45, 0x58, 0x54},
2638 Creator: [4]byte{0x54, 0x54, 0x58, 0x54},
2639 FileSize: [4]byte{0, 0, 0x04, 0},
2641 NameScript: [2]byte{},
2642 NameSize: [2]byte{0, 0x0b},
2644 name: []byte("testfile-1k"),
2646 b, _ := fnwi.MarshalBinary()
2653 wantErr: assert.NoError,
2656 for _, tt := range tests {
2657 t.Run(tt.name, func(t *testing.T) {
2658 gotRes, err := HandleGetFileNameList(tt.args.cc, tt.args.t)
2659 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetFileNameList(%v, %v)", tt.args.cc, tt.args.t)) {
2663 tranAssertEqual(t, tt.wantRes, gotRes)
2668 func TestHandleGetClientInfoText(t *testing.T) {
2676 wantRes []Transaction
2677 wantErr assert.ErrorAssertionFunc
2680 name: "when user does not have required permission",
2684 Access: func() *[]byte {
2685 var bits accessBitmap
2691 Accounts: map[string]*Account{},
2695 tranGetClientInfoText, &[]byte{0, 1},
2696 NewField(fieldUserID, []byte{0, 1}),
2699 wantRes: []Transaction{
2703 Type: []byte{0, 0x00},
2704 ID: []byte{0, 0, 0, 0},
2705 ErrorCode: []byte{0, 0, 0, 1},
2707 NewField(fieldError, []byte("You are not allowed to get client info.")),
2711 wantErr: assert.NoError,
2714 name: "with a valid user",
2717 UserName: []byte("Testy McTest"),
2718 RemoteAddr: "1.2.3.4:12345",
2720 Access: func() *[]byte {
2721 var bits accessBitmap
2722 bits.Set(accessGetClientInfo)
2730 Accounts: map[string]*Account{},
2731 Clients: map[uint16]*ClientConn{
2733 UserName: []byte("Testy McTest"),
2734 RemoteAddr: "1.2.3.4:12345",
2736 Access: func() *[]byte {
2737 var bits accessBitmap
2738 bits.Set(accessGetClientInfo)
2748 transfers: map[int]map[[4]byte]*FileTransfer{
2756 tranGetClientInfoText, &[]byte{0, 1},
2757 NewField(fieldUserID, []byte{0, 1}),
2760 wantRes: []Transaction{
2764 Type: []byte{0x1, 0x2f},
2765 ID: []byte{0, 0, 0, 0},
2766 ErrorCode: []byte{0, 0, 0, 0},
2768 NewField(fieldData, []byte(
2769 strings.Replace(`Nickname: Testy McTest
2772 Address: 1.2.3.4:12345
2774 -------- File Downloads ---------
2778 ------- Folder Downloads --------
2782 --------- File Uploads ----------
2786 -------- Folder Uploads ---------
2790 ------- Waiting Downloads -------
2794 `, "\n", "\r", -1)),
2796 NewField(fieldUserName, []byte("Testy McTest")),
2800 wantErr: assert.NoError,
2803 for _, tt := range tests {
2804 t.Run(tt.name, func(t *testing.T) {
2805 gotRes, err := HandleGetClientInfoText(tt.args.cc, tt.args.t)
2806 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetClientInfoText(%v, %v)", tt.args.cc, tt.args.t)) {
2809 tranAssertEqual(t, tt.wantRes, gotRes)
2814 func TestHandleTranAgreed(t *testing.T) {
2822 wantRes []Transaction
2823 wantErr assert.ErrorAssertionFunc
2826 name: "normal request flow",
2830 Access: func() *[]byte {
2831 var bits accessBitmap
2832 bits.Set(accessDisconUser)
2833 bits.Set(accessAnyName)
2837 Icon: &[]byte{0, 1},
2838 Flags: &[]byte{0, 1},
2839 Version: &[]byte{0, 1},
2841 logger: NewTestLogger(),
2844 BannerFile: "banner.jpg",
2850 NewField(fieldUserName, []byte("username")),
2851 NewField(fieldUserIconID, []byte{0, 1}),
2852 NewField(fieldOptions, []byte{0, 0}),
2855 wantRes: []Transaction{
2857 clientID: &[]byte{0, 1},
2860 Type: []byte{0, 0x7a},
2861 ID: []byte{0, 0, 0, 0},
2862 ErrorCode: []byte{0, 0, 0, 0},
2864 NewField(fieldBannerType, []byte("JPEG")),
2868 clientID: &[]byte{0, 1},
2871 Type: []byte{0, 0x79},
2872 ID: []byte{0, 0, 0, 0},
2873 ErrorCode: []byte{0, 0, 0, 0},
2877 wantErr: assert.NoError,
2880 for _, tt := range tests {
2881 t.Run(tt.name, func(t *testing.T) {
2882 gotRes, err := HandleTranAgreed(tt.args.cc, tt.args.t)
2883 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranAgreed(%v, %v)", tt.args.cc, tt.args.t)) {
2886 tranAssertEqual(t, tt.wantRes, gotRes)