From c735fddbb56bca67cc82ac4f4ddd217685e1d1a2 Mon Sep 17 00:00:00 2001 From: karmagood Date: Tue, 7 Mar 2017 16:17:16 +0200 Subject: [PATCH 1/2] Prohibition to remove startDate in tenderPeriod and enquiryPeriod --- openprocurement/auctions/flash/models.py | 5 +- .../auctions/flash/tests/chronograph.py | 20 -------- .../auctions/flash/tests/tender.py | 49 ++++++++++++++++--- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/openprocurement/auctions/flash/models.py b/openprocurement/auctions/flash/models.py index 5c7f7d4..06e63b8 100644 --- a/openprocurement/auctions/flash/models.py +++ b/openprocurement/auctions/flash/models.py @@ -20,7 +20,7 @@ LotValue, Bid, Revision, Question, Cancellation, Contract, Award, Feature, Lot, schematics_embedded_role, schematics_default_role, ORA_CODES, WORKING_DAYS, validate_features_uniq, validate_items_uniq, validate_lots_uniq, Period, - Complaint as BaseComplaint, TZ, get_now, set_parent, ComplaintModelType, + Complaint as BaseComplaint, TZ, get_now, set_parent, ComplaintModelType, CANT_DELETE_PERIOD_START_DATE_FROM, ) from openprocurement.auctions.core.models import IAuction, get_auction @@ -59,6 +59,9 @@ class AuctionPeriodEndRequired(PeriodEndRequired): def validate_startDate(self, data, period): if period and data.get('endDate') and data.get('endDate') < period: raise ValidationError(u"period should begin before its end") + auction = get_auction(data['__parent__']) + if auction.get('revisions') and auction['revisions'][0].date > CANT_DELETE_PERIOD_START_DATE_FROM and not period: + raise ValidationError([u'This field cannot be deleted']) def calc_auction_end_time(bids, start): diff --git a/openprocurement/auctions/flash/tests/chronograph.py b/openprocurement/auctions/flash/tests/chronograph.py index 5714f74..c755ee0 100644 --- a/openprocurement/auctions/flash/tests/chronograph.py +++ b/openprocurement/auctions/flash/tests/chronograph.py @@ -7,18 +7,6 @@ class AuctionSwitchtenderingResourceTest(BaseAuctionWebTest): - def test_switch_to_tendering_by_enquiryPeriod_endDate(self): - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) - self.assertEqual(response.status, '200 OK') - date_1 = response.json['data']['date'] - self.assertNotEqual(response.json['data']["status"], "active.tendering") - self.set_status('active.tendering', {'status': 'active.enquiries', "tenderPeriod": {"startDate": None}}) - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], "active.tendering") - self.assertNotEqual(date_1, response.json['data']['date']) - def test_switch_to_tendering_by_auctionPeriod_startDate(self): self.set_status('active.tendering', {'status': 'active.enquiries', "tenderPeriod": {}}) self.app.authorization = ('Basic', ('chronograph', '')) @@ -30,14 +18,6 @@ def test_switch_to_tendering_by_auctionPeriod_startDate(self): self.assertEqual(response.status, '200 OK') self.assertEqual(response.json['data']["status"], "active.tendering") - def test_switch_to_tendering_auctionPeriod(self): - self.set_status('active.tendering', {'status': 'active.enquiries', "tenderPeriod": {"startDate": None}}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], "active.tendering") - self.assertIn('auctionPeriod', response.json['data']) - class AuctionSwitchQualificationResourceTest(BaseAuctionWebTest): initial_status = 'active.tendering' diff --git a/openprocurement/auctions/flash/tests/tender.py b/openprocurement/auctions/flash/tests/tender.py index 88a2ae2..2f579a3 100644 --- a/openprocurement/auctions/flash/tests/tender.py +++ b/openprocurement/auctions/flash/tests/tender.py @@ -6,7 +6,7 @@ from uuid import uuid4 from openprocurement.api.utils import ROUTE_PREFIX -from openprocurement.api.models import get_now, SANDBOX_MODE +from openprocurement.api.models import get_now, SANDBOX_MODE, CANT_DELETE_PERIOD_START_DATE_FROM from openprocurement.auctions.flash.models import Auction from openprocurement.auctions.flash.tests.base import test_auction_data, test_organization, BaseWebTest, BaseAuctionWebTest @@ -779,6 +779,7 @@ def test_auction_features_invalid(self): def test_auction_features(self): data = test_auction_data.copy() + data['procuringEntity']['contactPoint']['faxNumber'] = u"0440000000" item = data['items'][0].copy() item['id'] = "1" data['items'] = [item] @@ -850,9 +851,11 @@ def test_auction_features(self): self.assertIn('features', response.json['data']) self.assertNotIn('relatedItem', response.json['data']['features'][0]) - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'tenderPeriod': {'startDate': None}}}) + response = self.app.patch_json('/auctions/{}'.format(auction['id']), + {'data': {'procuringEntity': {'contactPoint': {'faxNumber': None}}}}) self.assertEqual(response.status, '200 OK') self.assertIn('features', response.json['data']) + self.assertNotIn('faxNumber', response.json['data']['procuringEntity']['contactPoint']) response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'features': []}}) self.assertEqual(response.status, '200 OK') @@ -892,11 +895,13 @@ def test_patch_tender_jsonpatch(self): self.assertEqual(response.content_type, 'application/json') def test_patch_auction(self): + data = test_auction_data.copy() + data['procuringEntity']['contactPoint']['faxNumber'] = u"0440000000" response = self.app.get('/auctions') self.assertEqual(response.status, '200 OK') self.assertEqual(len(response.json['data']), 0) - response = self.app.post_json('/auctions', {'data': test_auction_data}) + response = self.app.post_json('/auctions', {'data': data}) self.assertEqual(response.status, '201 Created') auction = response.json['data'] owner_token = response.json['access']['token'] @@ -918,13 +923,13 @@ def test_patch_auction(self): self.assertNotIn('kind', response.json['data']['procuringEntity']) response = self.app.patch_json('/auctions/{}'.format( - auction['id']), {'data': {'tenderPeriod': {'startDate': None}}}) + auction['id']), {'data': {'procuringEntity': {'contactPoint': {'faxNumber': None}}}}) self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') - self.assertNotIn('startDate', response.json['data']['tenderPeriod']) + self.assertNotIn('faxNumber', response.json['data']['procuringEntity']['contactPoint']) response = self.app.patch_json('/auctions/{}'.format( - auction['id']), {'data': {'tenderPeriod': {'startDate': auction['enquiryPeriod']['endDate']}}}) + auction['id']), {'data': {'procuringEntity': {'contactPoint': {'faxNumber': u"0440000000"}}}}) self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') self.assertIn('startDate', response.json['data']['tenderPeriod']) @@ -953,12 +958,12 @@ def test_patch_auction(self): self.assertEqual(revisions[-1][u'changes'][0]['path'], u'/procurementMethodRationale') response = self.app.patch_json('/auctions/{}'.format( - auction['id']), {'data': {'items': [test_auction_data['items'][0]]}}) + auction['id']), {'data': {'items': [data['items'][0]]}}) self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') response = self.app.patch_json('/auctions/{}'.format( - auction['id']), {'data': {'items': [{}, test_auction_data['items'][0]]}}) + auction['id']), {'data': {'items': [{}, data['items'][0]]}}) self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') item0 = response.json['data']['items'][0] @@ -1023,6 +1028,34 @@ def test_patch_auction(self): self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.json['errors'][0]["description"], "Can't update auction in current (complete) status") + @unittest.skipIf(get_now() < CANT_DELETE_PERIOD_START_DATE_FROM, + "Can`t delete period start date only from {}".format(CANT_DELETE_PERIOD_START_DATE_FROM)) + def test_required_field_deletion(self): + response = self.app.post_json('/auctions', {'data': test_auction_data}) + self.assertEqual(response.status, '201 Created') + tender = response.json['data'] + + # TODO: Test all the required fields + response = self.app.patch_json('/auctions/{}'.format( + auction['id']), {'data': {'enquiryPeriod': {'startDate': None}}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': {u'startDate': [u'This field cannot be deleted']}, u'location': u'body', + u'name': u'enquiryPeriod'} + ]) + + response = self.app.patch_json('/auctions/{}'.format( + auction['id']), {'data': {'tenderPeriod': {'startDate': None}}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': {u'startDate': [u'This field cannot be deleted']}, u'location': u'body', + u'name': u'tenderPeriod'} + ]) + def test_dateModified_auction(self): response = self.app.get('/auctions') self.assertEqual(response.status, '200 OK') From 661422a3ccc834710ac3b6fc0f861f15d4e5160a Mon Sep 17 00:00:00 2001 From: vladyslav Date: Wed, 12 Apr 2017 04:41:05 +0300 Subject: [PATCH 2/2] Added it's own CANT_DELETE_PERIOD_START_DATE_FROM to flash. --- openprocurement/auctions/flash/models.py | 4 ++-- openprocurement/auctions/flash/tests/tender.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openprocurement/auctions/flash/models.py b/openprocurement/auctions/flash/models.py index 06e63b8..e5f0d71 100644 --- a/openprocurement/auctions/flash/models.py +++ b/openprocurement/auctions/flash/models.py @@ -20,7 +20,7 @@ LotValue, Bid, Revision, Question, Cancellation, Contract, Award, Feature, Lot, schematics_embedded_role, schematics_default_role, ORA_CODES, WORKING_DAYS, validate_features_uniq, validate_items_uniq, validate_lots_uniq, Period, - Complaint as BaseComplaint, TZ, get_now, set_parent, ComplaintModelType, CANT_DELETE_PERIOD_START_DATE_FROM, + Complaint as BaseComplaint, TZ, get_now, set_parent, ComplaintModelType, ) from openprocurement.auctions.core.models import IAuction, get_auction @@ -29,7 +29,7 @@ BIDDER_TIME = timedelta(minutes=3 * 3) SERVICE_TIME = timedelta(minutes=5 + 3 + 3) AUCTION_STAND_STILL_TIME = timedelta(minutes=15) - +CANT_DELETE_PERIOD_START_DATE_FROM = datetime(2017, 3, 18, tzinfo=TZ) def read_json(name): import os.path diff --git a/openprocurement/auctions/flash/tests/tender.py b/openprocurement/auctions/flash/tests/tender.py index 2f579a3..351f49d 100644 --- a/openprocurement/auctions/flash/tests/tender.py +++ b/openprocurement/auctions/flash/tests/tender.py @@ -6,8 +6,8 @@ from uuid import uuid4 from openprocurement.api.utils import ROUTE_PREFIX -from openprocurement.api.models import get_now, SANDBOX_MODE, CANT_DELETE_PERIOD_START_DATE_FROM -from openprocurement.auctions.flash.models import Auction +from openprocurement.api.models import get_now, SANDBOX_MODE +from openprocurement.auctions.flash.models import Auction, CANT_DELETE_PERIOD_START_DATE_FROM from openprocurement.auctions.flash.tests.base import test_auction_data, test_organization, BaseWebTest, BaseAuctionWebTest