Cybersecurity-Projects/PROJECTS/beginner/steganography-multi-tool/internal/report/report_test.go

167 lines
4.3 KiB
Go

/*
©AngelaMos | 2026
report_test.go
Table and JSON rendering tests for command output
*/
package report
import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"math"
"strings"
"testing"
"github.com/CarterPerez-dev/crypha/internal/config"
"github.com/CarterPerez-dev/crypha/internal/engine"
)
func TestFormatsHuman(t *testing.T) {
var buf bytes.Buffer
if err := Formats(&buf, false); err != nil {
t.Fatalf("Formats: %v", err)
}
out := buf.String()
for _, f := range []string{"image", "audio", "qr", "text", "pdf"} {
if !strings.Contains(out, f) {
t.Errorf("formats output missing %q", f)
}
}
if !strings.Contains(out, "attachment") {
t.Error("pdf technique options not listed")
}
}
func TestFormatsJSON(t *testing.T) {
var buf bytes.Buffer
if err := Formats(&buf, true); err != nil {
t.Fatalf("Formats: %v", err)
}
if !json.Valid(buf.Bytes()) {
t.Fatal("formats json is invalid")
}
var lines []formatLine
if err := json.Unmarshal(buf.Bytes(), &lines); err != nil {
t.Fatalf("unmarshal: %v", err)
}
if len(lines) != 5 {
t.Fatalf("got %d formats, want 5", len(lines))
}
}
func TestCapacityHuman(t *testing.T) {
rows := []engine.CapacityRow{
{Format: "qr", Capacity: 52},
{Format: "pdf", Capacity: math.MaxInt32},
{Format: "text", Err: errors.New("crypha/text: cover too small")},
}
var buf bytes.Buffer
if err := Capacity(&buf, rows, false); err != nil {
t.Fatalf("Capacity: %v", err)
}
out := buf.String()
for _, want := range []string{doesNotFit, unboundedLabel, notApplicable, "cover too small", "38"} {
if !strings.Contains(out, want) {
t.Errorf("capacity output missing %q\n%s", want, out)
}
}
}
func TestCapacityJSON(t *testing.T) {
rows := []engine.CapacityRow{
{Format: "qr", Capacity: 52},
{Format: "pdf", Capacity: math.MaxInt32},
{Format: "text", Err: errors.New("crypha/text: cover too small")},
}
var buf bytes.Buffer
if err := Capacity(&buf, rows, true); err != nil {
t.Fatalf("Capacity: %v", err)
}
var lines []capacityLine
if err := json.Unmarshal(buf.Bytes(), &lines); err != nil {
t.Fatalf("unmarshal: %v", err)
}
byFormat := map[string]capacityLine{}
for _, l := range lines {
byFormat[l.Format] = l
}
if got := byFormat["qr"]; got.MaxPlaintext != 38 || got.MaxEncrypted != 0 {
t.Errorf("qr line = %+v, want plaintext 38 encrypted 0", got)
}
if !byFormat["pdf"].Unbounded {
t.Error("pdf should be unbounded")
}
if byFormat["text"].Applicable {
t.Error("rejected cover should be inapplicable")
}
}
func TestHideSummary(t *testing.T) {
res := engine.HideResult{
Format: "image",
PayloadBytes: 12,
EnvelopeBytes: 80,
Encrypted: true,
}
var buf bytes.Buffer
if err := HideSummary(&buf, res, "out.png", false); err != nil {
t.Fatalf("HideSummary: %v", err)
}
out := buf.String()
for _, want := range []string{"image", "12", "80", "out.png", yesLabel} {
if !strings.Contains(out, want) {
t.Errorf("hide summary missing %q\n%s", want, out)
}
}
}
func TestVersion(t *testing.T) {
var buf bytes.Buffer
if err := Version(&buf, false); err != nil {
t.Fatalf("Version: %v", err)
}
out := buf.String()
if !strings.Contains(out, config.BinaryName) || !strings.Contains(out, config.Version) {
t.Errorf("version output = %q", out)
}
}
func TestRevealJSON(t *testing.T) {
res := engine.RevealResult{Format: "image", Data: []byte("hidden bytes"), Encrypted: true}
var toStdout bytes.Buffer
if err := RevealJSON(&toStdout, res, ""); err != nil {
t.Fatalf("RevealJSON: %v", err)
}
var line revealLine
if err := json.Unmarshal(toStdout.Bytes(), &line); err != nil {
t.Fatalf("unmarshal: %v", err)
}
decoded, err := base64.StdEncoding.DecodeString(line.Data)
if err != nil || string(decoded) != "hidden bytes" {
t.Fatalf("data = %q err %v", decoded, err)
}
if line.Bytes != len(res.Data) || !line.Encrypted || line.Format != "image" {
t.Fatalf("line = %+v", line)
}
var toFile bytes.Buffer
if err := RevealJSON(&toFile, res, "out.bin"); err != nil {
t.Fatalf("RevealJSON with file: %v", err)
}
var fileLine revealLine
if err := json.Unmarshal(toFile.Bytes(), &fileLine); err != nil {
t.Fatalf("unmarshal: %v", err)
}
if fileLine.Data != "" {
t.Error("data should be omitted when writing to a file")
}
if fileLine.Output != "out.bin" {
t.Errorf("output = %q, want out.bin", fileLine.Output)
}
}