6 "github.com/stretchr/testify/assert"
14 func TestHandleSetChatSubject(t *testing.T) {
26 name: "sends chat subject to private chat members",
29 UserName: []byte{0x00, 0x01},
31 PrivateChats: map[uint32]*PrivateChat{
34 ClientConn: map[uint16]*ClientConn{
37 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
43 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
50 Clients: map[uint16]*ClientConn{
53 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
59 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
69 Type: []byte{0, 0x6a},
70 ID: []byte{0, 0, 0, 1},
71 ErrorCode: []byte{0, 0, 0, 0},
73 NewField(fieldChatID, []byte{0, 0, 0, 1}),
74 NewField(fieldChatSubject, []byte("Test Subject")),
80 clientID: &[]byte{0, 1},
83 Type: []byte{0, 0x77},
84 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
85 ErrorCode: []byte{0, 0, 0, 0},
87 NewField(fieldChatID, []byte{0, 0, 0, 1}),
88 NewField(fieldChatSubject, []byte("Test Subject")),
92 clientID: &[]byte{0, 2},
95 Type: []byte{0, 0x77},
96 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
97 ErrorCode: []byte{0, 0, 0, 0},
99 NewField(fieldChatID, []byte{0, 0, 0, 1}),
100 NewField(fieldChatSubject, []byte("Test Subject")),
107 for _, tt := range tests {
108 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
110 t.Run(tt.name, func(t *testing.T) {
111 got, err := HandleSetChatSubject(tt.args.cc, tt.args.t)
112 if (err != nil) != tt.wantErr {
113 t.Errorf("HandleSetChatSubject() error = %v, wantErr %v", err, tt.wantErr)
116 if !assert.Equal(t, tt.want, got) {
117 t.Errorf("HandleSetChatSubject() got = %v, want %v", got, tt.want)
123 func TestHandleLeaveChat(t *testing.T) {
135 name: "returns expected transactions",
140 PrivateChats: map[uint32]*PrivateChat{
142 ClientConn: map[uint16]*ClientConn{
145 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
151 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
158 Clients: map[uint16]*ClientConn{
161 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
167 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
174 t: NewTransaction(tranDeleteUser, nil, NewField(fieldChatID, []byte{0, 0, 0, 1})),
178 clientID: &[]byte{0, 1},
181 Type: []byte{0, 0x76},
182 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
183 ErrorCode: []byte{0, 0, 0, 0},
185 NewField(fieldChatID, []byte{0, 0, 0, 1}),
186 NewField(fieldUserID, []byte{0, 2}),
193 for _, tt := range tests {
195 t.Run(tt.name, func(t *testing.T) {
196 got, err := HandleLeaveChat(tt.args.cc, tt.args.t)
197 if (err != nil) != tt.wantErr {
198 t.Errorf("HandleLeaveChat() error = %v, wantErr %v", err, tt.wantErr)
201 if !assert.Equal(t, tt.want, got) {
202 t.Errorf("HandleLeaveChat() got = %v, want %v", got, tt.want)
208 func TestHandleGetUserNameList(t *testing.T) {
220 name: "replies with userlist transaction",
226 Clients: map[uint16]*ClientConn{
230 Flags: &[]byte{0, 3},
231 UserName: []byte{0, 4},
237 Flags: &[]byte{0, 3},
238 UserName: []byte{0, 4},
244 Flags: &[]byte{0, 3},
245 UserName: []byte{0, 4},
252 ID: []byte{0, 0, 0, 1},
258 clientID: &[]byte{1, 1},
262 ID: []byte{0, 0, 0, 1},
263 ErrorCode: []byte{0, 0, 0, 0},
266 fieldUsernameWithInfo,
267 []byte{00, 01, 00, 02, 00, 03, 00, 02, 00, 04},
270 fieldUsernameWithInfo,
271 []byte{00, 02, 00, 02, 00, 03, 00, 02, 00, 04},
279 for _, tt := range tests {
280 t.Run(tt.name, func(t *testing.T) {
281 got, err := HandleGetUserNameList(tt.args.cc, tt.args.t)
282 if (err != nil) != tt.wantErr {
283 t.Errorf("HandleGetUserNameList() error = %v, wantErr %v", err, tt.wantErr)
286 assert.Equal(t, tt.want, got)
291 func TestHandleChatSend(t *testing.T) {
303 name: "sends chat msg transaction to all clients",
307 Access: func() *[]byte {
308 var bits accessBitmap
309 bits.Set(accessSendChat)
314 UserName: []byte{0x00, 0x01},
316 Clients: map[uint16]*ClientConn{
319 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
325 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
334 NewField(fieldData, []byte("hai")),
340 clientID: &[]byte{0, 1},
343 Type: []byte{0, 0x6a},
344 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
345 ErrorCode: []byte{0, 0, 0, 0},
347 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
351 clientID: &[]byte{0, 2},
354 Type: []byte{0, 0x6a},
355 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
356 ErrorCode: []byte{0, 0, 0, 0},
358 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
365 name: "when user does not have required permission",
369 Access: func() *[]byte {
370 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() *[]byte {
404 var bits accessBitmap
405 bits.Set(accessSendChat)
410 UserName: []byte("Testy McTest"),
412 Clients: map[uint16]*ClientConn{
415 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
421 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
430 NewField(fieldData, []byte("performed action")),
431 NewField(fieldChatOptions, []byte{0x00, 0x01}),
437 clientID: &[]byte{0, 1},
440 Type: []byte{0, 0x6a},
441 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
442 ErrorCode: []byte{0, 0, 0, 0},
444 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
448 clientID: &[]byte{0, 2},
451 Type: []byte{0, 0x6a},
452 ID: []byte{0xf0, 0xc5, 0x34, 0x1e},
453 ErrorCode: []byte{0, 0, 0, 0},
455 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
462 name: "only sends chat msg to clients with accessReadChat permission",
466 Access: func() *[]byte {
467 var bits accessBitmap
468 bits.Set(accessSendChat)
473 UserName: []byte{0x00, 0x01},
475 Clients: map[uint16]*ClientConn{
478 Access: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
484 Access: &[]byte{0, 0, 0, 0, 0, 0, 0, 0},
493 NewField(fieldData, []byte("hai")),
499 clientID: &[]byte{0, 1},
502 Type: []byte{0, 0x6a},
503 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
504 ErrorCode: []byte{0, 0, 0, 0},
506 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
513 name: "only sends private chat msg to members of private chat",
517 Access: func() *[]byte {
518 var bits accessBitmap
519 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: &[]byte{255, 255, 255, 255, 255, 255, 255, 255},
547 Access: &[]byte{0, 0, 0, 0, 0, 0, 0, 0},
553 Access: &[]byte{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},
629 FileRoot: func() string {
630 path, _ := os.Getwd()
631 return path + "/test/config/Files"
637 tranGetFileInfo, nil,
638 NewField(fieldFileName, []byte("testfile.txt")),
639 NewField(fieldFilePath, []byte{0x00, 0x00}),
642 wantRes: []Transaction{
644 clientID: &[]byte{0, 1},
647 Type: []byte{0, 0xce},
648 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
649 ErrorCode: []byte{0, 0, 0, 0},
651 NewField(fieldFileName, []byte("testfile.txt")),
652 NewField(fieldFileTypeString, []byte("TEXT")),
653 NewField(fieldFileCreatorString, []byte("ttxt")),
654 NewField(fieldFileComment, []byte{}),
655 NewField(fieldFileType, []byte("TEXT")),
656 NewField(fieldFileCreateDate, make([]byte, 8)),
657 NewField(fieldFileModifyDate, make([]byte, 8)),
658 NewField(fieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}),
665 for _, tt := range tests {
666 t.Run(tt.name, func(t *testing.T) {
667 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
669 gotRes, err := HandleGetFileInfo(tt.args.cc, tt.args.t)
670 if (err != nil) != tt.wantErr {
671 t.Errorf("HandleGetFileInfo() error = %v, wantErr %v", err, tt.wantErr)
675 // Clear the file timestamp fields to work around problems running the tests in multiple timezones
676 // TODO: revisit how to test this by mocking the stat calls
677 gotRes[0].Fields[5].Data = make([]byte, 8)
678 gotRes[0].Fields[6].Data = make([]byte, 8)
679 if !assert.Equal(t, tt.wantRes, gotRes) {
680 t.Errorf("HandleGetFileInfo() gotRes = %v, want %v", gotRes, tt.wantRes)
686 func TestHandleNewFolder(t *testing.T) {
695 wantRes []Transaction
699 name: "when path is nested",
710 tranNewFolder, &[]byte{0, 1},
711 NewField(fieldFileName, []byte("testFolder")),
712 NewField(fieldFilePath, []byte{
721 mfs := &MockFileStore{}
722 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
723 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
726 wantRes: []Transaction{
728 clientID: &[]byte{0, 1},
731 Type: []byte{0, 0xcd},
732 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
733 ErrorCode: []byte{0, 0, 0, 0},
739 name: "when path is not nested",
750 tranNewFolder, &[]byte{0, 1},
751 NewField(fieldFileName, []byte("testFolder")),
755 mfs := &MockFileStore{}
756 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
757 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
760 wantRes: []Transaction{
762 clientID: &[]byte{0, 1},
765 Type: []byte{0, 0xcd},
766 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
767 ErrorCode: []byte{0, 0, 0, 0},
773 name: "when UnmarshalBinary returns an err",
784 tranNewFolder, &[]byte{0, 1},
785 NewField(fieldFileName, []byte("testFolder")),
786 NewField(fieldFilePath, []byte{
792 mfs := &MockFileStore{}
793 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
794 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
797 wantRes: []Transaction{},
801 name: "fieldFileName does not allow directory traversal",
812 tranNewFolder, &[]byte{0, 1},
813 NewField(fieldFileName, []byte("../../testFolder")),
817 mfs := &MockFileStore{}
818 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
819 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
822 wantRes: []Transaction{
824 clientID: &[]byte{0, 1},
827 Type: []byte{0, 0xcd},
828 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
829 ErrorCode: []byte{0, 0, 0, 0},
834 name: "fieldFilePath does not allow directory traversal",
845 tranNewFolder, &[]byte{0, 1},
846 NewField(fieldFileName, []byte("testFolder")),
847 NewField(fieldFilePath, []byte{
859 mfs := &MockFileStore{}
860 mfs.On("Mkdir", "/Files/foo/testFolder", fs.FileMode(0777)).Return(nil)
861 mfs.On("Stat", "/Files/foo/testFolder").Return(nil, os.ErrNotExist)
864 wantRes: []Transaction{
866 clientID: &[]byte{0, 1},
869 Type: []byte{0, 0xcd},
870 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
871 ErrorCode: []byte{0, 0, 0, 0},
876 for _, tt := range tests {
877 t.Run(tt.name, func(t *testing.T) {
880 gotRes, err := HandleNewFolder(tt.args.cc, tt.args.t)
881 if (err != nil) != tt.wantErr {
882 t.Errorf("HandleNewFolder() error = %v, wantErr %v", err, tt.wantErr)
885 if !tranAssertEqual(t, tt.wantRes, gotRes) {
886 t.Errorf("HandleNewFolder() gotRes = %v, want %v", gotRes, tt.wantRes)
892 func TestHandleUploadFile(t *testing.T) {
900 wantRes []Transaction
904 name: "when request is valid and user has Upload Anywhere permission",
908 FileTransfers: map[uint32]*FileTransfer{},
911 Access: func() *[]byte {
912 var bits accessBitmap
913 bits.Set(accessUploadFile)
914 bits.Set(accessUploadAnywhere)
921 tranUploadFile, &[]byte{0, 1},
922 NewField(fieldFileName, []byte("testFile")),
923 NewField(fieldFilePath, []byte{
931 wantRes: []Transaction{
935 Type: []byte{0, 0xcb},
936 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
937 ErrorCode: []byte{0, 0, 0, 0},
939 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), // rand.Seed(1)
946 name: "when user does not have required access",
950 Access: func() *[]byte {
951 var bits accessBitmap
957 FileTransfers: map[uint32]*FileTransfer{},
961 tranUploadFile, &[]byte{0, 1},
962 NewField(fieldFileName, []byte("testFile")),
963 NewField(fieldFilePath, []byte{
971 wantRes: []Transaction{
975 Type: []byte{0, 0x00},
976 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
977 ErrorCode: []byte{0, 0, 0, 1},
979 NewField(fieldError, []byte("You are not allowed to upload files.")), // rand.Seed(1)
986 for _, tt := range tests {
987 t.Run(tt.name, func(t *testing.T) {
989 gotRes, err := HandleUploadFile(tt.args.cc, tt.args.t)
990 if (err != nil) != tt.wantErr {
991 t.Errorf("HandleUploadFile() error = %v, wantErr %v", err, tt.wantErr)
995 tranAssertEqual(t, tt.wantRes, gotRes)
1001 func TestHandleMakeAlias(t *testing.T) {
1010 wantRes []Transaction
1014 name: "with valid input and required permissions",
1016 mfs := &MockFileStore{}
1017 path, _ := os.Getwd()
1020 path+"/test/config/Files/foo/testFile",
1021 path+"/test/config/Files/bar/testFile",
1028 Access: func() *[]byte {
1029 var bits accessBitmap
1030 bits.Set(accessMakeAlias)
1037 FileRoot: func() string {
1038 path, _ := os.Getwd()
1039 return path + "/test/config/Files"
1042 Logger: NewTestLogger(),
1046 tranMakeFileAlias, &[]byte{0, 1},
1047 NewField(fieldFileName, []byte("testFile")),
1048 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1049 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1052 wantRes: []Transaction{
1056 Type: []byte{0, 0xd1},
1057 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1058 ErrorCode: []byte{0, 0, 0, 0},
1059 Fields: []Field(nil),
1065 name: "when symlink returns an error",
1067 mfs := &MockFileStore{}
1068 path, _ := os.Getwd()
1071 path+"/test/config/Files/foo/testFile",
1072 path+"/test/config/Files/bar/testFile",
1073 ).Return(errors.New("ohno"))
1079 Access: func() *[]byte {
1080 var bits accessBitmap
1081 bits.Set(accessMakeAlias)
1088 FileRoot: func() string {
1089 path, _ := os.Getwd()
1090 return path + "/test/config/Files"
1093 Logger: NewTestLogger(),
1097 tranMakeFileAlias, &[]byte{0, 1},
1098 NewField(fieldFileName, []byte("testFile")),
1099 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1100 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1103 wantRes: []Transaction{
1107 Type: []byte{0, 0x00},
1108 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1109 ErrorCode: []byte{0, 0, 0, 1},
1111 NewField(fieldError, []byte("Error creating alias")),
1118 name: "when user does not have required permission",
1123 Access: func() *[]byte {
1124 var bits accessBitmap
1131 FileRoot: func() string {
1132 path, _ := os.Getwd()
1133 return path + "/test/config/Files"
1139 tranMakeFileAlias, &[]byte{0, 1},
1140 NewField(fieldFileName, []byte("testFile")),
1141 NewField(fieldFilePath, []byte{
1147 NewField(fieldFileNewPath, []byte{
1155 wantRes: []Transaction{
1159 Type: []byte{0, 0x00},
1160 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1161 ErrorCode: []byte{0, 0, 0, 1},
1163 NewField(fieldError, []byte("You are not allowed to make aliases.")),
1170 for _, tt := range tests {
1171 t.Run(tt.name, func(t *testing.T) {
1174 gotRes, err := HandleMakeAlias(tt.args.cc, tt.args.t)
1175 if (err != nil) != tt.wantErr {
1176 t.Errorf("HandleMakeAlias(%v, %v)", tt.args.cc, tt.args.t)
1180 tranAssertEqual(t, tt.wantRes, gotRes)
1185 func TestHandleGetUser(t *testing.T) {
1193 wantRes []Transaction
1194 wantErr assert.ErrorAssertionFunc
1197 name: "when account is valid",
1201 Access: func() *[]byte {
1202 var bits accessBitmap
1203 bits.Set(accessOpenUser)
1209 Accounts: map[string]*Account{
1213 Password: "password",
1220 tranGetUser, &[]byte{0, 1},
1221 NewField(fieldUserLogin, []byte("guest")),
1224 wantRes: []Transaction{
1228 Type: []byte{0x01, 0x60},
1229 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1230 ErrorCode: []byte{0, 0, 0, 0},
1232 NewField(fieldUserName, []byte("Guest")),
1233 NewField(fieldUserLogin, negateString([]byte("guest"))),
1234 NewField(fieldUserPassword, []byte("password")),
1235 NewField(fieldUserAccess, []byte{1}),
1239 wantErr: assert.NoError,
1242 name: "when user does not have required permission",
1246 Access: func() *[]byte {
1247 var bits accessBitmap
1253 Accounts: map[string]*Account{},
1257 tranGetUser, &[]byte{0, 1},
1258 NewField(fieldUserLogin, []byte("nonExistentUser")),
1261 wantRes: []Transaction{
1265 Type: []byte{0, 0x00},
1266 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1267 ErrorCode: []byte{0, 0, 0, 1},
1269 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1273 wantErr: assert.NoError,
1276 name: "when account does not exist",
1280 Access: func() *[]byte {
1281 var bits accessBitmap
1282 bits.Set(accessOpenUser)
1288 Accounts: map[string]*Account{},
1292 tranGetUser, &[]byte{0, 1},
1293 NewField(fieldUserLogin, []byte("nonExistentUser")),
1296 wantRes: []Transaction{
1300 Type: []byte{0, 0x00},
1301 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1302 ErrorCode: []byte{0, 0, 0, 1},
1304 NewField(fieldError, []byte("Account does not exist.")),
1308 wantErr: assert.NoError,
1311 for _, tt := range tests {
1312 t.Run(tt.name, func(t *testing.T) {
1313 gotRes, err := HandleGetUser(tt.args.cc, tt.args.t)
1314 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetUser(%v, %v)", tt.args.cc, tt.args.t)) {
1318 tranAssertEqual(t, tt.wantRes, gotRes)
1323 func TestHandleDeleteUser(t *testing.T) {
1332 wantRes []Transaction
1333 wantErr assert.ErrorAssertionFunc
1336 name: "when user exists",
1338 mfs := &MockFileStore{}
1339 mfs.On("Remove", "Users/testuser.yaml").Return(nil)
1345 Access: func() *[]byte {
1346 var bits accessBitmap
1347 bits.Set(accessDeleteUser)
1353 Accounts: map[string]*Account{
1356 Name: "Testy McTest",
1357 Password: "password",
1364 tranDeleteUser, &[]byte{0, 1},
1365 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1368 wantRes: []Transaction{
1372 Type: []byte{0x1, 0x5f},
1373 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1374 ErrorCode: []byte{0, 0, 0, 0},
1375 Fields: []Field(nil),
1378 wantErr: assert.NoError,
1381 name: "when user does not have required permission",
1386 Access: func() *[]byte {
1387 var bits accessBitmap
1393 Accounts: map[string]*Account{},
1397 tranDeleteUser, &[]byte{0, 1},
1398 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1401 wantRes: []Transaction{
1405 Type: []byte{0, 0x00},
1406 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1407 ErrorCode: []byte{0, 0, 0, 1},
1409 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
1413 wantErr: assert.NoError,
1416 for _, tt := range tests {
1417 t.Run(tt.name, func(t *testing.T) {
1419 gotRes, err := HandleDeleteUser(tt.args.cc, tt.args.t)
1420 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteUser(%v, %v)", tt.args.cc, tt.args.t)) {
1424 tranAssertEqual(t, tt.wantRes, gotRes)
1429 func TestHandleGetMsgs(t *testing.T) {
1437 wantRes []Transaction
1438 wantErr assert.ErrorAssertionFunc
1441 name: "returns news data",
1445 Access: func() *[]byte {
1446 var bits accessBitmap
1447 bits.Set(accessNewsReadArt)
1453 FlatNews: []byte("TEST"),
1457 tranGetMsgs, &[]byte{0, 1},
1460 wantRes: []Transaction{
1464 Type: []byte{0, 0x65},
1465 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1466 ErrorCode: []byte{0, 0, 0, 0},
1468 NewField(fieldData, []byte("TEST")),
1472 wantErr: assert.NoError,
1475 name: "when user does not have required permission",
1479 Access: func() *[]byte {
1480 var bits accessBitmap
1486 Accounts: map[string]*Account{},
1490 tranGetMsgs, &[]byte{0, 1},
1493 wantRes: []Transaction{
1497 Type: []byte{0, 0x00},
1498 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1499 ErrorCode: []byte{0, 0, 0, 1},
1501 NewField(fieldError, []byte("You are not allowed to read news.")),
1505 wantErr: assert.NoError,
1508 for _, tt := range tests {
1509 t.Run(tt.name, func(t *testing.T) {
1510 gotRes, err := HandleGetMsgs(tt.args.cc, tt.args.t)
1511 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetMsgs(%v, %v)", tt.args.cc, tt.args.t)) {
1515 tranAssertEqual(t, tt.wantRes, gotRes)
1520 func TestHandleNewUser(t *testing.T) {
1528 wantRes []Transaction
1529 wantErr assert.ErrorAssertionFunc
1532 name: "when user does not have required permission",
1536 Access: func() *[]byte {
1537 var bits accessBitmap
1543 Accounts: map[string]*Account{},
1547 tranNewUser, &[]byte{0, 1},
1550 wantRes: []Transaction{
1554 Type: []byte{0, 0x00},
1555 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1556 ErrorCode: []byte{0, 0, 0, 1},
1558 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
1562 wantErr: assert.NoError,
1565 for _, tt := range tests {
1566 t.Run(tt.name, func(t *testing.T) {
1567 gotRes, err := HandleNewUser(tt.args.cc, tt.args.t)
1568 if !tt.wantErr(t, err, fmt.Sprintf("HandleNewUser(%v, %v)", tt.args.cc, tt.args.t)) {
1572 tranAssertEqual(t, tt.wantRes, gotRes)
1577 func TestHandleListUsers(t *testing.T) {
1585 wantRes []Transaction
1586 wantErr assert.ErrorAssertionFunc
1589 name: "when user does not have required permission",
1593 Access: func() *[]byte {
1594 var bits accessBitmap
1600 Accounts: map[string]*Account{},
1604 tranNewUser, &[]byte{0, 1},
1607 wantRes: []Transaction{
1611 Type: []byte{0, 0x00},
1612 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1613 ErrorCode: []byte{0, 0, 0, 1},
1615 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1619 wantErr: assert.NoError,
1622 for _, tt := range tests {
1623 t.Run(tt.name, func(t *testing.T) {
1624 gotRes, err := HandleListUsers(tt.args.cc, tt.args.t)
1625 if !tt.wantErr(t, err, fmt.Sprintf("HandleListUsers(%v, %v)", tt.args.cc, tt.args.t)) {
1629 tranAssertEqual(t, tt.wantRes, gotRes)
1634 func TestHandleDownloadFile(t *testing.T) {
1642 wantRes []Transaction
1643 wantErr assert.ErrorAssertionFunc
1646 name: "when user does not have required permission",
1650 Access: func() *[]byte {
1651 var bits accessBitmap
1658 t: NewTransaction(tranDownloadFile, &[]byte{0, 1}),
1660 wantRes: []Transaction{
1664 Type: []byte{0, 0x00},
1665 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1666 ErrorCode: []byte{0, 0, 0, 1},
1668 NewField(fieldError, []byte("You are not allowed to download files.")),
1672 wantErr: assert.NoError,
1675 name: "with a valid file",
1678 Transfers: make(map[int][]*FileTransfer),
1680 Access: func() *[]byte {
1681 var bits accessBitmap
1682 bits.Set(accessDownloadFile)
1688 FileTransfers: make(map[uint32]*FileTransfer),
1690 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1692 Accounts: map[string]*Account{},
1698 NewField(fieldFileName, []byte("testfile.txt")),
1699 NewField(fieldFilePath, []byte{0x0, 0x00}),
1702 wantRes: []Transaction{
1706 Type: []byte{0, 0x2},
1707 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1708 ErrorCode: []byte{0, 0, 0, 0},
1710 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
1711 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
1712 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x00, 0xa5}),
1713 NewField(fieldFileSize, []byte{0x00, 0x00, 0x00, 0x17}),
1717 wantErr: assert.NoError,
1720 for _, tt := range tests {
1721 t.Run(tt.name, func(t *testing.T) {
1722 // reset the rand seed so that the random fieldRefNum will be deterministic
1725 gotRes, err := HandleDownloadFile(tt.args.cc, tt.args.t)
1726 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadFile(%v, %v)", tt.args.cc, tt.args.t)) {
1730 tranAssertEqual(t, tt.wantRes, gotRes)
1735 func TestHandleUpdateUser(t *testing.T) {
1743 wantRes []Transaction
1744 wantErr assert.ErrorAssertionFunc
1747 name: "when action is create user without required permission",
1751 Logger: NewTestLogger(),
1754 Access: func() *[]byte {
1755 var bits accessBitmap
1764 NewField(fieldData, []byte{
1765 0x00, 0x04, // field count
1767 0x00, 0x69, // fieldUserLogin = 105
1771 0x00, 0x6a, // fieldUserPassword = 106
1775 0x00, 0x66, // fieldUserName = 102
1779 0x00, 0x6e, // fieldUserAccess = 110
1781 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
1785 wantRes: []Transaction{
1789 Type: []byte{0, 0x00},
1790 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1791 ErrorCode: []byte{0, 0, 0, 1},
1793 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
1797 wantErr: assert.NoError,
1800 name: "when action is modify user without required permission",
1804 Logger: NewTestLogger(),
1805 Accounts: map[string]*Account{
1810 Access: func() *[]byte {
1811 var bits accessBitmap
1820 NewField(fieldData, []byte{
1821 0x00, 0x04, // field count
1823 0x00, 0x69, // fieldUserLogin = 105
1827 0x00, 0x6a, // fieldUserPassword = 106
1831 0x00, 0x66, // fieldUserName = 102
1835 0x00, 0x6e, // fieldUserAccess = 110
1837 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
1841 wantRes: []Transaction{
1845 Type: []byte{0, 0x00},
1846 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1847 ErrorCode: []byte{0, 0, 0, 1},
1849 NewField(fieldError, []byte("You are not allowed to modify accounts.")),
1853 wantErr: assert.NoError,
1856 name: "when action is delete user without required permission",
1860 Logger: NewTestLogger(),
1861 Accounts: map[string]*Account{
1866 Access: func() *[]byte {
1867 var bits accessBitmap
1876 NewField(fieldData, []byte{
1884 wantRes: []Transaction{
1888 Type: []byte{0, 0x00},
1889 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1890 ErrorCode: []byte{0, 0, 0, 1},
1892 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
1896 wantErr: assert.NoError,
1899 for _, tt := range tests {
1900 t.Run(tt.name, func(t *testing.T) {
1901 gotRes, err := HandleUpdateUser(tt.args.cc, tt.args.t)
1902 if !tt.wantErr(t, err, fmt.Sprintf("HandleUpdateUser(%v, %v)", tt.args.cc, tt.args.t)) {
1906 tranAssertEqual(t, tt.wantRes, gotRes)