Files
vctp2/server/handler/encryptData_test.go

136 lines
3.8 KiB
Go

package handler
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"vctp/internal/secrets"
)
func newEncryptTestHandler() (*Handler, *secrets.Secrets) {
logger := newTestLogger()
key := []byte("0123456789abcdef0123456789abcdef")
secret := secrets.New(logger, key)
return &Handler{
Logger: logger,
Secret: secret,
}, secret
}
func decodeResponse(t *testing.T, rr *httptest.ResponseRecorder) map[string]string {
t.Helper()
var resp map[string]string
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
t.Fatalf("failed to decode response body %q: %v", rr.Body.String(), err)
}
return resp
}
func TestEncryptDataRejectsWrongMethod(t *testing.T) {
h, _ := newEncryptTestHandler()
req := httptest.NewRequest(http.MethodGet, "/api/encrypt", nil)
rr := httptest.NewRecorder()
h.EncryptData(rr, req)
if rr.Code != http.StatusMethodNotAllowed {
t.Fatalf("expected %d, got %d", http.StatusMethodNotAllowed, rr.Code)
}
resp := decodeResponse(t, rr)
if resp["status"] != "ERROR" {
t.Fatalf("expected status ERROR, got %#v", resp)
}
}
func TestEncryptDataRejectsInvalidJSON(t *testing.T) {
h, _ := newEncryptTestHandler()
req := httptest.NewRequest(http.MethodPost, "/api/encrypt", strings.NewReader("{"))
rr := httptest.NewRecorder()
h.EncryptData(rr, req)
if rr.Code != http.StatusBadRequest {
t.Fatalf("expected %d, got %d", http.StatusBadRequest, rr.Code)
}
resp := decodeResponse(t, rr)
if resp["status"] != "ERROR" {
t.Fatalf("expected status ERROR, got %#v", resp)
}
}
func TestEncryptDataAcceptsPlaintextField(t *testing.T) {
h, secret := newEncryptTestHandler()
req := httptest.NewRequest(http.MethodPost, "/api/encrypt", strings.NewReader(`{"plaintext":"super-secret"}`))
rr := httptest.NewRecorder()
h.EncryptData(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("expected %d, got %d", http.StatusOK, rr.Code)
}
resp := decodeResponse(t, rr)
if resp["status"] != "OK" {
t.Fatalf("expected status OK, got %#v", resp)
}
if resp["ciphertext"] == "" || resp["prefixed"] == "" {
t.Fatalf("expected ciphertext+prefixed fields, got %#v", resp)
}
if !strings.HasPrefix(resp["prefixed"], encryptedValuePrefixV1) {
t.Fatalf("expected prefixed value with %q, got %q", encryptedValuePrefixV1, resp["prefixed"])
}
if !strings.EqualFold(resp["message"], resp["ciphertext"]) {
t.Fatalf("expected message to mirror ciphertext, got %#v", resp)
}
plain, err := secret.Decrypt(resp["ciphertext"])
if err != nil {
t.Fatalf("unable to decrypt ciphertext response: %v", err)
}
if string(plain) != "super-secret" {
t.Fatalf("unexpected decrypted value %q", string(plain))
}
}
func TestEncryptDataAcceptsLegacyValueField(t *testing.T) {
h, secret := newEncryptTestHandler()
body := bytes.NewBufferString(`{"value":"legacy-input"}`)
req := httptest.NewRequest(http.MethodPost, "/api/encrypt", body)
rr := httptest.NewRecorder()
h.EncryptData(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("expected %d, got %d", http.StatusOK, rr.Code)
}
resp := decodeResponse(t, rr)
cipherText := resp["ciphertext"]
if cipherText == "" {
t.Fatalf("expected ciphertext in response, got %#v", resp)
}
plain, err := secret.Decrypt(cipherText)
if err != nil {
t.Fatalf("unable to decrypt ciphertext response: %v", err)
}
if string(plain) != "legacy-input" {
t.Fatalf("unexpected decrypted value %q", string(plain))
}
}
func TestEncryptDataRejectsMissingPayloadValue(t *testing.T) {
h, _ := newEncryptTestHandler()
req := httptest.NewRequest(http.MethodPost, "/api/encrypt", strings.NewReader(`{}`))
rr := httptest.NewRecorder()
h.EncryptData(rr, req)
if rr.Code != http.StatusBadRequest {
t.Fatalf("expected %d, got %d", http.StatusBadRequest, rr.Code)
}
resp := decodeResponse(t, rr)
if resp["status"] != "ERROR" {
t.Fatalf("expected status ERROR, got %#v", resp)
}
}