-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cover 100% tests for serializers/webhook.py with current coverage sta…
…tus is 40%.
- Loading branch information
Showing
1 changed file
with
264 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,271 @@ | ||
from django.test import TestCase | ||
from django.test import TestCase, override_settings | ||
|
||
from rest_framework.exceptions import ValidationError | ||
|
||
from pathlib import Path | ||
from json import loads as json_loads, dumps as json_dumps, load as json_stream_load | ||
|
||
from bc.serializers import BcPeopleSerializer | ||
from bc.serializers import BcPeopleSerializer, BcWebhookSerializer | ||
|
||
|
||
class WebhookSerializerTest(TestCase): | ||
fixtures = ["bc_bccompany", "bc_bcpeople", "bc_bcproject", "bc_bcprojecttool", | ||
"bc_bcvault", "bc_bctodolist"] | ||
|
||
@classmethod | ||
def setUpTestData(cls): # Run once to set up non-modified data for all class methods | ||
|
||
# api_sample.json is collections of API data from bc3-api site https://github.com/basecamp/bc3-api/tree/master | ||
test_dir = Path(__file__).resolve().parent | ||
with open(test_dir / "api_sample.json") as stream: | ||
api_sample_json = json_stream_load(stream) | ||
|
||
# sample API data from https://github.com/basecamp/bc3-api/blob/master/sections/webhooks.md | ||
cls.webhook_data_1479523571 = json_dumps(api_sample_json["webhook"]["1479523571"]) # "kind": "todo_copied" | ||
# dummy API data with "kind": "cloud_file_created" | ||
cls.webhook_data_1479523572 = json_dumps(api_sample_json["webhook"]["1479523572"]) | ||
|
||
def setUp(self): # Run once for every test method to set up clean data | ||
self.webhook_1479523571 = json_loads(self.webhook_data_1479523571) | ||
self.webhook_1479523572 = json_loads(self.webhook_data_1479523572) | ||
|
||
def test_deserialize_to_internal_value(self): | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523571) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_without_recording_bucket(self): | ||
""" | ||
without recording bucket should be invalid serializer | ||
:return: | ||
""" | ||
|
||
self.webhook_1479523571["recording"].pop('bucket') # remove bucket from webhook recording | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523571) | ||
self.assertFalse(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_get_recording_base_child_with_invalid_recording_type(self): | ||
serializer = BcWebhookSerializer(data=self.webhook_1479523571) | ||
# manually call get webhook recording base child, with incorrect type of recording (not child of base) | ||
serializer.get_webhook_recording_base_child(recording=self.webhook_1479523571["recording"]) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_create_recording_base_child_with_invalid_recording_type(self): | ||
""" | ||
with invalid recording type should be invalid serializer | ||
:return: | ||
""" | ||
serializer = BcWebhookSerializer(data=self.webhook_1479523571) | ||
# manually call create webhook recording base child, with incorrect type of recording (not child of base) | ||
serializer.create_webhook_recording_base_child(recording=self.webhook_1479523571["recording"]) | ||
self.assertFalse(serializer.is_valid()) | ||
|
||
@override_settings(INSTALLED_APPS=[]) | ||
def test_deserialize_to_internal_value_with_app_not_installed(self): | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523571) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_recording_base_children(self): | ||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
@override_settings(INSTALLED_APPS=[]) | ||
def test_deserialize_to_internal_value_recording_base_children_with_app_not_installed(self): | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
@override_settings(INSTALLED_APPS=[]) | ||
def test_deserialize_to_internal_value_recording_base_children_create_model_with_app_not_installed(self): | ||
""" | ||
construct BcWebhookSerializer with recording base child include call of create_webhook_recording_base_child(). | ||
with django app bc not installed, not include call of _create_webhook_recording_base_child_model(). | ||
test with call _create_webhook_recording_base_child_model() manually, without _bucket, _creator, _parent. | ||
:return: | ||
""" | ||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
serializer._create_webhook_recording_base_child_model( | ||
recording=self.webhook_1479523572["recording"], _bucket=None, _creator=None, _parent=None) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_recording_base_children_with_invalid_bucket(self): | ||
""" | ||
without recording bucket should be invalid serializer | ||
test the ability of method db_get_recording_bucket handle non-existence or invalid type, | ||
by manually call method create_webhook_recording_base_child as the parent of db_get_recording_bucket | ||
:return: | ||
""" | ||
# remove the recording bucket | ||
bucket_data = self.webhook_1479523572["recording"].pop('bucket') | ||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
# to_internal_value() already check the bucket existence and the bucket type, test with manually call the method | ||
serializer.create_webhook_recording_base_child(recording=self.webhook_1479523572["recording"]) | ||
self.assertFalse(serializer.is_valid()) | ||
|
||
self.webhook_1479523572 = json_loads(self.webhook_data_1479523572) # reload the data | ||
# re-entry the recording bucket with invalid bucket type (!= Project) | ||
self.webhook_1479523572["recording"]["bucket"]["type"] = '!Project' | ||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
# to_internal_value() already check the bucket existence and the bucket type, test with manually call the method | ||
serializer.create_webhook_recording_base_child(recording=self.webhook_1479523572["recording"]) | ||
self.assertFalse(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_with_invalid_recording_type(self): | ||
# change recording type from CloudFile to invalid type (Cloud) | ||
self.webhook_1479523572["recording"]["type"] = "Cloud" | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
|
||
# even though the recording type invalid, the serializer still, it will only save the raw data, but no recording | ||
self.assertTrue(serializer.is_valid()) | ||
self.assertEqual(serializer.recording, None) | ||
|
||
def test_deserialize_to_internal_value_with_not_exist_recording_bucket(self): | ||
# change recording bucket id with id that is not exist on db | ||
self.webhook_1479523572["recording"]["bucket"]["id"] = 1 | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_with_not_exist_recording_parent(self): | ||
# change recording parent id with id that is not exist on db | ||
self.webhook_1479523572["recording"]["parent"]["id"] = 1 | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_without_recording_creator(self): | ||
# change recording creator by remove the creator field | ||
self.webhook_1479523572["recording"].pop("creator") | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_with_not_exist_recording_creator(self): | ||
# change recording creator id with id that is not exist on db | ||
self.webhook_1479523572["recording"]["creator"]["id"] = 1 | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_with_not_exist_recording_creator_no_company(self): | ||
# change recording creator id with id that is not exist on db and remove company from creator | ||
self.webhook_1479523572["recording"]["creator"]["id"] = 1 | ||
self.webhook_1479523572["recording"]["creator"].pop('company') | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_with_no_parent(self): | ||
# change recording parent by removing parent field | ||
self.webhook_1479523572["recording"].pop('parent') | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
self.assertTrue(serializer.is_valid()) | ||
|
||
def test_deserialize_to_internal_value_with_invalid_recording_parent_type(self): | ||
# change recording parent type from Vault to invalid type (Cloud) | ||
self.webhook_1479523572["recording"]["parent"]["type"] = "Cloud" | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523572) | ||
|
||
# even though the recording parent type invalid, the serializer still valid, | ||
# it will only save the raw data, but no recording | ||
self.assertTrue(serializer.is_valid()) | ||
self.assertEqual(serializer.recording, None) | ||
|
||
def test_deserialize_to_create_with_exist_person(self): | ||
serializer = BcWebhookSerializer(data=self.webhook_1479523571) | ||
if serializer.is_valid(): | ||
webhook = serializer.save() # save will call create | ||
self.assertEqual(webhook.id, self.webhook_1479523571["id"]) | ||
else: | ||
self.fail(f'serializer error: {serializer.errors}') | ||
|
||
def test_deserialize_to_create_with_new_person_exist_company(self): | ||
""" | ||
deserialize with new person (new people id) that does not exist in fixture, with existing company | ||
:return: | ||
""" | ||
|
||
new_person_data = """{ | ||
"id": 1049715969, | ||
"attachable_sgid": "BAh7CEkiCGdpZAY6BkVUSSIrZ2lkOi8vYmMzL1BlcnNvbi8xMDQ5NzE1OTY5P2V4cGlyZXNfaW4GOwBUSSIMcHVycG9zZQY7AFRJIg9hdHRhY2hhYmxlBjsAVEkiD2V4cGlyZXNfYXQGOwBUMA==--f94940da9b0adc1ec997382934419905904c8692", | ||
"name": "Victor Copper", | ||
"email_address": "[email protected]", | ||
"personable_type": "User", | ||
"title": "Prankster", | ||
"bio": null, | ||
"location": null, | ||
"created_at": "2022-11-22T17:56:23.633Z", | ||
"updated_at": "2022-11-22T17:56:23.633Z", | ||
"admin": false, | ||
"owner": false, | ||
"client": false, | ||
"employee": false, | ||
"time_zone": "America/Chicago", | ||
"avatar_url": "https://3.basecamp-static.com/195539477/people/BAhpBAFlkT4=--b48efd42c6425ae51e7205e157d902971934e5b8/avatar?v=1", | ||
"company": { | ||
"id": 1033447817, | ||
"name": "Honcho Design" | ||
}, | ||
"can_manage_projects": true, | ||
"can_manage_people": true | ||
}""" | ||
new_person = json_loads(new_person_data) | ||
|
||
# change webhook creator with new_person data | ||
self.webhook_1479523571['creator'] = new_person | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523571) | ||
if serializer.is_valid(): | ||
webhook = serializer.save() # save will call create | ||
self.assertEqual(webhook.creator.id, new_person['id']) | ||
else: | ||
self.fail(f'serializer error: {serializer.errors}') | ||
|
||
def test_deserialize_to_create_with_new_person_no_company(self): | ||
""" | ||
deserialize with new person (new people id) that does not exist in fixture, with no company to trigger error | ||
:return: | ||
""" | ||
|
||
new_person_data = """{ | ||
"id": 1049715969, | ||
"attachable_sgid": "BAh7CEkiCGdpZAY6BkVUSSIrZ2lkOi8vYmMzL1BlcnNvbi8xMDQ5NzE1OTY5P2V4cGlyZXNfaW4GOwBUSSIMcHVycG9zZQY7AFRJIg9hdHRhY2hhYmxlBjsAVEkiD2V4cGlyZXNfYXQGOwBUMA==--f94940da9b0adc1ec997382934419905904c8692", | ||
"name": "Victor Copper", | ||
"email_address": "[email protected]", | ||
"personable_type": "User", | ||
"title": "Prankster", | ||
"bio": null, | ||
"location": null, | ||
"created_at": "2022-11-22T17:56:23.633Z", | ||
"updated_at": "2022-11-22T17:56:23.633Z", | ||
"admin": false, | ||
"owner": false, | ||
"client": false, | ||
"employee": false, | ||
"time_zone": "America/Chicago", | ||
"avatar_url": "https://3.basecamp-static.com/195539477/people/BAhpBAFlkT4=--b48efd42c6425ae51e7205e157d902971934e5b8/avatar?v=1", | ||
"can_manage_projects": true, | ||
"can_manage_people": true | ||
}""" | ||
new_person = json_loads(new_person_data) | ||
|
||
# change webhook creator with new_person data | ||
self.webhook_1479523571['creator'] = new_person | ||
|
||
serializer = BcWebhookSerializer(data=self.webhook_1479523571) | ||
if serializer.is_valid(): | ||
try: | ||
serializer.save() # save will call create, but ValidationError | ||
except ValidationError as e: | ||
self.assertEqual(str(e), "{'People Serializer error': {'people company error': " | ||
"ErrorDetail(string='people no company field', code='invalid')}}") | ||
else: | ||
self.fail(f'serializer error: {serializer.errors}') | ||
|
||
|
||
class PeopleSerializerTest(TestCase): | ||
|