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},
70 Type: [2]byte{0, 0x6a},
71 ID: [4]byte{0, 0, 0, 1},
73 NewField(FieldChatID, []byte{0, 0, 0, 1}),
74 NewField(FieldChatSubject, []byte("Test Subject")),
80 clientID: &[]byte{0, 1},
81 Type: [2]byte{0, 0x77},
83 NewField(FieldChatID, []byte{0, 0, 0, 1}),
84 NewField(FieldChatSubject, []byte("Test Subject")),
88 clientID: &[]byte{0, 2},
89 Type: [2]byte{0, 0x77},
91 NewField(FieldChatID, []byte{0, 0, 0, 1}),
92 NewField(FieldChatSubject, []byte("Test Subject")),
99 for _, tt := range tests {
100 t.Run(tt.name, func(t *testing.T) {
101 got, err := HandleSetChatSubject(tt.args.cc, tt.args.t)
102 if (err != nil) != tt.wantErr {
103 t.Errorf("HandleSetChatSubject() error = %v, wantErr %v", err, tt.wantErr)
106 if !tranAssertEqual(t, tt.want, got) {
107 t.Errorf("HandleSetChatSubject() got = %v, want %v", got, tt.want)
113 func TestHandleLeaveChat(t *testing.T) {
125 name: "returns expected transactions",
130 PrivateChats: map[uint32]*PrivateChat{
132 ClientConn: map[uint16]*ClientConn{
135 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
141 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
148 Clients: map[uint16]*ClientConn{
151 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
157 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
164 t: NewTransaction(TranDeleteUser, nil, NewField(FieldChatID, []byte{0, 0, 0, 1})),
168 clientID: &[]byte{0, 1},
171 Type: [2]byte{0, 0x76},
173 NewField(FieldChatID, []byte{0, 0, 0, 1}),
174 NewField(FieldUserID, []byte{0, 2}),
181 for _, tt := range tests {
182 t.Run(tt.name, func(t *testing.T) {
183 got, err := HandleLeaveChat(tt.args.cc, tt.args.t)
184 if (err != nil) != tt.wantErr {
185 t.Errorf("HandleLeaveChat() error = %v, wantErr %v", err, tt.wantErr)
188 if !tranAssertEqual(t, tt.want, got) {
189 t.Errorf("HandleLeaveChat() got = %v, want %v", got, tt.want)
195 func TestHandleGetUserNameList(t *testing.T) {
207 name: "replies with userlist transaction",
213 Clients: map[uint16]*ClientConn{
218 UserName: []byte{0, 4},
224 UserName: []byte{0, 4},
233 clientID: &[]byte{1, 1},
237 FieldUsernameWithInfo,
238 []byte{00, 01, 00, 02, 00, 03, 00, 02, 00, 04},
241 FieldUsernameWithInfo,
242 []byte{00, 02, 00, 02, 00, 03, 00, 02, 00, 04},
250 for _, tt := range tests {
251 t.Run(tt.name, func(t *testing.T) {
252 got, err := HandleGetUserNameList(tt.args.cc, tt.args.t)
253 if (err != nil) != tt.wantErr {
254 t.Errorf("HandleGetUserNameList() error = %v, wantErr %v", err, tt.wantErr)
257 assert.Equal(t, tt.want, got)
262 func TestHandleChatSend(t *testing.T) {
274 name: "sends chat msg transaction to all clients",
278 Access: func() accessBitmap {
279 var bits accessBitmap
280 bits.Set(accessSendChat)
284 UserName: []byte{0x00, 0x01},
286 Clients: map[uint16]*ClientConn{
289 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
295 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
304 NewField(FieldData, []byte("hai")),
310 clientID: &[]byte{0, 1},
313 Type: [2]byte{0, 0x6a},
315 NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
319 clientID: &[]byte{0, 2},
322 Type: [2]byte{0, 0x6a},
324 NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
331 name: "treats Chat ID 00 00 00 00 as a public chat message",
335 Access: func() accessBitmap {
336 var bits accessBitmap
337 bits.Set(accessSendChat)
341 UserName: []byte{0x00, 0x01},
343 Clients: map[uint16]*ClientConn{
346 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
352 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
361 NewField(FieldData, []byte("hai")),
362 NewField(FieldChatID, []byte{0, 0, 0, 0}),
368 clientID: &[]byte{0, 1},
369 Type: [2]byte{0, 0x6a},
371 NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
375 clientID: &[]byte{0, 2},
376 Type: [2]byte{0, 0x6a},
378 NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
385 name: "when user does not have required permission",
389 Access: func() accessBitmap {
390 var bits accessBitmap
395 Accounts: map[string]*Account{},
399 TranChatSend, &[]byte{0, 1},
400 NewField(FieldData, []byte("hai")),
406 ErrorCode: [4]byte{0, 0, 0, 1},
408 NewField(FieldError, []byte("You are not allowed to participate in chat.")),
415 name: "sends chat msg as emote if FieldChatOptions is set to 1",
419 Access: func() accessBitmap {
420 var bits accessBitmap
421 bits.Set(accessSendChat)
425 UserName: []byte("Testy McTest"),
427 Clients: map[uint16]*ClientConn{
430 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
436 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
445 NewField(FieldData, []byte("performed action")),
446 NewField(FieldChatOptions, []byte{0x00, 0x01}),
452 clientID: &[]byte{0, 1},
455 Type: [2]byte{0, 0x6a},
457 NewField(FieldData, []byte("\r*** Testy McTest performed action")),
461 clientID: &[]byte{0, 2},
464 Type: [2]byte{0, 0x6a},
466 NewField(FieldData, []byte("\r*** Testy McTest performed action")),
473 name: "does not send chat msg as emote if FieldChatOptions is set to 0",
477 Access: func() accessBitmap {
478 var bits accessBitmap
479 bits.Set(accessSendChat)
483 UserName: []byte("Testy McTest"),
485 Clients: map[uint16]*ClientConn{
488 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
494 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
503 NewField(FieldData, []byte("hello")),
504 NewField(FieldChatOptions, []byte{0x00, 0x00}),
510 clientID: &[]byte{0, 1},
511 Type: [2]byte{0, 0x6a},
513 NewField(FieldData, []byte("\r Testy McTest: hello")),
517 clientID: &[]byte{0, 2},
518 Type: [2]byte{0, 0x6a},
520 NewField(FieldData, []byte("\r Testy McTest: hello")),
527 name: "only sends chat msg to clients with accessReadChat permission",
531 Access: func() accessBitmap {
532 var bits accessBitmap
533 bits.Set(accessSendChat)
537 UserName: []byte{0x00, 0x01},
539 Clients: map[uint16]*ClientConn{
542 Access: func() accessBitmap {
543 var bits accessBitmap
544 bits.Set(accessReadChat)
551 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
560 NewField(FieldData, []byte("hai")),
566 clientID: &[]byte{0, 1},
567 Type: [2]byte{0, 0x6a},
569 NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
576 name: "only sends private chat msg to members of private chat",
580 Access: func() accessBitmap {
581 var bits accessBitmap
582 bits.Set(accessSendChat)
586 UserName: []byte{0x00, 0x01},
588 PrivateChats: map[uint32]*PrivateChat{
590 ClientConn: map[uint16]*ClientConn{
600 Clients: map[uint16]*ClientConn{
603 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
609 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
615 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
624 NewField(FieldData, []byte("hai")),
625 NewField(FieldChatID, []byte{0, 0, 0, 1}),
631 clientID: &[]byte{0, 1},
632 Type: [2]byte{0, 0x6a},
634 NewField(FieldChatID, []byte{0, 0, 0, 1}),
635 NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
639 clientID: &[]byte{0, 2},
640 Type: [2]byte{0, 0x6a},
642 NewField(FieldChatID, []byte{0, 0, 0, 1}),
643 NewField(FieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
650 for _, tt := range tests {
651 t.Run(tt.name, func(t *testing.T) {
652 got, err := HandleChatSend(tt.args.cc, tt.args.t)
654 if (err != nil) != tt.wantErr {
655 t.Errorf("HandleChatSend() error = %v, wantErr %v", err, tt.wantErr)
658 tranAssertEqual(t, tt.want, got)
663 func TestHandleGetFileInfo(t *testing.T) {
671 wantRes []Transaction
675 name: "returns expected fields when a valid file is requested",
678 ID: &[]byte{0x00, 0x01},
682 FileRoot: func() string {
683 path, _ := os.Getwd()
684 return filepath.Join(path, "/test/config/Files")
690 TranGetFileInfo, nil,
691 NewField(FieldFileName, []byte("testfile.txt")),
692 NewField(FieldFilePath, []byte{0x00, 0x00}),
695 wantRes: []Transaction{
697 clientID: &[]byte{0, 1},
701 NewField(FieldFileName, []byte("testfile.txt")),
702 NewField(FieldFileTypeString, []byte("Text File")),
703 NewField(FieldFileCreatorString, []byte("ttxt")),
704 NewField(FieldFileType, []byte("TEXT")),
705 NewField(FieldFileCreateDate, make([]byte, 8)),
706 NewField(FieldFileModifyDate, make([]byte, 8)),
707 NewField(FieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}),
714 for _, tt := range tests {
715 t.Run(tt.name, func(t *testing.T) {
716 gotRes, err := HandleGetFileInfo(tt.args.cc, tt.args.t)
717 if (err != nil) != tt.wantErr {
718 t.Errorf("HandleGetFileInfo() error = %v, wantErr %v", err, tt.wantErr)
722 // Clear the fileWrapper timestamp fields to work around problems running the tests in multiple timezones
723 // TODO: revisit how to test this by mocking the stat calls
724 gotRes[0].Fields[4].Data = make([]byte, 8)
725 gotRes[0].Fields[5].Data = make([]byte, 8)
727 if !tranAssertEqual(t, tt.wantRes, gotRes) {
728 t.Errorf("HandleGetFileInfo() gotRes = %v, want %v", gotRes, tt.wantRes)
734 func TestHandleNewFolder(t *testing.T) {
742 wantRes []Transaction
746 name: "without required permission",
750 Access: func() accessBitmap {
751 var bits accessBitmap
761 wantRes: []Transaction{
764 ErrorCode: [4]byte{0, 0, 0, 1},
766 NewField(FieldError, []byte("You are not allowed to create folders.")),
773 name: "when path is nested",
777 Access: func() accessBitmap {
778 var bits accessBitmap
779 bits.Set(accessCreateFolder)
788 FS: func() *MockFileStore {
789 mfs := &MockFileStore{}
790 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
791 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
797 TranNewFolder, &[]byte{0, 1},
798 NewField(FieldFileName, []byte("testFolder")),
799 NewField(FieldFilePath, []byte{
807 wantRes: []Transaction{
809 clientID: &[]byte{0, 1},
816 name: "when path is not nested",
820 Access: func() accessBitmap {
821 var bits accessBitmap
822 bits.Set(accessCreateFolder)
831 FS: func() *MockFileStore {
832 mfs := &MockFileStore{}
833 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
834 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
840 TranNewFolder, &[]byte{0, 1},
841 NewField(FieldFileName, []byte("testFolder")),
844 wantRes: []Transaction{
846 clientID: &[]byte{0, 1},
853 name: "when Write returns an err",
857 Access: func() accessBitmap {
858 var bits accessBitmap
859 bits.Set(accessCreateFolder)
868 FS: func() *MockFileStore {
869 mfs := &MockFileStore{}
870 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
871 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
877 TranNewFolder, &[]byte{0, 1},
878 NewField(FieldFileName, []byte("testFolder")),
879 NewField(FieldFilePath, []byte{
884 wantRes: []Transaction{},
888 name: "FieldFileName does not allow directory traversal",
892 Access: func() accessBitmap {
893 var bits accessBitmap
894 bits.Set(accessCreateFolder)
903 FS: func() *MockFileStore {
904 mfs := &MockFileStore{}
905 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
906 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
912 TranNewFolder, &[]byte{0, 1},
913 NewField(FieldFileName, []byte("../../testFolder")),
916 wantRes: []Transaction{
918 clientID: &[]byte{0, 1},
924 name: "FieldFilePath does not allow directory traversal",
928 Access: func() accessBitmap {
929 var bits accessBitmap
930 bits.Set(accessCreateFolder)
939 FS: func() *MockFileStore {
940 mfs := &MockFileStore{}
941 mfs.On("Mkdir", "/Files/foo/testFolder", fs.FileMode(0777)).Return(nil)
942 mfs.On("Stat", "/Files/foo/testFolder").Return(nil, os.ErrNotExist)
948 TranNewFolder, &[]byte{0, 1},
949 NewField(FieldFileName, []byte("testFolder")),
950 NewField(FieldFilePath, []byte{
961 wantRes: []Transaction{
963 clientID: &[]byte{0, 1},
969 for _, tt := range tests {
970 t.Run(tt.name, func(t *testing.T) {
971 gotRes, err := HandleNewFolder(tt.args.cc, tt.args.t)
972 if (err != nil) != tt.wantErr {
973 t.Errorf("HandleNewFolder() error = %v, wantErr %v", err, tt.wantErr)
977 if !tranAssertEqual(t, tt.wantRes, gotRes) {
978 t.Errorf("HandleNewFolder() gotRes = %v, want %v", gotRes, tt.wantRes)
984 func TestHandleUploadFile(t *testing.T) {
992 wantRes []Transaction
996 name: "when request is valid and user has Upload Anywhere permission",
1001 fileTransfers: map[[4]byte]*FileTransfer{},
1003 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1005 transfers: map[int]map[[4]byte]*FileTransfer{
1009 Access: func() accessBitmap {
1010 var bits accessBitmap
1011 bits.Set(accessUploadFile)
1012 bits.Set(accessUploadAnywhere)
1018 TranUploadFile, &[]byte{0, 1},
1019 NewField(FieldFileName, []byte("testFile")),
1020 NewField(FieldFilePath, []byte{
1028 wantRes: []Transaction{
1032 NewField(FieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), // rand.Seed(1)
1039 name: "when user does not have required access",
1043 Access: func() accessBitmap {
1044 var bits accessBitmap
1050 TranUploadFile, &[]byte{0, 1},
1051 NewField(FieldFileName, []byte("testFile")),
1052 NewField(FieldFilePath, []byte{
1060 wantRes: []Transaction{
1063 ErrorCode: [4]byte{0, 0, 0, 1},
1065 NewField(FieldError, []byte("You are not allowed to upload files.")), // rand.Seed(1)
1072 for _, tt := range tests {
1073 t.Run(tt.name, func(t *testing.T) {
1074 gotRes, err := HandleUploadFile(tt.args.cc, tt.args.t)
1075 if (err != nil) != tt.wantErr {
1076 t.Errorf("HandleUploadFile() error = %v, wantErr %v", err, tt.wantErr)
1080 tranAssertEqual(t, tt.wantRes, gotRes)
1085 func TestHandleMakeAlias(t *testing.T) {
1093 wantRes []Transaction
1097 name: "with valid input and required permissions",
1100 logger: NewTestLogger(),
1102 Access: func() accessBitmap {
1103 var bits accessBitmap
1104 bits.Set(accessMakeAlias)
1110 FileRoot: func() string {
1111 path, _ := os.Getwd()
1112 return path + "/test/config/Files"
1115 Logger: NewTestLogger(),
1116 FS: func() *MockFileStore {
1117 mfs := &MockFileStore{}
1118 path, _ := os.Getwd()
1121 path+"/test/config/Files/foo/testFile",
1122 path+"/test/config/Files/bar/testFile",
1129 TranMakeFileAlias, &[]byte{0, 1},
1130 NewField(FieldFileName, []byte("testFile")),
1131 NewField(FieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1132 NewField(FieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1135 wantRes: []Transaction{
1138 Fields: []Field(nil),
1144 name: "when symlink returns an error",
1147 logger: NewTestLogger(),
1149 Access: func() accessBitmap {
1150 var bits accessBitmap
1151 bits.Set(accessMakeAlias)
1157 FileRoot: func() string {
1158 path, _ := os.Getwd()
1159 return path + "/test/config/Files"
1162 Logger: NewTestLogger(),
1163 FS: func() *MockFileStore {
1164 mfs := &MockFileStore{}
1165 path, _ := os.Getwd()
1168 path+"/test/config/Files/foo/testFile",
1169 path+"/test/config/Files/bar/testFile",
1170 ).Return(errors.New("ohno"))
1176 TranMakeFileAlias, &[]byte{0, 1},
1177 NewField(FieldFileName, []byte("testFile")),
1178 NewField(FieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1179 NewField(FieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1182 wantRes: []Transaction{
1185 ErrorCode: [4]byte{0, 0, 0, 1},
1187 NewField(FieldError, []byte("Error creating alias")),
1194 name: "when user does not have required permission",
1197 logger: NewTestLogger(),
1199 Access: func() accessBitmap {
1200 var bits accessBitmap
1206 FileRoot: func() string {
1207 path, _ := os.Getwd()
1208 return path + "/test/config/Files"
1214 TranMakeFileAlias, &[]byte{0, 1},
1215 NewField(FieldFileName, []byte("testFile")),
1216 NewField(FieldFilePath, []byte{
1222 NewField(FieldFileNewPath, []byte{
1230 wantRes: []Transaction{
1233 ErrorCode: [4]byte{0, 0, 0, 1},
1235 NewField(FieldError, []byte("You are not allowed to make aliases.")),
1242 for _, tt := range tests {
1243 t.Run(tt.name, func(t *testing.T) {
1244 gotRes, err := HandleMakeAlias(tt.args.cc, tt.args.t)
1245 if (err != nil) != tt.wantErr {
1246 t.Errorf("HandleMakeAlias(%v, %v)", tt.args.cc, tt.args.t)
1250 tranAssertEqual(t, tt.wantRes, gotRes)
1255 func TestHandleGetUser(t *testing.T) {
1263 wantRes []Transaction
1264 wantErr assert.ErrorAssertionFunc
1267 name: "when account is valid",
1271 Access: func() accessBitmap {
1272 var bits accessBitmap
1273 bits.Set(accessOpenUser)
1278 Accounts: map[string]*Account{
1282 Password: "password",
1283 Access: accessBitmap{},
1289 TranGetUser, &[]byte{0, 1},
1290 NewField(FieldUserLogin, []byte("guest")),
1293 wantRes: []Transaction{
1297 NewField(FieldUserName, []byte("Guest")),
1298 NewField(FieldUserLogin, encodeString([]byte("guest"))),
1299 NewField(FieldUserPassword, []byte("password")),
1300 NewField(FieldUserAccess, []byte{0, 0, 0, 0, 0, 0, 0, 0}),
1304 wantErr: assert.NoError,
1307 name: "when user does not have required permission",
1311 Access: func() accessBitmap {
1312 var bits accessBitmap
1317 Accounts: map[string]*Account{},
1321 TranGetUser, &[]byte{0, 1},
1322 NewField(FieldUserLogin, []byte("nonExistentUser")),
1325 wantRes: []Transaction{
1328 ErrorCode: [4]byte{0, 0, 0, 1},
1330 NewField(FieldError, []byte("You are not allowed to view accounts.")),
1334 wantErr: assert.NoError,
1337 name: "when account does not exist",
1341 Access: func() accessBitmap {
1342 var bits accessBitmap
1343 bits.Set(accessOpenUser)
1348 Accounts: map[string]*Account{},
1352 TranGetUser, &[]byte{0, 1},
1353 NewField(FieldUserLogin, []byte("nonExistentUser")),
1356 wantRes: []Transaction{
1360 Type: [2]byte{0, 0},
1361 ErrorCode: [4]byte{0, 0, 0, 1},
1363 NewField(FieldError, []byte("Account does not exist.")),
1367 wantErr: assert.NoError,
1370 for _, tt := range tests {
1371 t.Run(tt.name, func(t *testing.T) {
1372 gotRes, err := HandleGetUser(tt.args.cc, tt.args.t)
1373 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetUser(%v, %v)", tt.args.cc, tt.args.t)) {
1377 tranAssertEqual(t, tt.wantRes, gotRes)
1382 func TestHandleDeleteUser(t *testing.T) {
1390 wantRes []Transaction
1391 wantErr assert.ErrorAssertionFunc
1394 name: "when user dataFile",
1398 Access: func() accessBitmap {
1399 var bits accessBitmap
1400 bits.Set(accessDeleteUser)
1405 Accounts: map[string]*Account{
1408 Name: "Testy McTest",
1409 Password: "password",
1410 Access: accessBitmap{},
1413 FS: func() *MockFileStore {
1414 mfs := &MockFileStore{}
1415 mfs.On("Remove", "Users/testuser.yaml").Return(nil)
1421 TranDeleteUser, &[]byte{0, 1},
1422 NewField(FieldUserLogin, encodeString([]byte("testuser"))),
1425 wantRes: []Transaction{
1429 Type: [2]byte{0, 0},
1430 Fields: []Field(nil),
1433 wantErr: assert.NoError,
1436 name: "when user does not have required permission",
1440 Access: func() accessBitmap {
1441 var bits accessBitmap
1446 Accounts: map[string]*Account{},
1450 TranDeleteUser, &[]byte{0, 1},
1451 NewField(FieldUserLogin, encodeString([]byte("testuser"))),
1454 wantRes: []Transaction{
1457 ErrorCode: [4]byte{0, 0, 0, 1},
1459 NewField(FieldError, []byte("You are not allowed to delete accounts.")),
1463 wantErr: assert.NoError,
1466 for _, tt := range tests {
1467 t.Run(tt.name, func(t *testing.T) {
1468 gotRes, err := HandleDeleteUser(tt.args.cc, tt.args.t)
1469 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteUser(%v, %v)", tt.args.cc, tt.args.t)) {
1473 tranAssertEqual(t, tt.wantRes, gotRes)
1478 func TestHandleGetMsgs(t *testing.T) {
1486 wantRes []Transaction
1487 wantErr assert.ErrorAssertionFunc
1490 name: "returns news data",
1494 Access: func() accessBitmap {
1495 var bits accessBitmap
1496 bits.Set(accessNewsReadArt)
1501 FlatNews: []byte("TEST"),
1505 TranGetMsgs, &[]byte{0, 1},
1508 wantRes: []Transaction{
1512 NewField(FieldData, []byte("TEST")),
1516 wantErr: assert.NoError,
1519 name: "when user does not have required permission",
1523 Access: func() accessBitmap {
1524 var bits accessBitmap
1529 Accounts: map[string]*Account{},
1533 TranGetMsgs, &[]byte{0, 1},
1536 wantRes: []Transaction{
1539 ErrorCode: [4]byte{0, 0, 0, 1},
1541 NewField(FieldError, []byte("You are not allowed to read news.")),
1545 wantErr: assert.NoError,
1548 for _, tt := range tests {
1549 t.Run(tt.name, func(t *testing.T) {
1550 gotRes, err := HandleGetMsgs(tt.args.cc, tt.args.t)
1551 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetMsgs(%v, %v)", tt.args.cc, tt.args.t)) {
1555 tranAssertEqual(t, tt.wantRes, gotRes)
1560 func TestHandleNewUser(t *testing.T) {
1568 wantRes []Transaction
1569 wantErr assert.ErrorAssertionFunc
1572 name: "when user does not have required permission",
1576 Access: func() accessBitmap {
1577 var bits accessBitmap
1582 Accounts: map[string]*Account{},
1586 TranNewUser, &[]byte{0, 1},
1589 wantRes: []Transaction{
1592 ErrorCode: [4]byte{0, 0, 0, 1},
1594 NewField(FieldError, []byte("You are not allowed to create new accounts.")),
1598 wantErr: assert.NoError,
1601 name: "when user attempts to create account with greater access",
1605 Access: func() accessBitmap {
1606 var bits accessBitmap
1607 bits.Set(accessCreateUser)
1612 Accounts: map[string]*Account{},
1616 TranNewUser, &[]byte{0, 1},
1617 NewField(FieldUserLogin, []byte("userB")),
1621 var bits accessBitmap
1622 bits.Set(accessDisconUser)
1628 wantRes: []Transaction{
1631 ErrorCode: [4]byte{0, 0, 0, 1},
1633 NewField(FieldError, []byte("Cannot create account with more access than yourself.")),
1637 wantErr: assert.NoError,
1640 for _, tt := range tests {
1641 t.Run(tt.name, func(t *testing.T) {
1642 gotRes, err := HandleNewUser(tt.args.cc, tt.args.t)
1643 if !tt.wantErr(t, err, fmt.Sprintf("HandleNewUser(%v, %v)", tt.args.cc, tt.args.t)) {
1647 tranAssertEqual(t, tt.wantRes, gotRes)
1652 func TestHandleListUsers(t *testing.T) {
1660 wantRes []Transaction
1661 wantErr assert.ErrorAssertionFunc
1664 name: "when user does not have required permission",
1668 Access: func() accessBitmap {
1669 var bits accessBitmap
1674 Accounts: map[string]*Account{},
1678 TranNewUser, &[]byte{0, 1},
1681 wantRes: []Transaction{
1684 ErrorCode: [4]byte{0, 0, 0, 1},
1686 NewField(FieldError, []byte("You are not allowed to view accounts.")),
1690 wantErr: assert.NoError,
1693 name: "when user has required permission",
1697 Access: func() accessBitmap {
1698 var bits accessBitmap
1699 bits.Set(accessOpenUser)
1704 Accounts: map[string]*Account{
1709 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
1715 TranGetClientInfoText, &[]byte{0, 1},
1716 NewField(FieldUserID, []byte{0, 1}),
1719 wantRes: []Transaction{
1723 NewField(FieldData, []byte{
1724 0x00, 0x04, 0x00, 0x66, 0x00, 0x05, 0x67, 0x75, 0x65, 0x73, 0x74, 0x00, 0x69, 0x00, 0x05, 0x98,
1725 0x8a, 0x9a, 0x8c, 0x8b, 0x00, 0x6e, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1726 0x00, 0x6a, 0x00, 0x01, 0x78,
1731 wantErr: assert.NoError,
1734 for _, tt := range tests {
1735 t.Run(tt.name, func(t *testing.T) {
1736 gotRes, err := HandleListUsers(tt.args.cc, tt.args.t)
1737 if !tt.wantErr(t, err, fmt.Sprintf("HandleListUsers(%v, %v)", tt.args.cc, tt.args.t)) {
1741 tranAssertEqual(t, tt.wantRes, gotRes)
1746 func TestHandleDownloadFile(t *testing.T) {
1754 wantRes []Transaction
1755 wantErr assert.ErrorAssertionFunc
1758 name: "when user does not have required permission",
1762 Access: func() accessBitmap {
1763 var bits accessBitmap
1769 t: NewTransaction(TranDownloadFile, &[]byte{0, 1}),
1771 wantRes: []Transaction{
1774 ErrorCode: [4]byte{0, 0, 0, 1},
1776 NewField(FieldError, []byte("You are not allowed to download files.")),
1780 wantErr: assert.NoError,
1783 name: "with a valid file",
1786 transfers: map[int]map[[4]byte]*FileTransfer{
1790 Access: func() accessBitmap {
1791 var bits accessBitmap
1792 bits.Set(accessDownloadFile)
1798 fileTransfers: map[[4]byte]*FileTransfer{},
1800 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1802 Accounts: map[string]*Account{},
1808 NewField(FieldFileName, []byte("testfile.txt")),
1809 NewField(FieldFilePath, []byte{0x0, 0x00}),
1812 wantRes: []Transaction{
1816 NewField(FieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
1817 NewField(FieldWaitingCount, []byte{0x00, 0x00}),
1818 NewField(FieldTransferSize, []byte{0x00, 0x00, 0x00, 0xa5}),
1819 NewField(FieldFileSize, []byte{0x00, 0x00, 0x00, 0x17}),
1823 wantErr: assert.NoError,
1826 name: "when client requests to resume 1k test file at offset 256",
1829 transfers: map[int]map[[4]byte]*FileTransfer{
1831 }, Account: &Account{
1832 Access: func() accessBitmap {
1833 var bits accessBitmap
1834 bits.Set(accessDownloadFile)
1841 // FS: func() *MockFileStore {
1842 // path, _ := os.Getwd()
1843 // testFile, err := os.Open(path + "/test/config/Files/testfile-1k")
1848 // mfi := &MockFileInfo{}
1849 // mfi.On("Mode").Return(fs.FileMode(0))
1850 // mfs := &MockFileStore{}
1851 // mfs.On("Stat", "/fakeRoot/Files/testfile.txt").Return(mfi, nil)
1852 // mfs.On("Open", "/fakeRoot/Files/testfile.txt").Return(testFile, nil)
1853 // mfs.On("Stat", "/fakeRoot/Files/.info_testfile.txt").Return(nil, errors.New("no"))
1854 // mfs.On("Stat", "/fakeRoot/Files/.rsrc_testfile.txt").Return(nil, errors.New("no"))
1858 fileTransfers: map[[4]byte]*FileTransfer{},
1860 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1862 Accounts: map[string]*Account{},
1868 NewField(FieldFileName, []byte("testfile-1k")),
1869 NewField(FieldFilePath, []byte{0x00, 0x00}),
1871 FieldFileResumeData,
1873 frd := FileResumeData{
1877 ForkCount: [2]byte{0, 2},
1878 ForkInfoList: []ForkInfoList{
1880 Fork: [4]byte{0x44, 0x41, 0x54, 0x41}, // "DATA"
1881 DataSize: [4]byte{0, 0, 0x01, 0x00}, // request offset 256
1886 Fork: [4]byte{0x4d, 0x41, 0x43, 0x52}, // "MACR"
1887 DataSize: [4]byte{0, 0, 0, 0},
1893 b, _ := frd.BinaryMarshal()
1899 wantRes: []Transaction{
1903 NewField(FieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
1904 NewField(FieldWaitingCount, []byte{0x00, 0x00}),
1905 NewField(FieldTransferSize, []byte{0x00, 0x00, 0x03, 0x8d}),
1906 NewField(FieldFileSize, []byte{0x00, 0x00, 0x03, 0x00}),
1910 wantErr: assert.NoError,
1913 for _, tt := range tests {
1914 t.Run(tt.name, func(t *testing.T) {
1915 gotRes, err := HandleDownloadFile(tt.args.cc, tt.args.t)
1916 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadFile(%v, %v)", tt.args.cc, tt.args.t)) {
1920 tranAssertEqual(t, tt.wantRes, gotRes)
1925 func TestHandleUpdateUser(t *testing.T) {
1933 wantRes []Transaction
1934 wantErr assert.ErrorAssertionFunc
1937 name: "when action is create user without required permission",
1940 logger: NewTestLogger(),
1942 Logger: NewTestLogger(),
1945 Access: func() accessBitmap {
1946 var bits accessBitmap
1954 NewField(FieldData, []byte{
1955 0x00, 0x04, // field count
1957 0x00, 0x69, // FieldUserLogin = 105
1961 0x00, 0x6a, // FieldUserPassword = 106
1965 0x00, 0x66, // FieldUserName = 102
1969 0x00, 0x6e, // FieldUserAccess = 110
1971 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
1975 wantRes: []Transaction{
1978 ErrorCode: [4]byte{0, 0, 0, 1},
1980 NewField(FieldError, []byte("You are not allowed to create new accounts.")),
1984 wantErr: assert.NoError,
1987 name: "when action is modify user without required permission",
1990 logger: NewTestLogger(),
1992 Logger: NewTestLogger(),
1993 Accounts: map[string]*Account{
1998 Access: func() accessBitmap {
1999 var bits accessBitmap
2007 NewField(FieldData, []byte{
2008 0x00, 0x04, // field count
2010 0x00, 0x69, // FieldUserLogin = 105
2014 0x00, 0x6a, // FieldUserPassword = 106
2018 0x00, 0x66, // FieldUserName = 102
2022 0x00, 0x6e, // FieldUserAccess = 110
2024 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
2028 wantRes: []Transaction{
2031 ErrorCode: [4]byte{0, 0, 0, 1},
2033 NewField(FieldError, []byte("You are not allowed to modify accounts.")),
2037 wantErr: assert.NoError,
2040 name: "when action is delete user without required permission",
2043 logger: NewTestLogger(),
2045 Accounts: map[string]*Account{
2050 Access: func() accessBitmap {
2051 var bits accessBitmap
2059 NewField(FieldData, []byte{
2067 wantRes: []Transaction{
2070 ErrorCode: [4]byte{0, 0, 0, 1},
2072 NewField(FieldError, []byte("You are not allowed to delete accounts.")),
2076 wantErr: assert.NoError,
2079 for _, tt := range tests {
2080 t.Run(tt.name, func(t *testing.T) {
2081 gotRes, err := HandleUpdateUser(tt.args.cc, tt.args.t)
2082 if !tt.wantErr(t, err, fmt.Sprintf("HandleUpdateUser(%v, %v)", tt.args.cc, tt.args.t)) {
2086 tranAssertEqual(t, tt.wantRes, gotRes)
2091 func TestHandleDelNewsArt(t *testing.T) {
2099 wantRes []Transaction
2100 wantErr assert.ErrorAssertionFunc
2103 name: "without required permission",
2107 Access: func() accessBitmap {
2108 var bits accessBitmap
2118 wantRes: []Transaction{
2121 ErrorCode: [4]byte{0, 0, 0, 1},
2123 NewField(FieldError, []byte("You are not allowed to delete news articles.")),
2127 wantErr: assert.NoError,
2130 for _, tt := range tests {
2131 t.Run(tt.name, func(t *testing.T) {
2132 gotRes, err := HandleDelNewsArt(tt.args.cc, tt.args.t)
2133 if !tt.wantErr(t, err, fmt.Sprintf("HandleDelNewsArt(%v, %v)", tt.args.cc, tt.args.t)) {
2136 tranAssertEqual(t, tt.wantRes, gotRes)
2141 func TestHandleDisconnectUser(t *testing.T) {
2149 wantRes []Transaction
2150 wantErr assert.ErrorAssertionFunc
2153 name: "without required permission",
2157 Access: func() accessBitmap {
2158 var bits accessBitmap
2168 wantRes: []Transaction{
2171 ErrorCode: [4]byte{0, 0, 0, 1},
2173 NewField(FieldError, []byte("You are not allowed to disconnect users.")),
2177 wantErr: assert.NoError,
2180 name: "when target user has 'cannot be disconnected' priv",
2184 Clients: map[uint16]*ClientConn{
2188 Access: func() accessBitmap {
2189 var bits accessBitmap
2190 bits.Set(accessCannotBeDiscon)
2198 Access: func() accessBitmap {
2199 var bits accessBitmap
2200 bits.Set(accessDisconUser)
2208 NewField(FieldUserID, []byte{0, 1}),
2211 wantRes: []Transaction{
2214 ErrorCode: [4]byte{0, 0, 0, 1},
2216 NewField(FieldError, []byte("unnamed is not allowed to be disconnected.")),
2220 wantErr: assert.NoError,
2223 for _, tt := range tests {
2224 t.Run(tt.name, func(t *testing.T) {
2225 gotRes, err := HandleDisconnectUser(tt.args.cc, tt.args.t)
2226 if !tt.wantErr(t, err, fmt.Sprintf("HandleDisconnectUser(%v, %v)", tt.args.cc, tt.args.t)) {
2229 tranAssertEqual(t, tt.wantRes, gotRes)
2234 func TestHandleSendInstantMsg(t *testing.T) {
2242 wantRes []Transaction
2243 wantErr assert.ErrorAssertionFunc
2246 name: "without required permission",
2250 Access: func() accessBitmap {
2251 var bits accessBitmap
2261 wantRes: []Transaction{
2264 ErrorCode: [4]byte{0, 0, 0, 1},
2266 NewField(FieldError, []byte("You are not allowed to send private messages.")),
2270 wantErr: assert.Error,
2273 name: "when client 1 sends a message to client 2",
2277 Access: func() accessBitmap {
2278 var bits accessBitmap
2279 bits.Set(accessSendPrivMsg)
2284 UserName: []byte("User1"),
2286 Clients: map[uint16]*ClientConn{
2288 AutoReply: []byte(nil),
2289 Flags: []byte{0, 0},
2297 NewField(FieldData, []byte("hai")),
2298 NewField(FieldUserID, []byte{0, 2}),
2301 wantRes: []Transaction{
2305 NewField(FieldData, []byte("hai")),
2306 NewField(FieldUserName, []byte("User1")),
2307 NewField(FieldUserID, []byte{0, 1}),
2308 NewField(FieldOptions, []byte{0, 1}),
2311 clientID: &[]byte{0, 1},
2313 Fields: []Field(nil),
2316 wantErr: assert.NoError,
2319 name: "when client 2 has autoreply enabled",
2323 Access: func() accessBitmap {
2324 var bits accessBitmap
2325 bits.Set(accessSendPrivMsg)
2330 UserName: []byte("User1"),
2332 Clients: map[uint16]*ClientConn{
2334 Flags: []byte{0, 0},
2336 UserName: []byte("User2"),
2337 AutoReply: []byte("autohai"),
2345 NewField(FieldData, []byte("hai")),
2346 NewField(FieldUserID, []byte{0, 2}),
2349 wantRes: []Transaction{
2353 NewField(FieldData, []byte("hai")),
2354 NewField(FieldUserName, []byte("User1")),
2355 NewField(FieldUserID, []byte{0, 1}),
2356 NewField(FieldOptions, []byte{0, 1}),
2361 NewField(FieldData, []byte("autohai")),
2362 NewField(FieldUserName, []byte("User2")),
2363 NewField(FieldUserID, []byte{0, 2}),
2364 NewField(FieldOptions, []byte{0, 1}),
2367 clientID: &[]byte{0, 1},
2369 Fields: []Field(nil),
2372 wantErr: assert.NoError,
2375 name: "when client 2 has refuse private messages enabled",
2379 Access: func() accessBitmap {
2380 var bits accessBitmap
2381 bits.Set(accessSendPrivMsg)
2386 UserName: []byte("User1"),
2388 Clients: map[uint16]*ClientConn{
2390 Flags: []byte{255, 255},
2392 UserName: []byte("User2"),
2400 NewField(FieldData, []byte("hai")),
2401 NewField(FieldUserID, []byte{0, 2}),
2404 wantRes: []Transaction{
2408 NewField(FieldData, []byte("User2 does not accept private messages.")),
2409 NewField(FieldUserName, []byte("User2")),
2410 NewField(FieldUserID, []byte{0, 2}),
2411 NewField(FieldOptions, []byte{0, 2}),
2414 clientID: &[]byte{0, 1},
2416 Fields: []Field(nil),
2419 wantErr: assert.NoError,
2422 for _, tt := range tests {
2423 t.Run(tt.name, func(t *testing.T) {
2424 gotRes, err := HandleSendInstantMsg(tt.args.cc, tt.args.t)
2425 if !tt.wantErr(t, err, fmt.Sprintf("HandleSendInstantMsg(%v, %v)", tt.args.cc, tt.args.t)) {
2429 tranAssertEqual(t, tt.wantRes, gotRes)
2434 func TestHandleDeleteFile(t *testing.T) {
2442 wantRes []Transaction
2443 wantErr assert.ErrorAssertionFunc
2446 name: "when user does not have required permission to delete a folder",
2450 Access: func() accessBitmap {
2451 var bits accessBitmap
2457 FileRoot: func() string {
2458 return "/fakeRoot/Files"
2461 FS: func() *MockFileStore {
2462 mfi := &MockFileInfo{}
2463 mfi.On("Mode").Return(fs.FileMode(0))
2464 mfi.On("Size").Return(int64(100))
2465 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2466 mfi.On("IsDir").Return(false)
2467 mfi.On("Name").Return("testfile")
2469 mfs := &MockFileStore{}
2470 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2471 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2472 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2476 Accounts: map[string]*Account{},
2480 TranDeleteFile, &[]byte{0, 1},
2481 NewField(FieldFileName, []byte("testfile")),
2482 NewField(FieldFilePath, []byte{
2490 wantRes: []Transaction{
2493 ErrorCode: [4]byte{0, 0, 0, 1},
2495 NewField(FieldError, []byte("You are not allowed to delete files.")),
2499 wantErr: assert.NoError,
2502 name: "deletes all associated metadata files",
2506 Access: func() accessBitmap {
2507 var bits accessBitmap
2508 bits.Set(accessDeleteFile)
2514 FileRoot: func() string {
2515 return "/fakeRoot/Files"
2518 FS: func() *MockFileStore {
2519 mfi := &MockFileInfo{}
2520 mfi.On("Mode").Return(fs.FileMode(0))
2521 mfi.On("Size").Return(int64(100))
2522 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2523 mfi.On("IsDir").Return(false)
2524 mfi.On("Name").Return("testfile")
2526 mfs := &MockFileStore{}
2527 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2528 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2529 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2531 mfs.On("RemoveAll", "/fakeRoot/Files/aaa/testfile").Return(nil)
2532 mfs.On("Remove", "/fakeRoot/Files/aaa/testfile.incomplete").Return(nil)
2533 mfs.On("Remove", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil)
2534 mfs.On("Remove", "/fakeRoot/Files/aaa/.info_testfile").Return(nil)
2538 Accounts: map[string]*Account{},
2542 TranDeleteFile, &[]byte{0, 1},
2543 NewField(FieldFileName, []byte("testfile")),
2544 NewField(FieldFilePath, []byte{
2552 wantRes: []Transaction{
2555 Fields: []Field(nil),
2558 wantErr: assert.NoError,
2561 for _, tt := range tests {
2562 t.Run(tt.name, func(t *testing.T) {
2563 gotRes, err := HandleDeleteFile(tt.args.cc, tt.args.t)
2564 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteFile(%v, %v)", tt.args.cc, tt.args.t)) {
2568 tranAssertEqual(t, tt.wantRes, gotRes)
2570 tt.args.cc.Server.FS.(*MockFileStore).AssertExpectations(t)
2575 func TestHandleGetFileNameList(t *testing.T) {
2583 wantRes []Transaction
2584 wantErr assert.ErrorAssertionFunc
2587 name: "when FieldFilePath is a drop box, but user does not have accessViewDropBoxes ",
2591 Access: func() accessBitmap {
2592 var bits accessBitmap
2599 FileRoot: func() string {
2600 path, _ := os.Getwd()
2601 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2607 TranGetFileNameList, &[]byte{0, 1},
2608 NewField(FieldFilePath, []byte{
2612 0x64, 0x72, 0x6f, 0x70, 0x20, 0x62, 0x6f, 0x78, // "drop box"
2616 wantRes: []Transaction{
2619 ErrorCode: [4]byte{0, 0, 0, 1},
2621 NewField(FieldError, []byte("You are not allowed to view drop boxes.")),
2625 wantErr: assert.NoError,
2628 name: "with file root",
2633 FileRoot: func() string {
2634 path, _ := os.Getwd()
2635 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2641 TranGetFileNameList, &[]byte{0, 1},
2642 NewField(FieldFilePath, []byte{
2648 wantRes: []Transaction{
2653 FieldFileNameWithInfo,
2655 fnwi := FileNameWithInfo{
2656 fileNameWithInfoHeader: fileNameWithInfoHeader{
2657 Type: [4]byte{0x54, 0x45, 0x58, 0x54},
2658 Creator: [4]byte{0x54, 0x54, 0x58, 0x54},
2659 FileSize: [4]byte{0, 0, 0x04, 0},
2661 NameScript: [2]byte{},
2662 NameSize: [2]byte{0, 0x0b},
2664 Name: []byte("testfile-1k"),
2666 b, _ := io.ReadAll(&fnwi)
2673 wantErr: assert.NoError,
2676 for _, tt := range tests {
2677 t.Run(tt.name, func(t *testing.T) {
2678 gotRes, err := HandleGetFileNameList(tt.args.cc, tt.args.t)
2679 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetFileNameList(%v, %v)", tt.args.cc, tt.args.t)) {
2683 tranAssertEqual(t, tt.wantRes, gotRes)
2688 func TestHandleGetClientInfoText(t *testing.T) {
2696 wantRes []Transaction
2697 wantErr assert.ErrorAssertionFunc
2700 name: "when user does not have required permission",
2704 Access: func() accessBitmap {
2705 var bits accessBitmap
2710 Accounts: map[string]*Account{},
2714 TranGetClientInfoText, &[]byte{0, 1},
2715 NewField(FieldUserID, []byte{0, 1}),
2718 wantRes: []Transaction{
2721 ErrorCode: [4]byte{0, 0, 0, 1},
2723 NewField(FieldError, []byte("You are not allowed to get client info.")),
2727 wantErr: assert.NoError,
2730 name: "with a valid user",
2733 UserName: []byte("Testy McTest"),
2734 RemoteAddr: "1.2.3.4:12345",
2736 Access: func() accessBitmap {
2737 var bits accessBitmap
2738 bits.Set(accessGetClientInfo)
2745 Accounts: map[string]*Account{},
2746 Clients: map[uint16]*ClientConn{
2748 UserName: []byte("Testy McTest"),
2749 RemoteAddr: "1.2.3.4:12345",
2751 Access: func() accessBitmap {
2752 var bits accessBitmap
2753 bits.Set(accessGetClientInfo)
2762 transfers: map[int]map[[4]byte]*FileTransfer{
2770 TranGetClientInfoText, &[]byte{0, 1},
2771 NewField(FieldUserID, []byte{0, 1}),
2774 wantRes: []Transaction{
2778 NewField(FieldData, []byte(
2779 strings.ReplaceAll(`Nickname: Testy McTest
2782 Address: 1.2.3.4:12345
2784 -------- File Downloads ---------
2788 ------- Folder Downloads --------
2792 --------- File Uploads ----------
2796 -------- Folder Uploads ---------
2800 ------- Waiting Downloads -------
2806 NewField(FieldUserName, []byte("Testy McTest")),
2810 wantErr: assert.NoError,
2813 for _, tt := range tests {
2814 t.Run(tt.name, func(t *testing.T) {
2815 gotRes, err := HandleGetClientInfoText(tt.args.cc, tt.args.t)
2816 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetClientInfoText(%v, %v)", tt.args.cc, tt.args.t)) {
2819 tranAssertEqual(t, tt.wantRes, gotRes)
2824 func TestHandleTranAgreed(t *testing.T) {
2832 wantRes []Transaction
2833 wantErr assert.ErrorAssertionFunc
2836 name: "normal request flow",
2840 Access: func() accessBitmap {
2841 var bits accessBitmap
2842 bits.Set(accessDisconUser)
2843 bits.Set(accessAnyName)
2847 Flags: []byte{0, 1},
2848 Version: []byte{0, 1},
2850 logger: NewTestLogger(),
2853 BannerFile: "banner.jpg",
2859 NewField(FieldUserName, []byte("username")),
2860 NewField(FieldUserIconID, []byte{0, 1}),
2861 NewField(FieldOptions, []byte{0, 0}),
2864 wantRes: []Transaction{
2866 clientID: &[]byte{0, 1},
2867 Type: [2]byte{0, 0x7a},
2869 NewField(FieldBannerType, []byte("JPEG")),
2873 clientID: &[]byte{0, 1},
2878 wantErr: assert.NoError,
2881 for _, tt := range tests {
2882 t.Run(tt.name, func(t *testing.T) {
2883 gotRes, err := HandleTranAgreed(tt.args.cc, tt.args.t)
2884 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranAgreed(%v, %v)", tt.args.cc, tt.args.t)) {
2887 tranAssertEqual(t, tt.wantRes, gotRes)
2892 func TestHandleSetClientUserInfo(t *testing.T) {
2900 wantRes []Transaction
2901 wantErr assert.ErrorAssertionFunc
2904 name: "when client does not have accessAnyName",
2908 Access: func() accessBitmap {
2909 var bits accessBitmap
2914 UserName: []byte("Guest"),
2915 Flags: []byte{0, 1},
2917 Clients: map[uint16]*ClientConn{
2925 TranSetClientUserInfo, nil,
2926 NewField(FieldUserIconID, []byte{0, 1}),
2927 NewField(FieldUserName, []byte("NOPE")),
2930 wantRes: []Transaction{
2932 clientID: &[]byte{0, 1},
2933 Type: [2]byte{0x01, 0x2d},
2935 NewField(FieldUserID, []byte{0, 1}),
2936 NewField(FieldUserIconID, []byte{0, 1}),
2937 NewField(FieldUserFlags, []byte{0, 1}),
2938 NewField(FieldUserName, []byte("Guest"))},
2941 wantErr: assert.NoError,
2944 for _, tt := range tests {
2945 t.Run(tt.name, func(t *testing.T) {
2946 gotRes, err := HandleSetClientUserInfo(tt.args.cc, tt.args.t)
2947 if !tt.wantErr(t, err, fmt.Sprintf("HandleSetClientUserInfo(%v, %v)", tt.args.cc, tt.args.t)) {
2951 tranAssertEqual(t, tt.wantRes, gotRes)
2956 func TestHandleDelNewsItem(t *testing.T) {
2964 wantRes []Transaction
2965 wantErr assert.ErrorAssertionFunc
2968 name: "when user does not have permission to delete a news category",
2972 Access: accessBitmap{},
2976 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
2978 Type: [2]byte{0, 3},
2985 TranDelNewsItem, nil,
2986 NewField(FieldNewsPath,
2991 0x74, 0x65, 0x73, 0x74,
2996 wantRes: []Transaction{
2998 clientID: &[]byte{0, 1},
3000 ErrorCode: [4]byte{0, 0, 0, 1},
3002 NewField(FieldError, []byte("You are not allowed to delete news categories.")),
3006 wantErr: assert.NoError,
3009 name: "when user does not have permission to delete a news folder",
3013 Access: accessBitmap{},
3017 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3019 Type: [2]byte{0, 2},
3026 TranDelNewsItem, nil,
3027 NewField(FieldNewsPath,
3032 0x74, 0x65, 0x73, 0x74,
3037 wantRes: []Transaction{
3039 clientID: &[]byte{0, 1},
3041 ErrorCode: [4]byte{0, 0, 0, 1},
3043 NewField(FieldError, []byte("You are not allowed to delete news folders.")),
3047 wantErr: assert.NoError,
3050 name: "when user deletes a news folder",
3054 Access: func() accessBitmap {
3055 var bits accessBitmap
3056 bits.Set(accessNewsDeleteFldr)
3062 ConfigDir: "/fakeConfigRoot",
3063 FS: func() *MockFileStore {
3064 mfs := &MockFileStore{}
3065 mfs.On("WriteFile", "/fakeConfigRoot/ThreadedNews.yaml", mock.Anything, mock.Anything).Return(nil, os.ErrNotExist)
3068 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3070 Type: [2]byte{0, 2},
3077 TranDelNewsItem, nil,
3078 NewField(FieldNewsPath,
3083 0x74, 0x65, 0x73, 0x74,
3088 wantRes: []Transaction{
3090 clientID: &[]byte{0, 1},
3095 wantErr: assert.NoError,
3098 for _, tt := range tests {
3099 t.Run(tt.name, func(t *testing.T) {
3100 gotRes, err := HandleDelNewsItem(tt.args.cc, tt.args.t)
3101 if !tt.wantErr(t, err, fmt.Sprintf("HandleDelNewsItem(%v, %v)", tt.args.cc, tt.args.t)) {
3104 tranAssertEqual(t, tt.wantRes, gotRes)
3109 func TestHandleTranOldPostNews(t *testing.T) {
3117 wantRes []Transaction
3118 wantErr assert.ErrorAssertionFunc
3121 name: "when user does not have required permission",
3125 Access: func() accessBitmap {
3126 var bits accessBitmap
3132 TranOldPostNews, &[]byte{0, 1},
3133 NewField(FieldData, []byte("hai")),
3136 wantRes: []Transaction{
3139 ErrorCode: [4]byte{0, 0, 0, 1},
3141 NewField(FieldError, []byte("You are not allowed to post news.")),
3145 wantErr: assert.NoError,
3148 name: "when user posts news update",
3152 Access: func() accessBitmap {
3153 var bits accessBitmap
3154 bits.Set(accessNewsPostArt)
3159 FS: func() *MockFileStore {
3160 mfs := &MockFileStore{}
3161 mfs.On("WriteFile", "/fakeConfigRoot/MessageBoard.txt", mock.Anything, mock.Anything).Return(nil, os.ErrNotExist)
3164 ConfigDir: "/fakeConfigRoot",
3169 TranOldPostNews, &[]byte{0, 1},
3170 NewField(FieldData, []byte("hai")),
3173 wantRes: []Transaction{
3178 wantErr: assert.NoError,
3181 for _, tt := range tests {
3182 t.Run(tt.name, func(t *testing.T) {
3183 gotRes, err := HandleTranOldPostNews(tt.args.cc, tt.args.t)
3184 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranOldPostNews(%v, %v)", tt.args.cc, tt.args.t)) {
3188 tranAssertEqual(t, tt.wantRes, gotRes)
3193 func TestHandleInviteNewChat(t *testing.T) {
3201 wantRes []Transaction
3202 wantErr assert.ErrorAssertionFunc
3205 name: "when user does not have required permission",
3209 Access: func() accessBitmap {
3210 var bits accessBitmap
3215 t: NewTransaction(TranInviteNewChat, &[]byte{0, 1}),
3217 wantRes: []Transaction{
3220 ErrorCode: [4]byte{0, 0, 0, 1},
3222 NewField(FieldError, []byte("You are not allowed to request private chat.")),
3226 wantErr: assert.NoError,
3229 name: "when userA invites userB to new private chat",
3234 Access: func() accessBitmap {
3235 var bits accessBitmap
3236 bits.Set(accessOpenChat)
3240 UserName: []byte("UserA"),
3242 Flags: []byte{0, 0},
3244 Clients: map[uint16]*ClientConn{
3247 UserName: []byte("UserB"),
3248 Flags: []byte{0, 0},
3251 PrivateChats: make(map[uint32]*PrivateChat),
3255 TranInviteNewChat, &[]byte{0, 1},
3256 NewField(FieldUserID, []byte{0, 2}),
3259 wantRes: []Transaction{
3261 clientID: &[]byte{0, 2},
3262 Type: [2]byte{0, 0x71},
3264 NewField(FieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3265 NewField(FieldUserName, []byte("UserA")),
3266 NewField(FieldUserID, []byte{0, 1}),
3271 clientID: &[]byte{0, 1},
3274 NewField(FieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3275 NewField(FieldUserName, []byte("UserA")),
3276 NewField(FieldUserID, []byte{0, 1}),
3277 NewField(FieldUserIconID, []byte{0, 1}),
3278 NewField(FieldUserFlags, []byte{0, 0}),
3282 wantErr: assert.NoError,
3285 name: "when userA invites userB to new private chat, but UserB has refuse private chat enabled",
3290 Access: func() accessBitmap {
3291 var bits accessBitmap
3292 bits.Set(accessOpenChat)
3296 UserName: []byte("UserA"),
3298 Flags: []byte{0, 0},
3300 Clients: map[uint16]*ClientConn{
3303 UserName: []byte("UserB"),
3304 Flags: []byte{255, 255},
3307 PrivateChats: make(map[uint32]*PrivateChat),
3311 TranInviteNewChat, &[]byte{0, 1},
3312 NewField(FieldUserID, []byte{0, 2}),
3315 wantRes: []Transaction{
3317 clientID: &[]byte{0, 1},
3318 Type: [2]byte{0, 0x68},
3320 NewField(FieldData, []byte("UserB does not accept private chats.")),
3321 NewField(FieldUserName, []byte("UserB")),
3322 NewField(FieldUserID, []byte{0, 2}),
3323 NewField(FieldOptions, []byte{0, 2}),
3327 clientID: &[]byte{0, 1},
3330 NewField(FieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3331 NewField(FieldUserName, []byte("UserA")),
3332 NewField(FieldUserID, []byte{0, 1}),
3333 NewField(FieldUserIconID, []byte{0, 1}),
3334 NewField(FieldUserFlags, []byte{0, 0}),
3338 wantErr: assert.NoError,
3341 for _, tt := range tests {
3342 t.Run(tt.name, func(t *testing.T) {
3343 gotRes, err := HandleInviteNewChat(tt.args.cc, tt.args.t)
3344 if !tt.wantErr(t, err, fmt.Sprintf("HandleInviteNewChat(%v, %v)", tt.args.cc, tt.args.t)) {
3347 tranAssertEqual(t, tt.wantRes, gotRes)
3352 func TestHandleGetNewsArtData(t *testing.T) {
3360 wantRes []Transaction
3361 wantErr assert.ErrorAssertionFunc
3364 name: "when user does not have required permission",
3368 Access: func() accessBitmap {
3369 var bits accessBitmap
3374 Accounts: map[string]*Account{},
3378 TranGetNewsArtData, &[]byte{0, 1},
3381 wantRes: []Transaction{
3384 ErrorCode: [4]byte{0, 0, 0, 1},
3386 NewField(FieldError, []byte("You are not allowed to read news.")),
3390 wantErr: assert.NoError,
3393 for _, tt := range tests {
3394 t.Run(tt.name, func(t *testing.T) {
3395 gotRes, err := HandleGetNewsArtData(tt.args.cc, tt.args.t)
3396 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetNewsArtData(%v, %v)", tt.args.cc, tt.args.t)) {
3399 tranAssertEqual(t, tt.wantRes, gotRes)
3404 func TestHandleGetNewsArtNameList(t *testing.T) {
3412 wantRes []Transaction
3413 wantErr assert.ErrorAssertionFunc
3416 name: "when user does not have required permission",
3420 Access: func() accessBitmap {
3421 var bits accessBitmap
3426 Accounts: map[string]*Account{},
3430 TranGetNewsArtNameList, &[]byte{0, 1},
3433 wantRes: []Transaction{
3437 Type: [2]byte{0, 0},
3438 ErrorCode: [4]byte{0, 0, 0, 1},
3440 NewField(FieldError, []byte("You are not allowed to read news.")),
3444 wantErr: assert.NoError,
3447 name: "when user has required access",
3451 Access: func() accessBitmap {
3452 var bits accessBitmap
3453 bits.Set(accessNewsReadArt)
3458 ThreadedNews: &ThreadedNews{
3459 Categories: map[string]NewsCategoryListData15{
3460 "Example Category": {
3461 Type: [2]byte{0, 2},
3463 Articles: map[uint32]*NewsArtData{
3466 Poster: "testPoster",
3473 DeleteSN: [4]byte{},
3478 //Accounts: map[string]*Account{
3483 // Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
3489 TranGetNewsArtNameList,
3491 // 00000000 00 01 00 00 10 45 78 61 6d 70 6c 65 20 43 61 74 |.....Example Cat|
3492 // 00000010 65 67 6f 72 79 |egory|
3493 NewField(FieldNewsPath, []byte{
3494 0x00, 0x01, 0x00, 0x00, 0x10, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79,
3498 wantRes: []Transaction{
3502 NewField(FieldNewsArtListData, []byte{
3503 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
3504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
3505 0x09, 0x74, 0x65, 0x73, 0x74, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x50,
3506 0x6f, 0x73, 0x74, 0x65, 0x72, 0x0a, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e,
3513 wantErr: assert.NoError,
3516 for _, tt := range tests {
3517 t.Run(tt.name, func(t *testing.T) {
3518 gotRes, err := HandleGetNewsArtNameList(tt.args.cc, tt.args.t)
3519 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetNewsArtNameList(%v, %v)", tt.args.cc, tt.args.t)) {
3522 tranAssertEqual(t, tt.wantRes, gotRes)
3527 func TestHandleNewNewsFldr(t *testing.T) {
3535 wantRes []Transaction
3536 wantErr assert.ErrorAssertionFunc
3539 name: "when user does not have required permission",
3543 Access: func() accessBitmap {
3544 var bits accessBitmap
3549 Accounts: map[string]*Account{},
3553 TranGetNewsArtNameList, &[]byte{0, 1},
3556 wantRes: []Transaction{
3560 Type: [2]byte{0, 0},
3561 ErrorCode: [4]byte{0, 0, 0, 1},
3563 NewField(FieldError, []byte("You are not allowed to create news folders.")),
3567 wantErr: assert.NoError,
3570 name: "with a valid request",
3574 Access: func() accessBitmap {
3575 var bits accessBitmap
3576 bits.Set(accessNewsCreateFldr)
3580 logger: NewTestLogger(),
3583 ConfigDir: "/fakeConfigRoot",
3584 FS: func() *MockFileStore {
3585 mfs := &MockFileStore{}
3586 mfs.On("WriteFile", "/fakeConfigRoot/ThreadedNews.yaml", mock.Anything, mock.Anything).Return(nil)
3589 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3591 Type: [2]byte{0, 2},
3593 SubCats: make(map[string]NewsCategoryListData15),
3599 TranGetNewsArtNameList, &[]byte{0, 1},
3600 NewField(FieldFileName, []byte("testFolder")),
3601 NewField(FieldNewsPath,
3606 0x74, 0x65, 0x73, 0x74,
3611 wantRes: []Transaction{
3613 clientID: &[]byte{0, 1},
3618 wantErr: assert.NoError,
3621 // Name: "when there is an error writing the threaded news file",
3624 // Account: &Account{
3625 // Access: func() accessBitmap {
3626 // var bits accessBitmap
3627 // bits.Set(accessNewsCreateFldr)
3631 // logger: NewTestLogger(),
3632 // ID: &[]byte{0, 1},
3634 // ConfigDir: "/fakeConfigRoot",
3635 // FS: func() *MockFileStore {
3636 // mfs := &MockFileStore{}
3637 // mfs.On("WriteFile", "/fakeConfigRoot/ThreadedNews.yaml", mock.Anything, mock.Anything).Return(os.ErrNotExist)
3640 // ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3642 // Type: []byte{0, 2},
3646 // SubCats: make(map[string]NewsCategoryListData15),
3651 // t: NewTransaction(
3652 // TranGetNewsArtNameList, &[]byte{0, 1},
3653 // NewField(FieldFileName, []byte("testFolder")),
3654 // NewField(FieldNewsPath,
3659 // 0x74, 0x65, 0x73, 0x74,
3664 // wantRes: []Transaction{
3666 // clientID: &[]byte{0, 1},
3669 // Type: [2]byte{0, 0},
3670 // ErrorCode: [4]byte{0, 0, 0, 1},
3672 // NewField(FieldError, []byte("Error creating news folder.")),
3676 // wantErr: assert.Error,
3679 for _, tt := range tests {
3680 t.Run(tt.name, func(t *testing.T) {
3681 gotRes, err := HandleNewNewsFldr(tt.args.cc, tt.args.t)
3682 if !tt.wantErr(t, err, fmt.Sprintf("HandleNewNewsFldr(%v, %v)", tt.args.cc, tt.args.t)) {
3685 tranAssertEqual(t, tt.wantRes, gotRes)
3690 func TestHandleDownloadBanner(t *testing.T) {
3698 wantRes []Transaction
3699 wantErr assert.ErrorAssertionFunc
3701 // TODO: Add test cases.
3703 for _, tt := range tests {
3704 t.Run(tt.name, func(t *testing.T) {
3705 gotRes, err := HandleDownloadBanner(tt.args.cc, tt.args.t)
3706 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadBanner(%v, %v)", tt.args.cc, tt.args.t)) {
3709 assert.Equalf(t, tt.wantRes, gotRes, "HandleDownloadBanner(%v, %v)", tt.args.cc, tt.args.t)