krz/octosentry

macOS menu bar app to monitor GitHub security alerts

clone: git clone https://gitbay.org/krz/octosentry.git

1.1: octosentryTests/AlertSortOrderTests.swift · raw

 1//
 2//  AlertSortOrderTests.swift
 3//  octosentryTests
 4//
 5
 6import Foundation
 7import Testing
 8@testable import octosentry
 9
10struct AlertSortOrderTests {
11
12    // Deliberately out of order on every axis.
13    private let events = [
14        TestEvents.event(id: "old-low", repo: "zulu/repo", severity: .low, ageInHours: 500),
15        TestEvents.event(id: "new-critical", repo: "alpha/repo", severity: .critical, ageInHours: 1),
16        TestEvents.event(id: "old-critical", repo: "mike/repo", severity: .critical, ageInHours: 100),
17        TestEvents.event(id: "new-medium", repo: "alpha/repo", severity: .medium, ageInHours: 2),
18    ]
19
20    @Test func severityOrdersHighestFirstThenNewest() {
21        let sorted = AlertSortOrder.severity.sorted(events)
22
23        #expect(sorted.map(\.id) == ["new-critical", "old-critical", "new-medium", "old-low"])
24    }
25
26    @Test func oldestOrdersLongestOpenFirst() {
27        let sorted = AlertSortOrder.oldest.sorted(events)
28
29        #expect(sorted.map(\.id) == ["old-low", "old-critical", "new-medium", "new-critical"])
30    }
31
32    @Test func repoGroupsByNameThenSeverityWithinRepo() {
33        let sorted = AlertSortOrder.repo.sorted(events)
34
35        #expect(sorted.map(\.repoFullName) == ["alpha/repo", "alpha/repo", "mike/repo", "zulu/repo"])
36        // Within alpha/repo, critical sorts above medium.
37        #expect(sorted.prefix(2).map(\.id) == ["new-critical", "new-medium"])
38    }
39
40    @Test func repoOrderIsCaseInsensitive() {
41        let mixedCase = [
42            TestEvents.event(id: "upper", repo: "Zulu/repo"),
43            TestEvents.event(id: "lower", repo: "alpha/repo"),
44        ]
45
46        #expect(AlertSortOrder.repo.sorted(mixedCase).map(\.id) == ["lower", "upper"])
47    }
48
49    @Test func sortingNeverDropsOrDuplicatesEvents() {
50        for order in AlertSortOrder.allCases {
51            #expect(Set(order.sorted(events).map(\.id)) == Set(events.map(\.id)))
52            #expect(order.sorted(events).count == events.count)
53        }
54    }
55
56    @Test func sortingAnEmptyFeedIsEmpty() {
57        for order in AlertSortOrder.allCases {
58            #expect(order.sorted([]).isEmpty)
59        }
60    }
61
62    // Raw values are persisted in state.json.
63    @Test func rawValuesAreStable() {
64        #expect(AlertSortOrder.severity.rawValue == "severity")
65        #expect(AlertSortOrder.oldest.rawValue == "oldest")
66        #expect(AlertSortOrder.repo.rawValue == "repo")
67    }
68}