]>
Commit | Line | Data |
---|---|---|
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 | "sync" | |
12 | "testing" | |
13 | ) | |
14 | ||
15 | type mockReadWriter struct { | |
16 | RBuf bytes.Buffer | |
17 | WBuf *bytes.Buffer | |
18 | } | |
19 | ||
20 | func (mrw mockReadWriter) Read(p []byte) (n int, err error) { | |
21 | return mrw.RBuf.Read(p) | |
22 | } | |
23 | ||
24 | func (mrw mockReadWriter) Write(p []byte) (n int, err error) { | |
25 | return mrw.WBuf.Write(p) | |
26 | } | |
27 | ||
28 | func TestServer_handleFileTransfer(t *testing.T) { | |
29 | type fields struct { | |
30 | Port int | |
31 | Accounts map[string]*Account | |
32 | Agreement []byte | |
33 | Clients map[uint16]*ClientConn | |
34 | ThreadedNews *ThreadedNews | |
35 | fileTransfers map[[4]byte]*FileTransfer | |
36 | Config *Config | |
37 | ConfigDir string | |
38 | Logger *slog.Logger | |
39 | PrivateChats map[uint32]*PrivateChat | |
40 | NextGuestID *uint16 | |
41 | TrackerPassID [4]byte | |
42 | Stats *Stats | |
43 | FS FileStore | |
44 | FlatNews []byte | |
45 | } | |
46 | type args struct { | |
47 | ctx context.Context | |
48 | rwc io.ReadWriter | |
49 | } | |
50 | tests := []struct { | |
51 | name string | |
52 | fields fields | |
53 | args args | |
54 | wantErr assert.ErrorAssertionFunc | |
55 | wantDump string | |
56 | }{ | |
57 | { | |
58 | name: "with invalid protocol", | |
59 | args: args{ | |
60 | ctx: func() context.Context { | |
61 | ctx := context.Background() | |
62 | ctx = context.WithValue(ctx, contextKeyReq, requestCtx{}) | |
63 | return ctx | |
64 | }(), | |
65 | rwc: func() io.ReadWriter { | |
66 | mrw := mockReadWriter{} | |
67 | mrw.WBuf = &bytes.Buffer{} | |
68 | mrw.RBuf.Write( | |
69 | []byte{ | |
70 | 0, 0, 0, 0, | |
71 | 0, 0, 0, 5, | |
72 | 0, 0, 0x01, 0, | |
73 | 0, 0, 0, 0, | |
74 | }, | |
75 | ) | |
76 | return mrw | |
77 | }(), | |
78 | }, | |
79 | wantErr: assert.Error, | |
80 | }, | |
81 | { | |
82 | name: "with invalid transfer ID", | |
83 | args: args{ | |
84 | ctx: func() context.Context { | |
85 | ctx := context.Background() | |
86 | ctx = context.WithValue(ctx, contextKeyReq, requestCtx{}) | |
87 | return ctx | |
88 | }(), | |
89 | rwc: func() io.ReadWriter { | |
90 | mrw := mockReadWriter{} | |
91 | mrw.WBuf = &bytes.Buffer{} | |
92 | mrw.RBuf.Write( | |
93 | []byte{ | |
94 | 0x48, 0x54, 0x58, 0x46, | |
95 | 0, 0, 0, 5, | |
96 | 0, 0, 0x01, 0, | |
97 | 0, 0, 0, 0, | |
98 | }, | |
99 | ) | |
100 | return mrw | |
101 | }(), | |
102 | }, | |
103 | wantErr: assert.Error, | |
104 | }, | |
105 | { | |
106 | name: "file download", | |
107 | fields: fields{ | |
108 | FS: &OSFileStore{}, | |
109 | Config: &Config{ | |
110 | FileRoot: func() string { | |
111 | path, _ := os.Getwd() | |
112 | return path + "/test/config/Files" | |
113 | }()}, | |
114 | Logger: NewTestLogger(), | |
115 | Stats: &Stats{}, | |
116 | fileTransfers: map[[4]byte]*FileTransfer{ | |
117 | [4]byte{0, 0, 0, 5}: { | |
118 | ReferenceNumber: []byte{0, 0, 0, 5}, | |
119 | Type: FileDownload, | |
120 | FileName: []byte("testfile-8b"), | |
121 | FilePath: []byte{}, | |
122 | ClientConn: &ClientConn{ | |
123 | Account: &Account{ | |
124 | Login: "foo", | |
125 | }, | |
126 | transfersMU: sync.Mutex{}, | |
127 | transfers: map[int]map[[4]byte]*FileTransfer{ | |
128 | FileDownload: { | |
129 | [4]byte{0, 0, 0, 5}: &FileTransfer{}, | |
130 | }, | |
131 | }, | |
132 | }, | |
133 | bytesSentCounter: &WriteCounter{}, | |
134 | }, | |
135 | }, | |
136 | }, | |
137 | args: args{ | |
138 | ctx: func() context.Context { | |
139 | ctx := context.Background() | |
140 | ctx = context.WithValue(ctx, contextKeyReq, requestCtx{}) | |
141 | return ctx | |
142 | }(), | |
143 | rwc: func() io.ReadWriter { | |
144 | mrw := mockReadWriter{} | |
145 | mrw.WBuf = &bytes.Buffer{} | |
146 | mrw.RBuf.Write( | |
147 | []byte{ | |
148 | 0x48, 0x54, 0x58, 0x46, | |
149 | 0, 0, 0, 5, | |
150 | 0, 0, 0x01, 0, | |
151 | 0, 0, 0, 0, | |
152 | }, | |
153 | ) | |
154 | return mrw | |
155 | }(), | |
156 | }, | |
157 | wantErr: assert.NoError, | |
158 | wantDump: `00000000 46 49 4c 50 00 01 00 00 00 00 00 00 00 00 00 00 |FILP............| | |
159 | 00000010 00 00 00 00 00 00 00 02 49 4e 46 4f 00 00 00 00 |........INFO....| | |
160 | 00000020 00 00 00 00 00 00 00 55 41 4d 41 43 54 45 58 54 |.......UAMACTEXT| | |
161 | 00000030 54 54 58 54 00 00 00 00 00 00 01 00 00 00 00 00 |TTXT............| | |
162 | 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| | |
163 | 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| | |
164 | 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0b |................| | |
165 | 00000070 74 65 73 74 66 69 6c 65 2d 38 62 00 00 44 41 54 |testfile-8b..DAT| | |
166 | 00000080 41 00 00 00 00 00 00 00 00 00 00 00 08 7c 39 e0 |A............|9.| | |
167 | 00000090 bc 64 e2 cd de 4d 41 43 52 00 00 00 00 00 00 00 |.d...MACR.......| | |
168 | 000000a0 00 00 00 00 00 |.....| | |
169 | `, | |
170 | }, | |
171 | } | |
172 | for _, tt := range tests { | |
173 | t.Run(tt.name, func(t *testing.T) { | |
174 | s := &Server{ | |
175 | Port: tt.fields.Port, | |
176 | Accounts: tt.fields.Accounts, | |
177 | Agreement: tt.fields.Agreement, | |
178 | Clients: tt.fields.Clients, | |
179 | ThreadedNews: tt.fields.ThreadedNews, | |
180 | fileTransfers: tt.fields.fileTransfers, | |
181 | Config: tt.fields.Config, | |
182 | ConfigDir: tt.fields.ConfigDir, | |
183 | Logger: tt.fields.Logger, | |
184 | Stats: tt.fields.Stats, | |
185 | FS: tt.fields.FS, | |
186 | } | |
187 | tt.wantErr(t, s.handleFileTransfer(tt.args.ctx, tt.args.rwc), fmt.Sprintf("handleFileTransfer(%v, %v)", tt.args.ctx, tt.args.rwc)) | |
188 | ||
189 | assertTransferBytesEqual(t, tt.wantDump, tt.args.rwc.(mockReadWriter).WBuf.Bytes()) | |
190 | }) | |
191 | } | |
192 | } |