swift-chat-core/Tests/MessagingChatCoreTests/CodingTests.swift
Lilith dd6fb45493 chore(models): 🔧 Update 11 Swift model files to maintain consistency
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-02-16 02:43:49 -08:00

284 lines
8.2 KiB
Swift

import XCTest
@testable import MessagingChatCore
final class CodingTests: XCTestCase {
private let encoder: JSONEncoder = {
let enc = JSONEncoder()
enc.dateEncodingStrategy = .iso8601
return enc
}()
private let decoder: JSONDecoder = {
let dec = JSONDecoder()
dec.dateDecodingStrategy = .iso8601
return dec
}()
// MARK: - Helpers
private func assertRoundTrip<T: Codable & Equatable>(_ value: T, file: StaticString = #filePath, line: UInt = #line) throws {
let data = try encoder.encode(value)
let decoded = try decoder.decode(T.self, from: data)
XCTAssertEqual(value, decoded, "Round-trip failed for \(T.self)", file: file, line: line)
}
private static let fixedDate = ISO8601DateFormatter().date(from: "2026-01-15T12:00:00Z")!
// MARK: - User
func testUserRoundTrip() throws {
let user = User(
id: "u1",
username: "lilith",
displayName: "Lilith",
avatarURL: URL(string: "https://example.com/avatar.png"),
provider: .creator,
isOnline: true,
lastSeenAt: Self.fixedDate
)
try assertRoundTrip(user)
}
// MARK: - Message
func testTextMessageRoundTrip() throws {
let message = Message(
id: "m1",
threadId: "t1",
senderId: "u1",
content: "Hello",
richContent: nil,
type: .text,
status: .sent,
createdAt: Self.fixedDate,
updatedAt: Self.fixedDate
)
try assertRoundTrip(message)
}
func testRichCardMessageRoundTrip() throws {
let rateCard = RateCardData(
services: [
ServiceRate(name: "Standard", durationMinutes: 60, priceAmount: 200, description: nil)
],
currency: "USD",
note: "Weekend rates",
validUntil: Self.fixedDate
)
let message = Message(
id: "m2",
threadId: "t1",
senderId: "u1",
content: nil,
richContent: .rateCard(rateCard),
type: .richCard,
status: .delivered,
createdAt: Self.fixedDate,
updatedAt: Self.fixedDate
)
try assertRoundTrip(message)
XCTAssertTrue(message.isRichCard)
XCTAssertEqual(message.displayText, "Rate card shared")
}
// MARK: - Thread
func testThreadRoundTrip() throws {
let user = User(
id: "u1",
username: "test",
displayName: "Test User",
avatarURL: nil,
provider: .client,
isOnline: false,
lastSeenAt: nil
)
let thread = Thread(
id: "t1",
participants: [user],
lastMessage: nil,
unreadCount: 3,
isArchived: false,
createdAt: Self.fixedDate,
updatedAt: Self.fixedDate,
metadata: ThreadMetadata(isPinned: true, isMuted: false, customLabel: nil, lastReadMessageId: nil)
)
try assertRoundTrip(thread)
XCTAssertEqual(thread.displayTitle, "Test User")
}
// MARK: - Rich Content Types
func testBookingProposalRoundTrip() throws {
let proposal = BookingProposalData(
id: "bp1",
title: "Evening session",
service: "Standard",
date: Self.fixedDate,
startTime: "20:00",
endTime: "21:00",
location: nil,
priceAmount: 300,
currency: "ISK",
status: .proposed,
note: nil
)
try assertRoundTrip(proposal)
}
func testCounterOfferRoundTrip() throws {
let counter = CounterOfferData(
originalProposalId: "bp1",
proposedDate: Self.fixedDate,
proposedStartTime: "19:00",
proposedEndTime: "20:00",
proposedPriceAmount: 250,
currency: "ISK",
message: "Can we adjust?",
status: .proposed
)
try assertRoundTrip(counter)
}
func testAgreementDataRoundTrip() throws {
let agreement = AgreementData(
bookingId: "b1",
service: "Premium",
date: Self.fixedDate,
startTime: "18:00",
endTime: "20:00",
location: "Downtown",
agreedPriceAmount: 500,
currency: "EUR",
terms: ["No photos", "Punctuality required"],
creatorConfirmed: true,
clientConfirmed: false
)
try assertRoundTrip(agreement)
}
func testScreeningDataRoundTrip() throws {
let screening = ScreeningData(
id: "s1",
requestedFields: [.legalName, .phoneNumber, .references],
status: .requested,
message: "Please provide screening info",
expiresAt: Self.fixedDate
)
try assertRoundTrip(screening)
}
func testPaymentDataRoundTrip() throws {
let payment = PaymentData(
id: "p1",
amount: 150.50,
currency: "USD",
description: "Session payment",
status: .pending,
dueDate: Self.fixedDate,
bookingId: "b1"
)
try assertRoundTrip(payment)
}
func testSystemMessageDataRoundTrip() throws {
let system = SystemMessageData(
text: "Thread created",
systemType: .threadCreated,
metadata: ["createdBy": "u1"]
)
try assertRoundTrip(system)
}
func testAutoResponseDataRoundTrip() throws {
let auto = AutoResponseData(
ruleId: "r1",
message: "Currently unavailable",
triggerType: .offlineHours
)
try assertRoundTrip(auto)
}
func testAvailabilityDataRoundTrip() throws {
let availability = AvailabilityData(
slots: [
AvailabilitySlot(
id: "slot1",
date: Self.fixedDate,
startTime: "10:00",
endTime: "14:00",
isAvailable: true
)
],
timezone: "Atlantic/Reykjavik",
note: nil
)
try assertRoundTrip(availability)
}
// MARK: - Automation
func testAutomationRuleRoundTrip() throws {
let rule = AutomationRule(
id: "ar1",
creatorId: "u1",
name: "Auto-reply for new contacts",
isEnabled: true,
trigger: .newMessage(fromNewContact: true),
action: .sendAutoReply(message: "Thanks for reaching out!"),
schedule: AutomationSchedule(
timezone: "Atlantic/Reykjavik",
activeDays: [.monday, .tuesday, .wednesday, .thursday, .friday],
activeStartTime: "09:00",
activeEndTime: "17:00"
),
conditions: [
AutomationCondition(field: .senderProvider, op: .equals, value: "client")
],
createdAt: Self.fixedDate,
updatedAt: Self.fixedDate
)
try assertRoundTrip(rule)
}
// MARK: - MessageContentConvertible
func testMessageContentConvertible() {
let rateCard = RateCardData(
services: [],
currency: "USD",
note: nil,
validUntil: nil
)
let content = rateCard.toRichContent()
XCTAssertEqual(content.cardType, "rateCard")
}
// MARK: - CardInteraction
func testCardInteractionRoundTrip() throws {
let interaction = CardInteraction(
id: "ci1",
messageId: "m1",
userId: "u1",
action: .accepted,
createdAt: Self.fixedDate
)
try assertRoundTrip(interaction)
}
// MARK: - Attachment
func testAttachmentRoundTrip() throws {
let attachment = Attachment(
id: "a1",
messageId: "m1",
fileName: "photo.jpg",
mimeType: "image/jpeg",
sizeBytes: 1024000,
url: URL(string: "https://cdn.example.com/photo.jpg")!
)
try assertRoundTrip(attachment)
}
}