fix balance check in server logic
[epoint] / pkg / document / document_test.go
1 package document
2
3 import (
4         "bytes"
5         "crypto/openpgp"
6         "fmt"
7         "testing"
8 )
9
10 var signedData = []struct {
11         text string
12         ok   bool
13         hash string
14         body string
15         sig  string
16 }{
17         {
18                 `-----BEGIN PGP SIGNED MESSAGE-----
19 Hash: SHA1
20
21 body
22 -----BEGIN PGP SIGNATURE-----
23 sig
24 `, true, "SHA1", "body", "-----BEGIN PGP SIGNATURE-----\nsig\n"},
25         {
26                 `-----BEGIN PGP SIGNED MESSAGE-----
27 Hash: SHA1
28 Hash: SHA256
29
30 - body  
31 -----BEGIN PGP SIGNATURE-----
32 sig
33 `, false, "", "body", "-----BEGIN PGP SIGNATURE-----\nsig\n"},
34 }
35
36 func TestSigned(t *testing.T) {
37         for _, x := range signedData {
38                 c, err := ParseSigned([]byte(x.text))
39                 if err != nil {
40                         t.Errorf("parsing %q failed: %s\n", x.text, err)
41                         continue
42                 }
43                 if string(c.Body) != x.body {
44                         t.Errorf("expected: %q, got %q\n", x.body, c.Body)
45                 }
46                 if string(c.Signature) != x.sig {
47                         t.Errorf("expected: %q, got %q\n", x.sig, c.Signature)
48                 }
49         }
50         for _, x := range signedData {
51                 if !x.ok {
52                         continue
53                 }
54                 c := &Signed{x.hash, []byte(x.body), []byte(x.sig)}
55                 s, err := FormatSigned(c)
56                 if err != nil {
57                         t.Errorf("formating %#v failed: %s\n", c, err)
58                         continue
59                 }
60                 if string(s) != x.text {
61                         t.Errorf("expected: %q, got %q\n", x.text, s)
62                 }
63         }
64 }
65
66 var docData = []struct {
67         text string
68         ok   bool
69         t    string
70         k    []string
71         v    []string
72 }{
73         {
74                 `Content-Type: text/vnd.epoint.draft; charset=utf-8
75
76 K1: v1
77 K2-Foo: v 2
78 K3: v 3
79 `, true, "Draft", []string{"K1", "K2-Foo", "K3"}, []string{"v1", "v 2", "v 3"}},
80         {
81                 `Content-Type: text/vnd.epoint.debit; charset=utf-8
82
83 K1:  v1
84 K2-Foo: v 2
85 K3: v 3
86 `, true, "DebitCert", []string{"K1", "K2-Foo", "K3"}, []string{" v1", "v 2", "v 3"}},
87         {
88                 `Content-Type: text/vnd.epoint.credit; charset=utf-8
89
90 K1: v1
91 K2-Foo: v 2
92 K3: v
93  3
94 `, false, "CreditCert", []string{"K1", "K2-Foo", "K3"}, []string{"v1", "v 2", "v 3"}},
95 }
96
97 func TestDocument(t *testing.T) {
98         for _, x := range docData {
99                 doc, err := ParseDocument([]byte(x.text))
100                 if err != nil {
101                         t.Errorf("parsing %q failed: %s\n", x.text, err)
102                         continue
103                 }
104                 if string(doc.Type) != x.t {
105                         t.Errorf("expected: %q, got %q\n", x.t, doc.Type)
106                 }
107                 if len(doc.Fields) != len(x.k) {
108                         t.Errorf("expected: %d fields, got %d\n", len(x.k), len(doc.Fields))
109                 }
110                 for i, k := range x.k {
111                         if doc.Fields[k] != x.v[i] {
112                                 t.Errorf("value of %s expected to be %s, got %s\n", k, x.v[i], doc.Fields[k])
113                         }
114                 }
115         }
116         for _, x := range docData {
117                 if !x.ok {
118                         continue
119                 }
120                 doc := new(Document)
121                 doc.Type = x.t
122                 doc.Fields = make(map[string]string)
123                 doc.Order = x.k
124                 for i, k := range x.k {
125                         doc.Fields[k] = x.v[i]
126                 }
127                 s, err := FormatDocument(doc)
128                 if err != nil {
129                         t.Errorf("formating %#v failed: %s\n", doc, err)
130                         continue
131                 }
132                 if string(s) != x.text {
133                         t.Errorf("expected: %q, got %q\n", x.text, s)
134                 }
135         }
136 }
137
138 const draftBody = `Content-Type: text/vnd.epoint.draft; charset=utf-8
139
140 Drawer: 000000000000000000000000000000000000000A
141 Beneficiary: 000000000000000000000000000000000000000B
142 Amount: 1
143 Denomination: half euro
144 Issuer: 000000000000000000000000000000000000000D
145 Authorized-By: 000000000000000000000000000000000000000C
146 Maturity-Date: 2011-11-13T12:20:35Z
147 Expiry-Date: 2011-12-27T09:18:46Z
148 Nonce: 42
149 Notes: some notes
150 `
151
152 func TestDraft(t *testing.T) {
153         doc, err := ParseDocument([]byte(draftBody))
154         if err != nil {
155                 t.Errorf("ParseDocument failed: %s\n", err)
156                 return
157         }
158         iv, err := ParseStruct(doc)
159         if err != nil {
160                 t.Errorf("ParseStruct %v failed: %s\n", doc, err)
161                 return
162         }
163         d, ok := iv.(*Draft)
164         if !ok {
165                 t.Errorf("expected *Draft got %#v\n", iv)
166                 return
167         }
168         doc, err = FormatStruct(d)
169         if err != nil {
170                 t.Errorf("format %v draft failed: %s\n", d, err)
171                 return
172         }
173         s, err := FormatDocument(doc)
174         if err != nil {
175                 t.Errorf("format %v doc failed: %s\n", doc, err)
176                 return
177         }
178         if string(s) != draftBody {
179                 t.Errorf("parsed %#v\nexpected: %s\ngot: %s\n", d, draftBody, s)
180         }
181 }
182
183 const debitBody = `Content-Type: text/vnd.epoint.debit; charset=utf-8
184
185 Holder: 0000000000000000000000000000000000000009
186 Serial: 13
187 Balance: 23
188 Denomination: half euro
189 Issuer: 000000000000000000000000000000000000000B
190 Date: 2011-11-13T12:20:35Z
191 Authorized-By: 000000000000000000000000000000000000000A
192 Notes: -
193 Last-Debit-Serial: 0
194 Last-Credit-Serial: 12
195 Last-Cert: 000000000000000000000000000000000000000C
196 References: 000000000000000000000000000000000000000C
197  000000000000000000000000000000000000000F
198 Difference: 1
199 Draft: 000000000000000000000000000000000000000D
200 Beneficiary: 000000000000000000000000000000000000000E
201 `
202
203 func TestCert(t *testing.T) {
204         doc, err := ParseDocument([]byte(debitBody))
205         if err != nil {
206                 t.Errorf("ParseDocument failed: %s\n", err)
207                 return
208         }
209         iv, err := ParseStruct(doc)
210         if err != nil {
211                 t.Errorf("ParseStruct %v failed: %s\n", doc, err)
212                 return
213         }
214         d, ok := iv.(*DebitCert)
215         if !ok {
216                 t.Errorf("expected *DebitCert got %#v\n", iv)
217                 return
218         }
219         doc, err = FormatStruct(d)
220         if err != nil {
221                 t.Errorf("format %v draft failed: %s\n", d, err)
222                 return
223         }
224         s, err := FormatDocument(doc)
225         if err != nil {
226                 t.Errorf("format %v doc failed: %s\n", doc, err)
227                 return
228         }
229         if string(s) != debitBody {
230                 t.Errorf("parsed %#v\nexpected: %s\ngot: %s\n", d, debitBody, s)
231         }
232 }
233
234 func parsekey(key []byte) (*openpgp.Entity, error) {
235         elist, err := openpgp.ReadArmoredKeyRing(bytes.NewBuffer(key))
236         if err != nil {
237                 return nil, err
238         }
239         if len(elist) != 1 {
240                 return nil, fmt.Errorf("expected one key, got %d", len(elist))
241         }
242         return elist[0], nil
243 }
244
245 func TestSign(t *testing.T) {
246         k1, err := parsekey(skey1)
247         if err != nil {
248                 t.Errorf("parsing key1 failed: %s", err)
249                 return
250         }
251         k2, err := parsekey(pkey2)
252         if err != nil {
253                 t.Errorf("parsing key2 failed: %s", err)
254                 return
255         }
256         signed, err := Sign([]byte(debitBody), k1)
257         if err != nil {
258                 t.Errorf("Sign failed: %s", err)
259                 return
260         }
261         err = Verify(signed, openpgp.EntityList{k1})
262         if err != nil {
263                 t.Errorf("Verify failed: %s", err)
264         }
265         err = Verify(signed, openpgp.EntityList{k2})
266         if err == nil {
267                 t.Errorf("Verify succeeded with wrong key")
268         }
269 }
270
271 func debitcert() (d *DebitCert, err error) {
272         doc, err := ParseDocument([]byte(debitBody))
273         if err != nil {
274                 return
275         }
276         iv, err := ParseStruct(doc)
277         if err != nil {
278                 return
279         }
280         d, ok := iv.(*DebitCert)
281         if !ok {
282                 err = fmt.Errorf("expecetd *DebitCert, got %T", d)
283         }
284         return
285 }
286
287 func BenchmarkSign(b *testing.B) {
288         d, err := debitcert()
289         if err != nil {
290                 panic(err)
291         }
292         b.ResetTimer()
293         for i := 0; i < b.N; i++ {
294                 k, err := parsekey(skey1)
295                 if err != nil {
296                         panic(err)
297                 }
298                 _, _, err = Format(d, k)
299                 if err != nil {
300                         panic(err)
301                 }
302         }
303 }
304
305 func BenchmarkVerify(b *testing.B) {
306         d, err := debitcert()
307         if err != nil {
308                 panic(err)
309         }
310         k, err := parsekey(skey1)
311         if err != nil {
312                 panic(err)
313         }
314         s, _, err := Format(d, k)
315         if err != nil {
316                 panic(err)
317         }
318         b.ResetTimer()
319         for i := 0; i < b.N; i++ {
320                 k, err := parsekey(skey1)
321                 if err != nil {
322                         panic(err)
323                 }
324                 _, signed, err := Parse(s)
325                 if err != nil {
326                         panic(err)
327                 }
328                 err = Verify(signed, openpgp.EntityList{k})
329                 if err != nil {
330                         panic(err)
331                 }
332         }
333 }
334
335 var skey1 = []byte(`-----BEGIN PGP PRIVATE KEY BLOCK-----
336
337 xcD7BAAAAAARBACk0rlXXCXw5iK4aUOHEop5PhrSfRL/9LW6EaN879Mck1vLsKlE
338 WBpubaEphvy6nWZmB9cdNlwoa5vLV/bZOL50mCt9dwzkOPA7CiCroC5WkUWMOdlu
339 boauVkF27Rpt+6+27nZ0zF7c+f62FYRx+z+rU7oc4bpkxWJrnoWF/O9dMQCg////
340 /////////yVOr555FtYHqq8D/36lyJh3e+S7KdzcRyiecY9ydMnNflcNPVUvOz7k
341 PD3ve6aOV3hpJlIMyscduhPzfEBkOV1a8zNKBKvYztXn/0dsZhlTk26K3elqOdjE
342 rBCAor4/6GOiSwi9Q4J+VK+tpyQzcE6jwS5Q5b0IwTDGihQC/CDaec/g3pMcQUNI
343 0ysQBACIdEX3XRinq+oFm3+YFu5bC1Ewry7eVxukto18dtMJnU69oMjF3x7Uio5A
344 kvYNWYPxdtLjEzk/HMo/3Mg6u/jK006CPqZRcx/m3B5R7gYb5D9PyF/tJsrht4nD
345 eDuCAT00kHKYMElgwSzXg03cFcC5AEMf6U7MsrX1JLwY5Dq12gAAoOX6RPKzHB+1
346 U7YCHnNg0H1dkf9eCuzNBklzc3VlcsJMBBMRCAAWBQIAAAAACRCRl3ps/DHg6wIZ
347 AQIbAwAAIroAoBn5gA6TmLKXU9ASu+ENhV0UxowzAKA9Y/4CiQzAeCDcKIcWCg7W
348 3r6Jow==
349 =NVdT
350 -----END PGP PRIVATE KEY BLOCK-----
351 `)
352
353 var pkey2 = []byte(`-----BEGIN PGP PUBLIC KEY BLOCK-----
354
355 xsDiBAAAAAARBACk0rlXXCXw5iK4aUOHEop5PhrSfRL/9LW6EaN879Mck1vLsKlE
356 WBpubaEphvy6nWZmB9cdNlwoa5vLV/bZOL50mCt9dwzkOPA7CiCroC5WkUWMOdlu
357 boauVkF27Rpt+6+27nZ0zF7c+f62FYRx+z+rU7oc4bpkxWJrnoWF/O9dMQCg////
358 /////////yVOr555FtYHqq8D/36lyJh3e+S7KdzcRyiecY9ydMnNflcNPVUvOz7k
359 PD3ve6aOV3hpJlIMyscduhPzfEBkOV1a8zNKBKvYztXn/0dsZhlTk26K3elqOdjE
360 rBCAor4/6GOiSwi9Q4J+VK+tpyQzcE6jwS5Q5b0IwTDGihQC/CDaec/g3pMcQUNI
361 0ysQBACFl7Go0A5UqlnmwRmsLfvAEBM2+tsIoBlBDEwcgd+nJZzCQpAqO/OpSqHk
362 Yx4imGcdknfPLkMmN+Kz9j4o0T+LZuYyblhuj2t1M9lf0Is/Go0Drf/7oc2KpHAo
363 nfKu7fkM5nfZWFsgE9TxOz8SQa2RuuhpbkpB2k0Vg2TbqTpFeM0GSXNzdWVywkwE
364 ExEIABYFAgAAAAAJEKqJF6U/VQ52AhkBAhsDAADIMwCgt/kmhRwmlzcnc1S3Qlfo
365 BD0PBa8AoG5Vm9U4gzWQM/BzVxDToJPB1ZHf
366 =MNqN
367 -----END PGP PUBLIC KEY BLOCK-----
368 `)