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: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
45 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
52 Clients: map[uint16]*ClientConn{
55 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
61 Access: accessBitmap{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: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
153 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
160 Clients: map[uint16]*ClientConn{
163 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
169 Access: accessBitmap{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() accessBitmap {
310 var bits accessBitmap
311 bits.Set(accessSendChat)
315 UserName: []byte{0x00, 0x01},
317 Clients: map[uint16]*ClientConn{
320 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
326 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
335 NewField(fieldData, []byte("hai")),
341 clientID: &[]byte{0, 1},
344 Type: []byte{0, 0x6a},
345 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
346 ErrorCode: []byte{0, 0, 0, 0},
348 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
352 clientID: &[]byte{0, 2},
355 Type: []byte{0, 0x6a},
356 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
357 ErrorCode: []byte{0, 0, 0, 0},
359 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
366 name: "when user does not have required permission",
370 Access: func() accessBitmap {
371 var bits accessBitmap
376 Accounts: map[string]*Account{},
380 tranChatSend, &[]byte{0, 1},
381 NewField(fieldData, []byte("hai")),
388 Type: []byte{0, 0x00},
389 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
390 ErrorCode: []byte{0, 0, 0, 1},
392 NewField(fieldError, []byte("You are not allowed to participate in chat.")),
399 name: "sends chat msg as emote if fieldChatOptions is set",
403 Access: func() accessBitmap {
404 var bits accessBitmap
405 bits.Set(accessSendChat)
409 UserName: []byte("Testy McTest"),
411 Clients: map[uint16]*ClientConn{
414 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
420 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
429 NewField(fieldData, []byte("performed action")),
430 NewField(fieldChatOptions, []byte{0x00, 0x01}),
436 clientID: &[]byte{0, 1},
439 Type: []byte{0, 0x6a},
440 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
441 ErrorCode: []byte{0, 0, 0, 0},
443 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
447 clientID: &[]byte{0, 2},
450 Type: []byte{0, 0x6a},
451 ID: []byte{0xf0, 0xc5, 0x34, 0x1e},
452 ErrorCode: []byte{0, 0, 0, 0},
454 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
461 name: "only sends chat msg to clients with accessReadChat permission",
465 Access: func() accessBitmap {
466 var bits accessBitmap
467 bits.Set(accessSendChat)
471 UserName: []byte{0x00, 0x01},
473 Clients: map[uint16]*ClientConn{
476 Access: func() accessBitmap {
477 var bits accessBitmap
478 bits.Set(accessReadChat)
485 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
494 NewField(fieldData, []byte("hai")),
500 clientID: &[]byte{0, 1},
503 Type: []byte{0, 0x6a},
504 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
505 ErrorCode: []byte{0, 0, 0, 0},
507 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
514 name: "only sends private chat msg to members of private chat",
518 Access: func() accessBitmap {
519 var bits accessBitmap
520 bits.Set(accessSendChat)
524 UserName: []byte{0x00, 0x01},
526 PrivateChats: map[uint32]*PrivateChat{
528 ClientConn: map[uint16]*ClientConn{
538 Clients: map[uint16]*ClientConn{
541 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
547 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
553 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
562 NewField(fieldData, []byte("hai")),
563 NewField(fieldChatID, []byte{0, 0, 0, 1}),
569 clientID: &[]byte{0, 1},
572 Type: []byte{0, 0x6a},
573 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
574 ErrorCode: []byte{0, 0, 0, 0},
576 NewField(fieldChatID, []byte{0, 0, 0, 1}),
577 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
581 clientID: &[]byte{0, 2},
584 Type: []byte{0, 0x6a},
585 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
586 ErrorCode: []byte{0, 0, 0, 0},
588 NewField(fieldChatID, []byte{0, 0, 0, 1}),
589 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
596 for _, tt := range tests {
597 t.Run(tt.name, func(t *testing.T) {
598 got, err := HandleChatSend(tt.args.cc, tt.args.t)
600 if (err != nil) != tt.wantErr {
601 t.Errorf("HandleChatSend() error = %v, wantErr %v", err, tt.wantErr)
604 tranAssertEqual(t, tt.want, got)
609 func TestHandleGetFileInfo(t *testing.T) {
610 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
619 wantRes []Transaction
623 name: "returns expected fields when a valid file is requested",
626 ID: &[]byte{0x00, 0x01},
630 FileRoot: func() string {
631 path, _ := os.Getwd()
632 return filepath.Join(path, "/test/config/Files")
638 tranGetFileInfo, nil,
639 NewField(fieldFileName, []byte("testfile.txt")),
640 NewField(fieldFilePath, []byte{0x00, 0x00}),
643 wantRes: []Transaction{
645 clientID: &[]byte{0, 1},
648 Type: []byte{0, 0xce},
649 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
650 ErrorCode: []byte{0, 0, 0, 0},
652 NewField(fieldFileName, []byte("testfile.txt")),
653 NewField(fieldFileTypeString, []byte("Text File")),
654 NewField(fieldFileCreatorString, []byte("ttxt")),
655 NewField(fieldFileComment, []byte{}),
656 NewField(fieldFileType, []byte("TEXT")),
657 NewField(fieldFileCreateDate, make([]byte, 8)),
658 NewField(fieldFileModifyDate, make([]byte, 8)),
659 NewField(fieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}),
666 for _, tt := range tests {
667 t.Run(tt.name, func(t *testing.T) {
668 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
670 gotRes, err := HandleGetFileInfo(tt.args.cc, tt.args.t)
671 if (err != nil) != tt.wantErr {
672 t.Errorf("HandleGetFileInfo() error = %v, wantErr %v", err, tt.wantErr)
676 // Clear the fileWrapper timestamp fields to work around problems running the tests in multiple timezones
677 // TODO: revisit how to test this by mocking the stat calls
678 gotRes[0].Fields[5].Data = make([]byte, 8)
679 gotRes[0].Fields[6].Data = make([]byte, 8)
680 if !assert.Equal(t, tt.wantRes, gotRes) {
681 t.Errorf("HandleGetFileInfo() gotRes = %v, want %v", gotRes, tt.wantRes)
687 func TestHandleNewFolder(t *testing.T) {
695 wantRes []Transaction
699 name: "without required permission",
703 Access: func() accessBitmap {
704 var bits accessBitmap
714 wantRes: []Transaction{
718 Type: []byte{0, 0x00},
719 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
720 ErrorCode: []byte{0, 0, 0, 1},
722 NewField(fieldError, []byte("You are not allowed to create folders.")),
729 name: "when path is nested",
733 Access: func() accessBitmap {
734 var bits accessBitmap
735 bits.Set(accessCreateFolder)
744 FS: func() *MockFileStore {
745 mfs := &MockFileStore{}
746 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
747 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
753 tranNewFolder, &[]byte{0, 1},
754 NewField(fieldFileName, []byte("testFolder")),
755 NewField(fieldFilePath, []byte{
763 wantRes: []Transaction{
765 clientID: &[]byte{0, 1},
768 Type: []byte{0, 0xcd},
769 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
770 ErrorCode: []byte{0, 0, 0, 0},
776 name: "when path is not nested",
780 Access: func() accessBitmap {
781 var bits accessBitmap
782 bits.Set(accessCreateFolder)
791 FS: func() *MockFileStore {
792 mfs := &MockFileStore{}
793 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
794 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
800 tranNewFolder, &[]byte{0, 1},
801 NewField(fieldFileName, []byte("testFolder")),
804 wantRes: []Transaction{
806 clientID: &[]byte{0, 1},
809 Type: []byte{0, 0xcd},
810 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
811 ErrorCode: []byte{0, 0, 0, 0},
817 name: "when UnmarshalBinary returns an err",
821 Access: func() accessBitmap {
822 var bits accessBitmap
823 bits.Set(accessCreateFolder)
832 FS: func() *MockFileStore {
833 mfs := &MockFileStore{}
834 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
835 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
841 tranNewFolder, &[]byte{0, 1},
842 NewField(fieldFileName, []byte("testFolder")),
843 NewField(fieldFilePath, []byte{
848 wantRes: []Transaction{},
852 name: "fieldFileName does not allow directory traversal",
856 Access: func() accessBitmap {
857 var bits accessBitmap
858 bits.Set(accessCreateFolder)
867 FS: func() *MockFileStore {
868 mfs := &MockFileStore{}
869 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
870 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
876 tranNewFolder, &[]byte{0, 1},
877 NewField(fieldFileName, []byte("../../testFolder")),
880 wantRes: []Transaction{
882 clientID: &[]byte{0, 1},
885 Type: []byte{0, 0xcd},
886 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
887 ErrorCode: []byte{0, 0, 0, 0},
892 name: "fieldFilePath does not allow directory traversal",
896 Access: func() accessBitmap {
897 var bits accessBitmap
898 bits.Set(accessCreateFolder)
907 FS: func() *MockFileStore {
908 mfs := &MockFileStore{}
909 mfs.On("Mkdir", "/Files/foo/testFolder", fs.FileMode(0777)).Return(nil)
910 mfs.On("Stat", "/Files/foo/testFolder").Return(nil, os.ErrNotExist)
916 tranNewFolder, &[]byte{0, 1},
917 NewField(fieldFileName, []byte("testFolder")),
918 NewField(fieldFilePath, []byte{
929 wantRes: []Transaction{
931 clientID: &[]byte{0, 1},
934 Type: []byte{0, 0xcd},
935 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
936 ErrorCode: []byte{0, 0, 0, 0},
941 for _, tt := range tests {
942 t.Run(tt.name, func(t *testing.T) {
944 gotRes, err := HandleNewFolder(tt.args.cc, tt.args.t)
945 if (err != nil) != tt.wantErr {
946 t.Errorf("HandleNewFolder() error = %v, wantErr %v", err, tt.wantErr)
950 if !tranAssertEqual(t, tt.wantRes, gotRes) {
951 t.Errorf("HandleNewFolder() gotRes = %v, want %v", gotRes, tt.wantRes)
957 func TestHandleUploadFile(t *testing.T) {
965 wantRes []Transaction
969 name: "when request is valid and user has Upload Anywhere permission",
974 fileTransfers: map[[4]byte]*FileTransfer{},
976 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
978 transfers: map[int]map[[4]byte]*FileTransfer{
982 Access: func() accessBitmap {
983 var bits accessBitmap
984 bits.Set(accessUploadFile)
985 bits.Set(accessUploadAnywhere)
991 tranUploadFile, &[]byte{0, 1},
992 NewField(fieldFileName, []byte("testFile")),
993 NewField(fieldFilePath, []byte{
1001 wantRes: []Transaction{
1005 Type: []byte{0, 0xcb},
1006 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1007 ErrorCode: []byte{0, 0, 0, 0},
1009 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), // rand.Seed(1)
1016 name: "when user does not have required access",
1020 Access: func() accessBitmap {
1021 var bits accessBitmap
1027 tranUploadFile, &[]byte{0, 1},
1028 NewField(fieldFileName, []byte("testFile")),
1029 NewField(fieldFilePath, []byte{
1037 wantRes: []Transaction{
1041 Type: []byte{0, 0x00},
1042 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1043 ErrorCode: []byte{0, 0, 0, 1},
1045 NewField(fieldError, []byte("You are not allowed to upload files.")), // rand.Seed(1)
1052 for _, tt := range tests {
1053 t.Run(tt.name, func(t *testing.T) {
1055 gotRes, err := HandleUploadFile(tt.args.cc, tt.args.t)
1056 if (err != nil) != tt.wantErr {
1057 t.Errorf("HandleUploadFile() error = %v, wantErr %v", err, tt.wantErr)
1061 tranAssertEqual(t, tt.wantRes, gotRes)
1067 func TestHandleMakeAlias(t *testing.T) {
1075 wantRes []Transaction
1079 name: "with valid input and required permissions",
1082 logger: NewTestLogger(),
1084 Access: func() accessBitmap {
1085 var bits accessBitmap
1086 bits.Set(accessMakeAlias)
1092 FileRoot: func() string {
1093 path, _ := os.Getwd()
1094 return path + "/test/config/Files"
1097 Logger: NewTestLogger(),
1098 FS: func() *MockFileStore {
1099 mfs := &MockFileStore{}
1100 path, _ := os.Getwd()
1103 path+"/test/config/Files/foo/testFile",
1104 path+"/test/config/Files/bar/testFile",
1111 tranMakeFileAlias, &[]byte{0, 1},
1112 NewField(fieldFileName, []byte("testFile")),
1113 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1114 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1117 wantRes: []Transaction{
1121 Type: []byte{0, 0xd1},
1122 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1123 ErrorCode: []byte{0, 0, 0, 0},
1124 Fields: []Field(nil),
1130 name: "when symlink returns an error",
1133 logger: NewTestLogger(),
1135 Access: func() accessBitmap {
1136 var bits accessBitmap
1137 bits.Set(accessMakeAlias)
1143 FileRoot: func() string {
1144 path, _ := os.Getwd()
1145 return path + "/test/config/Files"
1148 Logger: NewTestLogger(),
1149 FS: func() *MockFileStore {
1150 mfs := &MockFileStore{}
1151 path, _ := os.Getwd()
1154 path+"/test/config/Files/foo/testFile",
1155 path+"/test/config/Files/bar/testFile",
1156 ).Return(errors.New("ohno"))
1162 tranMakeFileAlias, &[]byte{0, 1},
1163 NewField(fieldFileName, []byte("testFile")),
1164 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1165 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1168 wantRes: []Transaction{
1172 Type: []byte{0, 0x00},
1173 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1174 ErrorCode: []byte{0, 0, 0, 1},
1176 NewField(fieldError, []byte("Error creating alias")),
1183 name: "when user does not have required permission",
1186 logger: NewTestLogger(),
1188 Access: func() accessBitmap {
1189 var bits accessBitmap
1195 FileRoot: func() string {
1196 path, _ := os.Getwd()
1197 return path + "/test/config/Files"
1203 tranMakeFileAlias, &[]byte{0, 1},
1204 NewField(fieldFileName, []byte("testFile")),
1205 NewField(fieldFilePath, []byte{
1211 NewField(fieldFileNewPath, []byte{
1219 wantRes: []Transaction{
1223 Type: []byte{0, 0x00},
1224 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1225 ErrorCode: []byte{0, 0, 0, 1},
1227 NewField(fieldError, []byte("You are not allowed to make aliases.")),
1234 for _, tt := range tests {
1235 t.Run(tt.name, func(t *testing.T) {
1236 gotRes, err := HandleMakeAlias(tt.args.cc, tt.args.t)
1237 if (err != nil) != tt.wantErr {
1238 t.Errorf("HandleMakeAlias(%v, %v)", tt.args.cc, tt.args.t)
1242 tranAssertEqual(t, tt.wantRes, gotRes)
1247 func TestHandleGetUser(t *testing.T) {
1255 wantRes []Transaction
1256 wantErr assert.ErrorAssertionFunc
1259 name: "when account is valid",
1263 Access: func() accessBitmap {
1264 var bits accessBitmap
1265 bits.Set(accessOpenUser)
1270 Accounts: map[string]*Account{
1274 Password: "password",
1275 Access: accessBitmap{},
1281 tranGetUser, &[]byte{0, 1},
1282 NewField(fieldUserLogin, []byte("guest")),
1285 wantRes: []Transaction{
1289 Type: []byte{0x01, 0x60},
1290 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1291 ErrorCode: []byte{0, 0, 0, 0},
1293 NewField(fieldUserName, []byte("Guest")),
1294 NewField(fieldUserLogin, negateString([]byte("guest"))),
1295 NewField(fieldUserPassword, []byte("password")),
1296 NewField(fieldUserAccess, []byte{0, 0, 0, 0, 0, 0, 0, 0}),
1300 wantErr: assert.NoError,
1303 name: "when user does not have required permission",
1307 Access: func() accessBitmap {
1308 var bits accessBitmap
1313 Accounts: map[string]*Account{},
1317 tranGetUser, &[]byte{0, 1},
1318 NewField(fieldUserLogin, []byte("nonExistentUser")),
1321 wantRes: []Transaction{
1325 Type: []byte{0, 0x00},
1326 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1327 ErrorCode: []byte{0, 0, 0, 1},
1329 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1333 wantErr: assert.NoError,
1336 name: "when account does not exist",
1340 Access: func() accessBitmap {
1341 var bits accessBitmap
1342 bits.Set(accessOpenUser)
1347 Accounts: map[string]*Account{},
1351 tranGetUser, &[]byte{0, 1},
1352 NewField(fieldUserLogin, []byte("nonExistentUser")),
1355 wantRes: []Transaction{
1359 Type: []byte{0, 0x00},
1360 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1361 ErrorCode: []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, negateString([]byte("testuser"))),
1425 wantRes: []Transaction{
1429 Type: []byte{0x1, 0x5f},
1430 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1431 ErrorCode: []byte{0, 0, 0, 0},
1432 Fields: []Field(nil),
1435 wantErr: assert.NoError,
1438 name: "when user does not have required permission",
1442 Access: func() accessBitmap {
1443 var bits accessBitmap
1448 Accounts: map[string]*Account{},
1452 tranDeleteUser, &[]byte{0, 1},
1453 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1456 wantRes: []Transaction{
1460 Type: []byte{0, 0x00},
1461 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1462 ErrorCode: []byte{0, 0, 0, 1},
1464 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
1468 wantErr: assert.NoError,
1471 for _, tt := range tests {
1472 t.Run(tt.name, func(t *testing.T) {
1473 gotRes, err := HandleDeleteUser(tt.args.cc, tt.args.t)
1474 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteUser(%v, %v)", tt.args.cc, tt.args.t)) {
1478 tranAssertEqual(t, tt.wantRes, gotRes)
1483 func TestHandleGetMsgs(t *testing.T) {
1491 wantRes []Transaction
1492 wantErr assert.ErrorAssertionFunc
1495 name: "returns news data",
1499 Access: func() accessBitmap {
1500 var bits accessBitmap
1501 bits.Set(accessNewsReadArt)
1506 FlatNews: []byte("TEST"),
1510 tranGetMsgs, &[]byte{0, 1},
1513 wantRes: []Transaction{
1517 Type: []byte{0, 0x65},
1518 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1519 ErrorCode: []byte{0, 0, 0, 0},
1521 NewField(fieldData, []byte("TEST")),
1525 wantErr: assert.NoError,
1528 name: "when user does not have required permission",
1532 Access: func() accessBitmap {
1533 var bits accessBitmap
1538 Accounts: map[string]*Account{},
1542 tranGetMsgs, &[]byte{0, 1},
1545 wantRes: []Transaction{
1549 Type: []byte{0, 0x00},
1550 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1551 ErrorCode: []byte{0, 0, 0, 1},
1553 NewField(fieldError, []byte("You are not allowed to read news.")),
1557 wantErr: assert.NoError,
1560 for _, tt := range tests {
1561 t.Run(tt.name, func(t *testing.T) {
1562 gotRes, err := HandleGetMsgs(tt.args.cc, tt.args.t)
1563 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetMsgs(%v, %v)", tt.args.cc, tt.args.t)) {
1567 tranAssertEqual(t, tt.wantRes, gotRes)
1572 func TestHandleNewUser(t *testing.T) {
1580 wantRes []Transaction
1581 wantErr assert.ErrorAssertionFunc
1584 name: "when user does not have required permission",
1588 Access: func() accessBitmap {
1589 var bits accessBitmap
1594 Accounts: map[string]*Account{},
1598 tranNewUser, &[]byte{0, 1},
1601 wantRes: []Transaction{
1605 Type: []byte{0, 0x00},
1606 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1607 ErrorCode: []byte{0, 0, 0, 1},
1609 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
1613 wantErr: assert.NoError,
1616 for _, tt := range tests {
1617 t.Run(tt.name, func(t *testing.T) {
1618 gotRes, err := HandleNewUser(tt.args.cc, tt.args.t)
1619 if !tt.wantErr(t, err, fmt.Sprintf("HandleNewUser(%v, %v)", tt.args.cc, tt.args.t)) {
1623 tranAssertEqual(t, tt.wantRes, gotRes)
1628 func TestHandleListUsers(t *testing.T) {
1636 wantRes []Transaction
1637 wantErr assert.ErrorAssertionFunc
1640 name: "when user does not have required permission",
1644 Access: func() accessBitmap {
1645 var bits accessBitmap
1650 Accounts: map[string]*Account{},
1654 tranNewUser, &[]byte{0, 1},
1657 wantRes: []Transaction{
1661 Type: []byte{0, 0x00},
1662 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1663 ErrorCode: []byte{0, 0, 0, 1},
1665 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1669 wantErr: assert.NoError,
1672 name: "when user has required permission",
1676 Access: func() accessBitmap {
1677 var bits accessBitmap
1678 bits.Set(accessOpenUser)
1683 Accounts: map[string]*Account{
1688 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
1694 tranGetClientInfoText, &[]byte{0, 1},
1695 NewField(fieldUserID, []byte{0, 1}),
1698 wantRes: []Transaction{
1702 Type: []byte{0x01, 0x2f},
1703 ID: []byte{0, 0, 0, 0},
1704 ErrorCode: []byte{0, 0, 0, 0},
1706 NewField(fieldData, []byte{
1707 0x00, 0x04, 0x00, 0x66, 0x00, 0x05, 0x67, 0x75, 0x65, 0x73, 0x74, 0x00, 0x69, 0x00, 0x05, 0x98,
1708 0x8a, 0x9a, 0x8c, 0x8b, 0x00, 0x6e, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1709 0x00, 0x6a, 0x00, 0x01, 0x78,
1714 wantErr: assert.NoError,
1717 for _, tt := range tests {
1718 t.Run(tt.name, func(t *testing.T) {
1719 gotRes, err := HandleListUsers(tt.args.cc, tt.args.t)
1720 if !tt.wantErr(t, err, fmt.Sprintf("HandleListUsers(%v, %v)", tt.args.cc, tt.args.t)) {
1724 tranAssertEqual(t, tt.wantRes, gotRes)
1729 func TestHandleDownloadFile(t *testing.T) {
1737 wantRes []Transaction
1738 wantErr assert.ErrorAssertionFunc
1741 name: "when user does not have required permission",
1745 Access: func() accessBitmap {
1746 var bits accessBitmap
1752 t: NewTransaction(tranDownloadFile, &[]byte{0, 1}),
1754 wantRes: []Transaction{
1758 Type: []byte{0, 0x00},
1759 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1760 ErrorCode: []byte{0, 0, 0, 1},
1762 NewField(fieldError, []byte("You are not allowed to download files.")),
1766 wantErr: assert.NoError,
1769 name: "with a valid file",
1772 transfers: map[int]map[[4]byte]*FileTransfer{
1776 Access: func() accessBitmap {
1777 var bits accessBitmap
1778 bits.Set(accessDownloadFile)
1784 fileTransfers: map[[4]byte]*FileTransfer{},
1786 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1788 Accounts: map[string]*Account{},
1794 NewField(fieldFileName, []byte("testfile.txt")),
1795 NewField(fieldFilePath, []byte{0x0, 0x00}),
1798 wantRes: []Transaction{
1802 Type: []byte{0, 0x2},
1803 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1804 ErrorCode: []byte{0, 0, 0, 0},
1806 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
1807 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
1808 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x00, 0xa5}),
1809 NewField(fieldFileSize, []byte{0x00, 0x00, 0x00, 0x17}),
1813 wantErr: assert.NoError,
1816 name: "when client requests to resume 1k test file at offset 256",
1819 transfers: map[int]map[[4]byte]*FileTransfer{
1821 }, Account: &Account{
1822 Access: func() accessBitmap {
1823 var bits accessBitmap
1824 bits.Set(accessDownloadFile)
1831 // FS: func() *MockFileStore {
1832 // path, _ := os.Getwd()
1833 // testFile, err := os.Open(path + "/test/config/Files/testfile-1k")
1838 // mfi := &MockFileInfo{}
1839 // mfi.On("Mode").Return(fs.FileMode(0))
1840 // mfs := &MockFileStore{}
1841 // mfs.On("Stat", "/fakeRoot/Files/testfile.txt").Return(mfi, nil)
1842 // mfs.On("Open", "/fakeRoot/Files/testfile.txt").Return(testFile, nil)
1843 // mfs.On("Stat", "/fakeRoot/Files/.info_testfile.txt").Return(nil, errors.New("no"))
1844 // mfs.On("Stat", "/fakeRoot/Files/.rsrc_testfile.txt").Return(nil, errors.New("no"))
1848 fileTransfers: map[[4]byte]*FileTransfer{},
1850 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1852 Accounts: map[string]*Account{},
1858 NewField(fieldFileName, []byte("testfile-1k")),
1859 NewField(fieldFilePath, []byte{0x00, 0x00}),
1861 fieldFileResumeData,
1863 frd := FileResumeData{
1867 ForkCount: [2]byte{0, 2},
1868 ForkInfoList: []ForkInfoList{
1870 Fork: [4]byte{0x44, 0x41, 0x54, 0x41}, // "DATA"
1871 DataSize: [4]byte{0, 0, 0x01, 0x00}, // request offset 256
1876 Fork: [4]byte{0x4d, 0x41, 0x43, 0x52}, // "MACR"
1877 DataSize: [4]byte{0, 0, 0, 0},
1883 b, _ := frd.BinaryMarshal()
1889 wantRes: []Transaction{
1893 Type: []byte{0, 0x2},
1894 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1895 ErrorCode: []byte{0, 0, 0, 0},
1897 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
1898 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
1899 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x03, 0x8d}),
1900 NewField(fieldFileSize, []byte{0x00, 0x00, 0x03, 0x00}),
1904 wantErr: assert.NoError,
1907 for _, tt := range tests {
1908 t.Run(tt.name, func(t *testing.T) {
1909 gotRes, err := HandleDownloadFile(tt.args.cc, tt.args.t)
1910 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadFile(%v, %v)", tt.args.cc, tt.args.t)) {
1914 tranAssertEqual(t, tt.wantRes, gotRes)
1919 func TestHandleUpdateUser(t *testing.T) {
1927 wantRes []Transaction
1928 wantErr assert.ErrorAssertionFunc
1931 name: "when action is create user without required permission",
1934 logger: NewTestLogger(),
1936 Logger: NewTestLogger(),
1939 Access: func() accessBitmap {
1940 var bits accessBitmap
1948 NewField(fieldData, []byte{
1949 0x00, 0x04, // field count
1951 0x00, 0x69, // fieldUserLogin = 105
1955 0x00, 0x6a, // fieldUserPassword = 106
1959 0x00, 0x66, // fieldUserName = 102
1963 0x00, 0x6e, // fieldUserAccess = 110
1965 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
1969 wantRes: []Transaction{
1973 Type: []byte{0, 0x00},
1974 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1975 ErrorCode: []byte{0, 0, 0, 1},
1977 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
1981 wantErr: assert.NoError,
1984 name: "when action is modify user without required permission",
1987 logger: NewTestLogger(),
1989 Logger: NewTestLogger(),
1990 Accounts: map[string]*Account{
1995 Access: func() accessBitmap {
1996 var bits accessBitmap
2004 NewField(fieldData, []byte{
2005 0x00, 0x04, // field count
2007 0x00, 0x69, // fieldUserLogin = 105
2011 0x00, 0x6a, // fieldUserPassword = 106
2015 0x00, 0x66, // fieldUserName = 102
2019 0x00, 0x6e, // fieldUserAccess = 110
2021 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
2025 wantRes: []Transaction{
2029 Type: []byte{0, 0x00},
2030 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2031 ErrorCode: []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{
2071 Type: []byte{0, 0x00},
2072 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2073 ErrorCode: []byte{0, 0, 0, 1},
2075 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
2079 wantErr: assert.NoError,
2082 for _, tt := range tests {
2083 t.Run(tt.name, func(t *testing.T) {
2084 gotRes, err := HandleUpdateUser(tt.args.cc, tt.args.t)
2085 if !tt.wantErr(t, err, fmt.Sprintf("HandleUpdateUser(%v, %v)", tt.args.cc, tt.args.t)) {
2089 tranAssertEqual(t, tt.wantRes, gotRes)
2094 func TestHandleDelNewsArt(t *testing.T) {
2102 wantRes []Transaction
2103 wantErr assert.ErrorAssertionFunc
2106 name: "without required permission",
2110 Access: func() accessBitmap {
2111 var bits accessBitmap
2121 wantRes: []Transaction{
2125 Type: []byte{0, 0x00},
2126 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2127 ErrorCode: []byte{0, 0, 0, 1},
2129 NewField(fieldError, []byte("You are not allowed to delete news articles.")),
2133 wantErr: assert.NoError,
2136 for _, tt := range tests {
2137 t.Run(tt.name, func(t *testing.T) {
2138 gotRes, err := HandleDelNewsArt(tt.args.cc, tt.args.t)
2139 if !tt.wantErr(t, err, fmt.Sprintf("HandleDelNewsArt(%v, %v)", tt.args.cc, tt.args.t)) {
2142 tranAssertEqual(t, tt.wantRes, gotRes)
2147 func TestHandleDisconnectUser(t *testing.T) {
2155 wantRes []Transaction
2156 wantErr assert.ErrorAssertionFunc
2159 name: "without required permission",
2163 Access: func() accessBitmap {
2164 var bits accessBitmap
2174 wantRes: []Transaction{
2178 Type: []byte{0, 0x00},
2179 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2180 ErrorCode: []byte{0, 0, 0, 1},
2182 NewField(fieldError, []byte("You are not allowed to disconnect users.")),
2186 wantErr: assert.NoError,
2189 name: "when target user has 'cannot be disconnected' priv",
2193 Clients: map[uint16]*ClientConn{
2197 Access: func() accessBitmap {
2198 var bits accessBitmap
2199 bits.Set(accessCannotBeDiscon)
2207 Access: func() accessBitmap {
2208 var bits accessBitmap
2209 bits.Set(accessDisconUser)
2217 NewField(fieldUserID, []byte{0, 1}),
2220 wantRes: []Transaction{
2224 Type: []byte{0, 0x00},
2225 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2226 ErrorCode: []byte{0, 0, 0, 1},
2228 NewField(fieldError, []byte("unnamed is not allowed to be disconnected.")),
2232 wantErr: assert.NoError,
2235 for _, tt := range tests {
2236 t.Run(tt.name, func(t *testing.T) {
2237 gotRes, err := HandleDisconnectUser(tt.args.cc, tt.args.t)
2238 if !tt.wantErr(t, err, fmt.Sprintf("HandleDisconnectUser(%v, %v)", tt.args.cc, tt.args.t)) {
2241 tranAssertEqual(t, tt.wantRes, gotRes)
2246 func TestHandleSendInstantMsg(t *testing.T) {
2254 wantRes []Transaction
2255 wantErr assert.ErrorAssertionFunc
2258 name: "without required permission",
2262 Access: func() accessBitmap {
2263 var bits accessBitmap
2273 wantRes: []Transaction{
2277 Type: []byte{0, 0x00},
2278 ID: []byte{0, 0, 0, 0},
2279 ErrorCode: []byte{0, 0, 0, 1},
2281 NewField(fieldError, []byte("You are not allowed to send private messages.")),
2285 wantErr: assert.NoError,
2288 name: "when client 1 sends a message to client 2",
2292 Access: func() accessBitmap {
2293 var bits accessBitmap
2294 bits.Set(accessSendPrivMsg)
2299 UserName: []byte("User1"),
2301 Clients: map[uint16]*ClientConn{
2303 AutoReply: []byte(nil),
2311 NewField(fieldData, []byte("hai")),
2312 NewField(fieldUserID, []byte{0, 2}),
2315 wantRes: []Transaction{
2319 NewField(fieldData, []byte("hai")),
2320 NewField(fieldUserName, []byte("User1")),
2321 NewField(fieldUserID, []byte{0, 1}),
2322 NewField(fieldOptions, []byte{0, 1}),
2325 clientID: &[]byte{0, 1},
2328 Type: []byte{0x0, 0x6c},
2329 ID: []byte{0, 0, 0, 0},
2330 ErrorCode: []byte{0, 0, 0, 0},
2331 Fields: []Field(nil),
2334 wantErr: assert.NoError,
2337 name: "when client 2 has autoreply enabled",
2341 Access: func() accessBitmap {
2342 var bits accessBitmap
2343 bits.Set(accessSendPrivMsg)
2348 UserName: []byte("User1"),
2350 Clients: map[uint16]*ClientConn{
2353 UserName: []byte("User2"),
2354 AutoReply: []byte("autohai"),
2362 NewField(fieldData, []byte("hai")),
2363 NewField(fieldUserID, []byte{0, 2}),
2366 wantRes: []Transaction{
2370 NewField(fieldData, []byte("hai")),
2371 NewField(fieldUserName, []byte("User1")),
2372 NewField(fieldUserID, []byte{0, 1}),
2373 NewField(fieldOptions, []byte{0, 1}),
2378 NewField(fieldData, []byte("autohai")),
2379 NewField(fieldUserName, []byte("User2")),
2380 NewField(fieldUserID, []byte{0, 2}),
2381 NewField(fieldOptions, []byte{0, 1}),
2384 clientID: &[]byte{0, 1},
2387 Type: []byte{0x0, 0x6c},
2388 ID: []byte{0, 0, 0, 0},
2389 ErrorCode: []byte{0, 0, 0, 0},
2390 Fields: []Field(nil),
2393 wantErr: assert.NoError,
2396 for _, tt := range tests {
2397 t.Run(tt.name, func(t *testing.T) {
2398 gotRes, err := HandleSendInstantMsg(tt.args.cc, tt.args.t)
2399 if !tt.wantErr(t, err, fmt.Sprintf("HandleSendInstantMsg(%v, %v)", tt.args.cc, tt.args.t)) {
2403 tranAssertEqual(t, tt.wantRes, gotRes)
2408 func TestHandleDeleteFile(t *testing.T) {
2416 wantRes []Transaction
2417 wantErr assert.ErrorAssertionFunc
2420 name: "when user does not have required permission to delete a folder",
2424 Access: func() accessBitmap {
2425 var bits accessBitmap
2431 FileRoot: func() string {
2432 return "/fakeRoot/Files"
2435 FS: func() *MockFileStore {
2436 mfi := &MockFileInfo{}
2437 mfi.On("Mode").Return(fs.FileMode(0))
2438 mfi.On("Size").Return(int64(100))
2439 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2440 mfi.On("IsDir").Return(false)
2441 mfi.On("Name").Return("testfile")
2443 mfs := &MockFileStore{}
2444 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2445 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2446 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2450 Accounts: map[string]*Account{},
2454 tranDeleteFile, &[]byte{0, 1},
2455 NewField(fieldFileName, []byte("testfile")),
2456 NewField(fieldFilePath, []byte{
2464 wantRes: []Transaction{
2468 Type: []byte{0, 0x00},
2469 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2470 ErrorCode: []byte{0, 0, 0, 1},
2472 NewField(fieldError, []byte("You are not allowed to delete files.")),
2476 wantErr: assert.NoError,
2479 name: "deletes all associated metadata files",
2483 Access: func() accessBitmap {
2484 var bits accessBitmap
2485 bits.Set(accessDeleteFile)
2491 FileRoot: func() string {
2492 return "/fakeRoot/Files"
2495 FS: func() *MockFileStore {
2496 mfi := &MockFileInfo{}
2497 mfi.On("Mode").Return(fs.FileMode(0))
2498 mfi.On("Size").Return(int64(100))
2499 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2500 mfi.On("IsDir").Return(false)
2501 mfi.On("Name").Return("testfile")
2503 mfs := &MockFileStore{}
2504 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2505 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2506 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2508 mfs.On("RemoveAll", "/fakeRoot/Files/aaa/testfile").Return(nil)
2509 mfs.On("Remove", "/fakeRoot/Files/aaa/testfile.incomplete").Return(nil)
2510 mfs.On("Remove", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil)
2511 mfs.On("Remove", "/fakeRoot/Files/aaa/.info_testfile").Return(nil)
2515 Accounts: map[string]*Account{},
2519 tranDeleteFile, &[]byte{0, 1},
2520 NewField(fieldFileName, []byte("testfile")),
2521 NewField(fieldFilePath, []byte{
2529 wantRes: []Transaction{
2533 Type: []byte{0x0, 0xcc},
2534 ID: []byte{0x0, 0x0, 0x0, 0x0},
2535 ErrorCode: []byte{0, 0, 0, 0},
2536 Fields: []Field(nil),
2539 wantErr: assert.NoError,
2542 for _, tt := range tests {
2543 t.Run(tt.name, func(t *testing.T) {
2544 gotRes, err := HandleDeleteFile(tt.args.cc, tt.args.t)
2545 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteFile(%v, %v)", tt.args.cc, tt.args.t)) {
2549 tranAssertEqual(t, tt.wantRes, gotRes)
2551 tt.args.cc.Server.FS.(*MockFileStore).AssertExpectations(t)
2556 func TestHandleGetFileNameList(t *testing.T) {
2564 wantRes []Transaction
2565 wantErr assert.ErrorAssertionFunc
2568 name: "when fieldFilePath is a drop box, but user does not have accessViewDropBoxes ",
2572 Access: func() accessBitmap {
2573 var bits accessBitmap
2580 FileRoot: func() string {
2581 path, _ := os.Getwd()
2582 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2588 tranGetFileNameList, &[]byte{0, 1},
2589 NewField(fieldFilePath, []byte{
2593 0x64, 0x72, 0x6f, 0x70, 0x20, 0x62, 0x6f, 0x78, // "drop box"
2597 wantRes: []Transaction{
2601 Type: []byte{0, 0x00},
2602 ID: []byte{0, 0, 0, 0},
2603 ErrorCode: []byte{0, 0, 0, 1},
2605 NewField(fieldError, []byte("You are not allowed to view drop boxes.")),
2609 wantErr: assert.NoError,
2612 name: "with file root",
2617 FileRoot: func() string {
2618 path, _ := os.Getwd()
2619 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2625 tranGetFileNameList, &[]byte{0, 1},
2626 NewField(fieldFilePath, []byte{
2632 wantRes: []Transaction{
2636 Type: []byte{0, 0xc8},
2637 ID: []byte{0, 0, 0, 0},
2638 ErrorCode: []byte{0, 0, 0, 0},
2641 fieldFileNameWithInfo,
2643 fnwi := FileNameWithInfo{
2644 fileNameWithInfoHeader: fileNameWithInfoHeader{
2645 Type: [4]byte{0x54, 0x45, 0x58, 0x54},
2646 Creator: [4]byte{0x54, 0x54, 0x58, 0x54},
2647 FileSize: [4]byte{0, 0, 0x04, 0},
2649 NameScript: [2]byte{},
2650 NameSize: [2]byte{0, 0x0b},
2652 name: []byte("testfile-1k"),
2654 b, _ := fnwi.MarshalBinary()
2661 wantErr: assert.NoError,
2664 for _, tt := range tests {
2665 t.Run(tt.name, func(t *testing.T) {
2666 gotRes, err := HandleGetFileNameList(tt.args.cc, tt.args.t)
2667 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetFileNameList(%v, %v)", tt.args.cc, tt.args.t)) {
2671 tranAssertEqual(t, tt.wantRes, gotRes)
2676 func TestHandleGetClientInfoText(t *testing.T) {
2684 wantRes []Transaction
2685 wantErr assert.ErrorAssertionFunc
2688 name: "when user does not have required permission",
2692 Access: func() accessBitmap {
2693 var bits accessBitmap
2698 Accounts: map[string]*Account{},
2702 tranGetClientInfoText, &[]byte{0, 1},
2703 NewField(fieldUserID, []byte{0, 1}),
2706 wantRes: []Transaction{
2710 Type: []byte{0, 0x00},
2711 ID: []byte{0, 0, 0, 0},
2712 ErrorCode: []byte{0, 0, 0, 1},
2714 NewField(fieldError, []byte("You are not allowed to get client info.")),
2718 wantErr: assert.NoError,
2721 name: "with a valid user",
2724 UserName: []byte("Testy McTest"),
2725 RemoteAddr: "1.2.3.4:12345",
2727 Access: func() accessBitmap {
2728 var bits accessBitmap
2729 bits.Set(accessGetClientInfo)
2736 Accounts: map[string]*Account{},
2737 Clients: map[uint16]*ClientConn{
2739 UserName: []byte("Testy McTest"),
2740 RemoteAddr: "1.2.3.4:12345",
2742 Access: func() accessBitmap {
2743 var bits accessBitmap
2744 bits.Set(accessGetClientInfo)
2753 transfers: map[int]map[[4]byte]*FileTransfer{
2761 tranGetClientInfoText, &[]byte{0, 1},
2762 NewField(fieldUserID, []byte{0, 1}),
2765 wantRes: []Transaction{
2769 Type: []byte{0x1, 0x2f},
2770 ID: []byte{0, 0, 0, 0},
2771 ErrorCode: []byte{0, 0, 0, 0},
2773 NewField(fieldData, []byte(
2774 strings.Replace(`Nickname: Testy McTest
2777 Address: 1.2.3.4:12345
2779 -------- File Downloads ---------
2783 ------- Folder Downloads --------
2787 --------- File Uploads ----------
2791 -------- Folder Uploads ---------
2795 ------- Waiting Downloads -------
2799 `, "\n", "\r", -1)),
2801 NewField(fieldUserName, []byte("Testy McTest")),
2805 wantErr: assert.NoError,
2808 for _, tt := range tests {
2809 t.Run(tt.name, func(t *testing.T) {
2810 gotRes, err := HandleGetClientInfoText(tt.args.cc, tt.args.t)
2811 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetClientInfoText(%v, %v)", tt.args.cc, tt.args.t)) {
2814 tranAssertEqual(t, tt.wantRes, gotRes)
2819 func TestHandleTranAgreed(t *testing.T) {
2827 wantRes []Transaction
2828 wantErr assert.ErrorAssertionFunc
2831 name: "normal request flow",
2835 Access: func() accessBitmap {
2836 var bits accessBitmap
2837 bits.Set(accessDisconUser)
2838 bits.Set(accessAnyName)
2842 Flags: []byte{0, 1},
2843 Version: []byte{0, 1},
2845 logger: NewTestLogger(),
2848 BannerFile: "banner.jpg",
2854 NewField(fieldUserName, []byte("username")),
2855 NewField(fieldUserIconID, []byte{0, 1}),
2856 NewField(fieldOptions, []byte{0, 0}),
2859 wantRes: []Transaction{
2861 clientID: &[]byte{0, 1},
2864 Type: []byte{0, 0x7a},
2865 ID: []byte{0, 0, 0, 0},
2866 ErrorCode: []byte{0, 0, 0, 0},
2868 NewField(fieldBannerType, []byte("JPEG")),
2872 clientID: &[]byte{0, 1},
2875 Type: []byte{0, 0x79},
2876 ID: []byte{0, 0, 0, 0},
2877 ErrorCode: []byte{0, 0, 0, 0},
2881 wantErr: assert.NoError,
2884 for _, tt := range tests {
2885 t.Run(tt.name, func(t *testing.T) {
2886 gotRes, err := HandleTranAgreed(tt.args.cc, tt.args.t)
2887 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranAgreed(%v, %v)", tt.args.cc, tt.args.t)) {
2890 tranAssertEqual(t, tt.wantRes, gotRes)
2895 func TestHandleSetClientUserInfo(t *testing.T) {
2903 wantRes []Transaction
2904 wantErr assert.ErrorAssertionFunc
2907 name: "when client does not have accessAnyName",
2911 Access: func() accessBitmap {
2912 var bits accessBitmap
2917 UserName: []byte("Guest"),
2918 Flags: []byte{0, 1},
2920 Clients: map[uint16]*ClientConn{
2928 tranSetClientUserInfo, nil,
2929 NewField(fieldUserIconID, []byte{0, 1}),
2930 NewField(fieldUserName, []byte("NOPE")),
2933 wantRes: []Transaction{
2935 clientID: &[]byte{0, 1},
2938 Type: []byte{0x01, 0x2d},
2939 ID: []byte{0, 0, 0, 0},
2940 ErrorCode: []byte{0, 0, 0, 0},
2942 NewField(fieldUserID, []byte{0, 1}),
2943 NewField(fieldUserIconID, []byte{0, 1}),
2944 NewField(fieldUserFlags, []byte{0, 1}),
2945 NewField(fieldUserName, []byte("Guest"))},
2948 wantErr: assert.NoError,
2951 for _, tt := range tests {
2952 t.Run(tt.name, func(t *testing.T) {
2953 gotRes, err := HandleSetClientUserInfo(tt.args.cc, tt.args.t)
2954 if !tt.wantErr(t, err, fmt.Sprintf("HandleSetClientUserInfo(%v, %v)", tt.args.cc, tt.args.t)) {
2958 tranAssertEqual(t, tt.wantRes, gotRes)