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

fix: audit and version limits for existing subscriptions #4780

Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Generated by Django 4.2.15 on 2024-10-29 11:11
import logging

from django.apps.registry import Apps
from django.db import migrations
from django.db.backends.base.schema import BaseDatabaseSchemaEditor

from organisations.subscriptions.constants import SubscriptionPlanFamily


def update_limits(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
subscription_model = apps.get_model("organisations", "Subscription")
organisation_subscription_information_cache_model = apps.get_model(
"organisations", "OrganisationSubscriptionInformationCache"
)

all_paid_subscriptions = subscription_model.objects.select_related(
"organisation", "organisation__subscription_information_cache"
).exclude(plan="free")

cache_models_to_update = []

for subscription in all_paid_subscriptions:
subscription_family = SubscriptionPlanFamily.get_by_plan_id(subscription.plan)
if subscription_family != SubscriptionPlanFamily.ENTERPRISE:
# We only want to update Enterprise plans since:
# 1. start up and scale up should only have the defaults
# 2. scale up plans are handled differently (using the VERSIONING_RELEASE_DATE setting) which
# is needed to avoid having to create another plan in chargebee.
continue

if (osic := getattr(subscription.organisation, "subscription_information_cache", None)) is None:
continue

osic.audit_log_visibility_days = osic.feature_history_visibility_days = None
cache_models_to_update.append(osic)

organisation_subscription_information_cache_model.objects.bulk_update(
cache_models_to_update,
fields=["audit_log_visibility_days", "feature_history_visibility_days"]
)


class Migration(migrations.Migration):

dependencies = [
("organisations", "0057_limit_audit_and_version_history"),
]

operations = [
migrations.RunPython(update_limits, reverse_code=migrations.RunPython.noop),
]
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
from django.conf import settings
from django_test_migrations.migrator import Migrator

from organisations.models import OrganisationRole
from organisations.permissions.permissions import (
Expand Down Expand Up @@ -166,3 +167,93 @@ def test_merge_duplicate_permissions_migration(migrator):
assert UserOrganisationPermission.objects.filter(
id=non_duplicate_permission.id
).exists()


def test_update_audit_and_history_limits(migrator: Migrator) -> None:
# Given
old_state = migrator.apply_initial_migration(
("organisations", "0056_create_organisation_breached_grace_period")
)

Organisation = old_state.apps.get_model("organisations", "Organisation")
Subscription = old_state.apps.get_model("organisations", "Subscription")
OrganisationSubscriptionInformationCache = old_state.apps.get_model(
"organisations", "OrganisationSubscriptionInformationCache"
)

# Free Organisation
free_organisation = Organisation.objects.create(name="Free Organisation")
Subscription.objects.create(organisation=free_organisation, plan="free")
OrganisationSubscriptionInformationCache.objects.create(
organisation=free_organisation,
)

# Start up organisation
start_up_organisation = Organisation.objects.create(name="Start up Organisation")
Subscription.objects.create(organisation=start_up_organisation, plan="start-up-v2")
OrganisationSubscriptionInformationCache.objects.create(
organisation=start_up_organisation,
allowed_seats=3,
allowed_30d_api_calls=1_000_000,
)

# Scale up organisation
scale_up_organisation = Organisation.objects.create(name="Scale up Organisation")
Subscription.objects.create(organisation=scale_up_organisation, plan="scale-up-v2")
OrganisationSubscriptionInformationCache.objects.create(
organisation=scale_up_organisation,
allowed_seats=5,
allowed_30d_api_calls=5_000_000,
)

# Enterprise organisation
enterprise_organisation = Organisation.objects.create(name="Enterprise Organisation")
Subscription.objects.create(organisation=enterprise_organisation, plan="enterprise")
OrganisationSubscriptionInformationCache.objects.create(
organisation=enterprise_organisation,
allowed_seats=20,
allowed_30d_api_calls=5_000_000,
)

# Enterprise organisation without OrganisationSubscriptionInformationCache
enterprise_organisation_no_osic = Organisation.objects.create(name="Enterprise Organisation No OSIC")
Subscription.objects.create(organisation=enterprise_organisation_no_osic, plan="enterprise")

# When
new_state = migrator.apply_tested_migration(
("organisations", "0058_update_audit_and_history_limits_in_sub_cache")
)
NewOrganisationSubscriptionInformationCache = new_state.apps.get_model(
"organisations", "OrganisationSubscriptionInformationCache"
)

# Then
migrated_free_osic = NewOrganisationSubscriptionInformationCache.objects.get(
organisation_id=free_organisation.id,
)
assert migrated_free_osic.audit_log_visibility_days == 0
assert migrated_free_osic.feature_history_visibility_days == 7

migrated_start_up_osic = NewOrganisationSubscriptionInformationCache.objects.get(
organisation_id=start_up_organisation.id,
)
assert migrated_start_up_osic.audit_log_visibility_days == 0
assert migrated_start_up_osic.feature_history_visibility_days == 7

# Note that scale up plans are not updated as the logic to grandfather old scale up
# plans is handled by the `VERSIONING_RELEASE_DATE` setting.
migrated_scale_up_osic = NewOrganisationSubscriptionInformationCache.objects.get(
organisation_id=scale_up_organisation.id,
)
assert migrated_scale_up_osic.audit_log_visibility_days == 0
assert migrated_scale_up_osic.feature_history_visibility_days == 7

migrated_enterprise_osic = NewOrganisationSubscriptionInformationCache.objects.get(
organisation_id=enterprise_organisation.id,
)
assert migrated_enterprise_osic.audit_log_visibility_days is None
assert migrated_enterprise_osic.feature_history_visibility_days is None

assert not NewOrganisationSubscriptionInformationCache.objects.filter(
organisation_id=enterprise_organisation_no_osic.id,
).exists()
Loading