]> git.r.bdr.sh - rbdr/mobius/blob - hotline/server_test.go
Update documentation
[rbdr/mobius] / hotline / server_test.go
1 package hotline
2
3 import (
4 "bytes"
5 "context"
6 "fmt"
7 "github.com/stretchr/testify/assert"
8 "io"
9 "log/slog"
10 "os"
11 "testing"
12 )
13
14 type mockReadWriter struct {
15 RBuf bytes.Buffer
16 WBuf *bytes.Buffer
17 }
18
19 func (mrw mockReadWriter) Read(p []byte) (n int, err error) {
20 return mrw.RBuf.Read(p)
21 }
22
23 func (mrw mockReadWriter) Write(p []byte) (n int, err error) {
24 return mrw.WBuf.Write(p)
25 }
26
27 func TestServer_handleFileTransfer(t *testing.T) {
28 type fields struct {
29 ThreadedNews *ThreadedNews
30 FileTransferMgr FileTransferMgr
31 Config Config
32 ConfigDir string
33 Stats *Stats
34 Logger *slog.Logger
35 FS FileStore
36 }
37 type args struct {
38 ctx context.Context
39 rwc io.ReadWriter
40 }
41 tests := []struct {
42 name string
43 fields fields
44 args args
45 wantErr assert.ErrorAssertionFunc
46 wantDump string
47 }{
48 {
49 name: "with invalid protocol",
50 args: args{
51 ctx: func() context.Context {
52 ctx := context.Background()
53 ctx = context.WithValue(ctx, contextKeyReq, requestCtx{})
54 return ctx
55 }(),
56 rwc: func() io.ReadWriter {
57 mrw := mockReadWriter{}
58 mrw.WBuf = &bytes.Buffer{}
59 mrw.RBuf.Write(
60 []byte{
61 0, 0, 0, 0,
62 0, 0, 0, 5,
63 0, 0, 0x01, 0,
64 0, 0, 0, 0,
65 },
66 )
67 return mrw
68 }(),
69 },
70 wantErr: assert.Error,
71 },
72 {
73 name: "with invalid transfer Type",
74 fields: fields{
75 FileTransferMgr: NewMemFileTransferMgr(),
76 },
77 args: args{
78 ctx: func() context.Context {
79 ctx := context.Background()
80 ctx = context.WithValue(ctx, contextKeyReq, requestCtx{})
81 return ctx
82 }(),
83 rwc: func() io.ReadWriter {
84 mrw := mockReadWriter{}
85 mrw.WBuf = &bytes.Buffer{}
86 mrw.RBuf.Write(
87 []byte{
88 0x48, 0x54, 0x58, 0x46,
89 0, 0, 0, 5,
90 0, 0, 0x01, 0,
91 0, 0, 0, 0,
92 },
93 )
94 return mrw
95 }(),
96 },
97 wantErr: assert.Error,
98 },
99 {
100 name: "file download",
101 fields: fields{
102 FS: &OSFileStore{},
103 Config: Config{
104 FileRoot: func() string {
105 path, _ := os.Getwd()
106 return path + "/test/config/Files"
107 }()},
108 Logger: NewTestLogger(),
109 Stats: NewStats(),
110 FileTransferMgr: &MemFileTransferMgr{
111 fileTransfers: map[FileTransferID]*FileTransfer{
112 {0, 0, 0, 5}: {
113 refNum: [4]byte{0, 0, 0, 5},
114 Type: FileDownload,
115 FileName: []byte("testfile-8b"),
116 FilePath: []byte{},
117 ClientConn: &ClientConn{
118 Account: &Account{
119 Login: "foo",
120 },
121 ClientFileTransferMgr: ClientFileTransferMgr{
122 transfers: map[FileTransferType]map[FileTransferID]*FileTransfer{
123 FileDownload: {
124 [4]byte{0, 0, 0, 5}: &FileTransfer{},
125 },
126 },
127 },
128 },
129 bytesSentCounter: &WriteCounter{},
130 },
131 },
132 },
133 },
134 args: args{
135 ctx: func() context.Context {
136 ctx := context.Background()
137 ctx = context.WithValue(ctx, contextKeyReq, requestCtx{})
138 return ctx
139 }(),
140 rwc: func() io.ReadWriter {
141 mrw := mockReadWriter{}
142 mrw.WBuf = &bytes.Buffer{}
143 mrw.RBuf.Write(
144 []byte{
145 0x48, 0x54, 0x58, 0x46,
146 0, 0, 0, 5,
147 0, 0, 0x01, 0,
148 0, 0, 0, 0,
149 },
150 )
151 return mrw
152 }(),
153 },
154 wantErr: assert.NoError,
155 wantDump: `00000000 46 49 4c 50 00 01 00 00 00 00 00 00 00 00 00 00 |FILP............|
156 00000010 00 00 00 00 00 00 00 02 49 4e 46 4f 00 00 00 00 |........INFO....|
157 00000020 00 00 00 00 00 00 00 55 41 4d 41 43 54 45 58 54 |.......UAMACTEXT|
158 00000030 54 54 58 54 00 00 00 00 00 00 01 00 00 00 00 00 |TTXT............|
159 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
160 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
161 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0b |................|
162 00000070 74 65 73 74 66 69 6c 65 2d 38 62 00 00 44 41 54 |testfile-8b..DAT|
163 00000080 41 00 00 00 00 00 00 00 00 00 00 00 08 7c 39 e0 |A............|9.|
164 00000090 bc 64 e2 cd de 4d 41 43 52 00 00 00 00 00 00 00 |.d...MACR.......|
165 000000a0 00 00 00 00 00 |.....|
166 `,
167 },
168 }
169 for _, tt := range tests {
170 t.Run(tt.name, func(t *testing.T) {
171 s := &Server{
172 FileTransferMgr: tt.fields.FileTransferMgr,
173 Config: tt.fields.Config,
174 ConfigDir: tt.fields.ConfigDir,
175 Logger: tt.fields.Logger,
176 Stats: tt.fields.Stats,
177 FS: tt.fields.FS,
178 }
179
180 tt.wantErr(t, s.handleFileTransfer(tt.args.ctx, tt.args.rwc), fmt.Sprintf("handleFileTransfer(%v, %v)", tt.args.ctx, tt.args.rwc))
181
182 assertTransferBytesEqual(t, tt.wantDump, tt.args.rwc.(mockReadWriter).WBuf.Bytes())
183 })
184 }
185 }
186
187 type TestData struct {
188 Name string `yaml:"name"`
189 Value int `yaml:"value"`
190 }
191
192 func TestLoadFromYAMLFile(t *testing.T) {
193 tests := []struct {
194 name string
195 fileName string
196 content string
197 wantData TestData
198 wantErr bool
199 }{
200 {
201 name: "Valid YAML file",
202 fileName: "valid.yaml",
203 content: "name: Test\nvalue: 123\n",
204 wantData: TestData{Name: "Test", Value: 123},
205 wantErr: false,
206 },
207 {
208 name: "File not found",
209 fileName: "nonexistent.yaml",
210 content: "",
211 wantData: TestData{},
212 wantErr: true,
213 },
214 {
215 name: "Invalid YAML content",
216 fileName: "invalid.yaml",
217 content: "name: Test\nvalue: invalid_int\n",
218 wantData: TestData{},
219 wantErr: true,
220 },
221 }
222
223 for _, tt := range tests {
224 t.Run(tt.name, func(t *testing.T) {
225 // Setup: Create a temporary file with the provided content if content is not empty
226 if tt.content != "" {
227 err := os.WriteFile(tt.fileName, []byte(tt.content), 0644)
228 assert.NoError(t, err)
229 defer os.Remove(tt.fileName) // Cleanup the file after the test
230 }
231
232 var data TestData
233 err := loadFromYAMLFile(tt.fileName, &data)
234
235 if tt.wantErr {
236 assert.Error(t, err)
237 } else {
238 assert.NoError(t, err)
239 assert.Equal(t, tt.wantData, data)
240 }
241 })
242 }
243 }