// // 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) } }