@@ -544,6 +544,64 @@ final class QueryViewModelTests: XCTestCase {
544544 XCTAssertTrue(vm.autoHiddenColumns.isEmpty)
545545 }
546546
547+ // MARK: - Pending column config from saved queries
548+
549+ func testApplyColumnConfigUsesPendingConfig() {
550+ let vm = QueryViewModel()
551+ vm.pendingColumnConfig = QueryViewModel.ColumnConfiguration(
552+ order: ["c", "a", "b"],
553+ hidden: ["b"]
554+ )
555+ vm.applyColumnConfig(extractedColumns: ["a", "b", "c"], stream: "test_stream")
556+ XCTAssertEqual(vm.columnOrder, ["c", "a", "b"])
557+ XCTAssertEqual(vm.hiddenColumns, ["b"])
558+ XCTAssertNil(vm.pendingColumnConfig, "Pending config should be consumed")
559+ }
560+
561+ func testApplyColumnConfigPendingOverridesStreamDefault() {
562+ let vm = QueryViewModel()
563+ // Save a stream-level config
564+ let streamConfig = QueryViewModel.ColumnConfiguration(order: ["a", "b", "c"], hidden: [])
565+ if let data = try? JSONEncoder().encode(streamConfig) {
566+ UserDefaults.standard.set(data, forKey: "parseable_column_config_pending_test_stream")
567+ }
568+
569+ // Set a different pending config (from saved query)
570+ vm.pendingColumnConfig = QueryViewModel.ColumnConfiguration(
571+ order: ["c", "b", "a"],
572+ hidden: ["a"]
573+ )
574+ vm.applyColumnConfig(extractedColumns: ["a", "b", "c"], stream: "pending_test_stream")
575+ XCTAssertEqual(vm.columnOrder, ["c", "b", "a"])
576+ XCTAssertEqual(vm.hiddenColumns, ["a"])
577+
578+ // Clean up
579+ UserDefaults.standard.removeObject(forKey: "parseable_column_config_pending_test_stream")
580+ }
581+
582+ func testApplyColumnConfigPendingMergesNewColumns() {
583+ let vm = QueryViewModel()
584+ // Pending config references columns a and b, but results also have c
585+ vm.pendingColumnConfig = QueryViewModel.ColumnConfiguration(
586+ order: ["b", "a"],
587+ hidden: []
588+ )
589+ vm.applyColumnConfig(extractedColumns: ["a", "b", "c"], stream: "test_stream")
590+ XCTAssertEqual(vm.columnOrder, ["b", "a", "c"])
591+ }
592+
593+ func testApplyColumnConfigPendingRemovesStaleColumns() {
594+ let vm = QueryViewModel()
595+ // Pending config references "old" which no longer exists in results
596+ vm.pendingColumnConfig = QueryViewModel.ColumnConfiguration(
597+ order: ["old", "a", "b"],
598+ hidden: ["old"]
599+ )
600+ vm.applyColumnConfig(extractedColumns: ["a", "b"], stream: "test_stream")
601+ XCTAssertEqual(vm.columnOrder, ["a", "b"])
602+ XCTAssertTrue(vm.hiddenColumns.isEmpty)
603+ }
604+
547605 func testCSVExportExcludesAutoHiddenColumns() {
548606 let vm = QueryViewModel()
549607 vm.results = [