-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add update self hosted settings mutation #559
Merged
rohitvinnakota-codecov
merged 20 commits into
main
from
rvinnakota/migrate-self-hosted-settings
May 22, 2024
Merged
Changes from 16 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
4e5fb27
Add self hosted settings gql type
rohitvinnakota-codecov 76f43c5
lint
rohitvinnakota-codecov 50f1360
Update typing
rohitvinnakota-codecov 10d60dc
fix functions
rohitvinnakota-codecov 2fa6dff
Update mutation
rohitvinnakota-codecov 39b7d40
reformat
rohitvinnakota-codecov ddd198b
Update owner command
rohitvinnakota-codecov ea626a5
remove type
rohitvinnakota-codecov 99b7c62
Merge branch 'main' of https://github.com/codecov/codecov-api into rv…
rohitvinnakota-codecov 0df31b6
add tests WIP
rohitvinnakota-codecov 35f201b
remove char
rohitvinnakota-codecov 876b260
lint
rohitvinnakota-codecov cf0f4fd
fix tests
rohitvinnakota-codecov fe6dadd
fix input
rohitvinnakota-codecov 2778622
fix
rohitvinnakota-codecov aef9ff5
remove comment
rohitvinnakota-codecov 6b20f1b
Merge branch 'main' into rvinnakota/migrate-self-hosted-settings
rohitvinnakota-codecov 08d6b30
fix sort
rohitvinnakota-codecov 9bc2f69
fix
rohitvinnakota-codecov 99c3b08
Merge branch 'main' into rvinnakota/migrate-self-hosted-settings
rohitvinnakota-codecov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
61 changes: 61 additions & 0 deletions
61
codecov_auth/commands/owner/interactors/tests/test_update_self_hosted_settings.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
from unittest.mock import patch | ||
|
||
import pytest | ||
from asgiref.sync import async_to_sync | ||
from django.contrib.auth.models import AnonymousUser | ||
from django.test import TransactionTestCase, override_settings | ||
|
||
from codecov.commands.exceptions import Unauthenticated, ValidationError | ||
from codecov_auth.commands.owner.interactors.update_self_hosted_settings import ( | ||
UpdateSelfHostedSettingsInteractor, | ||
) | ||
from codecov_auth.tests.factories import OwnerFactory | ||
|
||
|
||
class UpdateSelfHostedSettingsInteractorTest(TransactionTestCase): | ||
@async_to_sync | ||
def execute( | ||
self, | ||
current_user, | ||
input={ | ||
"shouldAutoActivate": None, | ||
}, | ||
): | ||
return UpdateSelfHostedSettingsInteractor(None, "github", current_user).execute( | ||
input=input, | ||
) | ||
|
||
@override_settings(IS_ENTERPRISE=True) | ||
def test_update_self_hosted_settings_when_auto_activate_is_true(self): | ||
owner = OwnerFactory(plan_auto_activate=False) | ||
self.execute(current_user=owner, input={"shouldAutoActivate": True}) | ||
owner.refresh_from_db() | ||
assert owner.plan_auto_activate == True | ||
|
||
@override_settings(IS_ENTERPRISE=True) | ||
def test_update_self_hosted_settings_when_auto_activate_is_false(self): | ||
owner = OwnerFactory(plan_auto_activate=True) | ||
self.execute(current_user=owner, input={"shouldAutoActivate": False}) | ||
owner.refresh_from_db() | ||
assert owner.plan_auto_activate == False | ||
|
||
@override_settings(IS_ENTERPRISE=False) | ||
def test_validation_error_when_not_self_hosted_instance(self): | ||
owner = OwnerFactory(plan_auto_activate=True) | ||
with pytest.raises(ValidationError): | ||
self.execute( | ||
current_user=owner, | ||
input={ | ||
"shouldAutoActivate": False, | ||
}, | ||
) | ||
|
||
@override_settings(IS_ENTERPRISE=True) | ||
def test_user_is_not_authenticated(self): | ||
with pytest.raises(Unauthenticated) as e: | ||
self.execute( | ||
current_user=AnonymousUser(), | ||
input={ | ||
"shouldAutoActivate": False, | ||
}, | ||
) |
38 changes: 38 additions & 0 deletions
38
codecov_auth/commands/owner/interactors/update_self_hosted_settings.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
from dataclasses import dataclass | ||
|
||
from django.conf import settings | ||
|
||
import services.self_hosted as self_hosted | ||
from codecov.commands.base import BaseInteractor | ||
from codecov.commands.exceptions import Unauthenticated, ValidationError | ||
from codecov.db import sync_to_async | ||
from services.refresh import RefreshService | ||
|
||
|
||
@dataclass | ||
class UpdateSelfHostedSettingsInput: | ||
auto_activate_members: bool = False | ||
|
||
|
||
class UpdateSelfHostedSettingsInteractor(BaseInteractor): | ||
def validate(self) -> None: | ||
if not self.current_user.is_authenticated: | ||
raise Unauthenticated() | ||
|
||
if not settings.IS_ENTERPRISE: | ||
raise ValidationError( | ||
"enable_autoactivation and disable_autoactivation are only available in self-hosted environments" | ||
) | ||
|
||
@sync_to_async | ||
def execute(self, input: UpdateSelfHostedSettingsInput) -> None: | ||
self.validate() | ||
typed_input = UpdateSelfHostedSettingsInput( | ||
auto_activate_members=input.get("shouldAutoActivate"), | ||
) | ||
|
||
should_auto_activate = typed_input.auto_activate_members | ||
if should_auto_activate: | ||
self_hosted.enable_autoactivation() | ||
else: | ||
self_hosted.disable_autoactivation() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
graphql_api/tests/mutation/test_update_self_hosted_settings.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import pytest | ||
from django.test import TransactionTestCase, override_settings | ||
|
||
from codecov.commands.exceptions import ValidationError | ||
from codecov_auth.tests.factories import OwnerFactory | ||
from graphql_api.tests.helper import GraphQLTestHelper | ||
|
||
query = """ | ||
mutation($input: UpdateSelfHostedSettingsInput!) { | ||
updateSelfHostedSettings(input: $input) { | ||
error { | ||
__typename | ||
... on ResolverError { | ||
message | ||
} | ||
} | ||
} | ||
} | ||
""" | ||
|
||
|
||
class UpdateSelfHostedSettingsTest(GraphQLTestHelper, TransactionTestCase): | ||
def _request(self, owner=None): | ||
return self.gql_request( | ||
query, | ||
variables={"input": {"shouldAutoActivate": True}}, | ||
owner=owner, | ||
) | ||
|
||
def _request_deactivate(self, owner=None): | ||
return self.gql_request( | ||
query, | ||
variables={"input": {"shouldAutoActivate": False}}, | ||
owner=owner, | ||
) | ||
|
||
@override_settings(IS_ENTERPRISE=True) | ||
def test_unauthenticated(self): | ||
assert self._request() == { | ||
"updateSelfHostedSettings": { | ||
"error": { | ||
"__typename": "UnauthenticatedError", | ||
"message": "You are not authenticated", | ||
} | ||
} | ||
} | ||
|
||
@override_settings(IS_ENTERPRISE=True) | ||
def test_authenticated_enable_autoactivation(self): | ||
owner = OwnerFactory() | ||
assert self._request(owner=owner) == {"updateSelfHostedSettings": None} | ||
|
||
@override_settings(IS_ENTERPRISE=True) | ||
def test_authenticate_disable_autoactivation(self): | ||
owner = OwnerFactory() | ||
assert self._request_deactivate(owner=owner) == { | ||
"updateSelfHostedSettings": None | ||
} | ||
|
||
@override_settings(IS_ENTERPRISE=False) | ||
def test_invalid_settings(self): | ||
owner = OwnerFactory() | ||
assert self._request(owner=owner) == { | ||
"updateSelfHostedSettings": { | ||
"error": { | ||
"__typename": "ValidationError", | ||
"message": "enable_autoactivation and disable_autoactivation are only available in self-hosted environments", | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
graphql_api/types/mutation/update_self_hosted_settings/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from graphql_api.helpers.ariadne import ariadne_load_local_graphql | ||
|
||
from .update_self_hosted_settings import ( | ||
error_update_self_hosted_settings, | ||
resolve_update_self_hosted_settings, | ||
) | ||
|
||
gql_update_self_hosted_settings = ariadne_load_local_graphql( | ||
__file__, "update_self_hosted_settings.graphql" | ||
) |
9 changes: 9 additions & 0 deletions
9
graphql_api/types/mutation/update_self_hosted_settings/update_self_hosted_settings.graphql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
union UpdateSelfHostedSettingsError = UnauthenticatedError | ValidationError | ||
|
||
type UpdateSelfHostedSettingsPayload { | ||
error: UpdateSelfHostedSettingsError | ||
} | ||
|
||
input UpdateSelfHostedSettingsInput { | ||
shouldAutoActivate: Boolean! | ||
} |
19 changes: 19 additions & 0 deletions
19
graphql_api/types/mutation/update_self_hosted_settings/update_self_hosted_settings.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from ariadne import UnionType | ||
|
||
from codecov_auth.commands.owner import OwnerCommands | ||
from graphql_api.helpers.mutation import ( | ||
require_authenticated, | ||
resolve_union_error_type, | ||
wrap_error_handling_mutation, | ||
) | ||
|
||
|
||
@wrap_error_handling_mutation | ||
@require_authenticated | ||
async def resolve_update_self_hosted_settings(_, info, input): | ||
command: OwnerCommands = info.context["executor"].get_command("owner") | ||
return await command.update_self_hosted_settings(input) | ||
|
||
|
||
error_update_self_hosted_settings = UnionType("UpdateSelfHostedSettingsError") | ||
error_update_self_hosted_settings.type_resolver(resolve_union_error_type) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: enable_auto_activation vs. enable_autoactivation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could see it either way, but because we're camelcasing the input on AutoActivate, it seems more consistent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are what the methods are called in
self_hosted.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooo okay makes sense