X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/22c599abc18895f73e96095f35b71cf3357d41b4..e995052ef530b1eae2d0476ff519f7225bbb481d:/hotline/server_test.go diff --git a/hotline/server_test.go b/hotline/server_test.go index 2e88202..7e2608e 100644 --- a/hotline/server_test.go +++ b/hotline/server_test.go @@ -1,806 +1,192 @@ package hotline -// -//import ( -// "bytes" -// "fmt" -// "github.com/google/go-cmp/cmp" -// "io/ioutil" -// "math/big" -// "net" -// "strings" -// "sync" -// "testing" -//) -// -//type transactionTest struct { -// description string // Human understandable description -// account Account // Account struct for a user that will test transaction will execute under -// request Transaction // transaction that will be sent by the client to the server -// want Transaction // transaction that the client expects to receive in response -// setup func() // Optional setup required for the test scenario -// teardown func() // Optional teardown for test scenario -//} -// -//func (tt *transactionTest) Setup(srv *Server) error { -// if err := srv.NewUser(tt.account.Login, tt.account.Name, NegatedUserString([]byte(tt.account.Password)), tt.account.Access); err != nil { -// return err -// } -// -// if tt.setup != nil { -// tt.setup() -// } -// -// return nil -//} -// -//func (tt *transactionTest) Teardown(srv *Server) error { -// if err := srv.DeleteUser(tt.account.Login); err != nil { -// return err -// } -// -// if tt.teardown != nil { -// tt.teardown() -// } -// -// return nil -//} -// -//// StartTestServer -//func StartTestServer() (srv *Server, lnPort int) { -// hotlineServer, _ := NewServer("test/config/") -// ln, err := net.Listen("tcp", ":0") -// -// if err != nil { -// panic(err) -// } -// go func() { -// for { -// conn, _ := ln.Accept() -// go hotlineServer.HandleConnection(conn) -// } -// }() -// return hotlineServer, ln.Addr().(*net.TCPAddr).Port -//} -// -//func StartTestClient(serverPort int, login, passwd string) (*Client, error) { -// c := NewClient("") -// -// err := c.JoinServer(fmt.Sprintf(":%v", serverPort), login, passwd) -// if err != nil { -// return nil, err -// } -// -// return c, nil -//} -// -//func StartTestServerWithClients(clientCount int) ([]*Client, int) { -// _, serverPort := StartTestServer() -// -// var clients []*Client -// for i := 0; i < clientCount; i++ { -// client, err := StartTestClient(serverPort, "admin", "") -// if err != nil { -// panic(err) -// } -// clients = append(clients, client) -// } -// clients[0].ReadN(2) -// -// return clients, serverPort -//} -// +import ( + "bytes" + "context" + "fmt" + "github.com/stretchr/testify/assert" + "go.uber.org/zap" + "io" + "os" + "sync" + "testing" +) +type mockReadWriter struct { + RBuf bytes.Buffer + WBuf *bytes.Buffer +} -////func TestHandleTranAgreed(t *testing.T) { -//// clients, _ := StartTestServerWithClients(2) -//// -//// chatMsg := "Test Chat" -//// -//// // Assert that both clients should receive the user join notification -//// var wg sync.WaitGroup -//// for _, client := range clients { -//// wg.Add(1) -//// go func(wg *sync.WaitGroup, c *Client) { -//// defer wg.Done() -//// -//// receivedMsg := c.ReadTransactions()[0].GetField(fieldData).Data -//// -//// want := []byte(fmt.Sprintf("test: %s\r", chatMsg)) -//// if bytes.Compare(receivedMsg, want) != 0 { -//// t.Errorf("%q, want %q", receivedMsg, want) -//// } -//// }(&wg, client) -//// } -//// -//// trans := clients[1].ReadTransactions() -//// spew.Dump(trans) -//// -//// // Send the agreement -//// clients[1].Connection.Write( -//// NewTransaction( -//// tranAgreed, 0, -//// []Field{ -//// NewField(fieldUserName, []byte("testUser")), -//// NewField(fieldUserIconID, []byte{0x00,0x07}), -//// }, -//// ).Payload(), -//// ) -//// -//// wg.Wait() -////} -// -//func TestChatSend(t *testing.T) { -// //srvPort := StartTestServer() -// // -// //senderClient := NewClient("senderClient") -// //senderClient.JoinServer(fmt.Sprintf(":%v", srvPort), "", "") -// // -// //receiverClient := NewClient("receiverClient") -// //receiverClient.JoinServer(fmt.Sprintf(":%v", srvPort), "", "") -// -// clients, _ := StartTestServerWithClients(2) -// -// chatMsg := "Test Chat" -// -// // Both clients should receive the chatMsg -// var wg sync.WaitGroup -// for _, client := range clients { -// wg.Add(1) -// go func(wg *sync.WaitGroup, c *Client) { -// defer wg.Done() -// -// receivedMsg := c.ReadTransactions()[0].GetField(fieldData).Data -// -// want := []byte(fmt.Sprintf(" test: %s\r", chatMsg)) -// if bytes.Compare(receivedMsg, want) != 0 { -// t.Errorf("%q, want %q", receivedMsg, want) -// } -// }(&wg, client) -// } -// -// // Send the chatMsg -// clients[1].Send( -// NewTransaction( -// tranChatSend, 0, -// []Field{ -// NewField(fieldData, []byte(chatMsg)), -// }, -// ), -// ) -// -// wg.Wait() -//} -// -//func TestSetClientUserInfo(t *testing.T) { -// clients, _ := StartTestServerWithClients(2) -// -// newIcon := []byte{0x00, 0x01} -// newUserName := "newName" -// -// // Both clients should receive the chatMsg -// var wg sync.WaitGroup -// for _, client := range clients { -// wg.Add(1) -// go func(wg *sync.WaitGroup, c *Client) { -// defer wg.Done() -// -// tran := c.ReadTransactions()[0] -// -// want := []byte(newUserName) -// got := tran.GetField(fieldUserName).Data -// if bytes.Compare(got, want) != 0 { -// t.Errorf("%q, want %q", got, want) -// } -// }(&wg, client) -// } -// -// _, err := clients[1].Connection.Write( -// NewTransaction( -// tranSetClientUserInfo, 0, -// []Field{ -// NewField(fieldUserIconID, newIcon), -// NewField(fieldUserName, []byte(newUserName)), -// }, -// ).Payload(), -// ) -// if err != nil { -// t.Errorf("%v", err) -// } -// -// wg.Wait() -//} -// -//// TestSendInstantMsg tests that client A can send an instant message to client B -//// -//func TestSendInstantMsg(t *testing.T) { -// clients, _ := StartTestServerWithClients(2) -// -// instantMsg := "Test IM" -// -// var wg sync.WaitGroup -// wg.Add(1) -// go func(wg *sync.WaitGroup, c *Client) { -// defer wg.Done() -// -// tran := c.WaitForTransaction(tranServerMsg) -// -// receivedMsg := tran.GetField(fieldData).Data -// want := []byte(fmt.Sprintf("%s", instantMsg)) -// if bytes.Compare(receivedMsg, want) != 0 { -// t.Errorf("%q, want %q", receivedMsg, want) -// } -// }(&wg, clients[0]) -// -// _ = clients[1].Send( -// NewTransaction(tranGetUserNameList, 0, []Field{}), -// ) -// //connectedUsersTran := clients[1].ReadTransactions()[0] -// ////connectedUsers := connectedUsersTran.Fields[0].Data[0:2] -// //spew.Dump(connectedUsersTran.Fields) -// //firstUserID := connectedUsersTran.Fields[0].Data[0:2] -// // -// //spew.Dump(firstUserID) -// -// // Send the IM -// err := clients[1].Send( -// NewTransaction( -// tranSendInstantMsg, 0, -// []Field{ -// NewField(fieldData, []byte(instantMsg)), -// NewField(fieldUserName, clients[1].UserName), -// NewField(fieldUserID, []byte{0, 2}), -// NewField(fieldOptions, []byte{0, 1}), -// }, -// ), -// ) -// if err != nil { -// t.Error(err) -// } -// -// wg.Wait() -//} -// -//func TestOldPostNews(t *testing.T) { -// clients, _ := StartTestServerWithClients(2) -// -// newsPost := "Test News Post" -// -// var wg sync.WaitGroup -// wg.Add(1) -// go func(wg *sync.WaitGroup, c *Client) { -// defer wg.Done() -// -// receivedMsg := c.ReadTransactions()[0].GetField(fieldData).Data -// -// if strings.Contains(string(receivedMsg), newsPost) == false { -// t.Errorf("news post missing") -// } -// }(&wg, clients[0]) -// -// clients[1].Connection.Write( -// NewTransaction( -// tranOldPostNews, 0, -// []Field{ -// NewField(fieldData, []byte(newsPost)), -// }, -// ).Payload(), -// ) -// -// wg.Wait() -//} -// -//// TODO: Fixme -////func TestGetFileNameList(t *testing.T) { -//// clients, _ := StartTestServerWithClients(2) -//// -//// clients[0].Connection.Write( -//// NewTransaction( -//// tranGetFileNameList, 0, -//// []Field{}, -//// ).Payload(), -//// ) -//// -//// ts := clients[0].ReadTransactions() -//// testfileSit := ReadFileNameWithInfo(ts[0].Fields[1].Data) -//// -//// want := "testfile.sit" -//// got := testfileSit.Name -//// diff := cmp.Diff(want, got) -//// if diff != "" { -//// t.Fatalf(diff) -//// } -//// if testfileSit.Name != "testfile.sit" { -//// t.Errorf("news post missing") -//// t.Errorf("%q, want %q", testfileSit.Name, "testfile.sit") -//// } -////} -// -//func TestNewsCategoryList(t *testing.T) { -// clients, _ := StartTestServerWithClients(2) -// client := clients[0] -// -// client.Send( -// NewTransaction( -// tranGetNewsCatNameList, 0, -// []Field{}, -// ), -// ) -// -// ts := client.ReadTransactions() -// cats := ts[0].GetFields(fieldNewsCatListData15) -// -// newsCat := ReadNewsCategoryListData(cats[0].Data) -// want := "TestBundle" -// got := newsCat.Name -// diff := cmp.Diff(want, got) -// if diff != "" { -// t.Fatalf(diff) -// } -// -// newsBundle := ReadNewsCategoryListData(cats[1].Data) -// want = "TestCat" -// got = newsBundle.Name -// diff = cmp.Diff(want, got) -// if diff != "" { -// t.Fatalf(diff) -// } -//} -// -//func TestNestedNewsCategoryList(t *testing.T) { -// clients, _ := StartTestServerWithClients(2) -// client := clients[0] -// newsPath := NewsPath{ -// []string{ -// "TestBundle", -// "NestedBundle", -// }, -// } -// -// _, err := client.Connection.Write( -// NewTransaction( -// tranGetNewsCatNameList, 0, -// []Field{ -// NewField( -// fieldNewsPath, -// newsPath.Payload(), -// ), -// }, -// ).Payload(), -// ) -// if err != nil { -// t.Errorf("%v", err) -// } -// -// ts := client.ReadTransactions() -// cats := ts[0].GetFields(fieldNewsCatListData15) -// -// newsCat := ReadNewsCategoryListData(cats[0].Data) -// want := "NestedCat" -// got := newsCat.Name -// diff := cmp.Diff(want, got) -// if diff != "" { -// t.Fatalf(diff) -// } -//} -// -//func TestFileDownload(t *testing.T) { -// clients, _ := StartTestServerWithClients(2) -// client := clients[0] -// -// type want struct { -// fileSize []byte -// transferSize []byte -// waitingCount []byte -// refNum []byte -// } -// var tests = []struct { -// fileName string -// want want -// }{ -// { -// fileName: "testfile.sit", -// want: want{ -// fileSize: []byte{0x0, 0x0, 0x0, 0x13}, -// transferSize: []byte{0x0, 0x0, 0x0, 0xa1}, -// }, -// }, -// { -// fileName: "testfile.txt", -// want: want{ -// fileSize: []byte{0x0, 0x0, 0x0, 0x17}, -// transferSize: []byte{0x0, 0x0, 0x0, 0xa5}, -// }, -// }, -// } -// -// for _, test := range tests { -// _, err := client.Connection.Write( -// NewTransaction( -// tranDownloadFile, 0, -// []Field{ -// NewField(fieldFileName, []byte(test.fileName)), -// NewField(fieldFilePath, []byte("")), -// }, -// ).Payload(), -// ) -// if err != nil { -// t.Errorf("%v", err) -// } -// tran := client.ReadTransactions()[0] -// -// if got := tran.GetField(fieldFileSize).Data; bytes.Compare(got, test.want.fileSize) != 0 { -// t.Errorf("TestFileDownload: fileSize got %#v, want %#v", got, test.want.fileSize) -// } -// -// if got := tran.GetField(fieldTransferSize).Data; bytes.Compare(got, test.want.transferSize) != 0 { -// t.Errorf("TestFileDownload: fieldTransferSize: %s: got %#v, want %#v", test.fileName, got, test.want.transferSize) -// } -// } -//} -// -//func TestFileUpload(t *testing.T) { -// clients, _ := StartTestServerWithClients(2) -// client := clients[0] -// -// var tests = []struct { -// fileName string -// want Transaction -// }{ -// { -// fileName: "testfile.sit", -// want: Transaction{ -// Fields: []Field{ -// NewField(fieldRefNum, []byte{0x16, 0x3f, 0x5f, 0xf}), -// }, -// }, -// }, -// } -// -// for _, test := range tests { -// err := client.Send( -// NewTransaction( -// tranUploadFile, 0, -// []Field{ -// NewField(fieldFileName, []byte(test.fileName)), -// NewField(fieldFilePath, []byte("")), -// }, -// ), -// ) -// if err != nil { -// t.Errorf("%v", err) -// } -// tran := client.ReadTransactions()[0] -// -// for _, f := range test.want.Fields { -// got := tran.GetField(f.Uint16ID()).Data -// want := test.want.GetField(fieldRefNum).Data -// if bytes.Compare(got, want) != 0 { -// t.Errorf("xxx: yyy got %#v, want %#v", got, want) -// } -// } -// } -//} -// -//// TODO: Make canonical -//func TestNewUser(t *testing.T) { -// srv, port := StartTestServer() -// -// var tests = []struct { -// description string -// setup func() -// teardown func() -// account Account -// request Transaction -// want Transaction -// }{ -// { -// description: "a valid new account", -// teardown: func() { -// _ = srv.DeleteUser("testUser") -// }, -// account: Account{ -// Login: "test", -// Name: "unnamed", -// Password: "test", -// Access: []byte{255, 255, 255, 255, 255, 255, 255, 255}, -// }, -// request: NewTransaction( -// tranNewUser, 0, -// []Field{ -// NewField(fieldUserLogin, []byte(NegatedUserString([]byte("testUser")))), -// NewField(fieldUserName, []byte("testUserName")), -// NewField(fieldUserPassword, []byte(NegatedUserString([]byte("testPw")))), -// NewField(fieldUserAccess, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), -// }, -// ), -// want: Transaction{ -// Fields: []Field{}, -// }, -// }, -// { -// description: "a newUser request from a user without the required access", -// teardown: func() { -// _ = srv.DeleteUser("testUser") -// }, -// account: Account{ -// Login: "test", -// Name: "unnamed", -// Password: "test", -// Access: []byte{0, 0, 0, 0, 0, 0, 0, 0}, -// }, -// request: NewTransaction( -// tranNewUser, 0, -// []Field{ -// NewField(fieldUserLogin, []byte(NegatedUserString([]byte("testUser")))), -// NewField(fieldUserName, []byte("testUserName")), -// NewField(fieldUserPassword, []byte(NegatedUserString([]byte("testPw")))), -// NewField(fieldUserAccess, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), -// }, -// ), -// want: Transaction{ -// Fields: []Field{ -// NewField(fieldError, []byte("You are not allowed to create new accounts.")), -// }, -// }, -// }, -// { -// description: "a request to create a user that already exists", -// teardown: func() { -// _ = srv.DeleteUser("testUser") -// }, -// account: Account{ -// Login: "test", -// Name: "unnamed", -// Password: "test", -// Access: []byte{255, 255, 255, 255, 255, 255, 255, 255}, -// }, -// request: NewTransaction( -// tranNewUser, 0, -// []Field{ -// NewField(fieldUserLogin, []byte(NegatedUserString([]byte("guest")))), -// NewField(fieldUserName, []byte("testUserName")), -// NewField(fieldUserPassword, []byte(NegatedUserString([]byte("testPw")))), -// NewField(fieldUserAccess, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), -// }, -// ), -// want: Transaction{ -// Fields: []Field{ -// NewField(fieldError, []byte("Cannot create account guest because there is already an account with that login.")), -// }, -// }, -// }, -// } -// -// for _, test := range tests { -// if test.setup != nil { -// test.setup() -// } -// -// if err := srv.NewUser(test.account.Login, test.account.Name, NegatedUserString([]byte(test.account.Password)), test.account.Access); err != nil { -// t.Errorf("%v", err) -// } -// -// c := NewClient("") -// err := c.JoinServer(fmt.Sprintf(":%v", port), test.account.Login, test.account.Password) -// if err != nil { -// t.Errorf("login failed: %v", err) -// } -// -// if err := c.Send(test.request); err != nil { -// t.Errorf("%v", err) -// } -// -// tran := c.ReadTransactions()[0] -// for _, want := range test.want.Fields { -// got := tran.GetField(want.Uint16ID()) -// if bytes.Compare(got.Data, want.Data) != 0 { -// t.Errorf("%v: field mismatch: want: %#v got: %#v", test.description, want.Data, got.Data) -// } -// } -// -// srv.DeleteUser(test.account.Login) -// -// if test.teardown != nil { -// test.teardown() -// } -// } -//} -// -//func TestDeleteUser(t *testing.T) { -// srv, port := StartTestServer() -// -// var tests = []transactionTest{ -// { -// description: "a deleteUser request from a user without the required access", -// account: Account{ -// Login: "test", -// Name: "unnamed", -// Password: "test", -// Access: []byte{0, 0, 0, 0, 0, 0, 0, 0}, -// }, -// request: NewTransaction( -// tranDeleteUser, 0, -// []Field{ -// NewField(fieldUserLogin, []byte(NegatedUserString([]byte("foo")))), -// }, -// ), -// want: Transaction{ -// Fields: []Field{ -// NewField(fieldError, []byte("You are not allowed to delete accounts.")), -// }, -// }, -// }, -// { -// description: "a valid deleteUser request", -// setup: func() { -// _ = srv.NewUser("foo", "foo", "foo", []byte{0, 0, 0, 0, 0, 0, 0, 0}) -// }, -// account: Account{ -// Login: "test", -// Name: "unnamed", -// Password: "test", -// Access: []byte{255, 255, 255, 255, 255, 255, 255, 255}, -// }, -// request: NewTransaction( -// tranDeleteUser, 0, -// []Field{ -// NewField(fieldUserLogin, []byte(NegatedUserString([]byte("foo")))), -// }, -// ), -// want: Transaction{ -// Fields: []Field{}, -// }, -// }, -// } -// -// for _, test := range tests { -// test.Setup(srv) -// -// c := NewClient("") -// err := c.JoinServer(fmt.Sprintf(":%v", port), test.account.Login, test.account.Password) -// if err != nil { -// t.Errorf("login failed: %v", err) -// } -// -// if err := c.Send(test.request); err != nil { -// t.Errorf("%v", err) -// } -// -// tran := c.ReadTransactions()[0] -// for _, want := range test.want.Fields { -// got := tran.GetField(want.Uint16ID()) -// if bytes.Compare(got.Data, want.Data) != 0 { -// t.Errorf("%v: field mismatch: want: %#v got: %#v", test.description, want.Data, got.Data) -// } -// } -// -// test.Teardown(srv) -// } -//} -// -//func TestDeleteFile(t *testing.T) { -// srv, port := StartTestServer() -// -// var tests = []transactionTest{ -// { -// description: "a request without the required access", -// account: Account{ -// Login: "test", -// Name: "unnamed", -// Password: "test", -// Access: []byte{0, 0, 0, 0, 0, 0, 0, 0}, -// }, -// request: NewTransaction( -// tranDeleteFile, 0, -// []Field{ -// NewField(fieldFileName, []byte("testFile")), -// NewField(fieldFilePath, []byte("")), -// }, -// ), -// want: Transaction{ -// Fields: []Field{}, -// }, -// }, -// { -// description: "a valid deleteFile request", -// setup: func() { -// _ = ioutil.WriteFile(srv.Config.FileRoot+"testFile", []byte{0x00}, 0666) -// }, -// account: Account{ -// Login: "test", -// Name: "unnamed", -// Password: "test", -// Access: []byte{255, 255, 255, 255, 255, 255, 255, 255}, -// }, -// request: NewTransaction( -// tranDeleteFile, 0, -// []Field{ -// NewField(fieldFileName, []byte("testFile")), -// NewField(fieldFilePath, []byte("")), -// }, -// ), -// want: Transaction{ -// Fields: []Field{}, -// }, -// }, -// { -// description: "an invalid request for a file that does not exist", -// account: Account{ -// Login: "test", -// Name: "unnamed", -// Password: "test", -// Access: []byte{255, 255, 255, 255, 255, 255, 255, 255}, -// }, -// request: NewTransaction( -// tranDeleteFile, 0, -// []Field{ -// NewField(fieldFileName, []byte("testFile")), -// NewField(fieldFilePath, []byte("")), -// }, -// ), -// want: Transaction{ -// Fields: []Field{ -// NewField(fieldError, []byte("Cannot delete file testFile because it does not exist or cannot be found.")), -// }, -// }, -// }, -// } -// -// for _, test := range tests { -// test.Setup(srv) -// -// c := NewClient("") -// -// if err := c.JoinServer(fmt.Sprintf(":%v", port), test.account.Login, test.account.Password); err != nil { -// t.Errorf("login failed: %v", err) -// } -// -// if err := c.Send(test.request); err != nil { -// t.Errorf("%v", err) -// } -// -// tran := c.ReadTransactions()[0] -// for _, want := range test.want.Fields { -// got := tran.GetField(want.Uint16ID()) -// if bytes.Compare(got.Data, want.Data) != 0 { -// t.Errorf("%v: field mismatch: want: %#v got: %#v", test.description, want.Data, got.Data) -// } -// } -// -// test.Teardown(srv) -// } -//} -// -//func Test_authorize(t *testing.T) { -// accessBitmap := big.NewInt(int64(0)) -// accessBitmap.SetBit(accessBitmap, accessCreateFolder, 1) -// fmt.Printf("%v %b %x\n", accessBitmap, accessBitmap, accessBitmap) -// fmt.Printf("%b\n", 0b10000) -// -// type args struct { -// access *[]byte -// reqAccess int -// } -// tests := []struct { -// name string -// args args -// want bool -// }{ -// { -// name: "fooz", -// args: args{ -// access: &[]byte{4, 0, 0, 0, 0, 0, 0, 0x02}, -// reqAccess: accessDownloadFile, -// }, -// want: true, -// }, -// } -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// if got := authorize(tt.args.access, tt.args.reqAccess); got != tt.want { -// t.Errorf("authorize() = %v, want %v", got, tt.want) -// } -// }) -// } -//} +func (mrw mockReadWriter) Read(p []byte) (n int, err error) { + return mrw.RBuf.Read(p) +} + +func (mrw mockReadWriter) Write(p []byte) (n int, err error) { + return mrw.WBuf.Write(p) +} + +func TestServer_handleFileTransfer(t *testing.T) { + type fields struct { + Port int + Accounts map[string]*Account + Agreement []byte + Clients map[uint16]*ClientConn + ThreadedNews *ThreadedNews + fileTransfers map[[4]byte]*FileTransfer + Config *Config + ConfigDir string + Logger *zap.SugaredLogger + PrivateChats map[uint32]*PrivateChat + NextGuestID *uint16 + TrackerPassID [4]byte + Stats *Stats + FS FileStore + FlatNews []byte + } + type args struct { + ctx context.Context + rwc io.ReadWriter + } + tests := []struct { + name string + fields fields + args args + wantErr assert.ErrorAssertionFunc + wantDump string + }{ + { + name: "with invalid protocol", + args: args{ + ctx: func() context.Context { + ctx := context.Background() + ctx = context.WithValue(ctx, contextKeyReq, requestCtx{}) + return ctx + }(), + rwc: func() io.ReadWriter { + mrw := mockReadWriter{} + mrw.WBuf = &bytes.Buffer{} + mrw.RBuf.Write( + []byte{ + 0, 0, 0, 0, + 0, 0, 0, 5, + 0, 0, 0x01, 0, + 0, 0, 0, 0, + }, + ) + return mrw + }(), + }, + wantErr: assert.Error, + }, + { + name: "with invalid transfer ID", + args: args{ + ctx: func() context.Context { + ctx := context.Background() + ctx = context.WithValue(ctx, contextKeyReq, requestCtx{}) + return ctx + }(), + rwc: func() io.ReadWriter { + mrw := mockReadWriter{} + mrw.WBuf = &bytes.Buffer{} + mrw.RBuf.Write( + []byte{ + 0x48, 0x54, 0x58, 0x46, + 0, 0, 0, 5, + 0, 0, 0x01, 0, + 0, 0, 0, 0, + }, + ) + return mrw + }(), + }, + wantErr: assert.Error, + }, + { + name: "file download", + fields: fields{ + FS: &OSFileStore{}, + Config: &Config{ + FileRoot: func() string { + path, _ := os.Getwd() + return path + "/test/config/Files" + }()}, + Logger: NewTestLogger(), + Stats: &Stats{}, + fileTransfers: map[[4]byte]*FileTransfer{ + [4]byte{0, 0, 0, 5}: { + ReferenceNumber: []byte{0, 0, 0, 5}, + Type: FileDownload, + FileName: []byte("testfile-8b"), + FilePath: []byte{}, + ClientConn: &ClientConn{ + Account: &Account{ + Login: "foo", + }, + transfersMU: sync.Mutex{}, + transfers: map[int]map[[4]byte]*FileTransfer{ + FileDownload: { + [4]byte{0, 0, 0, 5}: &FileTransfer{}, + }, + }, + }, + bytesSentCounter: &WriteCounter{}, + }, + }, + }, + args: args{ + ctx: func() context.Context { + ctx := context.Background() + ctx = context.WithValue(ctx, contextKeyReq, requestCtx{}) + return ctx + }(), + rwc: func() io.ReadWriter { + mrw := mockReadWriter{} + mrw.WBuf = &bytes.Buffer{} + mrw.RBuf.Write( + []byte{ + 0x48, 0x54, 0x58, 0x46, + 0, 0, 0, 5, + 0, 0, 0x01, 0, + 0, 0, 0, 0, + }, + ) + return mrw + }(), + }, + wantErr: assert.NoError, + wantDump: `00000000 46 49 4c 50 00 01 00 00 00 00 00 00 00 00 00 00 |FILP............| +00000010 00 00 00 00 00 00 00 02 49 4e 46 4f 00 00 00 00 |........INFO....| +00000020 00 00 00 00 00 00 00 55 41 4d 41 43 54 45 58 54 |.......UAMACTEXT| +00000030 54 54 58 54 00 00 00 00 00 00 01 00 00 00 00 00 |TTXT............| +00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0b |................| +00000070 74 65 73 74 66 69 6c 65 2d 38 62 00 00 44 41 54 |testfile-8b..DAT| +00000080 41 00 00 00 00 00 00 00 00 00 00 00 08 7c 39 e0 |A............|9.| +00000090 bc 64 e2 cd de 4d 41 43 52 00 00 00 00 00 00 00 |.d...MACR.......| +000000a0 00 00 00 00 00 |.....| +`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := &Server{ + Port: tt.fields.Port, + Accounts: tt.fields.Accounts, + Agreement: tt.fields.Agreement, + Clients: tt.fields.Clients, + ThreadedNews: tt.fields.ThreadedNews, + fileTransfers: tt.fields.fileTransfers, + Config: tt.fields.Config, + ConfigDir: tt.fields.ConfigDir, + Logger: tt.fields.Logger, + Stats: tt.fields.Stats, + FS: tt.fields.FS, + } + tt.wantErr(t, s.handleFileTransfer(tt.args.ctx, tt.args.rwc), fmt.Sprintf("handleFileTransfer(%v, %v)", tt.args.ctx, tt.args.rwc)) + + assertTransferBytesEqual(t, tt.wantDump, tt.args.rwc.(mockReadWriter).WBuf.Bytes()) + }) + } +}