From e10e469ab06a95f4b2a542c181694b0468067868 Mon Sep 17 00:00:00 2001 From: Karun Japhet Date: Sun, 13 Oct 2019 12:57:20 +0530 Subject: [PATCH] Add test for pull_request.py Part of #9 --- Pipfile | 4 + Pipfile.lock | 193 +++++++++++++++++++- client/models/pull_request.py | 8 +- client_test/__init__.py | 0 client_test/models/__init__.py | 0 client_test/models/empty_pr_data.json | 25 +++ client_test/models/pr_test_data.py | 60 ++++++ client_test/models/pull_request_test.py | 231 ++++++++++++++++++++++++ 8 files changed, 516 insertions(+), 5 deletions(-) create mode 100644 client_test/__init__.py create mode 100644 client_test/models/__init__.py create mode 100644 client_test/models/empty_pr_data.json create mode 100644 client_test/models/pr_test_data.py create mode 100644 client_test/models/pull_request_test.py diff --git a/Pipfile b/Pipfile index 834a1f2..8cd9a2d 100644 --- a/Pipfile +++ b/Pipfile @@ -5,9 +5,13 @@ verify_ssl = true [dev-packages] autopep8 = "*" +pytest = "*" [packages] requests = "*" +flask = "*" +flask-jsonpify = "*" +flask-restful = "*" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index a7454a9..419e553 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "dc880d041ee2e58dbf9314700241482abd44a1cab56c369c20ceda382f013327" + "sha256": "c7a8ed2cf9151fcbfce52168676d6d043ca72527f733b25150d3a57605005530" }, "pipfile-spec": 6, "requires": { @@ -16,6 +16,13 @@ ] }, "default": { + "aniso8601": { + "hashes": [ + "sha256:529dcb1f5f26ee0df6c0a1ee84b7b27197c3c50fc3a6321d66c544689237d072", + "sha256:c033f63d028b9a58e3ab0c2c7d0532ab4bfa7452bfc788fbfe3ddabd327b181a" + ], + "version": "==8.0.0" + }, "certifi": { "hashes": [ "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", @@ -30,6 +37,36 @@ ], "version": "==3.0.4" }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "version": "==7.0" + }, + "flask": { + "hashes": [ + "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", + "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" + ], + "index": "pypi", + "version": "==1.1.1" + }, + "flask-jsonpify": { + "hashes": [ + "sha256:8ac4c732aa5b11d9f6c2de58065d3b669f139518ca8f529bce943817e2fedbfb" + ], + "index": "pypi", + "version": "==1.5.0" + }, + "flask-restful": { + "hashes": [ + "sha256:ecd620c5cc29f663627f99e04f17d1f16d095c83dc1d618426e2ad68b03092f8", + "sha256:f8240ec12349afe8df1db168ea7c336c4e5b0271a36982bff7394f93275f2ca9" + ], + "index": "pypi", + "version": "==0.3.7" + }, "idna": { "hashes": [ "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", @@ -37,6 +74,60 @@ ], "version": "==2.8" }, + "itsdangerous": { + "hashes": [ + "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", + "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" + ], + "version": "==1.1.0" + }, + "jinja2": { + "hashes": [ + "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", + "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de" + ], + "version": "==2.10.3" + }, + "markupsafe": { + "hashes": [ + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + ], + "version": "==1.1.1" + }, + "pytz": { + "hashes": [ + "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", + "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" + ], + "version": "==2019.3" + }, "requests": { "hashes": [ "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", @@ -45,15 +136,43 @@ "index": "pypi", "version": "==2.22.0" }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, "urllib3": { "hashes": [ "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86" ], "version": "==1.25.6" + }, + "werkzeug": { + "hashes": [ + "sha256:7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7", + "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4" + ], + "version": "==0.16.0" } }, "develop": { + "atomicwrites": { + "hashes": [ + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" + ], + "version": "==1.3.0" + }, + "attrs": { + "hashes": [ + "sha256:ec20e7a4825331c1b5ebf261d111e16fa9612c1f7a5e1f884f12bd53a664dfd2", + "sha256:f913492e1663d3c36f502e5e9ba6cd13cf19d7fab50aa13239e420fef95e1396" + ], + "version": "==19.2.0" + }, "autopep8": { "hashes": [ "sha256:4d8eec30cc81bc5617dbf1218201d770dc35629363547f17577c61683ccfb3ee" @@ -61,12 +180,84 @@ "index": "pypi", "version": "==1.4.4" }, + "importlib-metadata": { + "hashes": [ + "sha256:aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26", + "sha256:d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af" + ], + "markers": "python_version < '3.8'", + "version": "==0.23" + }, + "more-itertools": { + "hashes": [ + "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", + "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4" + ], + "version": "==7.2.0" + }, + "packaging": { + "hashes": [ + "sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47", + "sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108" + ], + "version": "==19.2" + }, + "pluggy": { + "hashes": [ + "sha256:0db4b7601aae1d35b4a033282da476845aa19185c1e6964b25cf324b5e4ec3e6", + "sha256:fa5fa1622fa6dd5c030e9cad086fa19ef6a0cf6d7a2d12318e10cb49d6d68f34" + ], + "version": "==0.13.0" + }, + "py": { + "hashes": [ + "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", + "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53" + ], + "version": "==1.8.0" + }, "pycodestyle": { "hashes": [ "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" ], "version": "==2.5.0" + }, + "pyparsing": { + "hashes": [ + "sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", + "sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4" + ], + "version": "==2.4.2" + }, + "pytest": { + "hashes": [ + "sha256:7e4800063ccfc306a53c461442526c5571e1462f61583506ce97e4da6a1d88c8", + "sha256:ca563435f4941d0cb34767301c27bc65c510cb82e90b9ecf9cb52dc2c63caaa0" + ], + "index": "pypi", + "version": "==5.2.1" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, + "wcwidth": { + "hashes": [ + "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", + "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c" + ], + "version": "==0.1.7" + }, + "zipp": { + "hashes": [ + "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", + "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335" + ], + "version": "==0.6.0" } } } diff --git a/client/models/pull_request.py b/client/models/pull_request.py index 529d7cd..6c1848d 100644 --- a/client/models/pull_request.py +++ b/client/models/pull_request.py @@ -26,10 +26,10 @@ def score(self) -> int: def _self_pr_score(self) -> int: if self._merged: return 5 - elif self._state == 'closed': - return 1 elif self.is_spam(): return -10 + elif self._state == 'closed': + return 1 elif self._state == 'open': return 1 else: @@ -38,10 +38,10 @@ def _self_pr_score(self) -> int: def _pr_score(self) -> int: if self._merged: return 10 - elif self._state == 'closed': - return 3 elif self.is_spam(): return -5 + elif self._state == 'closed': + return 3 elif self._state == 'open': return 1 else: diff --git a/client_test/__init__.py b/client_test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/client_test/models/__init__.py b/client_test/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/client_test/models/empty_pr_data.json b/client_test/models/empty_pr_data.json new file mode 100644 index 0000000..5901e97 --- /dev/null +++ b/client_test/models/empty_pr_data.json @@ -0,0 +1,25 @@ +{ + "issues_data": { + "pull_request": { + "html_url": "" + }, + "state": "", + "labels": [], + "created_at": "" + }, + "pr_data": { + "base": { + "repo": { + "owner": { + "login": "" + } + } + }, + "head": { + "user": { + "login": "" + } + }, + "merged": true + } +} \ No newline at end of file diff --git a/client_test/models/pr_test_data.py b/client_test/models/pr_test_data.py new file mode 100644 index 0000000..7368d57 --- /dev/null +++ b/client_test/models/pr_test_data.py @@ -0,0 +1,60 @@ +import json +import copy + + +class PRData: + def __init__(self, data: dict = None): + if data == None: + with open('./client_test/models/empty_pr_data.json') as file: + self.data = json.load(file) + else: + self.data = data + + def with_pr_url(self, url: str = 'some-url'): + data = copy.deepcopy(self.data) + data['issues_data']['pull_request']['html_url'] = url + return PRData(data) + + def with_label(self, label_to_add: str = None): + data = copy.deepcopy(self.data) + if label_to_add == None: + label_number = len(data["issues_data"]["labels"]) + 1 + label_to_add = f'label-{label_number}' + + data['issues_data']['labels'].append({'name': label_to_add}) + return PRData(data) + + def with_created_at(self, created_at: str = '2014-04-24T16:34:47Z'): + data = copy.deepcopy(self.data) + data['issues_data']['created_at'] = created_at + return PRData(data) + + def with_owner(self, owner: str = 'owner_user_id'): + data = copy.deepcopy(self.data) + data['pr_data']['base']['repo']['owner']['login'] = owner + return PRData(data) + + def with_pr_raised_by(self, pr_raised_by: str = 'pr_raised_by_user_id'): + data = copy.deepcopy(self.data) + data['pr_data']['head']['user']['login'] = pr_raised_by + return PRData(data) + + def with_merged(self, merged=False): + data = copy.deepcopy(self.data) + data['pr_data']['merged'] = merged + return PRData(data) + + def with_state(self, state='some_state'): + data = copy.deepcopy(self.data) + data['issues_data']['state'] = state + return PRData(data) + + def with_defaults(self): + return PRData(self.data).with_pr_url()\ + .with_label()\ + .with_label()\ + .with_created_at()\ + .with_owner()\ + .with_pr_raised_by()\ + .with_merged()\ + .with_state() diff --git a/client_test/models/pull_request_test.py b/client_test/models/pull_request_test.py new file mode 100644 index 0000000..273dfcd --- /dev/null +++ b/client_test/models/pull_request_test.py @@ -0,0 +1,231 @@ +from datetime import datetime +from client.models.pull_request import PullRequest +from client_test.models.pr_test_data import PRData + + +_input = PRData().with_defaults() + + +class TestDefaults: + @staticmethod + def test_should_create_pull_request(): + data = _input.data + pr = PullRequest(**data) + + assert pr._url == 'some-url' + assert pr._state == 'some_state' + assert pr._labels == ['label-1', 'label-2'] + assert pr._created_at == datetime(2014, 4, 24, 16, 34, 47) + assert pr._owner == 'owner_user_id' + assert pr._pr_raised_by == 'pr_raised_by_user_id' + assert pr._merged == False + + @staticmethod + def test_summary(): + data = _input.data + pr = PullRequest(**data) + + assert pr.summary() == 'URL: some-url | Score: 0' + + +class TestIsSpam: + @staticmethod + def test_should_not_be_spam_when_labels_do_not_contain_invalid_and_spam(): + data = _input.data + pr = PullRequest(**data) + + assert pr.is_spam() == False + + @staticmethod + def test_should_be_spam_when_labels_contain_invalid(): + data = _input.with_label('invalid').data + pr = PullRequest(**data) + + assert pr._labels == ['label-1', 'label-2', 'invalid'] + assert pr.is_spam() + + @staticmethod + def test_should_be_spam_when_labels_contain_spam(): + data = _input.with_label('spam').data + pr = PullRequest(**data) + + assert pr._labels == ['label-1', 'label-2', 'spam'] + assert pr.is_spam() + + +class TestCreatedBetween: + @staticmethod + def test_in_between(): + data = _input.with_created_at('2019-12-25T16:35:49Z').data + pr = PullRequest(**data) + + assert pr.created_between( + start_date=datetime(2018, 1, 1), + end_date=datetime(2020, 1, 1) + ) + + @staticmethod + def test_not_in_between(): + data = _input.with_created_at('2019-12-25T16:35:49Z').data + pr = PullRequest(**data) + + assert pr.created_between( + start_date=datetime(2020, 1, 1), + end_date=datetime(2021, 1, 1) + ) == False + + @staticmethod + def test_created_at_start(): + data = _input.with_created_at('2019-12-25T16:35:49Z').data + pr = PullRequest(**data) + + assert pr.created_between( + start_date=datetime(2019, 12, 25, 16, 35, 49), + end_date=datetime(2021, 1, 1) + ) + + @staticmethod + def test_created_at_end(): + data = _input.with_created_at('2019-12-25T16:35:49Z').data + pr = PullRequest(**data) + + assert pr.created_between( + start_date=datetime(2017, 1, 1), + end_date=datetime(2019, 12, 25, 16, 35, 49) + ) + + +class TestPrScore: + @staticmethod + def test_merged_pr(): + data = _input.with_merged(True)\ + .data + pr = PullRequest(**data) + + assert pr.score() == 10 + + @staticmethod + def test_merged_closed_pr(): + data = _input.with_merged(True)\ + .with_state('closed')\ + .data + pr = PullRequest(**data) + + assert pr.score() == 10 + + @staticmethod + def test_spam_pr(): + data = _input.with_label('spam')\ + .data + pr = PullRequest(**data) + + assert pr.score() == -5 + + @staticmethod + def test_spam_closed_pr(): + data = _input.with_label('spam')\ + .with_state('closed')\ + .data + pr = PullRequest(**data) + + assert pr.score() == -5 + + @staticmethod + def test_closed_pr(): + data = _input.with_merged(False)\ + .with_state('closed')\ + .data + pr = PullRequest(**data) + + assert pr.score() == 3 + + @staticmethod + def test_open_pr(): + data = _input.with_merged(False)\ + .with_state('open')\ + .data + pr = PullRequest(**data) + + assert pr.score() == 1 + + @staticmethod + def test_default_pr(): + data = _input.data + pr = PullRequest(**data) + + assert pr.score() == 0 + + +class TestPersonalPrScore: + @staticmethod + def test_merged_pr(): + data = _input.with_owner('user-1')\ + .with_pr_raised_by('user-1')\ + .with_merged(True)\ + .data + pr = PullRequest(**data) + + assert pr.score() == 5 + + @staticmethod + def test_merged_closed_pr(): + data = _input.with_owner('user-1')\ + .with_pr_raised_by('user-1')\ + .with_merged(True)\ + .with_state('closed')\ + .data + pr = PullRequest(**data) + + assert pr.score() == 5 + + @staticmethod + def test_spam_pr(): + data = _input.with_owner('user-1')\ + .with_pr_raised_by('user-1')\ + .with_label('spam')\ + .data + pr = PullRequest(**data) + + assert pr.score() == -10 + + @staticmethod + def test_spam_closed_pr(): + data = _input.with_owner('user-1')\ + .with_pr_raised_by('user-1')\ + .with_label('spam')\ + .with_state('closed')\ + .data + pr = PullRequest(**data) + + assert pr.score() == -10 + + @staticmethod + def test_closed_pr(): + data = _input.with_owner('user-1')\ + .with_pr_raised_by('user-1')\ + .with_merged(False)\ + .with_state('closed')\ + .data + pr = PullRequest(**data) + + assert pr.score() == 1 + + @staticmethod + def test_open_pr(): + data = _input.with_owner('user-1')\ + .with_pr_raised_by('user-1')\ + .with_merged(False)\ + .with_state('open')\ + .data + pr = PullRequest(**data) + + assert pr.score() == 1 + + @staticmethod + def test_default_pr(): + data = _input.with_owner('user-1')\ + .with_pr_raised_by('user-1')\ + .data + pr = PullRequest(**data) + + assert pr.score() == 0