Skip to content

test(ios): unit tests for the three extracted iOS view models#1173

Merged
datlechin merged 2 commits intomainfrom
test/viewmodel-unit-tests
May 9, 2026
Merged

test(ios): unit tests for the three extracted iOS view models#1173
datlechin merged 2 commits intomainfrom
test/viewmodel-unit-tests

Conversation

@datlechin
Copy link
Copy Markdown
Member

Summary

Closes the original audit backlog by adding Swift Testing coverage for the three view models extracted in PR #1164, #1165, #1166. Each VM now has tests against an in-memory DatabaseDriver and SecureStore mock, which lock in the refactor surface so future regressions surface in CI rather than at runtime.

Coverage

DataBrowserViewModelTests (8 tests):

  • load without session sets loadError
  • load with session populates columns, legacyRows, columnDetails, hasPrimaryKeys
  • applySearch / clearSearch toggle hasActiveSearch and activeSearchText
  • goToPreviousPage clamps at 0 (no underflow)
  • primaryKeyValues(for:) extracts only PK columns from a row
  • deleteRow returns true on success and runs DELETE SQL through the driver
  • deleteRow returns false and sets operationError on driver failure
  • changePageSize resets currentPage and totalRows

ConnectionFormViewModelTests (7 tests):

  • init() reads default safe mode from AppPreferences
  • init(editing:) hydrates name, type, host, port, username, database, SSL, safe mode from a stored connection
  • Setting type updates port to the type's default (didSet)
  • canSave requires database for SQLite, host for server types
  • loadStoredCredentials(secureStore:) populates password and SSH password from the seeded mock store
  • clearSelectedFile() resets URL and database
  • createNewDatabase() builds a .db URL in Documents and primes the connection name

RowDetailViewModelTests (8 tests):

  • canEdit requires session, table, primary key, and not safe-mode-blocked
  • startEditing populates editedValues from the current row
  • cancelEditing clears edited values
  • toggleNull flips between empty string and nil
  • saveChanges with no changes early-returns true and exits edit mode without firing UPDATE
  • saveChanges with changes runs UPDATE with primary keys and modified columns
  • saveChanges returns false and sets operationError when no primary key value is present
  • loadFullValue populates the per-cell override and clears loadingCell

Mocks

  • MockDatabaseDriver is @unchecked Sendable (state mutated only from @MainActor test scope), implements all DatabaseDriver protocol requirements, and exposes scriptedExecuteResults: [Result<QueryResult, Error>] for sequenced responses
  • MockSecureStore is an in-memory [String: String] backing the SecureStore protocol, with seed(_:_:) for test setup and failNextStore for forcing keychain write failures

Signature change

ConnectionFormViewModel.loadStoredCredentials(secureStore:), .testConnection(appState:secureStore:), and .save(appState:secureStore:) now accept any SecureStore instead of the concrete KeychainSecureStore. KeychainSecureStore: SecureStore, so all existing call sites (ConnectionFormView) continue to work unchanged.

Required one-time Xcode setup

The test target is not in TableProMobile.xcodeproj yet. Before the tests can run:

  1. Open TableProMobile.xcodeproj in Xcode
  2. File → New → Target → iOS → Unit Testing Bundle
  3. Product Name: TableProMobileTests, Target to Test: TableProMobile, Testing System: Swift Testing
  4. Delete the stub TableProMobileTests.swift Xcode generated; the existing files in TableProMobileTests/ will be picked up via synchronized groups

Instructions are also in TableProMobile/TableProMobileTests/README.md.

Test plan

  • After Xcode test target setup, ⌘U runs all 23 tests green
  • Tests pass with no real network or keychain access (everything goes through the mocks)
  • Run a single suite via xcodebuild ... -only-testing:TableProMobileTests/DataBrowserViewModelTests to confirm filterable

@datlechin datlechin force-pushed the test/viewmodel-unit-tests branch from e4fe564 to d9c72fc Compare May 9, 2026 19:58
@datlechin datlechin merged commit 02a8e3d into main May 9, 2026
2 checks passed
@datlechin datlechin deleted the test/viewmodel-unit-tests branch May 9, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant