Files
element-x-ios/UnitTests/Sources/HealthChat/ExtendedProfileTests.swift
T
joel.poyet 00f08ab2dc Add HealthChat API and extended profile services (#9)
Expose OpenID tokens and homeserver credentials from the client proxy, and
add fork-only services for the HealthChat member directory backend
(api.healthchat.ch) plus a service that reads MSC4133 extended profile
fields directly from the homeserver. Groundwork for the members tab and
the profile screens.

Claude-Session: https://claude.ai/code/session_013qdTbAWsZj2quQzEkagXaS
2026-09-22 18:21:58 +02:00

150 lines
5.2 KiB
Swift

//
// Copyright 2026 Element Creations Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
@testable import ElementX
import Foundation
import Testing
final class ExtendedProfileTests {
@Test
func decodesFullProfile() throws {
let json = """
{
"displayname": "Dr. Alice Alpha",
"avatar_url": "mxc://healthchat.ch/abc123",
"io.element.profile.title": "Dr. med.",
"io.element.profile.first_name": "Alice",
"io.element.profile.last_name": "Alpha",
"io.element.profile.specialization": "Physiotherapie",
"io.element.profile.practice_name": "Praxis Alpha",
"io.element.profile.further_info": "Multi\\nline",
"io.element.profile.business_email": "praxis@example.ch",
"io.element.profile.business_tel": "+41 44 123 45 67",
"io.element.profile.business_street": "Friedaustrasse",
"io.element.profile.business_street_nr": "17",
"io.element.profile.business_plz": "8003",
"io.element.profile.business_city": "Zürich",
"io.element.profile.website": "https://example.ch"
}
"""
let profile = try JSONDecoder().decode(ExtendedProfile.self, from: Data(json.utf8))
#expect(profile.displayName == "Dr. Alice Alpha")
#expect(profile.avatarURL == URL(string: "mxc://healthchat.ch/abc123"))
#expect(profile.title == "Dr. med.")
#expect(profile.firstName == "Alice")
#expect(profile.lastName == "Alpha")
#expect(profile.specialty == "Physiotherapie")
#expect(profile.practiceName == "Praxis Alpha")
#expect(profile.furtherInfo == "Multi\nline")
#expect(profile.businessEmail == "praxis@example.ch")
#expect(profile.businessTel == "+41 44 123 45 67")
#expect(profile.street == "Friedaustrasse")
#expect(profile.houseNumber == "17")
#expect(profile.postalCode == "8003")
#expect(profile.city == "Zürich")
#expect(profile.website == "https://example.ch")
#expect(profile.hasContent)
}
@Test
func decodesLegacyAddressKeysAsFallback() throws {
let json = """
{
"io.element.profile.street": "Altweg",
"io.element.profile.house_number": "3",
"io.element.profile.postal_code": "9000"
}
"""
let profile = try JSONDecoder().decode(ExtendedProfile.self, from: Data(json.utf8))
#expect(profile.street == "Altweg")
#expect(profile.houseNumber == "3")
#expect(profile.postalCode == "9000")
}
@Test
func canonicalKeyPresenceWinsOverLegacyEvenWhenEmpty() throws {
let json = """
{
"io.element.profile.business_street": "",
"io.element.profile.street": "Altweg"
}
"""
let profile = try JSONDecoder().decode(ExtendedProfile.self, from: Data(json.utf8))
#expect(profile.street == nil)
}
@Test
func emptyAndNonStringValuesBecomeNil() throws {
let json = """
{
"displayname": "Alice",
"io.element.profile.title": "",
"io.element.profile.specialization": 5,
"us.cloke.msc4175.tz": "Europe/Zurich"
}
"""
let profile = try JSONDecoder().decode(ExtendedProfile.self, from: Data(json.utf8))
#expect(profile.title == nil)
#expect(profile.specialty == nil)
#expect(!profile.hasContent)
}
@Test
func hasContentWithSingleField() throws {
let json = """
{ "io.element.profile.business_tel": "+41 44 123 45 67" }
"""
let profile = try JSONDecoder().decode(ExtendedProfile.self, from: Data(json.utf8))
#expect(profile.hasContent)
}
@Test
func formattedAddressWithAllComponents() throws {
let json = """
{
"io.element.profile.business_street": "Friedaustrasse",
"io.element.profile.business_street_nr": "17",
"io.element.profile.business_plz": "8003",
"io.element.profile.business_city": "Zürich"
}
"""
let profile = try JSONDecoder().decode(ExtendedProfile.self, from: Data(json.utf8))
#expect(profile.formattedAddress == "Friedaustrasse 17, 8003 Zürich")
}
@Test
func formattedAddressWithPartialComponents() throws {
let cityOnly = try JSONDecoder().decode(ExtendedProfile.self, from: Data("""
{
"io.element.profile.business_plz": "8003",
"io.element.profile.business_city": "Zürich"
}
""".utf8))
#expect(cityOnly.formattedAddress == "8003 Zürich")
let streetOnly = try JSONDecoder().decode(ExtendedProfile.self, from: Data("""
{ "io.element.profile.business_street": "Friedaustrasse" }
""".utf8))
#expect(streetOnly.formattedAddress == "Friedaustrasse")
let empty = try JSONDecoder().decode(ExtendedProfile.self, from: Data("{}".utf8))
#expect(empty.formattedAddress == nil)
}
}