Skip to content
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

[ENG-5111] chore: add tests for api views and serializers #5

Merged
merged 2 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addon_service/authorized_storage_account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


class AuthorizedStorageAccount(AddonsServiceBaseModel):
# TODO: capabilities = ArrayField(...)
# TODO: authorized_capabilities = ArrayField(...)
default_root_folder = models.CharField(blank=True)

external_storage_service = models.ForeignKey(
Expand Down
4 changes: 2 additions & 2 deletions addon_service/configured_storage_addon/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
class ConfiguredStorageAddon(AddonsServiceBaseModel):
root_folder = models.CharField()

authorized_storage_account = models.ForeignKey(
base_account = models.ForeignKey(
"addon_service.AuthorizedStorageAccount",
on_delete=models.CASCADE,
related_name="configured_storage_addons",
)
internal_resource = models.ForeignKey(
authorized_resource = models.ForeignKey(
"addon_service.InternalResource",
on_delete=models.CASCADE,
related_name="configured_storage_addons",
Expand Down
15 changes: 8 additions & 7 deletions addon_service/configured_storage_addon/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from rest_framework_json_api.utils import get_resource_type_from_model

from addon_service.models import (
AuthorizedStorageAccount,
ConfiguredStorageAddon,
InternalResource,
)
Expand All @@ -13,29 +14,29 @@

class ConfiguredStorageAddonSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name=f"{RESOURCE_NAME}-detail")
authorized_storage_account = ResourceRelatedField(
queryset=ConfiguredStorageAddon.objects.all(),
base_account = ResourceRelatedField(
queryset=AuthorizedStorageAccount.objects.all(),
many=False,
related_link_view_name=f"{RESOURCE_NAME}-related",
)
internal_resource = ResourceRelatedField(
authorized_resource = ResourceRelatedField(
queryset=InternalResource.objects.all(),
many=False,
related_link_view_name=f"{RESOURCE_NAME}-related",
)

included_serializers = {
"authorized_storage_account": (
"base_account": (
"addon_service.serializers.AuthorizedStorageAccountSerializer"
),
"internal_resource": "addon_service.serializers.InternalResourceSerializer",
"authorized_resource": "addon_service.serializers.InternalResourceSerializer",
}

class Meta:
model = ConfiguredStorageAddon
fields = [
"url",
"root_folder",
"authorized_storage_account",
"internal_resource",
"base_account",
"authorized_resource",
]
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


# TODO: consider another name
class ExternalService(AddonsServiceBaseModel):
class CredentialsIssuer(AddonsServiceBaseModel):
name = models.CharField(null=False)

class Meta:
Expand Down
4 changes: 2 additions & 2 deletions addon_service/external_account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ class ExternalAccount(AddonsServiceBaseModel):
remote_account_id = models.CharField()
remote_account_display_name = models.CharField()

external_service = models.ForeignKey(
"addon_service.ExternalService",
credentials_issuer = models.ForeignKey(
"addon_service.CredentialsIssuer",
on_delete=models.CASCADE,
related_name="external_accounts",
)
Expand Down
4 changes: 2 additions & 2 deletions addon_service/external_storage_service/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ class ExternalStorageService(AddonsServiceBaseModel):

auth_uri = models.URLField(null=False)

external_service = models.ForeignKey(
"addon_service.ExternalService",
credentials_issuer = models.ForeignKey(
"addon_service.CredentialsIssuer",
on_delete=models.CASCADE,
related_name="external_storage_services",
)
Expand Down
1 change: 0 additions & 1 deletion addon_service/internal_resource/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class InternalResourceSerializer(serializers.HyperlinkedModelSerializer):
queryset=ConfiguredStorageAddon.objects.all(),
related_link_view_name=f"{RESOURCE_NAME}-related",
)

included_serializers = {
"configured_storage_addons": (
"addon_service.serializers.ConfiguredStorageAddonSerializer"
Expand Down
4 changes: 2 additions & 2 deletions addon_service/internal_resource/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from rest_framework_json_api.views import ModelViewSet
from rest_framework_json_api.views import ReadOnlyModelViewSet

from .models import InternalResource
from .serializers import InternalResourceSerializer


class InternalResourceViewSet(ModelViewSet): # TODO: read-only
class InternalResourceViewSet(ReadOnlyModelViewSet):
queryset = InternalResource.objects.all()
serializer_class = InternalResourceSerializer
# TODO: permissions_classes
4 changes: 2 additions & 2 deletions addon_service/internal_user/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from rest_framework_json_api.views import ModelViewSet
from rest_framework_json_api.views import ReadOnlyModelViewSet

from .models import InternalUser
from .serializers import InternalUserSerializer


class InternalUserViewSet(ModelViewSet): # TODO: read-only
class InternalUserViewSet(ReadOnlyModelViewSet):
queryset = InternalUser.objects.all()
serializer_class = InternalUserSerializer
# TODO: permissions_classes
10 changes: 5 additions & 5 deletions addon_service/management/commands/fill_garbage.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ class Command(LabelCommand):
def handle_label(self, label, **options):
if not settings.DEBUG:
raise Exception("must have DEBUG set to eat garbage")
_es = db.ExternalService.objects.create(name=f"entity-{label}")
_ci = db.CredentialsIssuer.objects.create(name=f"entity-{label}")
_ess = db.ExternalStorageService.objects.create(
max_concurrent_downloads=2,
max_upload_mb=2,
auth_uri=f"http://foo.example/{label}",
external_service=_es,
credentials_issuer=_ci,
)
for _i in range(3):
_iu, _ = db.InternalUser.objects.get_or_create(
Expand All @@ -28,7 +28,7 @@ def handle_label(self, label, **options):
_ea = db.ExternalAccount.objects.create(
remote_account_id=label,
remote_account_display_name=label,
external_service=_es,
credentials_issuer=_ci,
owner=_iu,
credentials=_ec,
)
Expand All @@ -41,7 +41,7 @@ def handle_label(self, label, **options):
resource_uri=f"http://osf.example/r{label}{_j}",
)
_csa = db.ConfiguredStorageAddon.objects.create(
authorized_storage_account=_asa,
internal_resource=_ir,
base_account=_asa,
authorized_resource=_ir,
)
return str(_csa)
45 changes: 26 additions & 19 deletions addon_service/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 4.2.7 on 2023-11-28 19:41
# Generated by Django 4.2.7 on 2023-12-11 20:02

import django.db.models.deletion
from django.db import (
Expand Down Expand Up @@ -35,7 +35,7 @@ class Migration(migrations.Migration):
},
),
migrations.CreateModel(
name="ExternalCredentials",
name="CredentialsIssuer",
fields=[
(
"id",
Expand All @@ -48,19 +48,15 @@ class Migration(migrations.Migration):
),
("created", models.DateTimeField(editable=False)),
("modified", models.DateTimeField()),
("oauth_key", models.CharField(blank=True, null=True)),
("oauth_secret", models.CharField(blank=True, null=True)),
("refresh_token", models.CharField(blank=True, null=True)),
("date_last_refreshed", models.DateTimeField(blank=True, null=True)),
("expires_at", models.DateTimeField(blank=True, null=True)),
("name", models.CharField()),
],
options={
"verbose_name": "External Credentials",
"verbose_name_plural": "External Credentials",
"verbose_name": "External Service",
"verbose_name_plural": "External Services",
},
),
migrations.CreateModel(
name="ExternalService",
name="ExternalCredentials",
fields=[
(
"id",
Expand All @@ -73,11 +69,15 @@ class Migration(migrations.Migration):
),
("created", models.DateTimeField(editable=False)),
("modified", models.DateTimeField()),
("name", models.CharField()),
("oauth_key", models.CharField(blank=True, null=True)),
("oauth_secret", models.CharField(blank=True, null=True)),
("refresh_token", models.CharField(blank=True, null=True)),
("date_last_refreshed", models.DateTimeField(blank=True, null=True)),
("expires_at", models.DateTimeField(blank=True, null=True)),
],
options={
"verbose_name": "External Service",
"verbose_name_plural": "External Services",
"verbose_name": "External Credentials",
"verbose_name_plural": "External Credentials",
},
),
migrations.CreateModel(
Expand Down Expand Up @@ -140,10 +140,11 @@ class Migration(migrations.Migration):
("max_upload_mb", models.IntegerField()),
("auth_uri", models.URLField()),
(
"external_service",
"credentials_issuer",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="addon_service.externalservice",
related_name="external_storage_services",
to="addon_service.credentialsissuer",
),
),
],
Expand Down Expand Up @@ -172,20 +173,23 @@ class Migration(migrations.Migration):
"credentials",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="external_accounts",
to="addon_service.externalcredentials",
),
),
(
"external_service",
"credentials_issuer",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="addon_service.externalservice",
related_name="external_accounts",
to="addon_service.credentialsissuer",
),
),
(
"owner",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="external_accounts",
to="addon_service.internaluser",
),
),
Expand All @@ -211,14 +215,15 @@ class Migration(migrations.Migration):
("modified", models.DateTimeField()),
("root_folder", models.CharField()),
(
"authorized_storage_account",
"base_account",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="configured_storage_addons",
to="addon_service.authorizedstorageaccount",
),
),
(
"internal_resource",
"authorized_resource",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="configured_storage_addons",
Expand All @@ -236,6 +241,7 @@ class Migration(migrations.Migration):
name="external_account",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="authorized_storage_accounts",
to="addon_service.externalaccount",
),
),
Expand All @@ -244,6 +250,7 @@ class Migration(migrations.Migration):
name="external_storage_service",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="authorized_storage_accounts",
to="addon_service.externalstorageservice",
),
),
Expand Down
4 changes: 2 additions & 2 deletions addon_service/models.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
""" Import models here so they auto-detect for makemigrations """
from addon_service.authorized_storage_account.models import AuthorizedStorageAccount
from addon_service.configured_storage_addon.models import ConfiguredStorageAddon
from addon_service.credentials_issuer.models import CredentialsIssuer
from addon_service.external_account.models import ExternalAccount
from addon_service.external_credentials.models import ExternalCredentials
from addon_service.external_service.models import ExternalService
from addon_service.external_storage_service.models import ExternalStorageService
from addon_service.internal_resource.models import InternalResource
from addon_service.internal_user.models import InternalUser
Expand All @@ -14,9 +14,9 @@
# 'AuthorizedComputeAccount',
"ConfiguredStorageAddon",
# 'ConfiguredComputeAddon',
"CredentialsIssuer",
"ExternalAccount",
"ExternalCredentials",
"ExternalService",
"ExternalStorageService",
# 'ExternalComputeService',
"InternalResource",
Expand Down
74 changes: 74 additions & 0 deletions addon_service/tests/_factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import factory
from factory.django import DjangoModelFactory

from addon_service import models as db


class InternalUserFactory(DjangoModelFactory):
class Meta:
model = db.InternalUser

user_uri = factory.Sequence(lambda n: f"http://osf.example/user{n}")


class InternalResourceFactory(DjangoModelFactory):
class Meta:
model = db.InternalResource

resource_uri = factory.Sequence(lambda n: f"http://osf.example/thing{n}")


class CredentialsIssuerFactory(DjangoModelFactory):
class Meta:
model = db.CredentialsIssuer


class ExternalCredentialsFactory(DjangoModelFactory):
class Meta:
model = db.ExternalCredentials


class ExternalAccountFactory(DjangoModelFactory):
class Meta:
model = db.ExternalAccount

remote_account_id = factory.Faker("word")
remote_account_display_name = factory.Faker("word")

credentials_issuer = factory.SubFactory(CredentialsIssuerFactory)
owner = factory.SubFactory(InternalUserFactory)
credentials = factory.SubFactory(ExternalCredentialsFactory)


###
# "Storage" models


class ExternalStorageServiceFactory(DjangoModelFactory):
class Meta:
model = db.ExternalStorageService

max_concurrent_downloads = factory.Faker("pyint")
max_upload_mb = factory.Faker("pyint")
auth_uri = factory.Sequence(lambda n: f"http://auth.example/{n}")
credentials_issuer = factory.SubFactory(CredentialsIssuerFactory)


class AuthorizedStorageAccountFactory(DjangoModelFactory):
class Meta:
model = db.AuthorizedStorageAccount

default_root_folder = "/"
external_storage_service = factory.SubFactory(ExternalStorageServiceFactory)
external_account = factory.SubFactory(ExternalAccountFactory)
# TODO: external_account.credentials_issuer same as
# external_storage_service.credentials_issuer


class ConfiguredStorageAddonFactory(DjangoModelFactory):
class Meta:
model = db.ConfiguredStorageAddon

root_folder = "/"
base_account = factory.SubFactory(AuthorizedStorageAccountFactory)
authorized_resource = factory.SubFactory(InternalResourceFactory)
Loading