iOS/Tests/Shared/Extensions/StringExtensions.test.swift
Copilot 9e8df8ad9d
Format BSSID MAC addresses with leading zeros for consistency with Android (#4095)
## Summary
BSSID sensor reported MAC addresses without leading zeros (e.g.,
`18:e8:29:a7:e9:b`), inconsistent with Android companion app and
standard MAC address notation. This breaks cross-platform room presence
tracking.

**Changes:**
- Added `String.formattedBSSID` extension that pads hex octets to 2
characters
- Applied formatting to BSSID sensor state in `ConnectivitySensor`
- Added test coverage for formatting edge cases

```swift
// Before: "18:e8:29:a7:e9:b"
// After:  "18:e8:29:a7:e9:0b"
sensor.State = bssid.formattedBSSID
```

## Screenshots
N/A - Sensor value formatting change only

## Link to pull request in Documentation repository
Documentation: home-assistant/companion.home-assistant#

## Any other notes
**Breaking change:** Users with BSSID-based automations must update to
the new zero-padded format. This aligns iOS with Android, standard MAC
notation, and network management tools like UniFi.

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>BSSID mac address format isn't consistant with Android
Companion app</issue_title>
> <issue_description>**iOS device model, version and app version**
> <!-- Please include your device 'Model Name' and 'Software Version' as
listed in iOS Settings>General>About. Please also give the app version
listed beneath "Home Assistant Companion" in the App Configuration>About
menu within the app, please include the number in brackets -->
> 
> Model Name: IPhone 6S
> Software Version: IOS 14.4.1
> App version: 2021.77
> 
> **Home Assistant Core Version**
> version | core-2021.3.4
> -- | --
> installation_type | Home Assistant Container
> dev | false
> hassio | false
> docker | true
> virtualenv | false
> python_version | 3.8.7
> os_name | Linux
> os_version | 5.3.18-3-pve
> arch | x86_64
> timezone | Europe/Paris
> 
> <details><summary>Home Assistant Community Store</summary>
> 
> GitHub API | ok
> -- | --
> Github API Calls Remaining | 4998
> Installed Version | 1.11.0
> Stage | running
> Available Repositories | 850
> Installed Repositories | 8
> 
> </details>
> 
> <details><summary>Home Assistant Cloud</summary>
> 
> logged_in | false
> -- | --
> can_reach_cert_server | ok
> can_reach_cloud_auth | ok
> can_reach_cloud | ok
> 
> </details>
> 
> <details><summary>Lovelace</summary>
> 
> dashboards | 9
> -- | --
> resources | 6
> views | 31
> mode | storage
> 
> </details>
> 
> **Describe the bug**
> The BSSID sensor reports access point mac address with leading zeros
omitted
> example:
> 
> ```
> 18:e8:29:a7:e9:b
> ```
> The last number is 0x0b
> 
> An adroid device connected the the same access point returns 
> 
> ```
> 18:e8:29:a7:e9:0b
> ```
> **To Reproduce**
> You need to have an access point with mac bytes lower then 0x10
> 
> **Expected behavior**
> Having same BSSID representation than reported by Android App
companion
> 
> **Screenshots**
> Iphone:
>
![image](https://user-images.githubusercontent.com/5980377/113318644-f3901d00-9310-11eb-94a8-63e53675946d.png)
> 
> Android phone
>
![image](https://user-images.githubusercontent.com/5980377/113318689-00ad0c00-9311-11eb-8594-8daa837dbb2a.png)
> 
> 
> **Additional context**
> I'm using BSSID to track room presence based on connected AP. I'm
trying to share BSSID --> access point for all household mobile.
> 
> I'd prefer the version with leading 0 witch is aligned with Unify
management tool.
> 
> </issue_description>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> <comment_new><author>@zacwest</author><body>
> We're just slurping the value we read from the system, so we'd need to
sanitize the input to change it. It would also be a breaking change for
modifying what values are sent up, which is less-than-ideal since users
get auto-updated in the apps. I'm not sure there's a great path forward
for resolving this.</body></comment_new>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes home-assistant/iOS#1563

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com>
2025-12-16 12:38:06 +00:00

72 lines
2.5 KiB
Swift

import Foundation
@testable import Shared
import Testing
@Suite("String Extensions Tests")
struct StringExtensionsTests {
@Test(
"Given BSSID with single-digit hex values when formatted then adds leading zeros",
arguments: [
("18:e8:29:a7:e9:b", "18:e8:29:a7:e9:0b"),
("a:b:c:d:e:f", "0a:0b:0c:0d:0e:0f"),
("1:2:3:4:5:6", "01:02:03:04:05:06"),
("aa:bb:cc:dd:ee:f", "aa:bb:cc:dd:ee:0f"),
("1:bb:c:dd:e:ff", "01:bb:0c:dd:0e:ff"),
]
)
func bssidFormattingAddsLeadingZeros(input: String, expected: String) async throws {
#expect(input.formattedBSSID == expected, "BSSID \(input) should be formatted as \(expected)")
}
@Test(
"Given BSSID with all two-digit hex values when formatted then remains unchanged",
arguments: [
"18:e8:29:a7:e9:0b",
"ff:ee:dd:cc:bb:aa",
"aa:bb:cc:dd:ee:ff",
"12:34:56:78:9a:bc",
]
)
func bssidFormattingPreservesFullValues(input: String) async throws {
#expect(input.formattedBSSID == input, "BSSID \(input) should remain unchanged")
}
@Test(
"Given invalid MAC address formats when formatted then returns unchanged",
arguments: [
"not-a-mac",
"18:e8:29:a7:e9", // Too few octets
"18:e8:29:a7:e9:0b:aa", // Too many octets
"", // Empty string
"invalid:format:here",
]
)
func bssidFormattingHandlesInvalidFormats(input: String) async throws {
#expect(
input.formattedBSSID == input,
"Invalid MAC address \(input) should be returned unchanged"
)
}
@Test("Given uppercase BSSID when formatted then preserves case")
func bssidFormattingPreservesCase() async throws {
let uppercase = "AA:BB:CC:DD:EE:F"
let expectedUppercase = "AA:BB:CC:DD:EE:0F"
#expect(
uppercase.formattedBSSID == expectedUppercase,
"Uppercase BSSID should be formatted with preserved case"
)
let lowercase = "aa:bb:cc:dd:ee:f"
let expectedLowercase = "aa:bb:cc:dd:ee:0f"
#expect(
lowercase.formattedBSSID == expectedLowercase,
"Lowercase BSSID should be formatted with preserved case"
)
let mixed = "aA:bB:cC:dD:eE:Ff"
let expectedMixed = "aA:bB:cC:dD:eE:Ff"
#expect(mixed.formattedBSSID == expectedMixed, "Mixed case BSSID should be formatted with preserved case")
}
}