summaryrefslogtreecommitdiff
path: root/DomainDigTests/DomainReportExporterTests.swift
blob: ddecabf4f6fc14b73add67faf407829df17c0dec (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import XCTest
@testable import DomainDig

/// Characterization tests for the export surface. These pin the format dispatch,
/// the JSON round-trip (the canonical machine contract), and the structural
/// invariants of the human-readable formats.
final class DomainReportExporterTests: XCTestCase {

    private let decoder: JSONDecoder = {
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .iso8601
        return decoder
    }()

    func testEveryFormatProducesNonEmptyData() throws {
        let report = SnapshotFixture.report(availability: .registered)
        for format in DomainExportFormat.allCases {
            let data = try DomainReportExporter.data(for: report, format: format)
            XCTAssertFalse(data.isEmpty, "\(format.rawValue) export was empty")
        }
    }

    func testJSONExportRoundTripsToReport() throws {
        let report = SnapshotFixture.report(domain: "roundtrip.example", availability: .registered)

        let data = try DomainReportExporter.data(for: report, format: .json)
        let decoded = try decoder.decode(DomainReport.self, from: data)

        XCTAssertEqual(decoded.domain, "roundtrip.example")
        XCTAssertEqual(decoded.availability, .registered)
        XCTAssertEqual(decoded.timestamp, report.timestamp)
    }

    func testBatchJSONExportRoundTripsToReportArray() throws {
        let reports = [
            SnapshotFixture.report(domain: "one.example"),
            SnapshotFixture.report(domain: "two.example")
        ]

        let data = try DomainReportExporter.data(for: reports, format: .json, title: "Batch")
        let decoded = try decoder.decode([DomainReport].self, from: data)

        XCTAssertEqual(decoded.map(\.domain), ["one.example", "two.example"])
    }

    func testCSVHasHeaderAndOneRowPerReport() {
        let reports = [
            SnapshotFixture.report(domain: "alpha.example"),
            SnapshotFixture.report(domain: "beta.example")
        ]

        let csv = DomainReportExporter.csv(for: reports)
        let lines = csv.split(separator: "\n", omittingEmptySubsequences: false)

        XCTAssertEqual(lines.count, 3, "one header line plus one row per report")
        XCTAssertTrue(lines[0].contains("\"domain\""))
        XCTAssertTrue(csv.contains("\"alpha.example\""))
        XCTAssertTrue(csv.contains("\"beta.example\""))
    }

    func testMarkdownIsHeadedAndNamesTheDomain() {
        let markdown = DomainReportExporter.markdown(for: SnapshotFixture.report(domain: "md.example"))

        XCTAssertTrue(markdown.hasPrefix("# "), "markdown export should open with an H1")
        XCTAssertTrue(markdown.contains("md.example"))
    }

    func testTextExportNamesTheDomain() {
        let text = DomainReportExporter.text(for: SnapshotFixture.report(domain: "txt.example"))
        XCTAssertTrue(text.contains("txt.example"))
    }

    func testBatchExportsCarryTitleAndEveryDomain() {
        let reports = [
            SnapshotFixture.report(domain: "first.example"),
            SnapshotFixture.report(domain: "second.example")
        ]

        let markdown = DomainReportExporter.batchMarkdown(for: reports, title: "Portfolio Sweep")
        XCTAssertTrue(markdown.contains("Portfolio Sweep"))
        XCTAssertTrue(markdown.contains("first.example"))
        XCTAssertTrue(markdown.contains("second.example"))

        let text = DomainReportExporter.batchText(for: reports, title: "Portfolio Sweep")
        XCTAssertTrue(text.contains("Portfolio Sweep"))
        XCTAssertTrue(text.contains("first.example"))
        XCTAssertTrue(text.contains("second.example"))
    }

    func testPDFExportHasPDFSignature() throws {
        let data = try DomainReportExporter.data(for: SnapshotFixture.report(), format: .pdf)
        XCTAssertTrue(data.starts(with: Array("%PDF".utf8)), "PDF export should begin with the %PDF signature")
    }

    func testTimelineTextNamesTheDomain() {
        let reports = [
            SnapshotFixture.report(domain: "timeline.example", timestamp: SnapshotFixture.referenceDate),
            SnapshotFixture.report(
                domain: "timeline.example",
                timestamp: SnapshotFixture.referenceDate.addingTimeInterval(86_400)
            )
        ]

        let text = DomainReportExporter.timelineText(for: reports, domain: "timeline.example", includeDiffSummary: false)
        XCTAssertTrue(text.contains("timeline.example"))
    }
}