feat: Ipad app production readiness, Colony orchestration, Social posting
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
import XCTest
|
||||
@testable import velocity
|
||||
|
||||
final class VelocityEnterpriseFlowTests: XCTestCase {
|
||||
func testImportWorkbenchDuplicateMergePoliciesDecodeForReviewFlow() throws {
|
||||
let payload = Data(
|
||||
"""
|
||||
{
|
||||
"batch_id": "batch-1",
|
||||
"summary": {
|
||||
"proposal_count": 3,
|
||||
"duplicate_count": 2,
|
||||
"validation_error_count": 1,
|
||||
"validation_warning_count": 1
|
||||
},
|
||||
"rows": [
|
||||
{
|
||||
"proposal_id": "proposal-create",
|
||||
"row_number": 1,
|
||||
"status": "pending",
|
||||
"confidence": 0.91,
|
||||
"validation": [],
|
||||
"duplicate_candidates": [],
|
||||
"duplicate_policy": "create_new",
|
||||
"field_diffs": []
|
||||
},
|
||||
{
|
||||
"proposal_id": "proposal-merge",
|
||||
"row_number": 2,
|
||||
"status": "approved",
|
||||
"confidence": 0.97,
|
||||
"validation": [],
|
||||
"duplicate_candidates": [
|
||||
{
|
||||
"person_id": "person-1",
|
||||
"full_name": "Asha Rao",
|
||||
"primary_email": "asha@example.com",
|
||||
"primary_phone": "+919999999999",
|
||||
"buyer_type": "hni_end_user",
|
||||
"source_confidence": 0.94,
|
||||
"created_at": "2026-05-01T00:00:00Z",
|
||||
"updated_at": "2026-05-01T00:00:00Z",
|
||||
"match_reason": "phone",
|
||||
"match_score": 95
|
||||
}
|
||||
],
|
||||
"duplicate_policy": "update_existing",
|
||||
"field_diffs": [
|
||||
{"field":"budget_band","proposed":"10-15 Cr","existing":"8-10 Cr","changed":true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"proposal_id": "proposal-skip",
|
||||
"row_number": 3,
|
||||
"status": "approved",
|
||||
"confidence": 0.88,
|
||||
"validation": [],
|
||||
"duplicate_candidates": [],
|
||||
"duplicate_policy": "skip_duplicate",
|
||||
"field_diffs": []
|
||||
}
|
||||
]
|
||||
}
|
||||
""".utf8
|
||||
)
|
||||
|
||||
let workbench = try JSONDecoder().decode(VelocityImportWorkbenchDTO.self, from: payload)
|
||||
XCTAssertEqual(workbench.summary.duplicateCount, 2)
|
||||
XCTAssertEqual(workbench.row(for: "proposal-create")?.duplicatePolicy, "create_new")
|
||||
XCTAssertEqual(workbench.row(for: "proposal-merge")?.duplicatePolicy, "update_existing")
|
||||
XCTAssertEqual(workbench.row(for: "proposal-skip")?.duplicatePolicy, "skip_duplicate")
|
||||
XCTAssertEqual(workbench.row(for: "proposal-merge")?.fieldDiffs.first?.field, "budget_band")
|
||||
}
|
||||
|
||||
func testEnterpriseIdentityContractsDecodeProviderObjectsAndSessionSwitch() throws {
|
||||
let providersPayload = Data(
|
||||
"""
|
||||
{
|
||||
"enabled": true,
|
||||
"tenantId": "tenant_velocity",
|
||||
"providers": [
|
||||
{
|
||||
"id": "azure_ad",
|
||||
"name": "Azure AD",
|
||||
"type": "oauth",
|
||||
"authorizationUrl": "https://login.microsoftonline.com/tenant/oauth2/v2.0/authorize",
|
||||
"metadataUrl": "https://login.microsoftonline.com/tenant/v2.0/.well-known/openid-configuration",
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
""".utf8
|
||||
)
|
||||
let providers = try JSONDecoder().decode(VelocitySSOProvidersDTO.self, from: providersPayload)
|
||||
XCTAssertTrue(providers.enabled)
|
||||
XCTAssertEqual(providers.providers.first?.id, "azure_ad")
|
||||
XCTAssertEqual(providers.providers.first?.type, "oauth")
|
||||
|
||||
let switchPayload = Data(
|
||||
"""
|
||||
{
|
||||
"switchAllowed": true,
|
||||
"targetUser": {
|
||||
"user_id": "user-2",
|
||||
"role": "SENIOR_BROKER",
|
||||
"tenant_id": "tenant_velocity",
|
||||
"full_name": "Second Operator",
|
||||
"email": "second@example.com"
|
||||
},
|
||||
"requiresReauthentication": false,
|
||||
"accessToken": "jwt-token",
|
||||
"tokenType": "bearer",
|
||||
"expiresIn": 28800
|
||||
}
|
||||
""".utf8
|
||||
)
|
||||
let switchResult = try JSONDecoder().decode(VelocitySessionSwitchDTO.self, from: switchPayload)
|
||||
XCTAssertTrue(switchResult.switchAllowed)
|
||||
XCTAssertEqual(switchResult.targetUser?.displayName, "Second Operator")
|
||||
XCTAssertEqual(switchResult.accessToken, "jwt-token")
|
||||
}
|
||||
|
||||
func testCalendarMutationStateMachineCoversCreateUpdateDoneCancelUndo() {
|
||||
var calendar = CalendarMutationHarness()
|
||||
let created = calendar.create(title: "Site visit")
|
||||
XCTAssertEqual(calendar.events[created]?.status, "confirmed")
|
||||
|
||||
calendar.update(id: created, title: "VIP site visit")
|
||||
XCTAssertEqual(calendar.events[created]?.title, "VIP site visit")
|
||||
|
||||
calendar.done(id: created)
|
||||
XCTAssertEqual(calendar.events[created]?.status, "done")
|
||||
|
||||
calendar.cancel(id: created)
|
||||
XCTAssertEqual(calendar.events[created]?.status, "cancelled")
|
||||
|
||||
calendar.undo()
|
||||
XCTAssertEqual(calendar.events[created]?.status, "done")
|
||||
}
|
||||
|
||||
func testDreamWeaverReadinessDecodesErrorAndHealthyStates() throws {
|
||||
let healthy = DreamWeaverReadiness(
|
||||
isReady: true,
|
||||
label: "Dream Weaver ready",
|
||||
detail: "Gateway, route, GPU, and checkpoint are healthy."
|
||||
)
|
||||
XCTAssertTrue(healthy.isReady)
|
||||
|
||||
let unhealthy = DreamWeaverReadiness(
|
||||
isReady: false,
|
||||
label: "Dream Weaver route unavailable",
|
||||
detail: "Generation remains disabled until the backend route probe succeeds."
|
||||
)
|
||||
XCTAssertFalse(unhealthy.isReady)
|
||||
}
|
||||
}
|
||||
|
||||
private struct CalendarMutationHarness {
|
||||
struct Event {
|
||||
var title: String
|
||||
var status: String
|
||||
}
|
||||
|
||||
private(set) var events: [String: Event] = [:]
|
||||
private var undoStack: [(String, Event)] = []
|
||||
|
||||
mutating func create(title: String) -> String {
|
||||
let id = UUID().uuidString
|
||||
events[id] = Event(title: title, status: "confirmed")
|
||||
return id
|
||||
}
|
||||
|
||||
mutating func update(id: String, title: String) {
|
||||
guard var event = events[id] else { return }
|
||||
event.title = title
|
||||
events[id] = event
|
||||
}
|
||||
|
||||
mutating func done(id: String) {
|
||||
guard var event = events[id] else { return }
|
||||
event.status = "done"
|
||||
events[id] = event
|
||||
}
|
||||
|
||||
mutating func cancel(id: String) {
|
||||
guard let event = events[id] else { return }
|
||||
undoStack.append((id, event))
|
||||
events[id]?.status = "cancelled"
|
||||
}
|
||||
|
||||
mutating func undo() {
|
||||
guard let (id, event) = undoStack.popLast() else { return }
|
||||
events[id] = event
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user