55// Tests for correct window tab grouping behavior:
66// - Same-connection tabs merge into the same window
77// - Different-connection tabs stay in separate windows
8- // - WindowOpener tracks pending connectionId for AppDelegate
8+ // - WindowOpener tracks pending payloads for tab-group attachment
99//
1010
1111import Foundation
@@ -16,86 +16,47 @@ import Testing
1616@Suite ( " WindowTabGrouping " )
1717@MainActor
1818struct WindowTabGroupingTests {
19- // MARK: - WindowOpener pending connectionId
19+ // MARK: - WindowOpener pending payload tracking
2020
21- @Test ( " openNativeTab sets pendingConnectionId from payload " )
22- func openNativeTabSetsPendingConnectionId ( ) {
21+ @Test ( " openNativeTab without openWindow action drops payload and removes from pending " )
22+ func openNativeTabWithoutOpenWindowDropsPayload ( ) {
2323 let connectionId = UUID ( )
2424 let opener = WindowOpener . shared
2525
26- // No openWindow action set, so it won't actually open — but pendingConnectionId should be set
2726 opener. openWindow = nil
2827 let payload = EditorTabPayload ( connectionId: connectionId, tabType: . table, tableName: " users " )
2928 opener. openNativeTab ( payload)
3029
31- #expect( opener. pendingConnectionId == connectionId )
30+ #expect( opener. pendingPayloads [ payload . id ] == nil )
3231 }
3332
34- @Test ( " pendingConnectionId is nil initially" )
35- func pendingConnectionIdNilInitially ( ) {
33+ @Test ( " pendingPayloads is empty initially" )
34+ func pendingPayloadsEmptyInitially ( ) {
3635 let opener = WindowOpener . shared
37- opener. pendingConnectionId = nil
36+ for id in opener. pendingPayloads. keys {
37+ opener. acknowledgePayload ( id)
38+ }
3839
39- #expect( opener. pendingConnectionId == nil )
40+ #expect( opener. pendingPayloads . isEmpty )
4041 }
4142
42- @Test ( " consumePendingConnectionId returns and clears the value " )
43- func consumePendingConnectionIdReturnsAndClears( ) {
44- let connectionId = UUID ( )
45- let opener = WindowOpener . shared
46- opener. pendingConnectionId = connectionId
47-
48- let consumed = opener. consumePendingConnectionId ( )
49-
50- #expect( consumed == connectionId)
51- #expect( opener. pendingConnectionId == nil )
52- }
53-
54- @Test ( " consumePendingConnectionId returns nil when nothing pending " )
55- func consumePendingConnectionIdReturnsNilWhenEmpty( ) {
43+ @Test ( " acknowledgePayload removes the id from pending " )
44+ func acknowledgePayloadRemovesId( ) {
5645 let opener = WindowOpener . shared
57- opener. pendingConnectionId = nil
58-
59- let consumed = opener. consumePendingConnectionId ( )
46+ let payloadId = UUID ( )
6047
61- #expect( consumed == nil )
48+ opener. acknowledgePayload ( payloadId)
49+ #expect( opener. pendingPayloads [ payloadId] == nil )
6250 }
6351
6452 // MARK: - TabbingIdentifier resolution
6553
66- @Test ( " tabbingIdentifier uses pending connectionId when available " )
67- func tabbingIdentifierUsesPendingConnectionId( ) {
68- let connectionId = UUID ( )
69- let expected = " com.TablePro.main. \( connectionId. uuidString) "
70-
71- let result = TabbingIdentifierResolver . resolve ( pendingConnectionId: connectionId, existingIdentifier: nil )
72-
73- #expect( result == expected)
74- }
75-
76- @Test ( " tabbingIdentifier falls back to existing window identifier when no pending " )
77- func tabbingIdentifierFallsBackToExistingWindow( ) {
78- let existingId = " com.TablePro.main.AAAA-BBBB "
79-
80- let result = TabbingIdentifierResolver . resolve ( pendingConnectionId: nil , existingIdentifier: existingId)
81-
82- #expect( result == existingId)
83- }
84-
85- @Test ( " tabbingIdentifier uses generic default when no pending and no existing window " )
86- func tabbingIdentifierUsesGenericDefault( ) {
87- let result = TabbingIdentifierResolver . resolve ( pendingConnectionId: nil , existingIdentifier: nil )
88-
89- #expect( result == " com.TablePro.main " )
90- }
91-
92- @Test ( " tabbingIdentifier prefers pending connectionId over existing window " )
93- func tabbingIdentifierPrefersPendingOverExisting( ) {
54+ @Test ( " tabbingIdentifier produces connection-specific identifier " )
55+ func tabbingIdentifierUsesConnectionId( ) {
9456 let connectionId = UUID ( )
9557 let expected = " com.TablePro.main. \( connectionId. uuidString) "
96- let existingId = " com.TablePro.main.DIFFERENT "
9758
98- let result = TabbingIdentifierResolver . resolve ( pendingConnectionId : connectionId, existingIdentifier : existingId )
59+ let result = WindowOpener . tabbingIdentifier ( for : connectionId)
9960
10061 #expect( result == expected)
10162 }
@@ -107,8 +68,8 @@ struct WindowTabGroupingTests {
10768 let connectionA = UUID ( )
10869 let connectionB = UUID ( )
10970
110- let idA = TabbingIdentifierResolver . resolve ( pendingConnectionId : connectionA, existingIdentifier : nil )
111- let idB = TabbingIdentifierResolver . resolve ( pendingConnectionId : connectionB, existingIdentifier : nil )
71+ let idA = WindowOpener . tabbingIdentifier ( for : connectionA)
72+ let idB = WindowOpener . tabbingIdentifier ( for : connectionB)
11273
11374 #expect( idA != idB)
11475 #expect( idA. contains ( connectionA. uuidString) )
@@ -119,56 +80,9 @@ struct WindowTabGroupingTests {
11980 func sameConnectionProducesSameIdentifier( ) {
12081 let connectionId = UUID ( )
12182
122- let id1 = TabbingIdentifierResolver . resolve ( pendingConnectionId : connectionId, existingIdentifier : nil )
123- let id2 = TabbingIdentifierResolver . resolve ( pendingConnectionId : connectionId, existingIdentifier : nil )
83+ let id1 = WindowOpener . tabbingIdentifier ( for : connectionId)
84+ let id2 = WindowOpener . tabbingIdentifier ( for : connectionId)
12485
12586 #expect( id1 == id2)
12687 }
127-
128- @Test ( " Opening table tab for connection B while connection A window exists uses B's identifier " )
129- func openingTabForConnectionBUsesCorrectIdentifier( ) {
130- let connectionA = UUID ( )
131- let connectionB = UUID ( )
132- let existingWindowIdentifier = " com.TablePro.main. \( connectionA. uuidString) "
133-
134- // When opening a tab for connection B, the pending connectionId should be B
135- // This should produce B's identifier, NOT copy A's identifier
136- let result = TabbingIdentifierResolver . resolve (
137- pendingConnectionId: connectionB,
138- existingIdentifier: existingWindowIdentifier
139- )
140-
141- #expect( result == " com.TablePro.main. \( connectionB. uuidString) " )
142- #expect( result != existingWindowIdentifier)
143- }
144-
145- // MARK: - groupAllConnections
146-
147- @Test ( " groupAllConnections returns shared identifier regardless of connectionId " )
148- func groupAllConnectionsReturnsSharedIdentifier( ) {
149- let connectionA = UUID ( )
150- let connectionB = UUID ( )
151-
152- let idA = TabbingIdentifierResolver . resolve (
153- pendingConnectionId: connectionA, existingIdentifier: nil , groupAllConnections: true
154- )
155- let idB = TabbingIdentifierResolver . resolve (
156- pendingConnectionId: connectionB, existingIdentifier: nil , groupAllConnections: true
157- )
158-
159- #expect( idA == " com.TablePro.main " )
160- #expect( idB == " com.TablePro.main " )
161- #expect( idA == idB)
162- }
163-
164- @Test ( " groupAllConnections ignores existingIdentifier " )
165- func groupAllConnectionsIgnoresExistingIdentifier( ) {
166- let existing = " com.TablePro.main.SOME-UUID "
167-
168- let result = TabbingIdentifierResolver . resolve (
169- pendingConnectionId: nil , existingIdentifier: existing, groupAllConnections: true
170- )
171-
172- #expect( result == " com.TablePro.main " )
173- }
17488}
0 commit comments