crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

OpenPuzzleBannerTests.swift (2140B)


      1 import Foundation
      2 import Testing
      3 
      4 @testable import Crossmate
      5 
      6 /// Covers the open-time banner reconciler. The access-revoked banner is
      7 /// otherwise posted only on the live revocation transition; a puzzle revoked
      8 /// in an earlier process must still surface it when reopened.
      9 @Suite("OpenPuzzleBanner")
     10 struct OpenPuzzleBannerTests {
     11 
     12     @Test("Opening a revoked game yields the sticky access-revoked banner")
     13     func revokedGameYieldsBanner() throws {
     14         let gameID = UUID()
     15         let announcements = OpenPuzzleBanner.announcements(
     16             for: OpenPuzzleState(
     17                 gameID: gameID,
     18                 isAccessRevoked: true,
     19                 isSyncSupported: true
     20             )
     21         )
     22         #expect(announcements.count == 1)
     23         let banner = try #require(announcements.first)
     24         #expect(banner.id == "access-revoked-\(gameID.uuidString)")
     25         #expect(banner.scope == .game(gameID))
     26         #expect(banner.severity == .error)
     27         #expect(banner.dismissal == .sticky)
     28         #expect(banner.blocksInput)
     29     }
     30 
     31     @Test("Opening a game with access intact yields no banners")
     32     func intactGameYieldsNothing() {
     33         let announcements = OpenPuzzleBanner.announcements(
     34             for: OpenPuzzleState(
     35                 gameID: UUID(),
     36                 isAccessRevoked: false,
     37                 isSyncSupported: true
     38             )
     39         )
     40         #expect(announcements.isEmpty)
     41     }
     42 
     43     @Test("Opening an unsupported sync version yields an input-blocking update banner")
     44     func unsupportedSyncVersionYieldsBanner() throws {
     45         let gameID = UUID()
     46         let announcements = OpenPuzzleBanner.announcements(
     47             for: OpenPuzzleState(
     48                 gameID: gameID,
     49                 isAccessRevoked: false,
     50                 isSyncSupported: false
     51             )
     52         )
     53         #expect(announcements.count == 1)
     54         let banner = try #require(announcements.first)
     55         #expect(banner.id == "unsupported-sync-version-\(gameID.uuidString)")
     56         #expect(banner.scope == .game(gameID))
     57         #expect(banner.dismissal == .sticky)
     58         #expect(banner.blocksInput)
     59     }
     60 }