Skip to content

Commit f7eaca3

Browse files
committed
feat: Don't show virtual default if desktop default is present
#13 Branch: Profiles-13 Signed-off-by: Gabe Goodhart <ghart@us.ibm.com>
1 parent 0062ba7 commit f7eaca3

2 files changed

Lines changed: 155 additions & 21 deletions

File tree

cforge/profile_utils.py

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ def validate_active_profile_id(cls, active_profile_id: Optional[str], info: Vali
100100
return active_profile_id
101101

102102

103+
def get_default_api_url() -> str:
104+
"""Get the default API URL if not set via a profile
105+
106+
Returns:
107+
URL based on configured settings
108+
"""
109+
return f"http://{get_settings().host}:{get_settings().port}"
110+
111+
103112
def get_profile_store_path() -> Path:
104113
"""Get the path to the profile store file.
105114
@@ -143,27 +152,31 @@ def get_all_profiles() -> List[AuthProfile]:
143152
"""Get all profiles, including the virtual default profile.
144153
145154
Returns:
146-
List of all profiles, including virtual default if no store exists
155+
List of all profiles, including virtual default if no Desktop default exists
147156
"""
148157
profiles = []
149158
if store := load_profile_store():
150159
profiles = list(store.profiles.values())
151160

152-
# Always include the virtual default profile
153-
settings = get_settings()
154-
default_profile = AuthProfile(
155-
id=DEFAULT_PROFILE_ID,
156-
name="Local Default",
157-
email="admin@localhost",
158-
api_url=f"http://{settings.host}:{settings.port}",
159-
is_active=not bool(store and store.active_profile_id),
160-
created_at=datetime.now(),
161-
metadata=ProfileMetadata(
162-
description="Default local development profile",
163-
environment="local",
164-
),
165-
)
166-
profiles.append(default_profile)
161+
# Check if Desktop app has created a default profile
162+
expected_default_url = get_default_api_url()
163+
has_desktop_default = any(p.api_url == expected_default_url and p.metadata and p.metadata.is_internal for p in profiles)
164+
165+
# Only include virtual default if Desktop hasn't created one
166+
if not has_desktop_default:
167+
default_profile = AuthProfile(
168+
id=DEFAULT_PROFILE_ID,
169+
name="Local Default",
170+
email="admin@localhost",
171+
api_url=expected_default_url,
172+
is_active=not bool(store and store.active_profile_id),
173+
created_at=datetime.now(),
174+
metadata=ProfileMetadata(
175+
description="Default local development profile",
176+
environment="local",
177+
),
178+
)
179+
profiles.append(default_profile)
167180

168181
return profiles
169182

@@ -179,13 +192,12 @@ def get_profile(profile_id: str) -> Optional[AuthProfile]:
179192
"""
180193
# Check for virtual default profile
181194
if profile_id == DEFAULT_PROFILE_ID:
182-
settings = get_settings()
183195
store = load_profile_store()
184196
return AuthProfile(
185197
id=DEFAULT_PROFILE_ID,
186198
name="Local Default",
187199
email="admin@localhost",
188-
api_url=f"http://{settings.host}:{settings.port}",
200+
api_url=get_default_api_url(),
189201
is_active=not bool(store and store.active_profile_id),
190202
created_at=datetime.now(),
191203
metadata=ProfileMetadata(
@@ -203,17 +215,26 @@ def get_active_profile() -> Optional[AuthProfile]:
203215
204216
Returns:
205217
AuthProfile if an active profile is set, or the virtual default profile
218+
if no Desktop default exists
206219
"""
207220
if (store := load_profile_store()) and store.active_profile_id:
208221
return store.profiles.get(store.active_profile_id)
209222

210-
# Return virtual default profile if no active profile
211-
settings = get_settings()
223+
# Check if Desktop app has created a default profile
224+
expected_default_url = get_default_api_url()
225+
226+
if store:
227+
for profile in store.profiles.values():
228+
if profile.api_url == expected_default_url and profile.metadata and profile.metadata.is_internal:
229+
# Desktop default exists, return None (no active profile)
230+
return None
231+
232+
# Return virtual default profile if no Desktop default exists
212233
return AuthProfile(
213234
id=DEFAULT_PROFILE_ID,
214235
name="Local Default",
215236
email="admin@localhost",
216-
api_url=f"http://{settings.host}:{settings.port}",
237+
api_url=expected_default_url,
217238
is_active=True,
218239
created_at=datetime.now(),
219240
metadata=ProfileMetadata(

tests/test_profile_utils.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,119 @@ def test_set_active_profile_updates_last_used(self, mock_settings) -> None:
638638
assert updated_store is not None
639639
assert updated_store.profiles["profile-1"].last_used is not None
640640

641+
642+
class TestDesktopDefaultProfile:
643+
"""Tests for Desktop app default profile detection."""
644+
645+
def test_get_all_profiles_with_desktop_default(self, mock_settings) -> None:
646+
"""Test that virtual default is not included when Desktop default exists."""
647+
# Create a Desktop-created default profile
648+
desktop_default = AuthProfile(
649+
id="random-desktop-id",
650+
name="Desktop Default",
651+
email="admin@localhost",
652+
apiUrl=f"http://{mock_settings.host}:{mock_settings.port}",
653+
isActive=True,
654+
createdAt=datetime.now(),
655+
metadata=ProfileMetadata(
656+
description="Desktop default profile",
657+
environment="local",
658+
is_internal=True,
659+
),
660+
)
661+
662+
store = ProfileStore(
663+
profiles={"random-desktop-id": desktop_default},
664+
activeProfileId="random-desktop-id",
665+
)
666+
save_profile_store(store)
667+
668+
profiles = get_all_profiles()
669+
670+
# Should only have the Desktop default, not the virtual default
671+
assert len(profiles) == 1
672+
assert profiles[0].id == "random-desktop-id"
673+
assert profiles[0].metadata.is_internal is True
674+
assert not any(p.id == DEFAULT_PROFILE_ID for p in profiles)
675+
676+
def test_get_all_profiles_without_desktop_default(self, mock_settings) -> None:
677+
"""Test that virtual default is included when no Desktop default exists."""
678+
# Create a non-default profile
679+
profile = AuthProfile(
680+
id="profile-1",
681+
name="Custom Profile",
682+
email="user@example.com",
683+
apiUrl="https://api.example.com",
684+
isActive=True,
685+
createdAt=datetime.now(),
686+
)
687+
688+
store = ProfileStore(
689+
profiles={"profile-1": profile},
690+
activeProfileId="profile-1",
691+
)
692+
save_profile_store(store)
693+
694+
profiles = get_all_profiles()
695+
696+
# Should have both the custom profile and virtual default
697+
assert len(profiles) == 2
698+
assert any(p.id == "profile-1" for p in profiles)
699+
assert any(p.id == DEFAULT_PROFILE_ID for p in profiles)
700+
701+
def test_get_active_profile_with_desktop_default_inactive(self, mock_settings) -> None:
702+
"""Test that None is returned when Desktop default exists but is not active."""
703+
# Create a Desktop-created default profile that is NOT active
704+
desktop_default = AuthProfile(
705+
id="random-desktop-id",
706+
name="Desktop Default",
707+
email="admin@localhost",
708+
apiUrl=f"http://{mock_settings.host}:{mock_settings.port}",
709+
isActive=False,
710+
createdAt=datetime.now(),
711+
metadata=ProfileMetadata(
712+
description="Desktop default profile",
713+
environment="local",
714+
is_internal=True,
715+
),
716+
)
717+
718+
store = ProfileStore(
719+
profiles={"random-desktop-id": desktop_default},
720+
activeProfileId=None,
721+
)
722+
save_profile_store(store)
723+
724+
result = get_active_profile()
725+
726+
# Should return None because Desktop default exists (even if not active)
727+
assert result is None
728+
729+
def test_get_active_profile_without_desktop_default(self, mock_settings) -> None:
730+
"""Test that virtual default is returned when no Desktop default exists."""
731+
# Create a non-default profile that is NOT active
732+
profile = AuthProfile(
733+
id="profile-1",
734+
name="Custom Profile",
735+
email="user@example.com",
736+
apiUrl="https://api.example.com",
737+
isActive=False,
738+
createdAt=datetime.now(),
739+
)
740+
741+
store = ProfileStore(
742+
profiles={"profile-1": profile},
743+
activeProfileId=None,
744+
)
745+
save_profile_store(store)
746+
747+
result = get_active_profile()
748+
749+
# Should return virtual default
750+
assert result is not None
751+
assert result.id == DEFAULT_PROFILE_ID
752+
assert result.name == "Local Default"
753+
641754
def test_set_active_profile_default_no_store(self, mock_settings) -> None:
642755
"""Test setting active profile to the default with no store passes"""
643756
result = set_active_profile(DEFAULT_PROFILE_ID)

0 commit comments

Comments
 (0)