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},
72 Type: []byte{0, 0x6a},
73 ID: []byte{0, 0, 0, 1},
74 ErrorCode: []byte{0, 0, 0, 0},
76 NewField(fieldChatID, []byte{0, 0, 0, 1}),
77 NewField(fieldChatSubject, []byte("Test Subject")),
83 clientID: &[]byte{0, 1},
86 Type: []byte{0, 0x77},
87 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
88 ErrorCode: []byte{0, 0, 0, 0},
90 NewField(fieldChatID, []byte{0, 0, 0, 1}),
91 NewField(fieldChatSubject, []byte("Test Subject")),
95 clientID: &[]byte{0, 2},
98 Type: []byte{0, 0x77},
99 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
100 ErrorCode: []byte{0, 0, 0, 0},
102 NewField(fieldChatID, []byte{0, 0, 0, 1}),
103 NewField(fieldChatSubject, []byte("Test Subject")),
110 for _, tt := range tests {
111 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
113 t.Run(tt.name, func(t *testing.T) {
114 got, err := HandleSetChatSubject(tt.args.cc, tt.args.t)
115 if (err != nil) != tt.wantErr {
116 t.Errorf("HandleSetChatSubject() error = %v, wantErr %v", err, tt.wantErr)
119 if !assert.Equal(t, tt.want, got) {
120 t.Errorf("HandleSetChatSubject() got = %v, want %v", got, tt.want)
126 func TestHandleLeaveChat(t *testing.T) {
138 name: "returns expected transactions",
143 PrivateChats: map[uint32]*PrivateChat{
145 ClientConn: map[uint16]*ClientConn{
148 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
154 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
161 Clients: map[uint16]*ClientConn{
164 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
170 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
177 t: NewTransaction(tranDeleteUser, nil, NewField(fieldChatID, []byte{0, 0, 0, 1})),
181 clientID: &[]byte{0, 1},
184 Type: []byte{0, 0x76},
185 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
186 ErrorCode: []byte{0, 0, 0, 0},
188 NewField(fieldChatID, []byte{0, 0, 0, 1}),
189 NewField(fieldUserID, []byte{0, 2}),
196 for _, tt := range tests {
198 t.Run(tt.name, func(t *testing.T) {
199 got, err := HandleLeaveChat(tt.args.cc, tt.args.t)
200 if (err != nil) != tt.wantErr {
201 t.Errorf("HandleLeaveChat() error = %v, wantErr %v", err, tt.wantErr)
204 if !assert.Equal(t, tt.want, got) {
205 t.Errorf("HandleLeaveChat() got = %v, want %v", got, tt.want)
211 func TestHandleGetUserNameList(t *testing.T) {
223 name: "replies with userlist transaction",
229 Clients: map[uint16]*ClientConn{
234 UserName: []byte{0, 4},
240 UserName: []byte{0, 4},
246 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() accessBitmap {
308 var bits accessBitmap
309 bits.Set(accessSendChat)
313 UserName: []byte{0x00, 0x01},
315 Clients: map[uint16]*ClientConn{
318 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
324 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
333 NewField(fieldData, []byte("hai")),
339 clientID: &[]byte{0, 1},
342 Type: []byte{0, 0x6a},
343 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
344 ErrorCode: []byte{0, 0, 0, 0},
346 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
350 clientID: &[]byte{0, 2},
353 Type: []byte{0, 0x6a},
354 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
355 ErrorCode: []byte{0, 0, 0, 0},
357 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
364 name: "treats Chat ID 00 00 00 00 as a public chat message",
368 Access: func() accessBitmap {
369 var bits accessBitmap
370 bits.Set(accessSendChat)
374 UserName: []byte{0x00, 0x01},
376 Clients: map[uint16]*ClientConn{
379 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
385 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
394 NewField(fieldData, []byte("hai")),
395 NewField(fieldChatID, []byte{0, 0, 0, 0}),
401 clientID: &[]byte{0, 1},
404 Type: []byte{0, 0x6a},
405 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
406 ErrorCode: []byte{0, 0, 0, 0},
408 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
412 clientID: &[]byte{0, 2},
415 Type: []byte{0, 0x6a},
416 ID: []byte{0xf0, 0xc5, 0x34, 0x1e}, // Random ID from rand.Seed(1)
417 ErrorCode: []byte{0, 0, 0, 0},
419 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
426 name: "when user does not have required permission",
430 Access: func() accessBitmap {
431 var bits accessBitmap
436 Accounts: map[string]*Account{},
440 tranChatSend, &[]byte{0, 1},
441 NewField(fieldData, []byte("hai")),
448 Type: []byte{0, 0x00},
449 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
450 ErrorCode: []byte{0, 0, 0, 1},
452 NewField(fieldError, []byte("You are not allowed to participate in chat.")),
459 name: "sends chat msg as emote if fieldChatOptions is set to 1",
463 Access: func() accessBitmap {
464 var bits accessBitmap
465 bits.Set(accessSendChat)
469 UserName: []byte("Testy McTest"),
471 Clients: map[uint16]*ClientConn{
474 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
480 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
489 NewField(fieldData, []byte("performed action")),
490 NewField(fieldChatOptions, []byte{0x00, 0x01}),
496 clientID: &[]byte{0, 1},
499 Type: []byte{0, 0x6a},
500 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
501 ErrorCode: []byte{0, 0, 0, 0},
503 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
507 clientID: &[]byte{0, 2},
510 Type: []byte{0, 0x6a},
511 ID: []byte{0xf0, 0xc5, 0x34, 0x1e},
512 ErrorCode: []byte{0, 0, 0, 0},
514 NewField(fieldData, []byte("\r*** Testy McTest performed action")),
521 name: "does not send chat msg as emote if fieldChatOptions is set to 0",
525 Access: func() accessBitmap {
526 var bits accessBitmap
527 bits.Set(accessSendChat)
531 UserName: []byte("Testy McTest"),
533 Clients: map[uint16]*ClientConn{
536 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
542 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
551 NewField(fieldData, []byte("hello")),
552 NewField(fieldChatOptions, []byte{0x00, 0x00}),
558 clientID: &[]byte{0, 1},
561 Type: []byte{0, 0x6a},
562 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
563 ErrorCode: []byte{0, 0, 0, 0},
565 NewField(fieldData, []byte("\r Testy McTest: hello")),
569 clientID: &[]byte{0, 2},
572 Type: []byte{0, 0x6a},
573 ID: []byte{0xf0, 0xc5, 0x34, 0x1e},
574 ErrorCode: []byte{0, 0, 0, 0},
576 NewField(fieldData, []byte("\r Testy McTest: hello")),
583 name: "only sends chat msg to clients with accessReadChat permission",
587 Access: func() accessBitmap {
588 var bits accessBitmap
589 bits.Set(accessSendChat)
593 UserName: []byte{0x00, 0x01},
595 Clients: map[uint16]*ClientConn{
598 Access: func() accessBitmap {
599 var bits accessBitmap
600 bits.Set(accessReadChat)
607 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
616 NewField(fieldData, []byte("hai")),
622 clientID: &[]byte{0, 1},
625 Type: []byte{0, 0x6a},
626 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
627 ErrorCode: []byte{0, 0, 0, 0},
629 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
636 name: "only sends private chat msg to members of private chat",
640 Access: func() accessBitmap {
641 var bits accessBitmap
642 bits.Set(accessSendChat)
646 UserName: []byte{0x00, 0x01},
648 PrivateChats: map[uint32]*PrivateChat{
650 ClientConn: map[uint16]*ClientConn{
660 Clients: map[uint16]*ClientConn{
663 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
669 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
675 Access: accessBitmap{0, 0, 0, 0, 0, 0, 0, 0},
684 NewField(fieldData, []byte("hai")),
685 NewField(fieldChatID, []byte{0, 0, 0, 1}),
691 clientID: &[]byte{0, 1},
694 Type: []byte{0, 0x6a},
695 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
696 ErrorCode: []byte{0, 0, 0, 0},
698 NewField(fieldChatID, []byte{0, 0, 0, 1}),
699 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
703 clientID: &[]byte{0, 2},
706 Type: []byte{0, 0x6a},
707 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
708 ErrorCode: []byte{0, 0, 0, 0},
710 NewField(fieldChatID, []byte{0, 0, 0, 1}),
711 NewField(fieldData, []byte{0x0d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x01, 0x3a, 0x20, 0x20, 0x68, 0x61, 0x69}),
718 for _, tt := range tests {
719 t.Run(tt.name, func(t *testing.T) {
720 got, err := HandleChatSend(tt.args.cc, tt.args.t)
722 if (err != nil) != tt.wantErr {
723 t.Errorf("HandleChatSend() error = %v, wantErr %v", err, tt.wantErr)
726 tranAssertEqual(t, tt.want, got)
731 func TestHandleGetFileInfo(t *testing.T) {
732 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
741 wantRes []Transaction
745 name: "returns expected fields when a valid file is requested",
748 ID: &[]byte{0x00, 0x01},
752 FileRoot: func() string {
753 path, _ := os.Getwd()
754 return filepath.Join(path, "/test/config/Files")
760 tranGetFileInfo, nil,
761 NewField(fieldFileName, []byte("testfile.txt")),
762 NewField(fieldFilePath, []byte{0x00, 0x00}),
765 wantRes: []Transaction{
767 clientID: &[]byte{0, 1},
771 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
772 ErrorCode: []byte{0, 0, 0, 0},
774 NewField(fieldFileName, []byte("testfile.txt")),
775 NewField(fieldFileTypeString, []byte("Text File")),
776 NewField(fieldFileCreatorString, []byte("ttxt")),
777 NewField(fieldFileComment, []byte{}),
778 NewField(fieldFileType, []byte("TEXT")),
779 NewField(fieldFileCreateDate, make([]byte, 8)),
780 NewField(fieldFileModifyDate, make([]byte, 8)),
781 NewField(fieldFileSize, []byte{0x0, 0x0, 0x0, 0x17}),
788 for _, tt := range tests {
789 t.Run(tt.name, func(t *testing.T) {
790 rand.Seed(1) // reset seed between tests to make transaction IDs predictable
792 gotRes, err := HandleGetFileInfo(tt.args.cc, tt.args.t)
793 if (err != nil) != tt.wantErr {
794 t.Errorf("HandleGetFileInfo() error = %v, wantErr %v", err, tt.wantErr)
798 // Clear the fileWrapper timestamp fields to work around problems running the tests in multiple timezones
799 // TODO: revisit how to test this by mocking the stat calls
800 gotRes[0].Fields[5].Data = make([]byte, 8)
801 gotRes[0].Fields[6].Data = make([]byte, 8)
802 if !assert.Equal(t, tt.wantRes, gotRes) {
803 t.Errorf("HandleGetFileInfo() gotRes = %v, want %v", gotRes, tt.wantRes)
809 func TestHandleNewFolder(t *testing.T) {
817 wantRes []Transaction
821 name: "without required permission",
825 Access: func() accessBitmap {
826 var bits accessBitmap
836 wantRes: []Transaction{
840 Type: []byte{0, 0x00},
841 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
842 ErrorCode: []byte{0, 0, 0, 1},
844 NewField(fieldError, []byte("You are not allowed to create folders.")),
851 name: "when path is nested",
855 Access: func() accessBitmap {
856 var bits accessBitmap
857 bits.Set(accessCreateFolder)
866 FS: func() *MockFileStore {
867 mfs := &MockFileStore{}
868 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
869 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
875 tranNewFolder, &[]byte{0, 1},
876 NewField(fieldFileName, []byte("testFolder")),
877 NewField(fieldFilePath, []byte{
885 wantRes: []Transaction{
887 clientID: &[]byte{0, 1},
891 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
892 ErrorCode: []byte{0, 0, 0, 0},
898 name: "when path is not nested",
902 Access: func() accessBitmap {
903 var bits accessBitmap
904 bits.Set(accessCreateFolder)
913 FS: func() *MockFileStore {
914 mfs := &MockFileStore{}
915 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
916 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
922 tranNewFolder, &[]byte{0, 1},
923 NewField(fieldFileName, []byte("testFolder")),
926 wantRes: []Transaction{
928 clientID: &[]byte{0, 1},
932 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
933 ErrorCode: []byte{0, 0, 0, 0},
939 name: "when Write returns an err",
943 Access: func() accessBitmap {
944 var bits accessBitmap
945 bits.Set(accessCreateFolder)
954 FS: func() *MockFileStore {
955 mfs := &MockFileStore{}
956 mfs.On("Mkdir", "/Files/aaa/testFolder", fs.FileMode(0777)).Return(nil)
957 mfs.On("Stat", "/Files/aaa/testFolder").Return(nil, os.ErrNotExist)
963 tranNewFolder, &[]byte{0, 1},
964 NewField(fieldFileName, []byte("testFolder")),
965 NewField(fieldFilePath, []byte{
970 wantRes: []Transaction{},
974 name: "fieldFileName does not allow directory traversal",
978 Access: func() accessBitmap {
979 var bits accessBitmap
980 bits.Set(accessCreateFolder)
989 FS: func() *MockFileStore {
990 mfs := &MockFileStore{}
991 mfs.On("Mkdir", "/Files/testFolder", fs.FileMode(0777)).Return(nil)
992 mfs.On("Stat", "/Files/testFolder").Return(nil, os.ErrNotExist)
998 tranNewFolder, &[]byte{0, 1},
999 NewField(fieldFileName, []byte("../../testFolder")),
1002 wantRes: []Transaction{
1004 clientID: &[]byte{0, 1},
1008 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
1009 ErrorCode: []byte{0, 0, 0, 0},
1014 name: "fieldFilePath does not allow directory traversal",
1018 Access: func() accessBitmap {
1019 var bits accessBitmap
1020 bits.Set(accessCreateFolder)
1027 FileRoot: "/Files/",
1029 FS: func() *MockFileStore {
1030 mfs := &MockFileStore{}
1031 mfs.On("Mkdir", "/Files/foo/testFolder", fs.FileMode(0777)).Return(nil)
1032 mfs.On("Stat", "/Files/foo/testFolder").Return(nil, os.ErrNotExist)
1038 tranNewFolder, &[]byte{0, 1},
1039 NewField(fieldFileName, []byte("testFolder")),
1040 NewField(fieldFilePath, []byte{
1051 wantRes: []Transaction{
1053 clientID: &[]byte{0, 1},
1057 ID: []byte{0x9a, 0xcb, 0x04, 0x42}, // Random ID from rand.Seed(1)
1058 ErrorCode: []byte{0, 0, 0, 0},
1063 for _, tt := range tests {
1064 t.Run(tt.name, func(t *testing.T) {
1066 gotRes, err := HandleNewFolder(tt.args.cc, tt.args.t)
1067 if (err != nil) != tt.wantErr {
1068 t.Errorf("HandleNewFolder() error = %v, wantErr %v", err, tt.wantErr)
1072 if !tranAssertEqual(t, tt.wantRes, gotRes) {
1073 t.Errorf("HandleNewFolder() gotRes = %v, want %v", gotRes, tt.wantRes)
1079 func TestHandleUploadFile(t *testing.T) {
1087 wantRes []Transaction
1091 name: "when request is valid and user has Upload Anywhere permission",
1096 fileTransfers: map[[4]byte]*FileTransfer{},
1098 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1100 transfers: map[int]map[[4]byte]*FileTransfer{
1104 Access: func() accessBitmap {
1105 var bits accessBitmap
1106 bits.Set(accessUploadFile)
1107 bits.Set(accessUploadAnywhere)
1113 tranUploadFile, &[]byte{0, 1},
1114 NewField(fieldFileName, []byte("testFile")),
1115 NewField(fieldFilePath, []byte{
1123 wantRes: []Transaction{
1128 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1129 ErrorCode: []byte{0, 0, 0, 0},
1131 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}), // rand.Seed(1)
1138 name: "when user does not have required access",
1142 Access: func() accessBitmap {
1143 var bits accessBitmap
1149 tranUploadFile, &[]byte{0, 1},
1150 NewField(fieldFileName, []byte("testFile")),
1151 NewField(fieldFilePath, []byte{
1159 wantRes: []Transaction{
1163 Type: []byte{0, 0x00},
1164 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1165 ErrorCode: []byte{0, 0, 0, 1},
1167 NewField(fieldError, []byte("You are not allowed to upload files.")), // rand.Seed(1)
1174 for _, tt := range tests {
1175 t.Run(tt.name, func(t *testing.T) {
1177 gotRes, err := HandleUploadFile(tt.args.cc, tt.args.t)
1178 if (err != nil) != tt.wantErr {
1179 t.Errorf("HandleUploadFile() error = %v, wantErr %v", err, tt.wantErr)
1183 tranAssertEqual(t, tt.wantRes, gotRes)
1189 func TestHandleMakeAlias(t *testing.T) {
1197 wantRes []Transaction
1201 name: "with valid input and required permissions",
1204 logger: NewTestLogger(),
1206 Access: func() accessBitmap {
1207 var bits accessBitmap
1208 bits.Set(accessMakeAlias)
1214 FileRoot: func() string {
1215 path, _ := os.Getwd()
1216 return path + "/test/config/Files"
1219 Logger: NewTestLogger(),
1220 FS: func() *MockFileStore {
1221 mfs := &MockFileStore{}
1222 path, _ := os.Getwd()
1225 path+"/test/config/Files/foo/testFile",
1226 path+"/test/config/Files/bar/testFile",
1233 tranMakeFileAlias, &[]byte{0, 1},
1234 NewField(fieldFileName, []byte("testFile")),
1235 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1236 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1239 wantRes: []Transaction{
1244 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1245 ErrorCode: []byte{0, 0, 0, 0},
1246 Fields: []Field(nil),
1252 name: "when symlink returns an error",
1255 logger: NewTestLogger(),
1257 Access: func() accessBitmap {
1258 var bits accessBitmap
1259 bits.Set(accessMakeAlias)
1265 FileRoot: func() string {
1266 path, _ := os.Getwd()
1267 return path + "/test/config/Files"
1270 Logger: NewTestLogger(),
1271 FS: func() *MockFileStore {
1272 mfs := &MockFileStore{}
1273 path, _ := os.Getwd()
1276 path+"/test/config/Files/foo/testFile",
1277 path+"/test/config/Files/bar/testFile",
1278 ).Return(errors.New("ohno"))
1284 tranMakeFileAlias, &[]byte{0, 1},
1285 NewField(fieldFileName, []byte("testFile")),
1286 NewField(fieldFilePath, EncodeFilePath(strings.Join([]string{"foo"}, "/"))),
1287 NewField(fieldFileNewPath, EncodeFilePath(strings.Join([]string{"bar"}, "/"))),
1290 wantRes: []Transaction{
1294 Type: []byte{0, 0x00},
1295 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1296 ErrorCode: []byte{0, 0, 0, 1},
1298 NewField(fieldError, []byte("Error creating alias")),
1305 name: "when user does not have required permission",
1308 logger: NewTestLogger(),
1310 Access: func() accessBitmap {
1311 var bits accessBitmap
1317 FileRoot: func() string {
1318 path, _ := os.Getwd()
1319 return path + "/test/config/Files"
1325 tranMakeFileAlias, &[]byte{0, 1},
1326 NewField(fieldFileName, []byte("testFile")),
1327 NewField(fieldFilePath, []byte{
1333 NewField(fieldFileNewPath, []byte{
1341 wantRes: []Transaction{
1345 Type: []byte{0, 0x00},
1346 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1347 ErrorCode: []byte{0, 0, 0, 1},
1349 NewField(fieldError, []byte("You are not allowed to make aliases.")),
1356 for _, tt := range tests {
1357 t.Run(tt.name, func(t *testing.T) {
1358 gotRes, err := HandleMakeAlias(tt.args.cc, tt.args.t)
1359 if (err != nil) != tt.wantErr {
1360 t.Errorf("HandleMakeAlias(%v, %v)", tt.args.cc, tt.args.t)
1364 tranAssertEqual(t, tt.wantRes, gotRes)
1369 func TestHandleGetUser(t *testing.T) {
1377 wantRes []Transaction
1378 wantErr assert.ErrorAssertionFunc
1381 name: "when account is valid",
1385 Access: func() accessBitmap {
1386 var bits accessBitmap
1387 bits.Set(accessOpenUser)
1392 Accounts: map[string]*Account{
1396 Password: "password",
1397 Access: accessBitmap{},
1403 tranGetUser, &[]byte{0, 1},
1404 NewField(fieldUserLogin, []byte("guest")),
1407 wantRes: []Transaction{
1412 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1413 ErrorCode: []byte{0, 0, 0, 0},
1415 NewField(fieldUserName, []byte("Guest")),
1416 NewField(fieldUserLogin, negateString([]byte("guest"))),
1417 NewField(fieldUserPassword, []byte("password")),
1418 NewField(fieldUserAccess, []byte{0, 0, 0, 0, 0, 0, 0, 0}),
1422 wantErr: assert.NoError,
1425 name: "when user does not have required permission",
1429 Access: func() accessBitmap {
1430 var bits accessBitmap
1435 Accounts: map[string]*Account{},
1439 tranGetUser, &[]byte{0, 1},
1440 NewField(fieldUserLogin, []byte("nonExistentUser")),
1443 wantRes: []Transaction{
1447 Type: []byte{0, 0x00},
1448 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1449 ErrorCode: []byte{0, 0, 0, 1},
1451 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1455 wantErr: assert.NoError,
1458 name: "when account does not exist",
1462 Access: func() accessBitmap {
1463 var bits accessBitmap
1464 bits.Set(accessOpenUser)
1469 Accounts: map[string]*Account{},
1473 tranGetUser, &[]byte{0, 1},
1474 NewField(fieldUserLogin, []byte("nonExistentUser")),
1477 wantRes: []Transaction{
1481 Type: []byte{0, 0x00},
1482 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1483 ErrorCode: []byte{0, 0, 0, 1},
1485 NewField(fieldError, []byte("Account does not exist.")),
1489 wantErr: assert.NoError,
1492 for _, tt := range tests {
1493 t.Run(tt.name, func(t *testing.T) {
1494 gotRes, err := HandleGetUser(tt.args.cc, tt.args.t)
1495 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetUser(%v, %v)", tt.args.cc, tt.args.t)) {
1499 tranAssertEqual(t, tt.wantRes, gotRes)
1504 func TestHandleDeleteUser(t *testing.T) {
1512 wantRes []Transaction
1513 wantErr assert.ErrorAssertionFunc
1516 name: "when user dataFile",
1520 Access: func() accessBitmap {
1521 var bits accessBitmap
1522 bits.Set(accessDeleteUser)
1527 Accounts: map[string]*Account{
1530 Name: "Testy McTest",
1531 Password: "password",
1532 Access: accessBitmap{},
1535 FS: func() *MockFileStore {
1536 mfs := &MockFileStore{}
1537 mfs.On("Remove", "Users/testuser.yaml").Return(nil)
1543 tranDeleteUser, &[]byte{0, 1},
1544 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1547 wantRes: []Transaction{
1552 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1553 ErrorCode: []byte{0, 0, 0, 0},
1554 Fields: []Field(nil),
1557 wantErr: assert.NoError,
1560 name: "when user does not have required permission",
1564 Access: func() accessBitmap {
1565 var bits accessBitmap
1570 Accounts: map[string]*Account{},
1574 tranDeleteUser, &[]byte{0, 1},
1575 NewField(fieldUserLogin, negateString([]byte("testuser"))),
1578 wantRes: []Transaction{
1582 Type: []byte{0, 0x00},
1583 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1584 ErrorCode: []byte{0, 0, 0, 1},
1586 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
1590 wantErr: assert.NoError,
1593 for _, tt := range tests {
1594 t.Run(tt.name, func(t *testing.T) {
1595 gotRes, err := HandleDeleteUser(tt.args.cc, tt.args.t)
1596 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteUser(%v, %v)", tt.args.cc, tt.args.t)) {
1600 tranAssertEqual(t, tt.wantRes, gotRes)
1605 func TestHandleGetMsgs(t *testing.T) {
1613 wantRes []Transaction
1614 wantErr assert.ErrorAssertionFunc
1617 name: "returns news data",
1621 Access: func() accessBitmap {
1622 var bits accessBitmap
1623 bits.Set(accessNewsReadArt)
1628 FlatNews: []byte("TEST"),
1632 tranGetMsgs, &[]byte{0, 1},
1635 wantRes: []Transaction{
1640 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1641 ErrorCode: []byte{0, 0, 0, 0},
1643 NewField(fieldData, []byte("TEST")),
1647 wantErr: assert.NoError,
1650 name: "when user does not have required permission",
1654 Access: func() accessBitmap {
1655 var bits accessBitmap
1660 Accounts: map[string]*Account{},
1664 tranGetMsgs, &[]byte{0, 1},
1667 wantRes: []Transaction{
1671 Type: []byte{0, 0x00},
1672 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1673 ErrorCode: []byte{0, 0, 0, 1},
1675 NewField(fieldError, []byte("You are not allowed to read news.")),
1679 wantErr: assert.NoError,
1682 for _, tt := range tests {
1683 t.Run(tt.name, func(t *testing.T) {
1684 gotRes, err := HandleGetMsgs(tt.args.cc, tt.args.t)
1685 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetMsgs(%v, %v)", tt.args.cc, tt.args.t)) {
1689 tranAssertEqual(t, tt.wantRes, gotRes)
1694 func TestHandleNewUser(t *testing.T) {
1702 wantRes []Transaction
1703 wantErr assert.ErrorAssertionFunc
1706 name: "when user does not have required permission",
1710 Access: func() accessBitmap {
1711 var bits accessBitmap
1716 Accounts: map[string]*Account{},
1720 tranNewUser, &[]byte{0, 1},
1723 wantRes: []Transaction{
1727 Type: []byte{0, 0x00},
1728 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1729 ErrorCode: []byte{0, 0, 0, 1},
1731 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
1735 wantErr: assert.NoError,
1738 name: "when user attempts to create account with greater access",
1742 Access: func() accessBitmap {
1743 var bits accessBitmap
1744 bits.Set(accessCreateUser)
1749 Accounts: map[string]*Account{},
1753 tranNewUser, &[]byte{0, 1},
1754 NewField(fieldUserLogin, []byte("userB")),
1758 var bits accessBitmap
1759 bits.Set(accessDisconUser)
1765 wantRes: []Transaction{
1769 Type: []byte{0, 0x00},
1770 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1771 ErrorCode: []byte{0, 0, 0, 1},
1773 NewField(fieldError, []byte("Cannot create account with more access than yourself.")),
1777 wantErr: assert.NoError,
1780 for _, tt := range tests {
1781 t.Run(tt.name, func(t *testing.T) {
1782 gotRes, err := HandleNewUser(tt.args.cc, tt.args.t)
1783 if !tt.wantErr(t, err, fmt.Sprintf("HandleNewUser(%v, %v)", tt.args.cc, tt.args.t)) {
1787 tranAssertEqual(t, tt.wantRes, gotRes)
1792 func TestHandleListUsers(t *testing.T) {
1800 wantRes []Transaction
1801 wantErr assert.ErrorAssertionFunc
1804 name: "when user does not have required permission",
1808 Access: func() accessBitmap {
1809 var bits accessBitmap
1814 Accounts: map[string]*Account{},
1818 tranNewUser, &[]byte{0, 1},
1821 wantRes: []Transaction{
1825 Type: []byte{0, 0x00},
1826 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1827 ErrorCode: []byte{0, 0, 0, 1},
1829 NewField(fieldError, []byte("You are not allowed to view accounts.")),
1833 wantErr: assert.NoError,
1836 name: "when user has required permission",
1840 Access: func() accessBitmap {
1841 var bits accessBitmap
1842 bits.Set(accessOpenUser)
1847 Accounts: map[string]*Account{
1852 Access: accessBitmap{255, 255, 255, 255, 255, 255, 255, 255},
1858 tranGetClientInfoText, &[]byte{0, 1},
1859 NewField(fieldUserID, []byte{0, 1}),
1862 wantRes: []Transaction{
1867 ID: []byte{0, 0, 0, 0},
1868 ErrorCode: []byte{0, 0, 0, 0},
1870 NewField(fieldData, []byte{
1871 0x00, 0x04, 0x00, 0x66, 0x00, 0x05, 0x67, 0x75, 0x65, 0x73, 0x74, 0x00, 0x69, 0x00, 0x05, 0x98,
1872 0x8a, 0x9a, 0x8c, 0x8b, 0x00, 0x6e, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1873 0x00, 0x6a, 0x00, 0x01, 0x78,
1878 wantErr: assert.NoError,
1881 for _, tt := range tests {
1882 t.Run(tt.name, func(t *testing.T) {
1883 gotRes, err := HandleListUsers(tt.args.cc, tt.args.t)
1884 if !tt.wantErr(t, err, fmt.Sprintf("HandleListUsers(%v, %v)", tt.args.cc, tt.args.t)) {
1888 tranAssertEqual(t, tt.wantRes, gotRes)
1893 func TestHandleDownloadFile(t *testing.T) {
1901 wantRes []Transaction
1902 wantErr assert.ErrorAssertionFunc
1905 name: "when user does not have required permission",
1909 Access: func() accessBitmap {
1910 var bits accessBitmap
1916 t: NewTransaction(tranDownloadFile, &[]byte{0, 1}),
1918 wantRes: []Transaction{
1922 Type: []byte{0, 0x00},
1923 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1924 ErrorCode: []byte{0, 0, 0, 1},
1926 NewField(fieldError, []byte("You are not allowed to download files.")),
1930 wantErr: assert.NoError,
1933 name: "with a valid file",
1936 transfers: map[int]map[[4]byte]*FileTransfer{
1940 Access: func() accessBitmap {
1941 var bits accessBitmap
1942 bits.Set(accessDownloadFile)
1948 fileTransfers: map[[4]byte]*FileTransfer{},
1950 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
1952 Accounts: map[string]*Account{},
1958 NewField(fieldFileName, []byte("testfile.txt")),
1959 NewField(fieldFilePath, []byte{0x0, 0x00}),
1962 wantRes: []Transaction{
1967 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
1968 ErrorCode: []byte{0, 0, 0, 0},
1970 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
1971 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
1972 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x00, 0xa5}),
1973 NewField(fieldFileSize, []byte{0x00, 0x00, 0x00, 0x17}),
1977 wantErr: assert.NoError,
1980 name: "when client requests to resume 1k test file at offset 256",
1983 transfers: map[int]map[[4]byte]*FileTransfer{
1985 }, Account: &Account{
1986 Access: func() accessBitmap {
1987 var bits accessBitmap
1988 bits.Set(accessDownloadFile)
1995 // FS: func() *MockFileStore {
1996 // path, _ := os.Getwd()
1997 // testFile, err := os.Open(path + "/test/config/Files/testfile-1k")
2002 // mfi := &MockFileInfo{}
2003 // mfi.On("Mode").Return(fs.FileMode(0))
2004 // mfs := &MockFileStore{}
2005 // mfs.On("Stat", "/fakeRoot/Files/testfile.txt").Return(mfi, nil)
2006 // mfs.On("Open", "/fakeRoot/Files/testfile.txt").Return(testFile, nil)
2007 // mfs.On("Stat", "/fakeRoot/Files/.info_testfile.txt").Return(nil, errors.New("no"))
2008 // mfs.On("Stat", "/fakeRoot/Files/.rsrc_testfile.txt").Return(nil, errors.New("no"))
2012 fileTransfers: map[[4]byte]*FileTransfer{},
2014 FileRoot: func() string { path, _ := os.Getwd(); return path + "/test/config/Files" }(),
2016 Accounts: map[string]*Account{},
2022 NewField(fieldFileName, []byte("testfile-1k")),
2023 NewField(fieldFilePath, []byte{0x00, 0x00}),
2025 fieldFileResumeData,
2027 frd := FileResumeData{
2031 ForkCount: [2]byte{0, 2},
2032 ForkInfoList: []ForkInfoList{
2034 Fork: [4]byte{0x44, 0x41, 0x54, 0x41}, // "DATA"
2035 DataSize: [4]byte{0, 0, 0x01, 0x00}, // request offset 256
2040 Fork: [4]byte{0x4d, 0x41, 0x43, 0x52}, // "MACR"
2041 DataSize: [4]byte{0, 0, 0, 0},
2047 b, _ := frd.BinaryMarshal()
2053 wantRes: []Transaction{
2058 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2059 ErrorCode: []byte{0, 0, 0, 0},
2061 NewField(fieldRefNum, []byte{0x52, 0xfd, 0xfc, 0x07}),
2062 NewField(fieldWaitingCount, []byte{0x00, 0x00}),
2063 NewField(fieldTransferSize, []byte{0x00, 0x00, 0x03, 0x8d}),
2064 NewField(fieldFileSize, []byte{0x00, 0x00, 0x03, 0x00}),
2068 wantErr: assert.NoError,
2071 for _, tt := range tests {
2072 t.Run(tt.name, func(t *testing.T) {
2073 gotRes, err := HandleDownloadFile(tt.args.cc, tt.args.t)
2074 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadFile(%v, %v)", tt.args.cc, tt.args.t)) {
2078 tranAssertEqual(t, tt.wantRes, gotRes)
2083 func TestHandleUpdateUser(t *testing.T) {
2091 wantRes []Transaction
2092 wantErr assert.ErrorAssertionFunc
2095 name: "when action is create user without required permission",
2098 logger: NewTestLogger(),
2100 Logger: NewTestLogger(),
2103 Access: func() accessBitmap {
2104 var bits accessBitmap
2112 NewField(fieldData, []byte{
2113 0x00, 0x04, // field count
2115 0x00, 0x69, // fieldUserLogin = 105
2119 0x00, 0x6a, // fieldUserPassword = 106
2123 0x00, 0x66, // fieldUserName = 102
2127 0x00, 0x6e, // fieldUserAccess = 110
2129 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
2133 wantRes: []Transaction{
2137 Type: []byte{0, 0x00},
2138 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2139 ErrorCode: []byte{0, 0, 0, 1},
2141 NewField(fieldError, []byte("You are not allowed to create new accounts.")),
2145 wantErr: assert.NoError,
2148 name: "when action is modify user without required permission",
2151 logger: NewTestLogger(),
2153 Logger: NewTestLogger(),
2154 Accounts: map[string]*Account{
2159 Access: func() accessBitmap {
2160 var bits accessBitmap
2168 NewField(fieldData, []byte{
2169 0x00, 0x04, // field count
2171 0x00, 0x69, // fieldUserLogin = 105
2175 0x00, 0x6a, // fieldUserPassword = 106
2179 0x00, 0x66, // fieldUserName = 102
2183 0x00, 0x6e, // fieldUserAccess = 110
2185 0x60, 0x70, 0x0c, 0x20, 0x03, 0x80, 0x00, 0x00,
2189 wantRes: []Transaction{
2193 Type: []byte{0, 0x00},
2194 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2195 ErrorCode: []byte{0, 0, 0, 1},
2197 NewField(fieldError, []byte("You are not allowed to modify accounts.")),
2201 wantErr: assert.NoError,
2204 name: "when action is delete user without required permission",
2207 logger: NewTestLogger(),
2209 Accounts: map[string]*Account{
2214 Access: func() accessBitmap {
2215 var bits accessBitmap
2223 NewField(fieldData, []byte{
2231 wantRes: []Transaction{
2235 Type: []byte{0, 0x00},
2236 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2237 ErrorCode: []byte{0, 0, 0, 1},
2239 NewField(fieldError, []byte("You are not allowed to delete accounts.")),
2243 wantErr: assert.NoError,
2246 for _, tt := range tests {
2247 t.Run(tt.name, func(t *testing.T) {
2248 gotRes, err := HandleUpdateUser(tt.args.cc, tt.args.t)
2249 if !tt.wantErr(t, err, fmt.Sprintf("HandleUpdateUser(%v, %v)", tt.args.cc, tt.args.t)) {
2253 tranAssertEqual(t, tt.wantRes, gotRes)
2258 func TestHandleDelNewsArt(t *testing.T) {
2266 wantRes []Transaction
2267 wantErr assert.ErrorAssertionFunc
2270 name: "without required permission",
2274 Access: func() accessBitmap {
2275 var bits accessBitmap
2285 wantRes: []Transaction{
2289 Type: []byte{0, 0x00},
2290 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2291 ErrorCode: []byte{0, 0, 0, 1},
2293 NewField(fieldError, []byte("You are not allowed to delete news articles.")),
2297 wantErr: assert.NoError,
2300 for _, tt := range tests {
2301 t.Run(tt.name, func(t *testing.T) {
2302 gotRes, err := HandleDelNewsArt(tt.args.cc, tt.args.t)
2303 if !tt.wantErr(t, err, fmt.Sprintf("HandleDelNewsArt(%v, %v)", tt.args.cc, tt.args.t)) {
2306 tranAssertEqual(t, tt.wantRes, gotRes)
2311 func TestHandleDisconnectUser(t *testing.T) {
2319 wantRes []Transaction
2320 wantErr assert.ErrorAssertionFunc
2323 name: "without required permission",
2327 Access: func() accessBitmap {
2328 var bits accessBitmap
2338 wantRes: []Transaction{
2342 Type: []byte{0, 0x00},
2343 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2344 ErrorCode: []byte{0, 0, 0, 1},
2346 NewField(fieldError, []byte("You are not allowed to disconnect users.")),
2350 wantErr: assert.NoError,
2353 name: "when target user has 'cannot be disconnected' priv",
2357 Clients: map[uint16]*ClientConn{
2361 Access: func() accessBitmap {
2362 var bits accessBitmap
2363 bits.Set(accessCannotBeDiscon)
2371 Access: func() accessBitmap {
2372 var bits accessBitmap
2373 bits.Set(accessDisconUser)
2381 NewField(fieldUserID, []byte{0, 1}),
2384 wantRes: []Transaction{
2388 Type: []byte{0, 0x00},
2389 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2390 ErrorCode: []byte{0, 0, 0, 1},
2392 NewField(fieldError, []byte("unnamed is not allowed to be disconnected.")),
2396 wantErr: assert.NoError,
2399 for _, tt := range tests {
2400 t.Run(tt.name, func(t *testing.T) {
2401 gotRes, err := HandleDisconnectUser(tt.args.cc, tt.args.t)
2402 if !tt.wantErr(t, err, fmt.Sprintf("HandleDisconnectUser(%v, %v)", tt.args.cc, tt.args.t)) {
2405 tranAssertEqual(t, tt.wantRes, gotRes)
2410 func TestHandleSendInstantMsg(t *testing.T) {
2418 wantRes []Transaction
2419 wantErr assert.ErrorAssertionFunc
2422 name: "without required permission",
2426 Access: func() accessBitmap {
2427 var bits accessBitmap
2437 wantRes: []Transaction{
2441 Type: []byte{0, 0x00},
2442 ID: []byte{0, 0, 0, 0},
2443 ErrorCode: []byte{0, 0, 0, 1},
2445 NewField(fieldError, []byte("You are not allowed to send private messages.")),
2449 wantErr: assert.NoError,
2452 name: "when client 1 sends a message to client 2",
2456 Access: func() accessBitmap {
2457 var bits accessBitmap
2458 bits.Set(accessSendPrivMsg)
2463 UserName: []byte("User1"),
2465 Clients: map[uint16]*ClientConn{
2467 AutoReply: []byte(nil),
2468 Flags: []byte{0, 0},
2476 NewField(fieldData, []byte("hai")),
2477 NewField(fieldUserID, []byte{0, 2}),
2480 wantRes: []Transaction{
2484 NewField(fieldData, []byte("hai")),
2485 NewField(fieldUserName, []byte("User1")),
2486 NewField(fieldUserID, []byte{0, 1}),
2487 NewField(fieldOptions, []byte{0, 1}),
2490 clientID: &[]byte{0, 1},
2494 ID: []byte{0, 0, 0, 0},
2495 ErrorCode: []byte{0, 0, 0, 0},
2496 Fields: []Field(nil),
2499 wantErr: assert.NoError,
2502 name: "when client 2 has autoreply enabled",
2506 Access: func() accessBitmap {
2507 var bits accessBitmap
2508 bits.Set(accessSendPrivMsg)
2513 UserName: []byte("User1"),
2515 Clients: map[uint16]*ClientConn{
2517 Flags: []byte{0, 0},
2519 UserName: []byte("User2"),
2520 AutoReply: []byte("autohai"),
2528 NewField(fieldData, []byte("hai")),
2529 NewField(fieldUserID, []byte{0, 2}),
2532 wantRes: []Transaction{
2536 NewField(fieldData, []byte("hai")),
2537 NewField(fieldUserName, []byte("User1")),
2538 NewField(fieldUserID, []byte{0, 1}),
2539 NewField(fieldOptions, []byte{0, 1}),
2544 NewField(fieldData, []byte("autohai")),
2545 NewField(fieldUserName, []byte("User2")),
2546 NewField(fieldUserID, []byte{0, 2}),
2547 NewField(fieldOptions, []byte{0, 1}),
2550 clientID: &[]byte{0, 1},
2554 ID: []byte{0, 0, 0, 0},
2555 ErrorCode: []byte{0, 0, 0, 0},
2556 Fields: []Field(nil),
2559 wantErr: assert.NoError,
2562 name: "when client 2 has refuse private messages enabled",
2566 Access: func() accessBitmap {
2567 var bits accessBitmap
2568 bits.Set(accessSendPrivMsg)
2573 UserName: []byte("User1"),
2575 Clients: map[uint16]*ClientConn{
2577 Flags: []byte{255, 255},
2579 UserName: []byte("User2"),
2587 NewField(fieldData, []byte("hai")),
2588 NewField(fieldUserID, []byte{0, 2}),
2591 wantRes: []Transaction{
2595 NewField(fieldData, []byte("User2 does not accept private messages.")),
2596 NewField(fieldUserName, []byte("User2")),
2597 NewField(fieldUserID, []byte{0, 2}),
2598 NewField(fieldOptions, []byte{0, 2}),
2601 clientID: &[]byte{0, 1},
2605 ID: []byte{0, 0, 0, 0},
2606 ErrorCode: []byte{0, 0, 0, 0},
2607 Fields: []Field(nil),
2610 wantErr: assert.NoError,
2613 for _, tt := range tests {
2614 t.Run(tt.name, func(t *testing.T) {
2615 gotRes, err := HandleSendInstantMsg(tt.args.cc, tt.args.t)
2616 if !tt.wantErr(t, err, fmt.Sprintf("HandleSendInstantMsg(%v, %v)", tt.args.cc, tt.args.t)) {
2620 tranAssertEqual(t, tt.wantRes, gotRes)
2625 func TestHandleDeleteFile(t *testing.T) {
2633 wantRes []Transaction
2634 wantErr assert.ErrorAssertionFunc
2637 name: "when user does not have required permission to delete a folder",
2641 Access: func() accessBitmap {
2642 var bits accessBitmap
2648 FileRoot: func() string {
2649 return "/fakeRoot/Files"
2652 FS: func() *MockFileStore {
2653 mfi := &MockFileInfo{}
2654 mfi.On("Mode").Return(fs.FileMode(0))
2655 mfi.On("Size").Return(int64(100))
2656 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2657 mfi.On("IsDir").Return(false)
2658 mfi.On("Name").Return("testfile")
2660 mfs := &MockFileStore{}
2661 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2662 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2663 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2667 Accounts: map[string]*Account{},
2671 tranDeleteFile, &[]byte{0, 1},
2672 NewField(fieldFileName, []byte("testfile")),
2673 NewField(fieldFilePath, []byte{
2681 wantRes: []Transaction{
2685 Type: []byte{0, 0x00},
2686 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
2687 ErrorCode: []byte{0, 0, 0, 1},
2689 NewField(fieldError, []byte("You are not allowed to delete files.")),
2693 wantErr: assert.NoError,
2696 name: "deletes all associated metadata files",
2700 Access: func() accessBitmap {
2701 var bits accessBitmap
2702 bits.Set(accessDeleteFile)
2708 FileRoot: func() string {
2709 return "/fakeRoot/Files"
2712 FS: func() *MockFileStore {
2713 mfi := &MockFileInfo{}
2714 mfi.On("Mode").Return(fs.FileMode(0))
2715 mfi.On("Size").Return(int64(100))
2716 mfi.On("ModTime").Return(time.Parse(time.Layout, time.Layout))
2717 mfi.On("IsDir").Return(false)
2718 mfi.On("Name").Return("testfile")
2720 mfs := &MockFileStore{}
2721 mfs.On("Stat", "/fakeRoot/Files/aaa/testfile").Return(mfi, nil)
2722 mfs.On("Stat", "/fakeRoot/Files/aaa/.info_testfile").Return(nil, errors.New("err"))
2723 mfs.On("Stat", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil, errors.New("err"))
2725 mfs.On("RemoveAll", "/fakeRoot/Files/aaa/testfile").Return(nil)
2726 mfs.On("Remove", "/fakeRoot/Files/aaa/testfile.incomplete").Return(nil)
2727 mfs.On("Remove", "/fakeRoot/Files/aaa/.rsrc_testfile").Return(nil)
2728 mfs.On("Remove", "/fakeRoot/Files/aaa/.info_testfile").Return(nil)
2732 Accounts: map[string]*Account{},
2736 tranDeleteFile, &[]byte{0, 1},
2737 NewField(fieldFileName, []byte("testfile")),
2738 NewField(fieldFilePath, []byte{
2746 wantRes: []Transaction{
2751 ID: []byte{0x0, 0x0, 0x0, 0x0},
2752 ErrorCode: []byte{0, 0, 0, 0},
2753 Fields: []Field(nil),
2756 wantErr: assert.NoError,
2759 for _, tt := range tests {
2760 t.Run(tt.name, func(t *testing.T) {
2761 gotRes, err := HandleDeleteFile(tt.args.cc, tt.args.t)
2762 if !tt.wantErr(t, err, fmt.Sprintf("HandleDeleteFile(%v, %v)", tt.args.cc, tt.args.t)) {
2766 tranAssertEqual(t, tt.wantRes, gotRes)
2768 tt.args.cc.Server.FS.(*MockFileStore).AssertExpectations(t)
2773 func TestHandleGetFileNameList(t *testing.T) {
2781 wantRes []Transaction
2782 wantErr assert.ErrorAssertionFunc
2785 name: "when fieldFilePath is a drop box, but user does not have accessViewDropBoxes ",
2789 Access: func() accessBitmap {
2790 var bits accessBitmap
2797 FileRoot: func() string {
2798 path, _ := os.Getwd()
2799 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2805 tranGetFileNameList, &[]byte{0, 1},
2806 NewField(fieldFilePath, []byte{
2810 0x64, 0x72, 0x6f, 0x70, 0x20, 0x62, 0x6f, 0x78, // "drop box"
2814 wantRes: []Transaction{
2818 Type: []byte{0, 0x00},
2819 ID: []byte{0, 0, 0, 0},
2820 ErrorCode: []byte{0, 0, 0, 1},
2822 NewField(fieldError, []byte("You are not allowed to view drop boxes.")),
2826 wantErr: assert.NoError,
2829 name: "with file root",
2834 FileRoot: func() string {
2835 path, _ := os.Getwd()
2836 return filepath.Join(path, "/test/config/Files/getFileNameListTestDir")
2842 tranGetFileNameList, &[]byte{0, 1},
2843 NewField(fieldFilePath, []byte{
2849 wantRes: []Transaction{
2854 ID: []byte{0, 0, 0, 0},
2855 ErrorCode: []byte{0, 0, 0, 0},
2858 fieldFileNameWithInfo,
2860 fnwi := FileNameWithInfo{
2861 fileNameWithInfoHeader: fileNameWithInfoHeader{
2862 Type: [4]byte{0x54, 0x45, 0x58, 0x54},
2863 Creator: [4]byte{0x54, 0x54, 0x58, 0x54},
2864 FileSize: [4]byte{0, 0, 0x04, 0},
2866 NameScript: [2]byte{},
2867 NameSize: [2]byte{0, 0x0b},
2869 name: []byte("testfile-1k"),
2871 b, _ := fnwi.MarshalBinary()
2878 wantErr: assert.NoError,
2881 for _, tt := range tests {
2882 t.Run(tt.name, func(t *testing.T) {
2883 gotRes, err := HandleGetFileNameList(tt.args.cc, tt.args.t)
2884 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetFileNameList(%v, %v)", tt.args.cc, tt.args.t)) {
2888 tranAssertEqual(t, tt.wantRes, gotRes)
2893 func TestHandleGetClientInfoText(t *testing.T) {
2901 wantRes []Transaction
2902 wantErr assert.ErrorAssertionFunc
2905 name: "when user does not have required permission",
2909 Access: func() accessBitmap {
2910 var bits accessBitmap
2915 Accounts: map[string]*Account{},
2919 tranGetClientInfoText, &[]byte{0, 1},
2920 NewField(fieldUserID, []byte{0, 1}),
2923 wantRes: []Transaction{
2927 Type: []byte{0, 0x00},
2928 ID: []byte{0, 0, 0, 0},
2929 ErrorCode: []byte{0, 0, 0, 1},
2931 NewField(fieldError, []byte("You are not allowed to get client info.")),
2935 wantErr: assert.NoError,
2938 name: "with a valid user",
2941 UserName: []byte("Testy McTest"),
2942 RemoteAddr: "1.2.3.4:12345",
2944 Access: func() accessBitmap {
2945 var bits accessBitmap
2946 bits.Set(accessGetClientInfo)
2953 Accounts: map[string]*Account{},
2954 Clients: map[uint16]*ClientConn{
2956 UserName: []byte("Testy McTest"),
2957 RemoteAddr: "1.2.3.4:12345",
2959 Access: func() accessBitmap {
2960 var bits accessBitmap
2961 bits.Set(accessGetClientInfo)
2970 transfers: map[int]map[[4]byte]*FileTransfer{
2978 tranGetClientInfoText, &[]byte{0, 1},
2979 NewField(fieldUserID, []byte{0, 1}),
2982 wantRes: []Transaction{
2987 ID: []byte{0, 0, 0, 0},
2988 ErrorCode: []byte{0, 0, 0, 0},
2990 NewField(fieldData, []byte(
2991 strings.Replace(`Nickname: Testy McTest
2994 Address: 1.2.3.4:12345
2996 -------- File Downloads ---------
3000 ------- Folder Downloads --------
3004 --------- File Uploads ----------
3008 -------- Folder Uploads ---------
3012 ------- Waiting Downloads -------
3016 `, "\n", "\r", -1)),
3018 NewField(fieldUserName, []byte("Testy McTest")),
3022 wantErr: assert.NoError,
3025 for _, tt := range tests {
3026 t.Run(tt.name, func(t *testing.T) {
3027 gotRes, err := HandleGetClientInfoText(tt.args.cc, tt.args.t)
3028 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetClientInfoText(%v, %v)", tt.args.cc, tt.args.t)) {
3031 tranAssertEqual(t, tt.wantRes, gotRes)
3036 func TestHandleTranAgreed(t *testing.T) {
3044 wantRes []Transaction
3045 wantErr assert.ErrorAssertionFunc
3048 name: "normal request flow",
3052 Access: func() accessBitmap {
3053 var bits accessBitmap
3054 bits.Set(accessDisconUser)
3055 bits.Set(accessAnyName)
3059 Flags: []byte{0, 1},
3060 Version: []byte{0, 1},
3062 logger: NewTestLogger(),
3065 BannerFile: "banner.jpg",
3071 NewField(fieldUserName, []byte("username")),
3072 NewField(fieldUserIconID, []byte{0, 1}),
3073 NewField(fieldOptions, []byte{0, 0}),
3076 wantRes: []Transaction{
3078 clientID: &[]byte{0, 1},
3081 Type: []byte{0, 0x7a},
3082 ID: []byte{0, 0, 0, 0},
3083 ErrorCode: []byte{0, 0, 0, 0},
3085 NewField(fieldBannerType, []byte("JPEG")),
3089 clientID: &[]byte{0, 1},
3093 ID: []byte{0, 0, 0, 0},
3094 ErrorCode: []byte{0, 0, 0, 0},
3098 wantErr: assert.NoError,
3101 for _, tt := range tests {
3102 t.Run(tt.name, func(t *testing.T) {
3103 gotRes, err := HandleTranAgreed(tt.args.cc, tt.args.t)
3104 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranAgreed(%v, %v)", tt.args.cc, tt.args.t)) {
3107 tranAssertEqual(t, tt.wantRes, gotRes)
3112 func TestHandleSetClientUserInfo(t *testing.T) {
3120 wantRes []Transaction
3121 wantErr assert.ErrorAssertionFunc
3124 name: "when client does not have accessAnyName",
3128 Access: func() accessBitmap {
3129 var bits accessBitmap
3134 UserName: []byte("Guest"),
3135 Flags: []byte{0, 1},
3137 Clients: map[uint16]*ClientConn{
3145 tranSetClientUserInfo, nil,
3146 NewField(fieldUserIconID, []byte{0, 1}),
3147 NewField(fieldUserName, []byte("NOPE")),
3150 wantRes: []Transaction{
3152 clientID: &[]byte{0, 1},
3155 Type: []byte{0x01, 0x2d},
3156 ID: []byte{0, 0, 0, 0},
3157 ErrorCode: []byte{0, 0, 0, 0},
3159 NewField(fieldUserID, []byte{0, 1}),
3160 NewField(fieldUserIconID, []byte{0, 1}),
3161 NewField(fieldUserFlags, []byte{0, 1}),
3162 NewField(fieldUserName, []byte("Guest"))},
3165 wantErr: assert.NoError,
3168 for _, tt := range tests {
3169 t.Run(tt.name, func(t *testing.T) {
3170 gotRes, err := HandleSetClientUserInfo(tt.args.cc, tt.args.t)
3171 if !tt.wantErr(t, err, fmt.Sprintf("HandleSetClientUserInfo(%v, %v)", tt.args.cc, tt.args.t)) {
3175 tranAssertEqual(t, tt.wantRes, gotRes)
3180 func TestHandleDelNewsItem(t *testing.T) {
3188 wantRes []Transaction
3189 wantErr assert.ErrorAssertionFunc
3192 name: "when user does not have permission to delete a news category",
3196 Access: accessBitmap{},
3200 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3211 tranDelNewsItem, nil,
3212 NewField(fieldNewsPath,
3217 0x74, 0x65, 0x73, 0x74,
3222 wantRes: []Transaction{
3224 clientID: &[]byte{0, 1},
3227 Type: []byte{0, 0x00},
3228 ID: []byte{0, 0, 0, 0},
3229 ErrorCode: []byte{0, 0, 0, 1},
3231 NewField(fieldError, []byte("You are not allowed to delete news categories.")),
3235 wantErr: assert.NoError,
3238 name: "when user does not have permission to delete a news folder",
3242 Access: accessBitmap{},
3246 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3257 tranDelNewsItem, nil,
3258 NewField(fieldNewsPath,
3263 0x74, 0x65, 0x73, 0x74,
3268 wantRes: []Transaction{
3270 clientID: &[]byte{0, 1},
3273 Type: []byte{0, 0x00},
3274 ID: []byte{0, 0, 0, 0},
3275 ErrorCode: []byte{0, 0, 0, 1},
3277 NewField(fieldError, []byte("You are not allowed to delete news folders.")),
3281 wantErr: assert.NoError,
3284 name: "when user deletes a news folder",
3288 Access: func() accessBitmap {
3289 var bits accessBitmap
3290 bits.Set(accessNewsDeleteFldr)
3296 ConfigDir: "/fakeConfigRoot",
3297 FS: func() *MockFileStore {
3298 mfs := &MockFileStore{}
3299 mfs.On("WriteFile", "/fakeConfigRoot/ThreadedNews.yaml", mock.Anything, mock.Anything).Return(nil, os.ErrNotExist)
3302 ThreadedNews: &ThreadedNews{Categories: map[string]NewsCategoryListData15{
3313 tranDelNewsItem, nil,
3314 NewField(fieldNewsPath,
3319 0x74, 0x65, 0x73, 0x74,
3324 wantRes: []Transaction{
3326 clientID: &[]byte{0, 1},
3330 ID: []byte{0, 0, 0, 0},
3331 ErrorCode: []byte{0, 0, 0, 0},
3335 wantErr: assert.NoError,
3338 for _, tt := range tests {
3339 t.Run(tt.name, func(t *testing.T) {
3340 gotRes, err := HandleDelNewsItem(tt.args.cc, tt.args.t)
3341 if !tt.wantErr(t, err, fmt.Sprintf("HandleDelNewsItem(%v, %v)", tt.args.cc, tt.args.t)) {
3344 tranAssertEqual(t, tt.wantRes, gotRes)
3349 func TestHandleDownloadBanner(t *testing.T) {
3357 wantRes []Transaction
3358 wantErr assert.ErrorAssertionFunc
3361 name: "returns expected response",
3365 transfers: map[int]map[[4]byte]*FileTransfer{
3369 ConfigDir: "/config",
3371 BannerFile: "banner.jpg",
3373 fileTransfers: map[[4]byte]*FileTransfer{},
3374 FS: func() *MockFileStore {
3375 mfi := &MockFileInfo{}
3376 mfi.On("Size").Return(int64(100))
3378 mfs := &MockFileStore{}
3379 mfs.On("Stat", "/config/banner.jpg").Return(mfi, nil)
3384 t: NewTransaction(tranDownloadBanner, nil),
3386 wantRes: []Transaction{
3388 clientID: &[]byte{0, 1},
3392 ID: []byte{0, 0, 0, 0},
3393 ErrorCode: []byte{0, 0, 0, 0},
3395 NewField(fieldRefNum, []byte{1, 2, 3, 4}),
3396 NewField(fieldTransferSize, []byte{0, 0, 0, 0x64}),
3400 wantErr: assert.NoError,
3403 for _, tt := range tests {
3404 t.Run(tt.name, func(t *testing.T) {
3405 gotRes, err := HandleDownloadBanner(tt.args.cc, tt.args.t)
3406 if !tt.wantErr(t, err, fmt.Sprintf("HandleDownloadBanner(%v, %v)", tt.args.cc, tt.args.t)) {
3410 tranAssertEqual(t, tt.wantRes, gotRes)
3415 func TestHandleTranOldPostNews(t *testing.T) {
3423 wantRes []Transaction
3424 wantErr assert.ErrorAssertionFunc
3427 name: "when user does not have required permission",
3431 Access: func() accessBitmap {
3432 var bits accessBitmap
3438 tranOldPostNews, &[]byte{0, 1},
3439 NewField(fieldData, []byte("hai")),
3442 wantRes: []Transaction{
3446 Type: []byte{0, 0x00},
3447 ID: []byte{0, 0, 0, 0},
3448 ErrorCode: []byte{0, 0, 0, 1},
3450 NewField(fieldError, []byte("You are not allowed to post news.")),
3454 wantErr: assert.NoError,
3457 name: "when user posts news update",
3461 Access: func() accessBitmap {
3462 var bits accessBitmap
3463 bits.Set(accessNewsPostArt)
3468 FS: func() *MockFileStore {
3469 mfs := &MockFileStore{}
3470 mfs.On("WriteFile", "/fakeConfigRoot/MessageBoard.txt", mock.Anything, mock.Anything).Return(nil, os.ErrNotExist)
3473 ConfigDir: "/fakeConfigRoot",
3478 tranOldPostNews, &[]byte{0, 1},
3479 NewField(fieldData, []byte("hai")),
3482 wantRes: []Transaction{
3487 ID: []byte{0, 0, 0, 0},
3488 ErrorCode: []byte{0, 0, 0, 0},
3491 wantErr: assert.NoError,
3494 for _, tt := range tests {
3495 t.Run(tt.name, func(t *testing.T) {
3496 gotRes, err := HandleTranOldPostNews(tt.args.cc, tt.args.t)
3497 if !tt.wantErr(t, err, fmt.Sprintf("HandleTranOldPostNews(%v, %v)", tt.args.cc, tt.args.t)) {
3501 tranAssertEqual(t, tt.wantRes, gotRes)
3506 func TestHandleInviteNewChat(t *testing.T) {
3514 wantRes []Transaction
3515 wantErr assert.ErrorAssertionFunc
3518 name: "when user does not have required permission",
3522 Access: func() accessBitmap {
3523 var bits accessBitmap
3528 t: NewTransaction(tranInviteNewChat, &[]byte{0, 1}),
3530 wantRes: []Transaction{
3534 Type: []byte{0, 0x00},
3535 ID: []byte{0, 0, 0, 0},
3536 ErrorCode: []byte{0, 0, 0, 1},
3538 NewField(fieldError, []byte("You are not allowed to request private chat.")),
3542 wantErr: assert.NoError,
3545 name: "when userA invites userB to new private chat",
3550 Access: func() accessBitmap {
3551 var bits accessBitmap
3552 bits.Set(accessOpenChat)
3556 UserName: []byte("UserA"),
3558 Flags: []byte{0, 0},
3560 Clients: map[uint16]*ClientConn{
3563 UserName: []byte("UserB"),
3564 Flags: []byte{0, 0},
3567 PrivateChats: make(map[uint32]*PrivateChat),
3571 tranInviteNewChat, &[]byte{0, 1},
3572 NewField(fieldUserID, []byte{0, 2}),
3575 wantRes: []Transaction{
3577 clientID: &[]byte{0, 2},
3580 Type: []byte{0, 0x71},
3581 ID: []byte{0, 0, 0, 0},
3582 ErrorCode: []byte{0, 0, 0, 0},
3584 NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3585 NewField(fieldUserName, []byte("UserA")),
3586 NewField(fieldUserID, []byte{0, 1}),
3591 clientID: &[]byte{0, 1},
3595 ID: []byte{0, 0, 0, 0},
3596 ErrorCode: []byte{0, 0, 0, 0},
3598 NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3599 NewField(fieldUserName, []byte("UserA")),
3600 NewField(fieldUserID, []byte{0, 1}),
3601 NewField(fieldUserIconID, []byte{0, 1}),
3602 NewField(fieldUserFlags, []byte{0, 0}),
3606 wantErr: assert.NoError,
3609 name: "when userA invites userB to new private chat, but UserB has refuse private chat enabled",
3614 Access: func() accessBitmap {
3615 var bits accessBitmap
3616 bits.Set(accessOpenChat)
3620 UserName: []byte("UserA"),
3622 Flags: []byte{0, 0},
3624 Clients: map[uint16]*ClientConn{
3627 UserName: []byte("UserB"),
3628 Flags: []byte{255, 255},
3631 PrivateChats: make(map[uint32]*PrivateChat),
3635 tranInviteNewChat, &[]byte{0, 1},
3636 NewField(fieldUserID, []byte{0, 2}),
3639 wantRes: []Transaction{
3641 clientID: &[]byte{0, 1},
3644 Type: []byte{0, 0x68},
3645 ID: []byte{0, 0, 0, 0},
3646 ErrorCode: []byte{0, 0, 0, 0},
3648 NewField(fieldData, []byte("UserB does not accept private chats.")),
3649 NewField(fieldUserName, []byte("UserB")),
3650 NewField(fieldUserID, []byte{0, 2}),
3651 NewField(fieldOptions, []byte{0, 2}),
3655 clientID: &[]byte{0, 1},
3659 ID: []byte{0, 0, 0, 0},
3660 ErrorCode: []byte{0, 0, 0, 0},
3662 NewField(fieldChatID, []byte{0x52, 0xfd, 0xfc, 0x07}),
3663 NewField(fieldUserName, []byte("UserA")),
3664 NewField(fieldUserID, []byte{0, 1}),
3665 NewField(fieldUserIconID, []byte{0, 1}),
3666 NewField(fieldUserFlags, []byte{0, 0}),
3670 wantErr: assert.NoError,
3673 for _, tt := range tests {
3674 t.Run(tt.name, func(t *testing.T) {
3676 gotRes, err := HandleInviteNewChat(tt.args.cc, tt.args.t)
3677 if !tt.wantErr(t, err, fmt.Sprintf("HandleInviteNewChat(%v, %v)", tt.args.cc, tt.args.t)) {
3680 tranAssertEqual(t, tt.wantRes, gotRes)
3685 func TestHandleGetNewsArtData(t *testing.T) {
3693 wantRes []Transaction
3694 wantErr assert.ErrorAssertionFunc
3697 name: "when user does not have required permission",
3701 Access: func() accessBitmap {
3702 var bits accessBitmap
3707 Accounts: map[string]*Account{},
3711 tranGetNewsArtData, &[]byte{0, 1},
3714 wantRes: []Transaction{
3718 Type: []byte{0, 0x00},
3719 ID: []byte{0x9a, 0xcb, 0x04, 0x42},
3720 ErrorCode: []byte{0, 0, 0, 1},
3722 NewField(fieldError, []byte("You are not allowed to read news.")),
3726 wantErr: assert.NoError,
3729 for _, tt := range tests {
3730 t.Run(tt.name, func(t *testing.T) {
3731 gotRes, err := HandleGetNewsArtData(tt.args.cc, tt.args.t)
3732 if !tt.wantErr(t, err, fmt.Sprintf("HandleGetNewsArtData(%v, %v)", tt.args.cc, tt.args.t)) {
3735 tranAssertEqual(t, tt.wantRes, gotRes)