Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/Ilhasoft/rapidpro-apps into…
Browse files Browse the repository at this point in the history
… fix/update-django-urls-to-re_path
  • Loading branch information
paulobernardoaf committed Nov 17, 2022
2 parents 5190b37 + 7beec69 commit d255de3
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 5 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
## [Unreleased]

## [1.0.32] - 2022-11-17
- Feat: Use internal_tickter false on TemplateOrg creation

## [1.0.31] - 2022-11-08
- Fix: fix org is_suspend endpoint

## [1.0.30] - 2022-11-07
- Feat: A endpoint to add a warning message to user showing org will be suspeded.
- Feat: A endpoint to suspend a org

## [1.0.29] - 2022-10-20
- Fix: Set Channel Stats start date to 01/01/2000

## [1.0.28] - 2022-10-07
- Update weni-protobuffers to 1.2.18

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "weni-rp-apps"
version = "1.0.28"
version = "1.0.32"
description = "Weni apps for Rapidpro Platform"
authors = ["jcbalmeida"]
license = "AGPL-3.0"
Expand Down
5 changes: 2 additions & 3 deletions weni/channel_stats/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from datetime import timedelta
from datetime import timedelta, datetime

from dateutil.relativedelta import relativedelta
from django.db.models import Sum
from django.utils import timezone
from rest_framework import serializers
Expand Down Expand Up @@ -29,7 +28,7 @@ def get_daily_count(self, obj):
channel = obj

end_date = (timezone.now() + timedelta(days=1)).date()
start_date = end_date - relativedelta(months=12)
start_date = datetime(2000, 1, 1).date()

message_stats = []
channels = [channel]
Expand Down
2 changes: 1 addition & 1 deletion weni/internal/orgs/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ def create(self, validated_data):
org = super().create(validated_data)

org.administrators.add(validated_data.get("created_by"))
org.initialize(sample_flows=False)
org.initialize(sample_flows=False, internal_ticketer=False)

return org
1 change: 1 addition & 0 deletions weni/orgs_api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = "weni.orgs_api.apps.OrgApiConfig"
11 changes: 11 additions & 0 deletions weni/orgs_api/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.apps import AppConfig


class OrgApiConfig(AppConfig):
name = "weni.orgs_api"

def ready(self):
from .urls import urlpatterns
from ..utils.app_config import update_urlpatterns

update_urlpatterns(urlpatterns)
34 changes: 34 additions & 0 deletions weni/orgs_api/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from datetime import datetime

from django.contrib.auth import get_user_model

from rest_framework import serializers

User = get_user_model()


class FlagOrgSerializer(serializers.Serializer):
date_billing_expired = serializers.DateField(
required=True,
format=r"%Y-%m-%d",
input_formats=[
r"%Y-%m-%d",
],
)
date_org_will_suspend = serializers.DateField(
required=True,
format=r"%Y-%m-%d",
input_formats=[
r"%Y-%m-%d",
],
)

def to_internal_value(self, data):
return {
"date_billing_expired": datetime.strptime(data.get("date_billing_expired"), r"%Y-%m-%d").strftime(
r"%m/%d/%Y"
),
"date_org_will_suspend": datetime.strptime(data.get("date_org_will_suspend"), r"%Y-%m-%d").strftime(
r"%m/%d/%Y"
),
}
123 changes: 123 additions & 0 deletions weni/orgs_api/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import json
from datetime import datetime
from dateutil.relativedelta import relativedelta
from random import randint
from abc import ABC, abstractmethod

from django.template.exceptions import TemplateDoesNotExist
from django.contrib.auth.models import Group
from django.contrib.auth.models import User
from django.utils.http import urlencode
from django.urls import reverse

from temba.orgs.models import Org

from temba.api.models import APIToken
from temba.tests import TembaTest


class TembaRequestMixin(ABC):
def reverse(self, viewname, kwargs=None, query_params=None):
url = reverse(viewname, kwargs=kwargs)

if query_params:
return "%s?%s" % (url, urlencode(query_params))
else:
return url

def request_post(self, uuid, data):
url = reverse(self.get_url_namespace(), kwargs={"uuid": uuid})
token = APIToken.get_or_create(self.org, self.admin, Group.objects.get(name="Administrators"))

return self.client.post(
url, HTTP_AUTHORIZATION=f"Token {token.key}", data=json.dumps(data), content_type="application/json"
)

def request_patch(self, uuid, data):
url = self.reverse(self.get_url_namespace(), kwargs={"uuid": uuid})
token = APIToken.get_or_create(self.org, self.admin, Group.objects.get(name="Administrators"))

return self.client.patch(
url, HTTP_AUTHORIZATION=f"Token {token.key}", data=json.dumps(data), content_type="application/json"
)

@abstractmethod
def get_url_namespace(self):
...


class SuspendOrgTest(TembaTest, TembaRequestMixin):
def setUp(self):
User.objects.create_user(username="testuser", password="123", email="[email protected]")

user = User.objects.get(username="testuser")

Org.objects.create(name="Tembinha", timezone="Africa/Kigali", created_by=user, modified_by=user)

super().setUp()

def test_block_org_without_config(self):
org = Org.objects.get(name="Tembinha")

is_suspended = bool(randint(0, 1))

self.request_patch(uuid=org.uuid, data={"is_suspended": is_suspended})

self.assertEqual(org.is_suspended, False)

org = Org.objects.get(name="Tembinha")

self.assertEqual(org.is_suspended, is_suspended)

def get_url_namespace(self):
return "org-is-suspended"


class FlagOrgTest(TembaTest, TembaRequestMixin):
def setUp(self):
User.objects.create_user(username="testuser", password="123", email="[email protected]")

user = User.objects.get(username="testuser")

Org.objects.create(name="Tembinha", timezone="Africa/Kigali", created_by=user, modified_by=user)

super().setUp()

def test_flag_org(self):
org = Org.objects.get(name="Tembinha")
org.config["another_key"] = "test"
org.save()

now = datetime.now()
next_month = now + relativedelta(months=+1)

data = {
"date_billing_expired": now.strftime(r"%Y-%m-%d"),
"date_org_will_suspend": next_month.strftime(r"%Y-%m-%d"),
}

response = self.request_post(uuid=org.uuid, data=data).json()

new_now = now.strftime(r"%m/%d/%Y")
new_next_month = next_month.strftime(r"%m/%d/%Y")

org = Org.objects.get(name="Tembinha")

self.assertEqual(new_now, response.get("date_billing_expired"))
self.assertEqual(new_next_month, response.get("date_org_will_suspend"))
self.assertEqual(new_now, org.config.get("date_billing_expired"))
self.assertEqual(new_next_month, org.config.get("date_org_will_suspend"))

def test_flag_org_invalid_data(self):
org = Org.objects.get(name="Tembinha")

data = {
"date_billing_expired": "10-11-2022",
"date_org_will_suspend": "10-12-2022",
}

with self.assertRaises(TemplateDoesNotExist):
self.request_post(uuid=org.uuid, data=data).json()

def get_url_namespace(self):
return "org-suspend-flag"
7 changes: 7 additions & 0 deletions weni/orgs_api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from rest_framework import routers
from .views import OrgViewSet

router = routers.DefaultRouter()
router.register(r"org", OrgViewSet, basename="org")

urlpatterns = router.urls
48 changes: 48 additions & 0 deletions weni/orgs_api/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from django.shortcuts import get_object_or_404
from django.http import JsonResponse

from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action

from temba.orgs.models import Org

from .serializers import FlagOrgSerializer


class OrgViewSet(GenericViewSet):
permission = "orgs.org_api"
lookup_field = "uuid"

@action(detail=True, methods=["PATCH"])
def is_suspended(self, request, uuid=None):
org = get_object_or_404(Org, uuid=uuid)

org.is_suspended = bool(request.data.get("is_suspended"))
org.save()

return JsonResponse(dict(is_suspended=org.is_suspended))

@action(detail=True, methods=["POST", "DELETE"])
def suspend_flag(self, request, uuid=None):
org = get_object_or_404(Org, uuid=uuid)

if request.method == "DELETE":
if org.config.get("date_billing_expired"):
org.config.pop("date_billing_expired")

if org.config.get("date_org_will_suspend"):
org.config.pop("date_org_will_suspend")

org.save()

return JsonResponse(data=dict(success=True), status=200)

serializer = FlagOrgSerializer(data=request.data)
serializer.is_valid(raise_exception=True)

for flag_name, date in serializer.data.items():
org.config[flag_name] = date

org.save()

return JsonResponse(data=serializer.data, status=200)

0 comments on commit d255de3

Please sign in to comment.