]> git.r.bdr.sh - rbdr/mobius/blob - hotline/transaction_test.go
Implement Don't Show Agreement permission
[rbdr/mobius] / hotline / transaction_test.go
1 package hotline
2
3 import (
4 "fmt"
5 "github.com/stretchr/testify/assert"
6 "testing"
7 )
8
9 func TestReadFields(t *testing.T) {
10 type args struct {
11 paramCount []byte
12 buf []byte
13 }
14 tests := []struct {
15 name string
16 args args
17 want []Field
18 wantErr bool
19 }{
20 {
21 name: "valid field data",
22 args: args{
23 paramCount: []byte{0x00, 0x02},
24 buf: []byte{
25 0x00, 0x65, // ID: fieldData
26 0x00, 0x04, // Size: 2 bytes
27 0x01, 0x02, 0x03, 0x04, // Data
28 0x00, 0x66, // ID: fieldUserName
29 0x00, 0x02, // Size: 2 bytes
30 0x00, 0x01, // Data
31 },
32 },
33 want: []Field{
34 {
35 ID: []byte{0x00, 0x65},
36 FieldSize: []byte{0x00, 0x04},
37 Data: []byte{0x01, 0x02, 0x03, 0x04},
38 },
39 {
40 ID: []byte{0x00, 0x66},
41 FieldSize: []byte{0x00, 0x02},
42 Data: []byte{0x00, 0x01},
43 },
44 },
45 wantErr: false,
46 },
47 {
48 name: "empty bytes",
49 args: args{
50 paramCount: []byte{0x00, 0x00},
51 buf: []byte{},
52 },
53 want: []Field(nil),
54 wantErr: false,
55 },
56 {
57 name: "when field size does not match data length",
58 args: args{
59 paramCount: []byte{0x00, 0x01},
60 buf: []byte{
61 0x00, 0x65, // ID: fieldData
62 0x00, 0x04, // Size: 4 bytes
63 0x01, 0x02, 0x03, // Data
64 },
65 },
66 want: []Field{},
67 wantErr: true,
68 },
69 {
70 name: "when field size of second field does not match data length",
71 args: args{
72 paramCount: []byte{0x00, 0x01},
73 buf: []byte{
74 0x00, 0x65, // ID: fieldData
75 0x00, 0x02, // Size: 2 bytes
76 0x01, 0x02, // Data
77 0x00, 0x65, // ID: fieldData
78 0x00, 0x04, // Size: 4 bytes
79 0x01, 0x02, 0x03, // Data
80 },
81 },
82 want: []Field{},
83 wantErr: true,
84 },
85 {
86 name: "when field data has extra bytes",
87 args: args{
88 paramCount: []byte{0x00, 0x01},
89 buf: []byte{
90 0x00, 0x65, // ID: fieldData
91 0x00, 0x02, // Size: 2 bytes
92 0x01, 0x02, 0x03, // Data
93 },
94 },
95 want: []Field{},
96 wantErr: true,
97 },
98 }
99 for _, tt := range tests {
100 t.Run(tt.name, func(t *testing.T) {
101 got, err := ReadFields(tt.args.paramCount, tt.args.buf)
102 if (err != nil) != tt.wantErr {
103 t.Errorf("ReadFields() error = %v, wantErr %v", err, tt.wantErr)
104 return
105 }
106
107 if !assert.Equal(t, tt.want, got) {
108 t.Errorf("ReadFields() got = %v, want %v", got, tt.want)
109 }
110 })
111 }
112 }
113
114 func TestReadTransaction(t *testing.T) {
115 sampleTransaction := &Transaction{
116 Flags: byte(0),
117 IsReply: byte(0),
118 Type: []byte{0x000, 0x93},
119 ID: []byte{0x000, 0x00, 0x00, 0x01},
120 ErrorCode: []byte{0x000, 0x00, 0x00, 0x00},
121 TotalSize: []byte{0x000, 0x00, 0x00, 0x08},
122 DataSize: []byte{0x000, 0x00, 0x00, 0x08},
123 ParamCount: []byte{0x00, 0x01},
124 Fields: []Field{
125 {
126 ID: []byte{0x00, 0x01},
127 FieldSize: []byte{0x00, 0x02},
128 Data: []byte{0xff, 0xff},
129 },
130 },
131 }
132
133 type args struct {
134 buf []byte
135 }
136 tests := []struct {
137 name string
138 args args
139 want *Transaction
140 want1 int
141 wantErr bool
142 }{
143 {
144 name: "when buf contains all bytes for a single transaction",
145 args: args{
146 buf: func() []byte {
147 b, _ := sampleTransaction.MarshalBinary()
148 return b
149 }(),
150 },
151 want: sampleTransaction,
152 want1: func() int {
153 b, _ := sampleTransaction.MarshalBinary()
154 return len(b)
155 }(),
156 wantErr: false,
157 },
158 {
159 name: "when len(buf) is less than the length of the transaction",
160 args: args{
161 buf: func() []byte {
162 b, _ := sampleTransaction.MarshalBinary()
163 return b[:len(b)-1]
164 }(),
165 },
166 want: nil,
167 want1: 0,
168 wantErr: true,
169 },
170 }
171 for _, tt := range tests {
172 t.Run(tt.name, func(t *testing.T) {
173 got, got1, err := ReadTransaction(tt.args.buf)
174 if (err != nil) != tt.wantErr {
175 t.Errorf("ReadTransaction() error = %v, wantErr %v", err, tt.wantErr)
176 return
177 }
178 if !assert.Equal(t, tt.want, got) {
179 t.Errorf("ReadTransaction() got = %v, want %v", got, tt.want)
180 }
181 if got1 != tt.want1 {
182 t.Errorf("ReadTransaction() got1 = %v, want %v", got1, tt.want1)
183 }
184 })
185 }
186 }
187
188 func Test_transactionScanner(t *testing.T) {
189 type args struct {
190 data []byte
191 in1 bool
192 }
193 tests := []struct {
194 name string
195 args args
196 wantAdvance int
197 wantToken []byte
198 wantErr assert.ErrorAssertionFunc
199 }{
200 {
201 name: "when too few bytes are provided to read the transaction size",
202 args: args{
203 data: []byte{},
204 in1: false,
205 },
206 wantAdvance: 0,
207 wantToken: []byte(nil),
208 wantErr: assert.NoError,
209 },
210 {
211 name: "when too few bytes are provided to read the full payload",
212 args: args{
213 data: []byte{
214 0,
215 1,
216 0, 0,
217 0, 00, 00, 04,
218 00, 00, 00, 00,
219 00, 00, 00, 10,
220 00, 00, 00, 10,
221 },
222 in1: false,
223 },
224 wantAdvance: 0,
225 wantToken: []byte(nil),
226 wantErr: assert.NoError,
227 },
228 {
229 name: "when a full transaction is provided",
230 args: args{
231 data: []byte{
232 0,
233 1,
234 0, 0,
235 0, 00, 00, 0x04,
236 00, 00, 00, 0x00,
237 00, 00, 00, 0x10,
238 00, 00, 00, 0x10,
239 00, 02,
240 00, 0x6c, // 108 - fieldTransferSize
241 00, 02,
242 0x63, 0x3b,
243 00, 0x6b, // 107 = fieldRefNum
244 00, 0x04,
245 00, 0x02, 0x93, 0x47,
246 },
247 in1: false,
248 },
249 wantAdvance: 36,
250 wantToken: []byte{
251 0,
252 1,
253 0, 0,
254 0, 00, 00, 0x04,
255 00, 00, 00, 0x00,
256 00, 00, 00, 0x10,
257 00, 00, 00, 0x10,
258 00, 02,
259 00, 0x6c, // 108 - fieldTransferSize
260 00, 02,
261 0x63, 0x3b,
262 00, 0x6b, // 107 = fieldRefNum
263 00, 0x04,
264 00, 0x02, 0x93, 0x47,
265 },
266 wantErr: assert.NoError,
267 },
268 {
269 name: "when a full transaction plus extra bytes are provided",
270 args: args{
271 data: []byte{
272 0,
273 1,
274 0, 0,
275 0, 00, 00, 0x04,
276 00, 00, 00, 0x00,
277 00, 00, 00, 0x10,
278 00, 00, 00, 0x10,
279 00, 02,
280 00, 0x6c, // 108 - fieldTransferSize
281 00, 02,
282 0x63, 0x3b,
283 00, 0x6b, // 107 = fieldRefNum
284 00, 0x04,
285 00, 0x02, 0x93, 0x47,
286 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
287 },
288 in1: false,
289 },
290 wantAdvance: 36,
291 wantToken: []byte{
292 0,
293 1,
294 0, 0,
295 0, 00, 00, 0x04,
296 00, 00, 00, 0x00,
297 00, 00, 00, 0x10,
298 00, 00, 00, 0x10,
299 00, 02,
300 00, 0x6c, // 108 - fieldTransferSize
301 00, 02,
302 0x63, 0x3b,
303 00, 0x6b, // 107 = fieldRefNum
304 00, 0x04,
305 00, 0x02, 0x93, 0x47,
306 },
307 wantErr: assert.NoError,
308 },
309 {
310 name: "when two full transactions are provided",
311 args: args{
312 data: []byte{
313 0,
314 1,
315 0, 0,
316 0, 00, 00, 0x04,
317 00, 00, 00, 0x00,
318 00, 00, 00, 0x10,
319 00, 00, 00, 0x10,
320 00, 02,
321 00, 0x6c, // 108 - fieldTransferSize
322 00, 02,
323 0x63, 0x3b,
324 00, 0x6b, // 107 = fieldRefNum
325 00, 0x04,
326 00, 0x02, 0x93, 0x47,
327 0,
328 1,
329 0, 0,
330 0, 00, 00, 0x04,
331 00, 00, 00, 0x00,
332 00, 00, 00, 0x10,
333 00, 00, 00, 0x10,
334 00, 02,
335 00, 0x6c, // 108 - fieldTransferSize
336 00, 02,
337 0x63, 0x3b,
338 00, 0x6b, // 107 = fieldRefNum
339 00, 0x04,
340 00, 0x02, 0x93, 0x47,
341 },
342 in1: false,
343 },
344 wantAdvance: 36,
345 wantToken: []byte{
346 0,
347 1,
348 0, 0,
349 0, 00, 00, 0x04,
350 00, 00, 00, 0x00,
351 00, 00, 00, 0x10,
352 00, 00, 00, 0x10,
353 00, 02,
354 00, 0x6c, // 108 - fieldTransferSize
355 00, 02,
356 0x63, 0x3b,
357 00, 0x6b, // 107 = fieldRefNum
358 00, 0x04,
359 00, 0x02, 0x93, 0x47,
360 },
361 wantErr: assert.NoError,
362 },
363 }
364 for _, tt := range tests {
365 t.Run(tt.name, func(t *testing.T) {
366 gotAdvance, gotToken, err := transactionScanner(tt.args.data, tt.args.in1)
367 if !tt.wantErr(t, err, fmt.Sprintf("transactionScanner(%v, %v)", tt.args.data, tt.args.in1)) {
368 return
369 }
370 assert.Equalf(t, tt.wantAdvance, gotAdvance, "transactionScanner(%v, %v)", tt.args.data, tt.args.in1)
371 assert.Equalf(t, tt.wantToken, gotToken, "transactionScanner(%v, %v)", tt.args.data, tt.args.in1)
372 })
373 }
374 }