Skip to content

Commit

Permalink
Merge pull request #5 from CenterForOpenScience/feature/tests
Browse files Browse the repository at this point in the history
[ENG-5111] chore: add tests for api views and serializers
  • Loading branch information
aaxelb authored Jan 22, 2024
2 parents 3d0ee82 + bceae6b commit cbb2fad
Show file tree
Hide file tree
Showing 25 changed files with 1,017 additions and 117 deletions.
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",
]
File renamed without changes.
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

0 comments on commit cbb2fad

Please sign in to comment.