Skip to content

Commit

Permalink
feat: Creates tests for the example app - Redo (#59)
Browse files Browse the repository at this point in the history
* redoing example tests

* checked format

* added a line in changelog and added test to makefile

* Revert "added a line in changelog and added test to makefile"

This reverts commit 2fc7cf0.

* added to changelog

* added example test to makefile

* added a new makefile in example directory

* Revert "added a new makefile in example directory"

This reverts commit 44d6bf1.

* added makefiles

* added install requirements to makefile
  • Loading branch information
hmanalai authored Jun 7, 2021
1 parent 70a263d commit 4afd64d
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 11 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ and this project adheres to [Semantic
Versioning](https://semver.org/spec/v2.0.0.html).

# [unreleased] - YYYY-MM-DD
### Added
- [PR 59](https://github.com/salesforce/django-declarative-apis/pull/59) Add test cases for example app's model and responses

### Fixed
- [PR 55](https://github.com/salesforce/django-declarative-apis/pull/55) Backwards compatibility fix for field expansion headers, update example app

Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ readme:

# Test targets

test-all: coverage vuln-static formatcheck
test-all: coverage vuln-static formatcheck subsystem
.PHONY: test-all

test:
Expand All @@ -60,3 +60,6 @@ vuln-static:
formatcheck:
${FORMATCHECK_CMD}
.PHONY: formatcheck

subsystem:
$(MAKE) -C example
12 changes: 12 additions & 0 deletions example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
COVERAGE_CMD = coverage run manage.py test --noinput && coverage xml && coverage report

install:
pip install -r requirements.txt
.PHONY: install

example-tests: coverage
.PHONY: example-tests

coverage:
${COVERAGE_CMD}
.PHONY: coverage
36 changes: 36 additions & 0 deletions example/myapp/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Generated by Django 2.2.23 on 2021-06-03 13:22

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [("django_declarative_apis", "0002_add_consumer_type_field")]

operations = [
migrations.CreateModel(
name="User",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=50)),
(
"consumer",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="django_declarative_apis.OauthConsumer",
),
),
],
)
]
10 changes: 0 additions & 10 deletions example/myapp/tests.py

This file was deleted.

Empty file added example/myapp/tests/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions example/myapp/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.test import TestCase
from django_declarative_apis import models

from myapp.models import User


class ModelsTestCase(TestCase):
def test_create_user(self):
consumer = models.OauthConsumer.objects.create(name="smith")

user = User(consumer=consumer, name="smith")
user.save()

self.assertEqual(user.consumer.content_type_id, consumer.content_type_id)
self.assertEqual(user.consumer.id, consumer.id)
self.assertEqual(user.consumer.key, consumer.key)
self.assertEqual(user.consumer.name, consumer.name)
self.assertEqual(user.consumer.object_id, consumer.object_id)
self.assertEqual(user.consumer.secret, consumer.secret)
self.assertEqual(user.consumer.type, consumer.type)
self.assertEqual(user.name, "smith")
20 changes: 20 additions & 0 deletions example/myapp/tests/test_responses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import http

from django.test import TestCase
from .testutils import OAuthClient
from django_declarative_apis.models import OauthConsumer


class ResponseTestCase(TestCase):
def test_ping_definition(self):
resp = self.client.get("/ping")
self.assertEqual(resp.json(), {"ping": "pong"})

def test_create_me(self):
self.client = OAuthClient()
consumer = OauthConsumer.objects.create(name="smith")

resp = self.client.post("/me", {}, consumer=consumer, secure=True)
self.assertEqual(resp.status_code, http.HTTPStatus.OK)
self.assertEqual(resp.json()["key"], consumer.key)
self.assertEqual(resp.json()["name"], consumer.name)
110 changes: 110 additions & 0 deletions example/myapp/tests/testutils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import oauth2
import oauthlib
import time

from django.test.client import ClientHandler
from django.http import QueryDict
from django import test
from django_declarative_apis.models import OauthConsumer


class OAuthClientHandler(ClientHandler):
def __init__(self, *args, **kwargs):
super(OAuthClientHandler, self).__init__(*args, **kwargs)

def get_response(self, request):
consumer = OauthConsumer.objects.get(name="smith")

# Make request params mutable so we can add authorization parameters.
# We make the params immutable again before processing the request
request.POST = request.POST.copy()
request.GET = request.GET.copy()

if consumer:
if request.method == "POST":
data = request.POST
else:
data = request.GET

# This provides a way for us to override default values for testing.
oauth_version = request.META.get("oauth_version", "1.0")
oauth_nonce = request.META.get("oauth_nonce", oauth2.generate_nonce())
oauth_client_timestamp = request.META.get(
"oauth_timestamp", int(time.time())
)

rsa_key = request.META.get("rsa_key", None)
oauth_signature_method = oauthlib.oauth1.SIGNATURE_HMAC

oauth_signature_data = {
"oauth_version": oauth_version,
"oauth_nonce": oauth_nonce,
"oauth_timestamp": str(oauth_client_timestamp),
"oauth_consumer_key": consumer.key,
"oauth_signature_method": oauth_signature_method,
}

# collect ALL request parameters (original + OAuth) for signing
all_request_parameters = data.copy()
all_request_parameters.update(oauth_signature_data)

# use HMAC-SHA1 signature method
oauth_signature_data.update({"oauth_signature_method": "HMAC-SHA1"})

# Create oauth request object to compute signature
oauth_request = oauth2.Request.from_consumer_and_token(
consumer,
None,
request.method,
request.build_absolute_uri(request.path),
all_request_parameters,
is_form_encoded=True,
)

# Add signature to django request
signature_method = oauth2.SignatureMethod_HMAC_SHA1()
oauth_request.sign_request(signature_method, consumer, None)
oauth_signature_data["oauth_signature"] = oauth_request.get_parameter(
"oauth_signature"
).decode("utf-8")

use_auth_header_signature = request.META.pop(
"use_auth_header_signature", False
)
if use_auth_header_signature:
auth_header_string = "OAuth " + ",".join(
[
'{0}="{1}"'.format(key, value)
for key, value in oauth_signature_data.items()
]
)
request.META["HTTP_AUTHORIZATION"] = auth_header_string
else:
data.update(oauth_signature_data)

# Recreate the GET and POST QueryDicts to make them immutable, as in production
request.POST = QueryDict(request.POST.urlencode().encode("utf-8"))
request.GET = QueryDict(request.GET.urlencode().encode("utf-8"))

return ClientHandler.get_response(self, request)


class OAuthClient(test.Client):
def __init__(self, *args, **kwargs):
test.Client.__init__(self, *args, **kwargs)
self.handler = OAuthClientHandler()

def request(self, **kwargs):
response = super(OAuthClient, self).request(**kwargs)

return response

def post(self, path, data=None, **kwargs):
if "content_type" not in kwargs:
data = data or {}
kwargs["content_type"] = "application/x-www-form-urlencoded"
data_qd = QueryDict(mutable=True)
data_qd.update(data)
data = data_qd.urlencode()

return super(OAuthClient, self).post(path, data, **kwargs)
2 changes: 2 additions & 0 deletions example/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
../../django-declarative-apis
Django~=2.2.0
django-sslserver==0.20
oauth2==1.9.0.post1
oauthlib==2.0.6

0 comments on commit 4afd64d

Please sign in to comment.