Skip to content

Commit

Permalink
change plan and member urls for gitlab users
Browse files Browse the repository at this point in the history
  • Loading branch information
nora-codecov committed Jan 8, 2025
1 parent 5249894 commit b1ea58a
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 8 deletions.
13 changes: 8 additions & 5 deletions database/models/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import uuid
from datetime import datetime
from functools import cached_property
from typing import Optional

from shared.plan.constants import PlanName
from sqlalchemy import Column, ForeignKey, Index, UniqueConstraint, types
Expand Down Expand Up @@ -154,11 +155,11 @@ class Owner(CodecovBaseModel):
)

@property
def slug(self):
def slug(self: "Owner") -> str:
return self.username

@property
def root_organization(self):
def root_organization(self: "Owner") -> Optional["Owner"]:
"""
Find the root organization of Gitlab OwnerOrg, by using the root_parent_service_id
if it exists, otherwise iterating through the parents and cache it in root_parent_service_id
Expand All @@ -178,17 +179,19 @@ def root_organization(self):
db_session.commit()
return root

def _get_owner_by_service_id(self, db_session, service_id):
def _get_owner_by_service_id(
self: "Owner", db_session: Session, service_id: str
) -> "Owner":
"""
Helper method to fetch an Owner by service_id.
"""
return (
db_session.query(Owner)
.filter_by(service_id=service_id, service=self.service)
.one_or_none()
.one()
)

def __repr__(self):
def __repr__(self: "Owner") -> str:
return f"Owner<{self.ownerid}@service<{self.service}>>"


Expand Down
60 changes: 59 additions & 1 deletion services/tests/test_urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from services.urls import append_tracking_params_to_urls
from database.tests.factories import OwnerFactory, PullFactory, RepositoryFactory
from services.urls import append_tracking_params_to_urls, get_members_url, get_plan_url


def test_append_tracking_params_to_urls():
Expand Down Expand Up @@ -29,3 +30,60 @@ def test_append_tracking_params_to_urls():
]

assert result == expected_result


class TestURLs(object):
def test_gitlab_url_username_swap(self, dbsession):
base_for_member_url = "https://app.codecov.io/members/"
base_for_plan_url = "https://app.codecov.io/plan/"

github_org = OwnerFactory.create(
service="github",
username="gh",
)
dbsession.add(github_org)
r = RepositoryFactory.create(owner=github_org)
dbsession.add(r)
gh_pull = PullFactory.create(repository=r)
dbsession.add(gh_pull)
dbsession.flush()
member_url = get_members_url(gh_pull)
assert member_url == base_for_member_url + "gh/gh"

gitlab_root_org = OwnerFactory.create(service="gitlab", username="gl_root")
dbsession.add(gitlab_root_org)
r = RepositoryFactory.create(owner=gitlab_root_org)
dbsession.add(r)
gl_root_pull = PullFactory.create(repository=r)
dbsession.add(gl_root_pull)
dbsession.flush()
plan_url = get_plan_url(gl_root_pull)
assert plan_url == base_for_plan_url + "gl/gl_root"

gitlab_mid_org = OwnerFactory.create(
service="gitlab",
username="gl_mid",
parent_service_id=gitlab_root_org.service_id,
)
dbsession.add(gitlab_mid_org)
r = RepositoryFactory.create(owner=gitlab_mid_org)
dbsession.add(r)
gl_mid_pull = PullFactory.create(repository=r)
dbsession.add(gl_mid_pull)
dbsession.flush()
member_url = get_members_url(gl_mid_pull)
assert member_url == base_for_member_url + "gl/gl_root"

gitlab_sub_org = OwnerFactory.create(
service="gitlab",
username="gl_child",
parent_service_id=gitlab_mid_org.service_id,
)
dbsession.add(gitlab_sub_org)
r = RepositoryFactory.create(owner=gitlab_sub_org)
dbsession.add(r)
gl_child_pull = PullFactory.create(repository=r)
dbsession.add(gl_child_pull)
dbsession.flush()
plan_url = get_plan_url(gl_child_pull)
assert plan_url == base_for_plan_url + "gl/gl_root"
17 changes: 15 additions & 2 deletions services/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from urllib.parse import parse_qs, quote_plus, urlencode, urlparse, urlunparse

from shared.config import get_config
from shared.django_apps.codecov_auth.models import Service

from database.models import Commit, Pull, Repository
from services.license import requires_license
Expand Down Expand Up @@ -57,6 +58,16 @@ def get_dashboard_base_url() -> str:
return configured_dashboard_url or "https://app.codecov.io"


def _get_username_for_url(repository: Repository) -> str:
username = repository.owner.username
if repository.owner.service == Service.GITLAB.value:
# if GL, direct url to root org not subgroup
root_org = repository.owner.root_organization
if root_org is not None:
username = root_org.username
return username


def get_commit_url(commit: Commit) -> str:
return SiteUrls.commit_url.get_url(
base_url=get_dashboard_base_url(),
Expand Down Expand Up @@ -162,11 +173,12 @@ def get_org_account_url(pull: Pull) -> str:

def get_members_url(pull: Pull) -> str:
repository = pull.repository
username = _get_username_for_url(repository=repository)
if not requires_license():
return SiteUrls.members_url.get_url(
dashboard_base_url=get_dashboard_base_url(),
service_short=services_short_dict.get(repository.service),
username=repository.owner.username,
username=username,
)
else:
return SiteUrls.members_url_self_hosted.get_url(
Expand All @@ -178,10 +190,11 @@ def get_members_url(pull: Pull) -> str:

def get_plan_url(pull: Pull) -> str:
repository = pull.repository
username = _get_username_for_url(repository=repository)
return SiteUrls.plan_url.get_url(
dashboard_base_url=get_dashboard_base_url(),
service_short=services_short_dict.get(repository.service),
username=repository.owner.username,
username=username,
)


Expand Down

0 comments on commit b1ea58a

Please sign in to comment.