1package jsonutil
2
3import (
4	"bytes"
5	"compress/gzip"
6	"fmt"
7	"reflect"
8	"strings"
9	"testing"
10
11	"github.com/hashicorp/vault/sdk/helper/compressutil"
12)
13
14func TestJSONUtil_CompressDecompressJSON(t *testing.T) {
15	expected := map[string]interface{}{
16		"test":       "data",
17		"validation": "process",
18	}
19
20	// Compress an object
21	compressedBytes, err := EncodeJSONAndCompress(expected, nil)
22	if err != nil {
23		t.Fatal(err)
24	}
25	if len(compressedBytes) == 0 {
26		t.Fatal("expected compressed data")
27	}
28
29	// Check if canary is present in the compressed data
30	if compressedBytes[0] != compressutil.CompressionCanaryGzip {
31		t.Fatalf("canary missing in compressed data")
32	}
33
34	// Decompress and decode the compressed information and verify the functional
35	// behavior
36	var actual map[string]interface{}
37	if err = DecodeJSON(compressedBytes, &actual); err != nil {
38		t.Fatal(err)
39	}
40	if !reflect.DeepEqual(expected, actual) {
41		t.Fatalf("bad: expected: %#v\nactual: %#v", expected, actual)
42	}
43	for key, _ := range actual {
44		delete(actual, key)
45	}
46
47	// Test invalid data
48	if err = DecodeJSON([]byte{}, &actual); err == nil {
49		t.Fatalf("expected a failure")
50	}
51
52	// Test invalid data after the canary byte
53	var buf bytes.Buffer
54	buf.Write([]byte{compressutil.CompressionCanaryGzip})
55	if err = DecodeJSON(buf.Bytes(), &actual); err == nil {
56		t.Fatalf("expected a failure")
57	}
58
59	// Compress an object
60	compressedBytes, err = EncodeJSONAndCompress(expected, &compressutil.CompressionConfig{
61		Type:                 compressutil.CompressionTypeGzip,
62		GzipCompressionLevel: gzip.BestSpeed,
63	})
64	if err != nil {
65		t.Fatal(err)
66	}
67	if len(compressedBytes) == 0 {
68		t.Fatal("expected compressed data")
69	}
70
71	// Check if canary is present in the compressed data
72	if compressedBytes[0] != compressutil.CompressionCanaryGzip {
73		t.Fatalf("canary missing in compressed data")
74	}
75
76	// Decompress and decode the compressed information and verify the functional
77	// behavior
78	if err = DecodeJSON(compressedBytes, &actual); err != nil {
79		t.Fatal(err)
80	}
81	if !reflect.DeepEqual(expected, actual) {
82		t.Fatalf("bad: expected: %#v\nactual: %#v", expected, actual)
83	}
84}
85
86func TestJSONUtil_EncodeJSON(t *testing.T) {
87	input := map[string]interface{}{
88		"test":       "data",
89		"validation": "process",
90	}
91
92	actualBytes, err := EncodeJSON(input)
93	if err != nil {
94		t.Fatalf("failed to encode JSON: %v", err)
95	}
96
97	actual := strings.TrimSpace(string(actualBytes))
98	expected := `{"test":"data","validation":"process"}`
99
100	if actual != expected {
101		t.Fatalf("bad: encoded JSON: expected:%s\nactual:%s\n", expected, string(actualBytes))
102	}
103}
104
105func TestJSONUtil_DecodeJSON(t *testing.T) {
106	input := `{"test":"data","validation":"process"}`
107
108	var actual map[string]interface{}
109
110	err := DecodeJSON([]byte(input), &actual)
111	if err != nil {
112		fmt.Printf("decoding err: %v\n", err)
113	}
114
115	expected := map[string]interface{}{
116		"test":       "data",
117		"validation": "process",
118	}
119	if !reflect.DeepEqual(actual, expected) {
120		t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
121	}
122}
123
124func TestJSONUtil_DecodeJSONFromReader(t *testing.T) {
125	input := `{"test":"data","validation":"process"}`
126
127	var actual map[string]interface{}
128
129	err := DecodeJSONFromReader(bytes.NewReader([]byte(input)), &actual)
130	if err != nil {
131		fmt.Printf("decoding err: %v\n", err)
132	}
133
134	expected := map[string]interface{}{
135		"test":       "data",
136		"validation": "process",
137	}
138	if !reflect.DeepEqual(actual, expected) {
139		t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
140	}
141}
142