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{
233 UserName: []byte{0, 4},
240 UserName: []byte{0, 4},
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: "without required permission",
2295 Access: func() *[]byte {
2296 var bits accessBitmap
2307 wantRes: []Transaction{
2311 Type: []byte{0, 0x00},
2312 ID: []byte{0, 0, 0, 0},
2313 ErrorCode: []byte{0, 0, 0, 1},
2315 NewField(fieldError, []byte("You are not allowed to send private messages.")),
2319 wantErr: assert.NoError,
2322 name: "when client 1 sends a message to client 2",
2326 Access: func() *[]byte {
2327 var bits accessBitmap
2328 bits.Set(accessSendPrivMsg)
2334 UserName: []byte("User1"),
2336 Clients: map[uint16]*ClientConn{
2338 AutoReply: []byte(nil),
2346 NewField(fieldData, []byte("hai")),
2347 NewField(fieldUserID, []byte{0, 2}),
2350 wantRes: []Transaction{
2354 NewField(fieldData, []byte("hai")),
2355 NewField(fieldUserName, []byte("User1")),
2356 NewField(fieldUserID, []byte{0, 1}),
2357 NewField(fieldOptions, []byte{0, 1}),
2360 clientID: &[]byte{0, 1},
2363 Type: []byte{0x0, 0x6c},
2364 ID: []byte{0, 0, 0, 0},
2365 ErrorCode: []byte{0, 0, 0, 0},
2366 Fields: []Field(nil),
2369 wantErr: assert.NoError,
2372 name: "when client 2 has autoreply enabled",
2376 Access: func() *[]byte {
2377 var bits accessBitmap
2378 bits.Set(accessSendPrivMsg)
2384 UserName: []byte("User1"),
2386 Clients: map[uint16]*ClientConn{
2389 UserName: []byte("User2"),
2390 AutoReply: []byte("autohai"),
2398 NewField(fieldData, []byte("hai")),
2399 NewField(fieldUserID, []byte{0, 2}),
2402 wantRes: []Transaction{
2406 NewField(fieldData, []byte("hai")),
2407 NewField(fieldUserName, []byte("User1")),
2408 NewField(fieldUserID, []byte{0, 1}),
2409 NewField(fieldOptions, []byte{0, 1}),
2414 NewField(fieldData, []byte("autohai")),
2415 NewField(fieldUserName, []byte("User2")),
2416 NewField(fieldUserID, []byte{0, 2}),
2417 NewField(fieldOptions, []byte{0, 1}),
2420 clientID: &[]byte{0, 1},
2423 Type: []byte{0x0, 0x6c},
2424 ID: []byte{0, 0, 0, 0},
2425 ErrorCode: []byte{0, 0, 0, 0},
2426 Fields: []Field(nil),
2429 wantErr: assert.NoError,
2432 for _, tt := range tests {
2433 t.Run(tt.name, func(t *testing.T) {
2434 gotRes, err := HandleSendInstantMsg(tt.args.cc, tt.args.t)
2435 if !tt.wantErr(t, err, fmt.Sprintf("HandleSendInstantMsg(%v, %v)", tt.args.cc, tt.args.t)) {
2439 tranAssertEqual(t, tt.wantRes, gotRes)
2444 func TestHandleDeleteFile(t *testing.T) {
2452 wantRes []Transaction
2453 wantErr assert.ErrorAssertionFunc
2456 name: "when user does not have required permission to delete a folder",
2460 Access: func() *[]byte {
2461 var bits accessBitmap
2468 FileRoot: func() string {
2469 return "/fakeRoot/Files"
2472 FS: func() *MockFileStore {
2473 mfi := &MockFileInfo{}
2474 mfi.On("Mode").Return(fs.FileMode(0))
2475 mfi.On("Size").Return(int64(100))
2476 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2477 mfi.On("IsDir").Return(false)
2478 mfi.On("Name").Return("testfile")
2480 mfs := &MockFileStore{}
2481 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2482 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2483 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2487 Accounts: map[string]*Account{},
2491 tranDeleteFile, &[]byte{0, 1},
2492 NewField(fieldFileName, []byte("testfile")),
2493 NewField(fieldFilePath, []byte{
2501 wantRes: []Transaction{
2505 Type: []byte{0, 0x00},
2506 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2507 ErrorCode: []byte{0, 0, 0, 1},
2509 NewField(fieldError, []byte("You are not allowed to delete files.")),
2513 wantErr: assert.NoError,
2516 name: "deletes all associated metadata files",
2520 Access: func() *[]byte {
2521 var bits accessBitmap
2522 bits.Set(accessDeleteFile)
2529 FileRoot: func() string {
2530 return "/fakeRoot/Files"
2533 FS: func() *MockFileStore {
2534 mfi := &MockFileInfo{}
2535 mfi.On("Mode").Return(fs.FileMode(0))
2536 mfi.On("Size").Return(int64(100))
2537 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2538 mfi.On("IsDir").Return(false)
2539 mfi.On("Name").Return("testfile")
2541 mfs := &MockFileStore{}
2542 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2543 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2544 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2546 mfs.On("RemoveAll", "/fakeRoot/Files/aaa/testfile").Return(nil)
2547 mfs.On("Remove", "/fakeRoot/Files/aaa/testfile.incomplete").Return(nil)
2548 mfs.On("Remove", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil)
2549 mfs.On("Remove", "/fakeRoot/Files/aaa/.info_testfile").Return(nil)
2553 Accounts: map[string]*Account{},
2557 tranDeleteFile, &[]byte{0, 1},
2558 NewField(fieldFileName, []byte("testfile")),
2559 NewField(fieldFilePath, []byte{
2567 wantRes: []Transaction{
2571 Type: []byte{0x0, 0xcc},
2572 ID: []byte{0x0, 0x0, 0x0, 0x0},
2573 ErrorCode: []byte{0, 0, 0, 0},
2574 Fields: []Field(nil),
2577 wantErr: assert.NoError,
2580 for _, tt := range tests {
2581 t.Run(tt.name, func(t *testing.T) {
2582 gotRes, err := HandleDeleteFile(tt.args.cc, tt.args.t)
2583 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteFile(%v, %v)", tt.args.cc, tt.args.t)) {
2587 tranAssertEqual(t, tt.wantRes, gotRes)
2589 tt.args.cc.Server.FS.(*MockFileStore).AssertExpectations(t)
2594 func TestHandleGetFileNameList(t *testing.T) {
2602 wantRes []Transaction
2603 wantErr assert.ErrorAssertionFunc
2606 name: "when fieldFilePath is a drop box, but user does not have accessViewDropBoxes ",
2610 Access: func() *[]byte {
2611 var bits accessBitmap
2619 FileRoot: func() string {
2620 path, _ := os.Getwd()
2621 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2627 tranGetFileNameList, &[]byte{0, 1},
2628 NewField(fieldFilePath, []byte{
2632 0x64, 0x72, 0x6f, 0x70, 0x20, 0x62, 0x6f, 0x78, // "drop box"
2636 wantRes: []Transaction{
2640 Type: []byte{0, 0x00},
2641 ID: []byte{0, 0, 0, 0},
2642 ErrorCode: []byte{0, 0, 0, 1},
2644 NewField(fieldError, []byte("You are not allowed to view drop boxes.")),
2648 wantErr: assert.NoError,
2651 name: "with file root",
2656 FileRoot: func() string {
2657 path, _ := os.Getwd()
2658 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2664 tranGetFileNameList, &[]byte{0, 1},
2665 NewField(fieldFilePath, []byte{
2671 wantRes: []Transaction{
2675 Type: []byte{0, 0xc8},
2676 ID: []byte{0, 0, 0, 0},
2677 ErrorCode: []byte{0, 0, 0, 0},
2680 fieldFileNameWithInfo,
2682 fnwi := FileNameWithInfo{
2683 fileNameWithInfoHeader: fileNameWithInfoHeader{
2684 Type: [4]byte{0x54, 0x45, 0x58, 0x54},
2685 Creator: [4]byte{0x54, 0x54, 0x58, 0x54},
2686 FileSize: [4]byte{0, 0, 0x04, 0},
2688 NameScript: [2]byte{},
2689 NameSize: [2]byte{0, 0x0b},
2691 name: []byte("testfile-1k"),
2693 b, _ := fnwi.MarshalBinary()
2700 wantErr: assert.NoError,
2703 for _, tt := range tests {
2704 t.Run(tt.name, func(t *testing.T) {
2705 gotRes, err := HandleGetFileNameList(tt.args.cc, tt.args.t)
2706 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetFileNameList(%v, %v)", tt.args.cc, tt.args.t)) {
2710 tranAssertEqual(t, tt.wantRes, gotRes)
2715 func TestHandleGetClientInfoText(t *testing.T) {
2723 wantRes []Transaction
2724 wantErr assert.ErrorAssertionFunc
2727 name: "when user does not have required permission",
2731 Access: func() *[]byte {
2732 var bits accessBitmap
2738 Accounts: map[string]*Account{},
2742 tranGetClientInfoText, &[]byte{0, 1},
2743 NewField(fieldUserID, []byte{0, 1}),
2746 wantRes: []Transaction{
2750 Type: []byte{0, 0x00},
2751 ID: []byte{0, 0, 0, 0},
2752 ErrorCode: []byte{0, 0, 0, 1},
2754 NewField(fieldError, []byte("You are not allowed to get client info.")),
2758 wantErr: assert.NoError,
2761 name: "with a valid user",
2764 UserName: []byte("Testy McTest"),
2765 RemoteAddr: "1.2.3.4:12345",
2767 Access: func() *[]byte {
2768 var bits accessBitmap
2769 bits.Set(accessGetClientInfo)
2777 Accounts: map[string]*Account{},
2778 Clients: map[uint16]*ClientConn{
2780 UserName: []byte("Testy McTest"),
2781 RemoteAddr: "1.2.3.4:12345",
2783 Access: func() *[]byte {
2784 var bits accessBitmap
2785 bits.Set(accessGetClientInfo)
2795 transfers: map[int]map[[4]byte]*FileTransfer{
2803 tranGetClientInfoText, &[]byte{0, 1},
2804 NewField(fieldUserID, []byte{0, 1}),
2807 wantRes: []Transaction{
2811 Type: []byte{0x1, 0x2f},
2812 ID: []byte{0, 0, 0, 0},
2813 ErrorCode: []byte{0, 0, 0, 0},
2815 NewField(fieldData, []byte(
2816 strings.Replace(`Nickname: Testy McTest
2819 Address: 1.2.3.4:12345
2821 -------- File Downloads ---------
2825 ------- Folder Downloads --------
2829 --------- File Uploads ----------
2833 -------- Folder Uploads ---------
2837 ------- Waiting Downloads -------
2841 `, "\n", "\r", -1)),
2843 NewField(fieldUserName, []byte("Testy McTest")),
2847 wantErr: assert.NoError,
2850 for _, tt := range tests {
2851 t.Run(tt.name, func(t *testing.T) {
2852 gotRes, err := HandleGetClientInfoText(tt.args.cc, tt.args.t)
2853 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetClientInfoText(%v, %v)", tt.args.cc, tt.args.t)) {
2856 tranAssertEqual(t, tt.wantRes, gotRes)
2861 func TestHandleTranAgreed(t *testing.T) {
2869 wantRes []Transaction
2870 wantErr assert.ErrorAssertionFunc
2873 name: "normal request flow",
2877 Access: func() *[]byte {
2878 var bits accessBitmap
2879 bits.Set(accessDisconUser)
2880 bits.Set(accessAnyName)
2885 Flags: []byte{0, 1},
2886 Version: []byte{0, 1},
2888 logger: NewTestLogger(),
2891 BannerFile: "banner.jpg",
2897 NewField(fieldUserName, []byte("username")),
2898 NewField(fieldUserIconID, []byte{0, 1}),
2899 NewField(fieldOptions, []byte{0, 0}),
2902 wantRes: []Transaction{
2904 clientID: &[]byte{0, 1},
2907 Type: []byte{0, 0x7a},
2908 ID: []byte{0, 0, 0, 0},
2909 ErrorCode: []byte{0, 0, 0, 0},
2911 NewField(fieldBannerType, []byte("JPEG")),
2915 clientID: &[]byte{0, 1},
2918 Type: []byte{0, 0x79},
2919 ID: []byte{0, 0, 0, 0},
2920 ErrorCode: []byte{0, 0, 0, 0},
2924 wantErr: assert.NoError,
2927 for _, tt := range tests {
2928 t.Run(tt.name, func(t *testing.T) {
2929 gotRes, err := HandleTranAgreed(tt.args.cc, tt.args.t)
2930 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranAgreed(%v, %v)", tt.args.cc, tt.args.t)) {
2933 tranAssertEqual(t, tt.wantRes, gotRes)
2938 func TestHandleSetClientUserInfo(t *testing.T) {
2946 wantRes []Transaction
2947 wantErr assert.ErrorAssertionFunc
2950 name: "when client does not have accessAnyName",
2954 Access: func() *[]byte {
2955 var bits accessBitmap
2961 UserName: []byte("Guest"),
2962 Flags: []byte{0, 1},
2964 Clients: map[uint16]*ClientConn{
2972 tranSetClientUserInfo, nil,
2973 NewField(fieldUserIconID, []byte{0, 1}),
2974 NewField(fieldUserName, []byte("NOPE")),
2977 wantRes: []Transaction{
2979 clientID: &[]byte{0, 1},
2982 Type: []byte{0x01, 0x2d},
2983 ID: []byte{0, 0, 0, 0},
2984 ErrorCode: []byte{0, 0, 0, 0},
2986 NewField(fieldUserID, []byte{0, 1}),
2987 NewField(fieldUserIconID, []byte{0, 1}),
2988 NewField(fieldUserFlags, []byte{0, 1}),
2989 NewField(fieldUserName, []byte("Guest"))},
2992 wantErr: assert.NoError,
2995 for _, tt := range tests {
2996 t.Run(tt.name, func(t *testing.T) {
2997 gotRes, err := HandleSetClientUserInfo(tt.args.cc, tt.args.t)
2998 if !tt.wantErr(t, err, fmt.Sprintf("HandleSetClientUserInfo(%v, %v)", tt.args.cc, tt.args.t)) {
3002 tranAssertEqual(t, tt.wantRes, gotRes)