Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.

Commit 4e30b1e

Browse files
Merge branch 'main' into joseph/computed-name
2 parents 97722a6 + 7c3c6ae commit 4e30b1e

37 files changed

+1107
-2925
lines changed

.github/workflows/ci.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@ permissions:
1919
jobs:
2020
lint:
2121
name: Run Lint
22-
uses: codecov/gha-workflows/.github/workflows/[email protected].23
22+
uses: codecov/gha-workflows/.github/workflows/[email protected].24
2323

2424
build:
2525
name: Build API
26-
uses: codecov/gha-workflows/.github/workflows/[email protected].23
26+
uses: codecov/gha-workflows/.github/workflows/[email protected].24
2727
secrets: inherit
2828
with:
2929
repo: ${{ vars.CODECOV_IMAGE_V2 || 'codecov/self-hosted-api' }}
3030

3131
codecovstartup:
3232
name: Codecov Startup
3333
needs: build
34-
uses: codecov/gha-workflows/.github/workflows/[email protected].23
34+
uses: codecov/gha-workflows/.github/workflows/[email protected].24
3535
secrets: inherit
3636

3737
# ats:
@@ -47,15 +47,15 @@ jobs:
4747
test:
4848
name: Test
4949
needs: [build]
50-
uses: codecov/gha-workflows/.github/workflows/[email protected].23
50+
uses: codecov/gha-workflows/.github/workflows/[email protected].24
5151
secrets: inherit
5252
with:
5353
repo: ${{ vars.CODECOV_IMAGE_V2 || 'codecov/self-hosted-api' }}
5454

5555
build-self-hosted:
5656
name: Build Self Hosted API
5757
needs: [build, test]
58-
uses: codecov/gha-workflows/.github/workflows/[email protected].23
58+
uses: codecov/gha-workflows/.github/workflows/[email protected].24
5959
secrets: inherit
6060
with:
6161
repo: ${{ vars.CODECOV_IMAGE_V2 || 'codecov/self-hosted-api' }}
@@ -64,7 +64,7 @@ jobs:
6464
name: Push Staging Image
6565
needs: [build, test]
6666
if: ${{ github.event_name == 'push' && github.event.ref == 'refs/heads/staging' && github.repository_owner == 'codecov' }}
67-
uses: codecov/gha-workflows/.github/workflows/[email protected].23
67+
uses: codecov/gha-workflows/.github/workflows/[email protected].24
6868
secrets: inherit
6969
with:
7070
environment: staging
@@ -74,7 +74,7 @@ jobs:
7474
name: Push Production Image
7575
needs: [build, test]
7676
if: ${{ github.event_name == 'push' && github.event.ref == 'refs/heads/main' && github.repository_owner == 'codecov' }}
77-
uses: codecov/gha-workflows/.github/workflows/[email protected].23
77+
uses: codecov/gha-workflows/.github/workflows/[email protected].24
7878
secrets: inherit
7979
with:
8080
environment: production
@@ -85,7 +85,7 @@ jobs:
8585
needs: [build-self-hosted, test]
8686
secrets: inherit
8787
if: ${{ github.event_name == 'push' && github.event.ref == 'refs/heads/main' && github.repository_owner == 'codecov' }}
88-
uses: codecov/gha-workflows/.github/workflows/[email protected].23
88+
uses: codecov/gha-workflows/.github/workflows/[email protected].24
8989
with:
9090
push_rolling: true
9191
repo: ${{ vars.CODECOV_IMAGE_V2 || 'codecov/self-hosted-api' }}

api/public/v2/owner/views.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class UserSessionViewSet(UserSessionViewSetMixin, mixins.ListModelMixin):
6363
def list(self, request: Request, *args: Any, **kwargs: Any) -> Response:
6464
"""
6565
Returns a paginated list of users' login session for the specified owner (org)
66+
67+
Note: Requires the caller to be an admin of the requested organization
6668
"""
6769
return super().list(request, *args, **kwargs)
6870

codecov_auth/tests/factories.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class Meta:
7777
)
7878
user = factory.SubFactory(UserFactory)
7979
trial_status = TrialStatus.NOT_STARTED.value
80+
upload_token_required_for_public_repos = True
8081

8182

8283
class SentryUserFactory(DjangoModelFactory):

graphql_api/tests/test_account.py

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,246 @@ def test_fetch_activated_user_count(self) -> None:
8181
assert "errors" not in result
8282
activatedUserCount = result["owner"]["account"]["activatedUserCount"]
8383
assert activatedUserCount == 7
84+
85+
def test_fetch_organizations(self) -> None:
86+
account = AccountFactory(name="account")
87+
owner = OwnerFactory(
88+
username="owner-0",
89+
plan_activated_users=[],
90+
account=account,
91+
)
92+
OwnerFactory(
93+
username="owner-1",
94+
plan_activated_users=[0],
95+
account=account,
96+
)
97+
OwnerFactory(
98+
username="owner-2",
99+
plan_activated_users=[0, 1],
100+
account=account,
101+
)
102+
103+
query = """
104+
query {
105+
owner(username: "%s") {
106+
account {
107+
organizations(first: 20) {
108+
edges {
109+
node {
110+
username
111+
activatedUserCount
112+
}
113+
}
114+
}
115+
}
116+
}
117+
}
118+
""" % (owner.username)
119+
120+
result = self.gql_request(query, owner=owner)
121+
122+
assert "errors" not in result
123+
124+
orgs = [
125+
node["node"]["username"]
126+
for node in result["owner"]["account"]["organizations"]["edges"]
127+
]
128+
129+
assert orgs == ["owner-2", "owner-1", "owner-0"]
130+
131+
def test_fetch_organizations_order_by_activated_users_asc(self) -> None:
132+
account = AccountFactory(name="account")
133+
owner = OwnerFactory(
134+
username="owner-0",
135+
plan_activated_users=[],
136+
account=account,
137+
)
138+
OwnerFactory(
139+
username="owner-1",
140+
plan_activated_users=[0],
141+
account=account,
142+
)
143+
OwnerFactory(
144+
username="owner-2",
145+
plan_activated_users=[0, 1],
146+
account=account,
147+
)
148+
149+
query = """
150+
query {
151+
owner(username: "%s") {
152+
account {
153+
organizations(first: 20, ordering: ACTIVATED_USERS, orderingDirection: ASC) {
154+
edges {
155+
node {
156+
username
157+
activatedUserCount
158+
}
159+
}
160+
}
161+
}
162+
}
163+
}
164+
""" % (owner.username)
165+
166+
result = self.gql_request(query, owner=owner)
167+
168+
assert "errors" not in result
169+
170+
orgs = [
171+
node["node"]["username"]
172+
for node in result["owner"]["account"]["organizations"]["edges"]
173+
]
174+
175+
assert orgs == ["owner-0", "owner-1", "owner-2"]
176+
177+
def test_fetch_organizations_order_by_name(self) -> None:
178+
account = AccountFactory(name="account")
179+
owner = OwnerFactory(
180+
username="owner-0",
181+
plan_activated_users=[],
182+
account=account,
183+
)
184+
OwnerFactory(
185+
username="owner-1",
186+
plan_activated_users=[0],
187+
account=account,
188+
)
189+
OwnerFactory(
190+
username="owner-2",
191+
plan_activated_users=[0, 1],
192+
account=account,
193+
)
194+
195+
query = """
196+
query {
197+
owner(username: "%s") {
198+
account {
199+
organizations(first: 20, ordering: NAME) {
200+
edges {
201+
node {
202+
username
203+
activatedUserCount
204+
}
205+
}
206+
}
207+
}
208+
}
209+
}
210+
""" % (owner.username)
211+
212+
result = self.gql_request(query, owner=owner)
213+
214+
assert "errors" not in result
215+
216+
orgs = [
217+
node["node"]["username"]
218+
for node in result["owner"]["account"]["organizations"]["edges"]
219+
]
220+
221+
assert orgs == ["owner-2", "owner-1", "owner-0"]
222+
223+
def test_fetch_organizations_order_by_name_asc(self) -> None:
224+
account = AccountFactory(name="account")
225+
owner = OwnerFactory(
226+
username="owner-0",
227+
plan_activated_users=[],
228+
account=account,
229+
)
230+
OwnerFactory(
231+
username="owner-1",
232+
plan_activated_users=[0],
233+
account=account,
234+
)
235+
OwnerFactory(
236+
username="owner-2",
237+
plan_activated_users=[0, 1],
238+
account=account,
239+
)
240+
241+
query = """
242+
query {
243+
owner(username: "%s") {
244+
account {
245+
organizations(first: 20, ordering: NAME, orderingDirection: ASC) {
246+
edges {
247+
node {
248+
username
249+
activatedUserCount
250+
}
251+
}
252+
}
253+
}
254+
}
255+
}
256+
""" % (owner.username)
257+
258+
result = self.gql_request(query, owner=owner)
259+
260+
assert "errors" not in result
261+
262+
orgs = [
263+
node["node"]["username"]
264+
for node in result["owner"]["account"]["organizations"]["edges"]
265+
]
266+
267+
assert orgs == ["owner-0", "owner-1", "owner-2"]
268+
269+
def test_fetch_organizations_pagination(self) -> None:
270+
account = AccountFactory(name="account")
271+
owner = OwnerFactory(
272+
username="owner-0",
273+
plan_activated_users=[],
274+
account=account,
275+
)
276+
OwnerFactory(
277+
username="owner-1",
278+
plan_activated_users=[0],
279+
account=account,
280+
)
281+
OwnerFactory(
282+
username="owner-2",
283+
plan_activated_users=[0, 1],
284+
account=account,
285+
)
286+
287+
query = """
288+
query {
289+
owner(username: "%s") {
290+
account {
291+
organizations(first: 2) {
292+
edges {
293+
node {
294+
username
295+
activatedUserCount
296+
}
297+
}
298+
totalCount
299+
pageInfo {
300+
hasNextPage
301+
}
302+
}
303+
}
304+
}
305+
}
306+
""" % (owner.username)
307+
308+
result = self.gql_request(query, owner=owner)
309+
310+
assert "errors" not in result
311+
312+
totalCount = result["owner"]["account"]["organizations"]["totalCount"]
313+
314+
assert totalCount == 3
315+
316+
orgs = [
317+
node["node"]["username"]
318+
for node in result["owner"]["account"]["organizations"]["edges"]
319+
]
320+
321+
assert orgs == ["owner-2", "owner-1"]
322+
323+
hasNextPage = result["owner"]["account"]["organizations"]["pageInfo"][
324+
"hasNextPage"
325+
]
326+
assert hasNextPage

0 commit comments

Comments
 (0)