From 60290a18b75445456d9fe53184e6e27df30f9ec3 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 14 Mar 2018 12:08:59 +0200 Subject: [PATCH 01/45] Move award views to core.plugins --- .../auctions/dgf/views/other/award.py | 354 ------------------ .../dgf/views/other/award_complaint.py | 145 ------- .../views/other/award_complaint_document.py | 133 ------- .../dgf/views/other/award_document.py | 112 ------ 4 files changed, 744 deletions(-) delete mode 100644 openprocurement/auctions/dgf/views/other/award.py delete mode 100644 openprocurement/auctions/dgf/views/other/award_complaint.py delete mode 100644 openprocurement/auctions/dgf/views/other/award_complaint_document.py delete mode 100644 openprocurement/auctions/dgf/views/other/award_document.py diff --git a/openprocurement/auctions/dgf/views/other/award.py b/openprocurement/auctions/dgf/views/other/award.py deleted file mode 100644 index 7d7c612d..00000000 --- a/openprocurement/auctions/dgf/views/other/award.py +++ /dev/null @@ -1,354 +0,0 @@ -# -*- coding: utf-8 -*- -from openprocurement.api.models import get_now -from openprocurement.api.utils import ( - json_view, - context_unpack, - APIResource, -) -from openprocurement.auctions.core.utils import ( - apply_patch, - save_auction, - opresource, -) -from openprocurement.auctions.core.validation import ( - validate_award_data, - validate_patch_award_data, -) -from openprocurement.auctions.dgf.utils import switch_to_next_award, check_auction_protocol - - -@opresource(name='dgfOtherAssets:Auction Awards', - collection_path='/auctions/{auction_id}/awards', - path='/auctions/{auction_id}/awards/{award_id}', - auctionsprocurementMethodType="dgfOtherAssets", - description="Auction awards") -class AuctionAwardResource(APIResource): - - @json_view(permission='view_auction') - def collection_get(self): - """Auction Awards List - - Get Awards List - --------------- - - Example request to get awards list: - - .. sourcecode:: http - - GET /auctions/4879d3f8ee2443169b5fbbc9f89fa607/awards HTTP/1.1 - Host: example.com - Accept: application/json - - This is what one should expect in response: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - { - "data": [ - { - "status": "active", - "suppliers": [ - { - "id": { - "name": "Державне управління справами", - "scheme": "https://ns.openprocurement.org/ua/edrpou", - "uid": "00037256", - "uri": "http://www.dus.gov.ua/" - }, - "address": { - "countryName": "Україна", - "postalCode": "01220", - "region": "м. Київ", - "locality": "м. Київ", - "streetAddress": "вул. Банкова, 11, корпус 1" - } - } - ], - "value": { - "amount": 489, - "currency": "UAH", - "valueAddedTaxIncluded": true - } - } - ] - } - - """ - return {'data': [i.serialize("view") for i in self.request.validated['auction'].awards]} - - @json_view(content_type="application/json", permission='create_award', validators=(validate_award_data,)) - def collection_post(self): - """Accept or reject bidder application - - Creating new Award - ------------------ - - Example request to create award: - - .. sourcecode:: http - - POST /auctions/4879d3f8ee2443169b5fbbc9f89fa607/awards HTTP/1.1 - Host: example.com - Accept: application/json - - { - "data": { - "status": "active", - "suppliers": [ - { - "id": { - "name": "Державне управління справами", - "scheme": "https://ns.openprocurement.org/ua/edrpou", - "uid": "00037256", - "uri": "http://www.dus.gov.ua/" - }, - "address": { - "countryName": "Україна", - "postalCode": "01220", - "region": "м. Київ", - "locality": "м. Київ", - "streetAddress": "вул. Банкова, 11, корпус 1" - } - } - ], - "value": { - "amount": 489, - "currency": "UAH", - "valueAddedTaxIncluded": true - } - } - } - - This is what one should expect in response: - - .. sourcecode:: http - - HTTP/1.1 201 Created - Content-Type: application/json - - { - "data": { - "id": "4879d3f8ee2443169b5fbbc9f89fa607", - "date": "2014-10-28T11:44:17.947Z", - "status": "active", - "suppliers": [ - { - "id": { - "name": "Державне управління справами", - "scheme": "https://ns.openprocurement.org/ua/edrpou", - "uid": "00037256", - "uri": "http://www.dus.gov.ua/" - }, - "address": { - "countryName": "Україна", - "postalCode": "01220", - "region": "м. Київ", - "locality": "м. Київ", - "streetAddress": "вул. Банкова, 11, корпус 1" - } - } - ], - "value": { - "amount": 489, - "currency": "UAH", - "valueAddedTaxIncluded": true - } - } - } - - """ - auction = self.request.validated['auction'] - if auction.status != 'active.qualification': - self.request.errors.add('body', 'data', 'Can\'t create award in current ({}) auction status'.format(auction.status)) - self.request.errors.status = 403 - return - award = self.request.validated['award'] - if any([i.status != 'active' for i in auction.lots if i.id == award.lotID]): - self.request.errors.add('body', 'data', 'Can create award only in active lot status') - self.request.errors.status = 403 - return - now = get_now() - award.verificationPeriod = award.paymentPeriod = award.signingPeriod = {'startDate': now} - award.complaintPeriod = award.signingPeriod - auction.awards.append(award) - if save_auction(self.request): - self.LOGGER.info('Created auction award {}'.format(award.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_create'}, {'award_id': award.id})) - self.request.response.status = 201 - route = self.request.matched_route.name.replace("collection_", "") - self.request.response.headers['Location'] = self.request.current_route_url(_route_name=route, award_id=award.id, _query={}) - return {'data': award.serialize("view")} - - @json_view(permission='view_auction') - def get(self): - """Retrieving the award - - Example request for retrieving the award: - - .. sourcecode:: http - - GET /auctions/4879d3f8ee2443169b5fbbc9f89fa607/awards/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1 - Host: example.com - Accept: application/json - - And here is the response to be expected: - - .. sourcecode:: http - - HTTP/1.0 200 OK - Content-Type: application/json - - { - "data": { - "id": "4879d3f8ee2443169b5fbbc9f89fa607", - "date": "2014-10-28T11:44:17.947Z", - "status": "active", - "suppliers": [ - { - "id": { - "name": "Державне управління справами", - "scheme": "https://ns.openprocurement.org/ua/edrpou", - "uid": "00037256", - "uri": "http://www.dus.gov.ua/" - }, - "address": { - "countryName": "Україна", - "postalCode": "01220", - "region": "м. Київ", - "locality": "м. Київ", - "streetAddress": "вул. Банкова, 11, корпус 1" - } - } - ], - "value": { - "amount": 489, - "currency": "UAH", - "valueAddedTaxIncluded": true - } - } - } - - """ - return {'data': self.request.validated['award'].serialize("view")} - - @json_view(content_type="application/json", permission='edit_auction_award', validators=(validate_patch_award_data,)) - def patch(self): - """Update of award - - Example request to change the award: - - .. sourcecode:: http - - PATCH /auctions/4879d3f8ee2443169b5fbbc9f89fa607/awards/71b6c23ed8944d688e92a31ec8c3f61a HTTP/1.1 - Host: example.com - Accept: application/json - - { - "data": { - "value": { - "amount": 600 - } - } - } - - And here is the response to be expected: - - .. sourcecode:: http - - HTTP/1.0 200 OK - Content-Type: application/json - - { - "data": { - "id": "4879d3f8ee2443169b5fbbc9f89fa607", - "date": "2014-10-28T11:44:17.947Z", - "status": "active", - "suppliers": [ - { - "id": { - "name": "Державне управління справами", - "scheme": "https://ns.openprocurement.org/ua/edrpou", - "uid": "00037256", - "uri": "http://www.dus.gov.ua/" - }, - "address": { - "countryName": "Україна", - "postalCode": "01220", - "region": "м. Київ", - "locality": "м. Київ", - "streetAddress": "вул. Банкова, 11, корпус 1" - } - } - ], - "value": { - "amount": 600, - "currency": "UAH", - "valueAddedTaxIncluded": true - } - } - } - - """ - auction = self.request.validated['auction'] - if auction.status not in ['active.qualification', 'active.awarded']: - self.request.errors.add('body', 'data', 'Can\'t update award in current ({}) auction status'.format(auction.status)) - self.request.errors.status = 403 - return - award = self.request.context - award_status = award.status - if award_status in ['unsuccessful', 'cancelled']: - self.request.errors.add('body', 'data', 'Can\'t update award in current ({}) status'.format(award_status)) - self.request.errors.status = 403 - return - apply_patch(self.request, save=False, src=self.request.context.serialize()) - now = get_now() - if award_status == 'pending.waiting' and award.status == 'cancelled': - if self.request.authenticated_role == 'bid_owner': - award.complaintPeriod.endDate = now - else: - self.request.errors.add('body', 'data', 'Only bid owner may cancel award in current ({}) status'.format(award_status)) - self.request.errors.status = 403 - return - elif award_status == 'pending.verification' and award.status == 'pending.payment': - if check_auction_protocol(award): - award.verificationPeriod.endDate = now - else: - self.request.errors.add('body', 'data', 'Can\'t switch award status to (pending.payment) before auction owner load auction protocol') - self.request.errors.status = 403 - return - elif award_status == 'pending.payment' and award.status == 'active': - award.complaintPeriod.endDate = award.paymentPeriod.endDate = now - auction.contracts.append(type(auction).contracts.model_class({ - 'awardID': award.id, - 'suppliers': award.suppliers, - 'value': award.value, - 'date': now, - 'items': [i for i in auction.items if i.relatedLot == award.lotID], - 'contractID': '{}-{}{}'.format(auction.auctionID, self.server_id, len(auction.contracts) + 1)})) - auction.status = 'active.awarded' - auction.awardPeriod.endDate = now - elif award_status != 'pending.waiting' and award.status == 'unsuccessful': - if award_status == 'pending.verification': - award.verificationPeriod.endDate = award.complaintPeriod.endDate = award.paymentPeriod.endDate = award.signingPeriod.endDate = now - elif award_status == 'pending.payment': - award.paymentPeriod.endDate = now - elif award_status == 'active': - award.signingPeriod.endDate = now - auction.awardPeriod.endDate = None - auction.status = 'active.qualification' - for i in auction.contracts: - if i.awardID == award.id: - i.status = 'cancelled' - award.complaintPeriod.endDate = now - switch_to_next_award(self.request) - elif award_status != award.status: - self.request.errors.add('body', 'data', 'Can\'t switch award ({}) status to ({}) status'.format(award_status, award.status)) - self.request.errors.status = 403 - return - if save_auction(self.request): - self.LOGGER.info('Updated auction award {}'.format(self.request.context.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_patch'})) - return {'data': award.serialize("view")} diff --git a/openprocurement/auctions/dgf/views/other/award_complaint.py b/openprocurement/auctions/dgf/views/other/award_complaint.py deleted file mode 100644 index 36df76ad..00000000 --- a/openprocurement/auctions/dgf/views/other/award_complaint.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- -from openprocurement.api.models import get_now -from openprocurement.api.utils import ( - context_unpack, - json_view, - set_ownership, - APIResource, -) -from openprocurement.auctions.core.utils import ( - apply_patch, - check_auction_status, - opresource, - save_auction, - -) -from openprocurement.auctions.core.validation import ( - validate_complaint_data, - validate_patch_complaint_data, -) - - -@opresource(name='dgfOtherAssets:Auction Award Complaints', - collection_path='/auctions/{auction_id}/awards/{award_id}/complaints', - path='/auctions/{auction_id}/awards/{award_id}/complaints/{complaint_id}', - auctionsprocurementMethodType="dgfOtherAssets", - description="Auction award complaints") -class AuctionAwardComplaintResource(APIResource): - - @json_view(content_type="application/json", permission='nobody', validators=(validate_complaint_data,)) - def collection_post(self): - """Post a complaint for award - """ - auction = self.request.validated['auction'] - if auction.status not in ['active.qualification', 'active.awarded']: - self.request.errors.add('body', 'data', 'Can\'t add complaint in current ({}) auction status'.format(auction.status)) - self.request.errors.status = 403 - return - if any([i.status != 'active' for i in auction.lots if i.id == self.context.lotID]): - self.request.errors.add('body', 'data', 'Can add complaint only in active lot status') - self.request.errors.status = 403 - return - if self.context.complaintPeriod and \ - (self.context.complaintPeriod.startDate and self.context.complaintPeriod.startDate > get_now() or - self.context.complaintPeriod.endDate and self.context.complaintPeriod.endDate < get_now()): - self.request.errors.add('body', 'data', 'Can add complaint only in complaintPeriod') - self.request.errors.status = 403 - return - complaint = self.request.validated['complaint'] - complaint.date = get_now() - complaint.relatedLot = self.context.lotID - if complaint.status == 'claim': - complaint.dateSubmitted = get_now() - else: - complaint.status = 'draft' - complaint.complaintID = '{}.{}{}'.format(auction.auctionID, self.server_id, sum([len(i.complaints) for i in auction.awards], len(auction.complaints)) + 1) - set_ownership(complaint, self.request) - self.context.complaints.append(complaint) - if save_auction(self.request): - self.LOGGER.info('Created auction award complaint {}'.format(complaint.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_complaint_create'}, {'complaint_id': complaint.id})) - self.request.response.status = 201 - route = self.request.matched_route.name.replace("collection_", "") - self.request.response.headers['Location'] = self.request.current_route_url(_route_name=route, complaint_id=complaint.id, _query={}) - return { - 'data': complaint.serialize("view"), - 'access': { - 'token': complaint.owner_token - } - } - - @json_view(permission='view_auction') - def collection_get(self): - """List complaints for award - """ - return {'data': [i.serialize("view") for i in self.context.complaints]} - - @json_view(permission='view_auction') - def get(self): - """Retrieving the complaint for award - """ - return {'data': self.context.serialize("view")} - - @json_view(content_type="application/json", permission='edit_complaint', validators=(validate_patch_complaint_data,)) - def patch(self): - """Post a complaint resolution for award - """ - auction = self.request.validated['auction'] - if auction.status not in ['active.qualification', 'active.awarded']: - self.request.errors.add('body', 'data', 'Can\'t update complaint in current ({}) auction status'.format(auction.status)) - self.request.errors.status = 403 - return - if any([i.status != 'active' for i in auction.lots if i.id == self.request.validated['award'].lotID]): - self.request.errors.add('body', 'data', 'Can update complaint only in active lot status') - self.request.errors.status = 403 - return - if self.context.status not in ['draft', 'claim', 'answered', 'pending']: - self.request.errors.add('body', 'data', 'Can\'t update complaint in current ({}) status'.format(self.context.status)) - self.request.errors.status = 403 - return - data = self.request.validated['data'] - complaintPeriod = self.request.validated['award'].complaintPeriod - is_complaintPeriod = complaintPeriod.startDate < get_now() and complaintPeriod.endDate > get_now() if complaintPeriod.endDate else complaintPeriod.startDate < get_now() - # complaint_owner - if self.request.authenticated_role == 'complaint_owner' and self.context.status in ['draft', 'claim', 'answered', 'pending'] and data.get('status', self.context.status) == 'cancelled': - apply_patch(self.request, save=False, src=self.context.serialize()) - self.context.dateCanceled = get_now() - elif self.request.authenticated_role == 'complaint_owner' and is_complaintPeriod and self.context.status == 'draft' and data.get('status', self.context.status) == self.context.status: - apply_patch(self.request, save=False, src=self.context.serialize()) - elif self.request.authenticated_role == 'complaint_owner' and is_complaintPeriod and self.context.status == 'draft' and data.get('status', self.context.status) == 'claim': - apply_patch(self.request, save=False, src=self.context.serialize()) - self.context.dateSubmitted = get_now() - elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('status', self.context.status) == self.context.status: - apply_patch(self.request, save=False, src=self.context.serialize()) - elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('satisfied', self.context.satisfied) is True and data.get('status', self.context.status) == 'resolved': - apply_patch(self.request, save=False, src=self.context.serialize()) - elif self.request.authenticated_role == 'complaint_owner' and self.context.status == 'answered' and data.get('satisfied', self.context.satisfied) is False and data.get('status', self.context.status) == 'pending': - apply_patch(self.request, save=False, src=self.context.serialize()) - self.context.type = 'complaint' - self.context.dateEscalated = get_now() - # auction_owner - elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get('status', self.context.status) == self.context.status: - apply_patch(self.request, save=False, src=self.context.serialize()) - elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'claim' and data.get('resolution', self.context.resolution) and len(data.get('resolution', self.context.resolution or "")) >= 20 and data.get('resolutionType', self.context.resolutionType) and data.get('status', self.context.status) == 'answered': - apply_patch(self.request, save=False, src=self.context.serialize()) - self.context.dateAnswered = get_now() - elif self.request.authenticated_role == 'auction_owner' and self.context.status == 'pending': - apply_patch(self.request, save=False, src=self.context.serialize()) - # reviewers - elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get('status', self.context.status) == self.context.status: - apply_patch(self.request, save=False, src=self.context.serialize()) - elif self.request.authenticated_role == 'reviewers' and self.context.status == 'pending' and data.get('status', self.context.status) in ['resolved', 'invalid', 'declined']: - apply_patch(self.request, save=False, src=self.context.serialize()) - self.context.dateDecision = get_now() - else: - self.request.errors.add('body', 'data', 'Can\'t update complaint') - self.request.errors.status = 403 - return - if self.context.tendererAction and not self.context.tendererActionDate: - self.context.tendererActionDate = get_now() - if self.context.status not in ['draft', 'claim', 'answered', 'pending'] and auction.status in ['active.qualification', 'active.awarded']: - check_auction_status(self.request) - if save_auction(self.request): - self.LOGGER.info('Updated auction award complaint {}'.format(self.context.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_complaint_patch'})) - return {'data': self.context.serialize("view")} diff --git a/openprocurement/auctions/dgf/views/other/award_complaint_document.py b/openprocurement/auctions/dgf/views/other/award_complaint_document.py deleted file mode 100644 index bbe4a9ed..00000000 --- a/openprocurement/auctions/dgf/views/other/award_complaint_document.py +++ /dev/null @@ -1,133 +0,0 @@ -# -*- coding: utf-8 -*- -from openprocurement.api.utils import ( - get_file, - upload_file, - update_file_content_type, - json_view, - context_unpack, - APIResource, -) -from openprocurement.auctions.core.validation import ( - validate_file_update, - validate_file_upload, - validate_patch_document_data, -) -from openprocurement.auctions.core.utils import ( - save_auction, - apply_patch, - opresource, -) -from openprocurement.api.views.complaint_document import STATUS4ROLE - - -@opresource(name='dgfOtherAssets:Auction Award Complaint Documents', - collection_path='/auctions/{auction_id}/awards/{award_id}/complaints/{complaint_id}/documents', - path='/auctions/{auction_id}/awards/{award_id}/complaints/{complaint_id}/documents/{document_id}', - auctionsprocurementMethodType="dgfOtherAssets", - description="Auction award complaint documents") -class AuctionAwardComplaintDocumentResource(APIResource): - - @json_view(permission='view_auction') - def collection_get(self): - """Auction Award Complaint Documents List""" - if self.request.params.get('all', ''): - collection_data = [i.serialize("view") for i in self.context.documents] - else: - collection_data = sorted(dict([ - (i.id, i.serialize("view")) - for i in self.context.documents - ]).values(), key=lambda i: i['dateModified']) - return {'data': collection_data} - - @json_view(permission='edit_complaint', validators=(validate_file_upload,)) - def collection_post(self): - """Auction Award Complaint Document Upload - """ - if self.request.validated['auction_status'] not in ['active.qualification', 'active.awarded']: - self.request.errors.add('body', 'data', 'Can\'t add document in current ({}) auction status'.format(self.request.validated['auction_status'])) - self.request.errors.status = 403 - return - if any([i.status != 'active' for i in self.request.validated['auction'].lots if i.id == self.request.validated['award'].lotID]): - self.request.errors.add('body', 'data', 'Can add document only in active lot status') - self.request.errors.status = 403 - return - if self.context.status not in STATUS4ROLE.get(self.request.authenticated_role, []): - self.request.errors.add('body', 'data', 'Can\'t add document in current ({}) complaint status'.format(self.context.status)) - self.request.errors.status = 403 - return - document = upload_file(self.request) - document.author = self.request.authenticated_role - self.context.documents.append(document) - if save_auction(self.request): - self.LOGGER.info('Created auction award complaint document {}'.format(document.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_complaint_document_create'}, {'document_id': document.id})) - self.request.response.status = 201 - document_route = self.request.matched_route.name.replace("collection_", "") - self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={}) - return {'data': document.serialize("view")} - - @json_view(permission='view_auction') - def get(self): - """Auction Award Complaint Document Read""" - if self.request.params.get('download'): - return get_file(self.request) - document = self.request.validated['document'] - document_data = document.serialize("view") - document_data['previousVersions'] = [ - i.serialize("view") - for i in self.request.validated['documents'] - if i.url != document.url - ] - return {'data': document_data} - - @json_view(validators=(validate_file_update,), permission='edit_complaint') - def put(self): - """Auction Award Complaint Document Update""" - if self.request.authenticated_role != self.context.author: - self.request.errors.add('url', 'role', 'Can update document only author') - self.request.errors.status = 403 - return - if self.request.validated['auction_status'] not in ['active.qualification', 'active.awarded']: - self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status'])) - self.request.errors.status = 403 - return - if any([i.status != 'active' for i in self.request.validated['auction'].lots if i.id == self.request.validated['award'].lotID]): - self.request.errors.add('body', 'data', 'Can update document only in active lot status') - self.request.errors.status = 403 - return - if self.request.validated['complaint'].status not in STATUS4ROLE.get(self.request.authenticated_role, []): - self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) complaint status'.format(self.request.validated['complaint'].status)) - self.request.errors.status = 403 - return - document = upload_file(self.request) - document.author = self.request.authenticated_role - self.request.validated['complaint'].documents.append(document) - if save_auction(self.request): - self.LOGGER.info('Updated auction award complaint document {}'.format(self.request.context.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_complaint_document_put'})) - return {'data': document.serialize("view")} - - @json_view(content_type="application/json", validators=(validate_patch_document_data,), permission='edit_complaint') - def patch(self): - """Auction Award Complaint Document Update""" - if self.request.authenticated_role != self.context.author: - self.request.errors.add('url', 'role', 'Can update document only author') - self.request.errors.status = 403 - return - if self.request.validated['auction_status'] not in ['active.qualification', 'active.awarded']: - self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) auction status'.format(self.request.validated['auction_status'])) - self.request.errors.status = 403 - return - if any([i.status != 'active' for i in self.request.validated['auction'].lots if i.id == self.request.validated['award'].lotID]): - self.request.errors.add('body', 'data', 'Can update document only in active lot status') - self.request.errors.status = 403 - return - if self.request.validated['complaint'].status not in STATUS4ROLE.get(self.request.authenticated_role, []): - self.request.errors.add('body', 'data', 'Can\'t update document in current ({}) complaint status'.format(self.request.validated['complaint'].status)) - self.request.errors.status = 403 - return - if apply_patch(self.request, src=self.request.context.serialize()): - update_file_content_type(self.request) - self.LOGGER.info('Updated auction award complaint document {}'.format(self.request.context.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_complaint_document_patch'})) - return {'data': self.request.context.serialize("view")} diff --git a/openprocurement/auctions/dgf/views/other/award_document.py b/openprocurement/auctions/dgf/views/other/award_document.py deleted file mode 100644 index 06f1af94..00000000 --- a/openprocurement/auctions/dgf/views/other/award_document.py +++ /dev/null @@ -1,112 +0,0 @@ -# -*- coding: utf-8 -*- -from openprocurement.api.utils import ( - get_file, - upload_file, - update_file_content_type, - json_view, - context_unpack, - APIResource, -) -from openprocurement.auctions.core.validation import ( - validate_file_update, - validate_file_upload, - validate_patch_document_data, -) -from openprocurement.auctions.core.utils import ( - save_auction, - apply_patch, - opresource, -) - - -@opresource(name='dgfOtherAssets:Auction Award Documents', - collection_path='/auctions/{auction_id}/awards/{award_id}/documents', - path='/auctions/{auction_id}/awards/{award_id}/documents/{document_id}', - auctionsprocurementMethodType="dgfOtherAssets", - description="Auction award documents") -class AuctionAwardDocumentResource(APIResource): - - def validate_award_document(self, operation): - if operation == 'update' and self.request.authenticated_role != self.context.author: - self.request.errors.add('url', 'role', 'Can update document only author') - self.request.errors.status = 403 - return - if self.request.validated['auction_status'] != 'active.qualification': - self.request.errors.add('body', 'data', 'Can\'t {} document in current ({}) auction status'.format(operation, - self.request.validated[ - 'auction_status'])) - self.request.errors.status = 403 - return - if any([i.status != 'active' for i in self.request.validated['auction'].lots if - i.id == self.request.validated['award'].lotID]): - self.request.errors.add('body', 'data', 'Can {} document only in active lot status'.format(operation)) - self.request.errors.status = 403 - return - return True - - @json_view(permission='view_auction') - def collection_get(self): - """Auction Award Documents List""" - if self.request.params.get('all', ''): - collection_data = [i.serialize("view") for i in self.context.documents] - else: - collection_data = sorted(dict([ - (i.id, i.serialize("view")) - for i in self.context.documents - ]).values(), key=lambda i: i['dateModified']) - return {'data': collection_data} - - @json_view(validators=(validate_file_upload,), permission='edit_auction_award') - def collection_post(self): - """Auction Award Document Upload - """ - if not self.validate_award_document('add'): - return - document = upload_file(self.request) - document.author = self.request.authenticated_role - self.context.documents.append(document) - if save_auction(self.request): - self.LOGGER.info('Created auction award document {}'.format(document.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_document_create'}, {'document_id': document.id})) - self.request.response.status = 201 - document_route = self.request.matched_route.name.replace("collection_", "") - self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={}) - return {'data': document.serialize("view")} - - @json_view(permission='view_auction') - def get(self): - """Auction Award Document Read""" - if self.request.params.get('download'): - return get_file(self.request) - document = self.request.validated['document'] - document_data = document.serialize("view") - document_data['previousVersions'] = [ - i.serialize("view") - for i in self.request.validated['documents'] - if i.url != document.url - ] - return {'data': document_data} - - @json_view(validators=(validate_file_update,), permission='edit_auction_award') - def put(self): - """Auction Award Document Update""" - if not self.validate_award_document('update'): - return - document = upload_file(self.request) - document.author = self.request.authenticated_role - self.request.validated['award'].documents.append(document) - if save_auction(self.request): - self.LOGGER.info('Updated auction award document {}'.format(self.request.context.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_document_put'})) - return {'data': document.serialize("view")} - - @json_view(content_type="application/json", validators=(validate_patch_document_data,), permission='edit_auction_award') - def patch(self): - """Auction Award Document Update""" - if not self.validate_award_document('update'): - return - if apply_patch(self.request, src=self.request.context.serialize()): - update_file_content_type(self.request) - self.LOGGER.info('Updated auction award document {}'.format(self.request.context.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_award_document_patch'})) - return {'data': self.request.context.serialize("view")} From 0ba22137b156d57a70b0ba0094894138bee6079b Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 14 Mar 2018 12:09:32 +0200 Subject: [PATCH 02/45] Delete financial award views --- .../auctions/dgf/views/financial/award.py | 17 ----------------- .../dgf/views/financial/award_complaint.py | 16 ---------------- .../views/financial/award_complaint_document.py | 17 ----------------- .../dgf/views/financial/award_document.py | 17 ----------------- 4 files changed, 67 deletions(-) delete mode 100644 openprocurement/auctions/dgf/views/financial/award.py delete mode 100644 openprocurement/auctions/dgf/views/financial/award_complaint.py delete mode 100644 openprocurement/auctions/dgf/views/financial/award_complaint_document.py delete mode 100644 openprocurement/auctions/dgf/views/financial/award_document.py diff --git a/openprocurement/auctions/dgf/views/financial/award.py b/openprocurement/auctions/dgf/views/financial/award.py deleted file mode 100644 index 3be267d3..00000000 --- a/openprocurement/auctions/dgf/views/financial/award.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- - -from openprocurement.auctions.core.utils import ( - opresource, -) -from openprocurement.auctions.dgf.views.other.award import ( - AuctionAwardResource, -) - - -@opresource(name='dgfFinancialAssets:Auction Awards', - collection_path='/auctions/{auction_id}/awards', - path='/auctions/{auction_id}/awards/{award_id}', - auctionsprocurementMethodType="dgfFinancialAssets", - description="Financial auction awards") -class FinancialAuctionAwardResource(AuctionAwardResource): - pass diff --git a/openprocurement/auctions/dgf/views/financial/award_complaint.py b/openprocurement/auctions/dgf/views/financial/award_complaint.py deleted file mode 100644 index 88c04998..00000000 --- a/openprocurement/auctions/dgf/views/financial/award_complaint.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- - -from openprocurement.auctions.core.utils import ( - opresource, -) -from openprocurement.auctions.dgf.views.other.award_complaint import ( - AuctionAwardComplaintResource, -) - -@opresource(name='dgfFinancialAssets:Auction Award Complaints', - collection_path='/auctions/{auction_id}/awards/{award_id}/complaints', - path='/auctions/{auction_id}/awards/{award_id}/complaints/{complaint_id}', - auctionsprocurementMethodType="dgfFinancialAssets", - description="Financial auction award complaints") -class FinancialAuctionAwardComplaintResource(AuctionAwardComplaintResource): - pass \ No newline at end of file diff --git a/openprocurement/auctions/dgf/views/financial/award_complaint_document.py b/openprocurement/auctions/dgf/views/financial/award_complaint_document.py deleted file mode 100644 index 343eb961..00000000 --- a/openprocurement/auctions/dgf/views/financial/award_complaint_document.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- - -from openprocurement.auctions.core.utils import ( - opresource, -) -from openprocurement.auctions.dgf.views.other.award_complaint_document import ( - AuctionAwardComplaintDocumentResource, -) - - -@opresource(name='dgfFinancialAssets:Auction Award Complaint Documents', - collection_path='/auctions/{auction_id}/awards/{award_id}/complaints/{complaint_id}/documents', - path='/auctions/{auction_id}/awards/{award_id}/complaints/{complaint_id}/documents/{document_id}', - auctionsprocurementMethodType="dgfFinancialAssets", - description="Financial auction award complaint documents") -class FinancialAuctionAwardComplaintDocumentResource(AuctionAwardComplaintDocumentResource): - pass \ No newline at end of file diff --git a/openprocurement/auctions/dgf/views/financial/award_document.py b/openprocurement/auctions/dgf/views/financial/award_document.py deleted file mode 100644 index ba972e12..00000000 --- a/openprocurement/auctions/dgf/views/financial/award_document.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- - -from openprocurement.auctions.core.utils import ( - opresource, -) -from openprocurement.auctions.dgf.views.other.award_document import ( - AuctionAwardDocumentResource, -) - - -@opresource(name='dgfFinancialAssets:Auction Award Documents', - collection_path='/auctions/{auction_id}/awards/{award_id}/documents', - path='/auctions/{auction_id}/awards/{award_id}/documents/{document_id}', - auctionsprocurementMethodType="dgfFinancialAssets", - description="Financial auction award documents") -class FinancialAuctionAwardDocumentResource(AuctionAwardDocumentResource): - pass From bd123dc0061d495b129eb06ef83b6ea1190f7964 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 14 Mar 2018 12:10:32 +0200 Subject: [PATCH 03/45] Move functionality of awarding in core.plugins --- openprocurement/auctions/dgf/migration.py | 49 ++----------------- openprocurement/auctions/dgf/utils.py | 58 +---------------------- 2 files changed, 5 insertions(+), 102 deletions(-) diff --git a/openprocurement/auctions/dgf/migration.py b/openprocurement/auctions/dgf/migration.py index 6949c67f..115b837c 100644 --- a/openprocurement/auctions/dgf/migration.py +++ b/openprocurement/auctions/dgf/migration.py @@ -5,6 +5,9 @@ from barbecue import chef from uuid import uuid4 +from openprocurement.auctions.core.plugins.awarding.v2_1.migration import ( + migrate_awarding_1_0_to_awarding_2_1 +) LOGGER = logging.getLogger(__name__) SCHEMA_VERSION = 1 @@ -49,51 +52,7 @@ def __init__(self, registry): docs = [] for i in results: auction = i.doc - if auction['procurementMethodType'] not in ['dgfOtherAssets', 'dgfFinancialAssets'] \ - or auction['status'] not in ['active.qualification', 'active.awarded'] \ - or 'awards' not in auction: - continue - - now = get_now().isoformat() - awards = auction["awards"] - award = [a for a in awards if a['status'] in ['active', 'pending']][0] - award_create_date = award['complaintPeriod']['startDate'] - award.update({ - 'verificationPeriod': { - 'startDate': award_create_date, - 'endDate': award_create_date - }, - 'paymentPeriod': { - 'startDate': award_create_date, - }, - 'signingPeriod': { - 'startDate': award_create_date, - } - }) - - if award['status'] == 'pending': - award['status'] = 'pending.payment' - - elif award['status'] == 'active': - award['paymentPeriod']['endDate'] = now - - awarded_bids = set([a['bid_id'] for a in awards]) - sorted_bids = chef(auction['bids'], auction.get('features'), [], True) - filtered_bids = [bid for bid in sorted_bids if bid['id'] not in awarded_bids] - - for bid in filtered_bids: - award = { - 'id': uuid4().hex, - 'bid_id': bid['id'], - 'status': 'pending.waiting', - 'date': award_create_date, - 'value': bid['value'], - 'suppliers': bid['tenderers'], - 'complaintPeriod': { - 'startDate': award_create_date - } - } - awards.append(award) + migrate_awarding_1_0_to_awarding_2_1(auction) model = registry.auction_procurementMethodTypes.get(auction['procurementMethodType']) if model: diff --git a/openprocurement/auctions/dgf/utils.py b/openprocurement/auctions/dgf/utils.py index 22d9ff05..266d8d48 100644 --- a/openprocurement/auctions/dgf/utils.py +++ b/openprocurement/auctions/dgf/utils.py @@ -17,7 +17,6 @@ from .constants import ( DOCUMENT_TYPE_URL_ONLY, DOCUMENT_TYPE_OFFLINE, - NUMBER_OF_BIDS_TO_BE_QUALIFIED, MINIMAL_PERIOD_FROM_RECTIFICATION_END ) @@ -58,7 +57,7 @@ def check_bids(request): auction.status = 'unsuccessful' elif auction.numberOfBids == 1: auction.auctionPeriod.startDate = None - create_awards(request) + request.content_configurator.start_awarding(request) def check_auction_status(request): @@ -77,61 +76,6 @@ def check_auction_status(request): auction.status = 'complete' -def create_awards(request): - """ - Function create NUMBER_OF_BIDS_TO_BE_QUALIFIED awards objects - First award always in pending.verification status - others in pending.waiting status - """ - auction = request.validated['auction'] - auction.status = 'active.qualification' - now = get_now() - auction.awardPeriod = type(auction).awardPeriod({'startDate': now}) - bids = chef(auction.bids, auction.features or [], [], True) - # minNumberOfQualifiedBids == 1 - bids_to_qualify = NUMBER_OF_BIDS_TO_BE_QUALIFIED \ - if (len(bids) > NUMBER_OF_BIDS_TO_BE_QUALIFIED) \ - else len(bids) - for bid, status in izip_longest(bids[:bids_to_qualify], - ['pending.verification'], - fillvalue='pending.waiting'): - bid = bid.serialize() - award = type(auction).awards.model_class({ - '__parent__': request.context, - 'bid_id': bid['id'], - 'status': status, - 'date': now, - 'value': bid['value'], - 'suppliers': bid['tenderers'], - 'complaintPeriod': {'startDate': now} - }) - if bid['status'] == 'invalid': - award.status = 'unsuccessful' - award.complaintPeriod.endDate = now - if award.status == 'pending.verification': - award.verificationPeriod = award.paymentPeriod = award.signingPeriod = {'startDate': now} - request.response.headers['Location'] = request.route_url('{}:Auction Awards'.format( - auction.procurementMethodType), - auction_id=auction.id, - award_id=award['id']) - auction.awards.append(award) - - -def switch_to_next_award(request): - auction = request.validated['auction'] - now = get_now() - waiting_awards = [i for i in auction.awards if i['status'] == 'pending.waiting'] - if waiting_awards: - award = waiting_awards[0] - award.status = 'pending.verification' - award.verificationPeriod = award.paymentPeriod = award.signingPeriod = {'startDate': now} - request.response.headers['Location'] = request.route_url('{}:Auction Awards'.format(auction.procurementMethodType), auction_id=auction.id, award_id=award['id']) - - elif all([award.status in ['cancelled', 'unsuccessful'] for award in auction.awards]): - auction.awardPeriod.endDate = now - auction.status = 'unsuccessful' - - def check_auction_protocol(award): if award.documents: for document in award.documents: From f6327604b4b4f5824fa2eada611847eb8cf8936e Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 14 Mar 2018 12:10:52 +0200 Subject: [PATCH 04/45] Move constants used in awarding in core.plugins --- openprocurement/auctions/dgf/constants.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openprocurement/auctions/dgf/constants.py b/openprocurement/auctions/dgf/constants.py index 73176f86..bc629612 100644 --- a/openprocurement/auctions/dgf/constants.py +++ b/openprocurement/auctions/dgf/constants.py @@ -42,3 +42,13 @@ def read_json(name): '65', '66', '71', '72', '73', '75', '76', '77', '79', '80', '85', '90', '92', '98') CAV_NON_SPECIFIC_LOCATION_UNITS = ('07', '08') + +#Views location + +FINANCIAL_VIEW_LOCATIONS = [ + "openprocurement.auctions.dgf.views.financial", +] + +OTHER_VIEW_LOCATIONS = [ + "openprocurement.auctions.dgf.views.other", +] From f40eefd7345c44ad00cf9aa778e17d375444ddd7 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 14 Mar 2018 12:11:58 +0200 Subject: [PATCH 05/45] Move part of functionality in next_check in core.plugins and use content_configurator --- openprocurement/auctions/dgf/models.py | 60 +++++++------------------- 1 file changed, 16 insertions(+), 44 deletions(-) diff --git a/openprocurement/auctions/dgf/models.py b/openprocurement/auctions/dgf/models.py index 4a52cf80..324b5e01 100644 --- a/openprocurement/auctions/dgf/models.py +++ b/openprocurement/auctions/dgf/models.py @@ -16,7 +16,8 @@ Classification, validate_items_uniq, ORA_CODES, Address, Location, schematics_embedded_role, SANDBOX_MODE, CPV_CODES, IsoDateTimeType ) -from openprocurement.api.utils import calculate_business_date +from openprocurement.api.utils import calculate_business_date, get_request_from_root +from openprocurement.api.interfaces import IAwardingNextCheck from openprocurement.auctions.core.models import IAuction from openprocurement.auctions.flash.models import ( @@ -105,8 +106,10 @@ class Options: additionalClassifications = ListType(ModelType(AdditionalClassification), default=list()) address = ModelType(Address) location = ModelType(Location) + deliveryDate = None def validate_address(self, data, address): + import pdb; pdb.set_trace() if not address: if get_auction_creation_date(data) > DGF_ADDRESS_REQUIRED_FROM: non_specific_location_cav = data['classification']['scheme'] == u'CAV-PS' and not data['classification']['id'].startswith(CAV_NON_SPECIFIC_LOCATION_UNITS) @@ -350,7 +353,12 @@ class RectificationPeriod(Period): Administrator_role = (Administrator_role + whitelist('awards')) -@implementer(IAuction) + +class IDgfAuction(IAuction): + """Marker interface for Dgf auctions""" + + +@implementer(IDgfAuction) class Auction(BaseAuction): """Data regarding auction process - publicly inviting prospective contractors to submit bids for evaluation and selecting a winner or winners.""" class Options: @@ -450,48 +458,12 @@ def next_check(self): checks.append(lot.auctionPeriod.startDate.astimezone(TZ)) elif now < calc_auction_end_time(lot.numberOfBids, lot.auctionPeriod.startDate).astimezone(TZ): checks.append(calc_auction_end_time(lot.numberOfBids, lot.auctionPeriod.startDate).astimezone(TZ)) - elif not self.lots and self.status == 'active.awarded' and not any([ - i.status in self.block_complaint_status - for i in self.complaints - ]) and not any([ - i.status in self.block_complaint_status - for a in self.awards - for i in a.complaints - ]): - standStillEnds = [ - a.complaintPeriod.endDate.astimezone(TZ) - for a in self.awards - if a.complaintPeriod.endDate - ] - - last_award_status = self.awards[-1].status if self.awards else '' - if standStillEnds and last_award_status == 'unsuccessful': - checks.append(max(standStillEnds)) - elif self.lots and self.status in ['active.qualification', 'active.awarded'] and not any([ - i.status in self.block_complaint_status and i.relatedLot is None - for i in self.complaints - ]): - for lot in self.lots: - if lot['status'] != 'active': - continue - lot_awards = [i for i in self.awards if i.lotID == lot.id] - pending_complaints = any([ - i['status'] in self.block_complaint_status and i.relatedLot == lot.id - for i in self.complaints - ]) - pending_awards_complaints = any([ - i.status in self.block_complaint_status - for a in lot_awards - for i in a.complaints - ]) - standStillEnds = [ - a.complaintPeriod.endDate.astimezone(TZ) - for a in lot_awards - if a.complaintPeriod.endDate - ] - last_award_status = lot_awards[-1].status if lot_awards else '' - if not pending_complaints and not pending_awards_complaints and standStillEnds and last_award_status == 'unsuccessful': - checks.append(max(standStillEnds)) + # Use next_check part from awarding + request = get_request_from_root(self) + if request is not None: + awarding_check = request.registry.getAdapter(self, IAwardingNextCheck).add_awarding_checks(self) + if awarding_check is not None: + checks.append(awarding_check) if self.status.startswith('active'): from openprocurement.api.utils import calculate_business_date for complaint in self.complaints: From cceb24911e048048d581bedc72e0b48ed27f1b75 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 14 Mar 2018 12:12:48 +0200 Subject: [PATCH 06/45] Create adapters and make includeme --- openprocurement/auctions/dgf/adapters.py | 21 ++++++++ openprocurement/auctions/dgf/includeme.py | 59 +++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 openprocurement/auctions/dgf/adapters.py create mode 100644 openprocurement/auctions/dgf/includeme.py diff --git a/openprocurement/auctions/dgf/adapters.py b/openprocurement/auctions/dgf/adapters.py new file mode 100644 index 00000000..55e3833e --- /dev/null +++ b/openprocurement/auctions/dgf/adapters.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from openprocurement.auctions.core.adapters import AuctionConfigurator +from openprocurement.auctions.dgf.models import ( + DGFOtherAssets, + DGFFinancialAssets +) +from openprocurement.auctions.core.plugins.awarding.v2_1.adapters import ( + AwardingV2_1ConfiguratorMixin +) + + +class AuctionDGFOtherAssetsConfigurator(AuctionConfigurator, + AwardingV2_1ConfiguratorMixin): + name = 'Auction Dgf Configurator' + model = DGFOtherAssets + + +class AuctionDGFFinancialAssetsConfigurator(AuctionConfigurator, + AwardingV2_1ConfiguratorMixin): + name = 'Auction Dgf Configurator' + model = DGFFinancialAssets \ No newline at end of file diff --git a/openprocurement/auctions/dgf/includeme.py b/openprocurement/auctions/dgf/includeme.py new file mode 100644 index 00000000..df4790b3 --- /dev/null +++ b/openprocurement/auctions/dgf/includeme.py @@ -0,0 +1,59 @@ +from pyramid.interfaces import IRequest +from openprocurement.auctions.dgf.models import ( + IDgfAuction, + DGFOtherAssets, + DGFFinancialAssets +) +from openprocurement.auctions.dgf.adapters import ( + AuctionDGFOtherAssetsConfigurator, + AuctionDGFFinancialAssetsConfigurator +) +from openprocurement.auctions.core.plugins.awarding.v2_1.adapters import ( + AwardingNextCheckV2_1 +) +from openprocurement.api.interfaces import ( + IContentConfigurator, + IAwardingNextCheck +) +from openprocurement.auctions.dgf.constants import ( + FINANCIAL_VIEW_LOCATIONS, + OTHER_VIEW_LOCATIONS, +) + + +def includeme_other(config): + config.add_auction_procurementMethodType(DGFOtherAssets) + + for view_location in OTHER_VIEW_LOCATIONS: + config.scan(view_location) + + # Register adapters + config.registry.registerAdapter( + AuctionDGFOtherAssetsConfigurator, + (IDgfAuction, IRequest), + IContentConfigurator + ) + config.registry.registerAdapter( + AwardingNextCheckV2_1, + (IDgfAuction, ), + IAwardingNextCheck + ) + + +def includeme_financial(config): + config.add_auction_procurementMethodType(DGFFinancialAssets) + + for view_location in FINANCIAL_VIEW_LOCATIONS: + config.scan(view_location) + + # Register Adapters + config.registry.registerAdapter( + AuctionDGFFinancialAssetsConfigurator, + (IDgfAuction, IRequest), + IContentConfigurator + ) + config.registry.registerAdapter( + AwardingNextCheckV2_1, + (IDgfAuction, ), + IAwardingNextCheck +) \ No newline at end of file From 20c49d19f6b351abe7090312c92054f8ec153fd5 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 14 Mar 2018 12:13:32 +0200 Subject: [PATCH 07/45] Use content_configurator in views --- openprocurement/auctions/dgf/views/other/auction.py | 9 ++++----- openprocurement/auctions/dgf/views/other/cancellation.py | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/openprocurement/auctions/dgf/views/other/auction.py b/openprocurement/auctions/dgf/views/other/auction.py index a1110c8d..0f59eb41 100644 --- a/openprocurement/auctions/dgf/views/other/auction.py +++ b/openprocurement/auctions/dgf/views/other/auction.py @@ -11,7 +11,6 @@ opresource, ) from openprocurement.auctions.dgf.utils import ( - create_awards, invalidate_bids_under_threshold ) from openprocurement.auctions.core.validation import ( @@ -167,8 +166,8 @@ def collection_post(self): apply_patch(self.request, save=False, src=self.request.validated['auction_src']) auction = self.request.validated['auction'] invalidate_bids_under_threshold(auction) - if any([i.status == 'active' for i in auction.bids]): - create_awards(self.request) + if any([i.status == 'active' for i in auction.bids]): + self.request.content_configurator.start_awarding() else: auction.status = 'unsuccessful' if save_auction(self.request): @@ -192,8 +191,8 @@ def post(self): if all([i.auctionPeriod and i.auctionPeriod.endDate for i in auction.lots if i.numberOfBids > 1 and i.status == 'active']): cleanup_bids_for_cancelled_lots(auction) invalidate_bids_under_threshold(auction) - if any([i.status == 'active' for i in auction.bids]): - create_awards(self.request) + if any([i.status == 'active' for i in auction.bids]): + self.request.content_configurator.start_awarding() else: auction.status = 'unsuccessful' if save_auction(self.request): diff --git a/openprocurement/auctions/dgf/views/other/cancellation.py b/openprocurement/auctions/dgf/views/other/cancellation.py index 91cef485..fe7dcd21 100644 --- a/openprocurement/auctions/dgf/views/other/cancellation.py +++ b/openprocurement/auctions/dgf/views/other/cancellation.py @@ -8,7 +8,7 @@ from openprocurement.auctions.core.utils import ( apply_patch, save_auction, - add_next_award, + # add_next_award, opresource, ) From b77e5ec3c54a57168a31863562b8aa96eb7c5f48 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 14 Mar 2018 12:13:48 +0200 Subject: [PATCH 08/45] Update setup.py --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 824201c5..e965b9cd 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,8 @@ entry_points = { 'openprocurement.auctions.core.plugins': [ - 'auctions.dgf = openprocurement.auctions.dgf:includeme' + 'auctions.dgf.other = openprocurement.auctions.dgf.includeme:includeme_other', + 'auctions.dgf.financial = openprocurement.auctions.dgf.includeme:includeme_financial' ], 'openprocurement.api.migrations': [ 'auctions = openprocurement.auctions.dgf.migration:migrate_data' From 89d8fed60eaa05232d6ab09a3ffe7ff787604aa8 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 14 Mar 2018 12:14:00 +0200 Subject: [PATCH 09/45] Update tests.ini --- openprocurement/auctions/dgf/tests/tests.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openprocurement/auctions/dgf/tests/tests.ini b/openprocurement/auctions/dgf/tests/tests.ini index ab3a55da..73d5cb07 100644 --- a/openprocurement/auctions/dgf/tests/tests.ini +++ b/openprocurement/auctions/dgf/tests/tests.ini @@ -12,7 +12,7 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -plugins = auctions.core,auctions.dgf +plugins = auctions.core,auctions.dgf.other,auctions.dgf.financial [server:main] use = egg:chaussette From 2630740e511027c908fe58838b3ef0b3bcd5fba0 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 15 Mar 2018 16:07:14 +0200 Subject: [PATCH 10/45] Move contract views to core.plugins --- .../auctions/dgf/views/financial/contract.py | 17 --- .../dgf/views/financial/contract_document.py | 17 --- .../auctions/dgf/views/other/contract.py | 120 ------------------ .../dgf/views/other/contract_document.py | 111 ---------------- 4 files changed, 265 deletions(-) delete mode 100644 openprocurement/auctions/dgf/views/financial/contract.py delete mode 100644 openprocurement/auctions/dgf/views/financial/contract_document.py delete mode 100644 openprocurement/auctions/dgf/views/other/contract.py delete mode 100644 openprocurement/auctions/dgf/views/other/contract_document.py diff --git a/openprocurement/auctions/dgf/views/financial/contract.py b/openprocurement/auctions/dgf/views/financial/contract.py deleted file mode 100644 index 3ea6501a..00000000 --- a/openprocurement/auctions/dgf/views/financial/contract.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- - -from openprocurement.auctions.core.utils import ( - opresource, -) -from openprocurement.auctions.dgf.views.other.contract import ( - AuctionAwardContractResource, -) - - -@opresource(name='dgfFinancialAssets:Auction Contracts', - collection_path='/auctions/{auction_id}/contracts', - path='/auctions/{auction_id}/contracts/{contract_id}', - auctionsprocurementMethodType="dgfFinancialAssets", - description=" Financial auction contracts") -class FinancialAuctionAwardContractResource(AuctionAwardContractResource): - pass diff --git a/openprocurement/auctions/dgf/views/financial/contract_document.py b/openprocurement/auctions/dgf/views/financial/contract_document.py deleted file mode 100644 index 6a14eaba..00000000 --- a/openprocurement/auctions/dgf/views/financial/contract_document.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- - -from openprocurement.auctions.core.utils import ( - opresource, -) -from openprocurement.auctions.dgf.views.other.contract_document import ( - AuctionAwardContractDocumentResource, -) - - -@opresource(name='dgfFinancialAssets:Auction Contract Documents', - collection_path='/auctions/{auction_id}/contracts/{contract_id}/documents', - path='/auctions/{auction_id}/contracts/{contract_id}/documents/{document_id}', - auctionsprocurementMethodType="dgfFinancialAssets", - description="Financial auction contract documents") -class FinancialAuctionAwardContractDocumentResource(AuctionAwardContractDocumentResource): - pass diff --git a/openprocurement/auctions/dgf/views/other/contract.py b/openprocurement/auctions/dgf/views/other/contract.py deleted file mode 100644 index ef4cc136..00000000 --- a/openprocurement/auctions/dgf/views/other/contract.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: utf-8 -*- -from openprocurement.api.models import get_now -from openprocurement.api.utils import ( - json_view, - context_unpack, - APIResource, -) -from openprocurement.auctions.core.utils import ( - apply_patch, - save_auction, - opresource, -) -from openprocurement.auctions.dgf.utils import check_auction_status -from openprocurement.auctions.core.validation import ( - validate_contract_data, - validate_patch_contract_data, -) - - -@opresource(name='dgfOtherAssets:Auction Contracts', - collection_path='/auctions/{auction_id}/contracts', - path='/auctions/{auction_id}/contracts/{contract_id}', - auctionsprocurementMethodType="dgfOtherAssets", - description="Auction contracts") -class AuctionAwardContractResource(APIResource): - - @json_view(content_type="application/json", permission='create_contract', validators=(validate_contract_data,)) - def collection_post(self): - """Post a contract for award - """ - auction = self.request.validated['auction'] - if auction.status not in ['active.qualification', 'active.awarded']: - self.request.errors.add('body', 'data', 'Can\'t add contract in current ({}) auction status'.format(auction.status)) - self.request.errors.status = 403 - return - contract = self.request.validated['contract'] - auction.contracts.append(contract) - if save_auction(self.request): - self.LOGGER.info('Created auction contract {}'.format(contract.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_contract_create'}, {'contract_id': contract.id})) - self.request.response.status = 201 - route = self.request.matched_route.name.replace("collection_", "") - self.request.response.headers['Location'] = self.request.current_route_url(_route_name=route, contract_id=contract.id, _query={}) - return {'data': contract.serialize()} - - @json_view(permission='view_auction') - def collection_get(self): - """List contracts for award - """ - return {'data': [i.serialize() for i in self.request.context.contracts]} - - @json_view(permission='view_auction') - def get(self): - """Retrieving the contract for award - """ - return {'data': self.request.validated['contract'].serialize()} - - @json_view(content_type="application/json", permission='edit_auction', validators=(validate_patch_contract_data,)) - def patch(self): - """Update of contract - """ - if self.request.validated['auction_status'] not in ['active.qualification', 'active.awarded']: - self.request.errors.add('body', 'data', 'Can\'t update contract in current ({}) auction status'.format(self.request.validated['auction_status'])) - self.request.errors.status = 403 - return - auction = self.request.validated['auction'] - if any([i.status != 'active' for i in auction.lots if i.id in [a.lotID for a in auction.awards if a.id == self.request.context.awardID]]): - self.request.errors.add('body', 'data', 'Can update contract only in active lot status') - self.request.errors.status = 403 - return - data = self.request.validated['data'] - - if data['value']: - for ro_attr in ('valueAddedTaxIncluded', 'currency'): - if data['value'][ro_attr] != getattr(self.context.value, ro_attr): - self.request.errors.add('body', 'data', 'Can\'t update {} for contract value'.format(ro_attr)) - self.request.errors.status = 403 - return - - award = [a for a in auction.awards if a.id == self.request.context.awardID][0] - if data['value']['amount'] < award.value.amount: - self.request.errors.add('body', 'data', 'Value amount should be greater or equal to awarded amount ({})'.format(award.value.amount)) - self.request.errors.status = 403 - return - - if self.request.context.status != 'active' and 'status' in data and data['status'] == 'active': - award = [a for a in auction.awards if a.id == self.request.context.awardID][0] - stand_still_end = award.complaintPeriod.endDate - if stand_still_end > get_now(): - self.request.errors.add('body', 'data', 'Can\'t sign contract before stand-still period end ({})'.format(stand_still_end.isoformat())) - self.request.errors.status = 403 - return - pending_complaints = [ - i - for i in auction.complaints - if i.status in ['claim', 'answered', 'pending'] and i.relatedLot in [None, award.lotID] - ] - pending_awards_complaints = [ - i - for a in auction.awards - for i in a.complaints - if i.status in ['claim', 'answered', 'pending'] and a.lotID == award.lotID - ] - if pending_complaints or pending_awards_complaints: - self.request.errors.add('body', 'data', 'Can\'t sign contract before reviewing all complaints') - self.request.errors.status = 403 - return - contract_status = self.request.context.status - apply_patch(self.request, save=False, src=self.request.context.serialize()) - if contract_status != self.request.context.status and (contract_status != 'pending' or self.request.context.status != 'active'): - self.request.errors.add('body', 'data', 'Can\'t update contract status') - self.request.errors.status = 403 - return - if self.request.context.status == 'active' and not self.request.context.dateSigned: - self.request.context.dateSigned = get_now() - check_auction_status(self.request) - if save_auction(self.request): - self.LOGGER.info('Updated auction contract {}'.format(self.request.context.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_contract_patch'})) - return {'data': self.request.context.serialize()} diff --git a/openprocurement/auctions/dgf/views/other/contract_document.py b/openprocurement/auctions/dgf/views/other/contract_document.py deleted file mode 100644 index 852969a4..00000000 --- a/openprocurement/auctions/dgf/views/other/contract_document.py +++ /dev/null @@ -1,111 +0,0 @@ -# -*- coding: utf-8 -*- -from openprocurement.api.utils import ( - get_file, - upload_file, - update_file_content_type, - json_view, - context_unpack, - APIResource, -) -from openprocurement.auctions.core.validation import ( - validate_file_update, - validate_file_upload, - validate_patch_document_data, -) -from openprocurement.auctions.core.utils import ( - save_auction, - apply_patch, - opresource, -) - - -@opresource(name='dgfOtherAssets:Auction Contract Documents', - collection_path='/auctions/{auction_id}/contracts/{contract_id}/documents', - path='/auctions/{auction_id}/contracts/{contract_id}/documents/{document_id}', - auctionsprocurementMethodType="dgfOtherAssets", - description="Auction contract documents") -class AuctionAwardContractDocumentResource(APIResource): - - def validate_contract_document(self, operation): - if self.request.validated['auction_status'] not in ['active.qualification', 'active.awarded']: - self.request.errors.add('body', 'data', 'Can\'t {} document in current ({}) auction status'.format(operation, - self.request.validated[ - 'auction_status'])) - self.request.errors.status = 403 - return - if any([i.status != 'active' for i in self.request.validated['auction'].lots if - i.id in [a.lotID for a in self.request.validated['auction'].awards if - a.id == self.request.validated['contract'].awardID]]): - self.request.errors.add('body', 'data', 'Can {} document only in active lot status'.format(operation)) - self.request.errors.status = 403 - return - if self.request.validated['contract'].status not in ['pending', 'active']: - self.request.errors.add('body', 'data', 'Can\'t {} document in current contract status'.format(operation)) - self.request.errors.status = 403 - return - return True - - @json_view(permission='view_auction') - def collection_get(self): - """Auction Contract Documents List""" - if self.request.params.get('all', ''): - collection_data = [i.serialize("view") for i in self.context.documents] - else: - collection_data = sorted(dict([ - (i.id, i.serialize("view")) - for i in self.context.documents - ]).values(), key=lambda i: i['dateModified']) - return {'data': collection_data} - - @json_view(permission='edit_auction', validators=(validate_file_upload,)) - def collection_post(self): - """Auction Contract Document Upload - """ - if not self.validate_contract_document('add'): - return - document = upload_file(self.request) - self.context.documents.append(document) - if save_auction(self.request): - self.LOGGER.info('Created auction contract document {}'.format(document.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_contract_document_create'}, {'document_id': document.id})) - self.request.response.status = 201 - document_route = self.request.matched_route.name.replace("collection_", "") - self.request.response.headers['Location'] = self.request.current_route_url(_route_name=document_route, document_id=document.id, _query={}) - return {'data': document.serialize("view")} - - @json_view(permission='view_auction') - def get(self): - """Auction Contract Document Read""" - if self.request.params.get('download'): - return get_file(self.request) - document = self.request.validated['document'] - document_data = document.serialize("view") - document_data['previousVersions'] = [ - i.serialize("view") - for i in self.request.validated['documents'] - if i.url != document.url - ] - return {'data': document_data} - - @json_view(validators=(validate_file_update,), permission='edit_auction') - def put(self): - """Auction Contract Document Update""" - if not self.validate_contract_document('update'): - return - document = upload_file(self.request) - self.request.validated['contract'].documents.append(document) - if save_auction(self.request): - self.LOGGER.info('Updated auction contract document {}'.format(self.request.context.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_contract_document_put'})) - return {'data': document.serialize("view")} - - @json_view(content_type="application/json", validators=(validate_patch_document_data,), permission='edit_auction') - def patch(self): - """Auction Contract Document Update""" - if not self.validate_contract_document('update'): - return - if apply_patch(self.request, src=self.request.context.serialize()): - update_file_content_type(self.request) - self.LOGGER.info('Updated auction contract document {}'.format(self.request.context.id), - extra=context_unpack(self.request, {'MESSAGE_ID': 'auction_contract_document_patch'})) - return {'data': self.request.context.serialize("view")} From 71d3e7bd7862b41b52d8b2e6e317321146d3f35a Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 15 Mar 2018 16:09:16 +0200 Subject: [PATCH 11/45] Move constants to core.constants --- openprocurement/auctions/dgf/constants.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/openprocurement/auctions/dgf/constants.py b/openprocurement/auctions/dgf/constants.py index bc629612..dc5f43d6 100644 --- a/openprocurement/auctions/dgf/constants.py +++ b/openprocurement/auctions/dgf/constants.py @@ -25,30 +25,22 @@ def read_json(name): #time constants DGF_ID_REQUIRED_FROM = datetime(2017, 1, 1, tzinfo=TZ) DGF_DECISION_REQUIRED_FROM = datetime(2017, 1, 1, tzinfo=TZ) -CLASSIFICATION_PRECISELY_FROM = datetime(2017, 7, 19, tzinfo=TZ) MINIMAL_EXPOSITION_REQUIRED_FROM = datetime(2017, 11, 17, tzinfo=TZ) -DGF_ADDRESS_REQUIRED_FROM = datetime(2020, 2, 8, tzinfo=TZ) -#codes -CAVPS_CODES = read_json('cav_ps.json') -CPVS_CODES = read_json('cpvs.json') +DGF_ADDRESS_REQUIRED_FROM = datetime(2020, 2, 8, tzinfo=TZ) ORA_CODES[0:0] = ["UA-IPN", "UA-FIN"] NUMBER_OF_BIDS_TO_BE_QUALIFIED = 2 -#code units -CPV_NON_SPECIFIC_LOCATION_UNITS = ('45', '48', '50', '51', '55', '60', '63', '64', - '65', '66', '71', '72', '73', '75', '76', '77', - '79', '80', '85', '90', '92', '98') -CAV_NON_SPECIFIC_LOCATION_UNITS = ('07', '08') - #Views location FINANCIAL_VIEW_LOCATIONS = [ "openprocurement.auctions.dgf.views.financial", + "openprocurement.auctions.core.plugins", ] OTHER_VIEW_LOCATIONS = [ "openprocurement.auctions.dgf.views.other", + "openprocurement.auctions.core.plugins", ] From f81c18d50232380be4ec82d10c6dcdefe0d2e260 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 15 Mar 2018 16:14:12 +0200 Subject: [PATCH 12/45] Fix imports --- openprocurement/auctions/dgf/tests/tender.py | 7 +++++-- openprocurement/auctions/dgf/views/other/cancellation.py | 3 +-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/openprocurement/auctions/dgf/tests/tender.py b/openprocurement/auctions/dgf/tests/tender.py index 669fa78b..8bb7df5d 100644 --- a/openprocurement/auctions/dgf/tests/tender.py +++ b/openprocurement/auctions/dgf/tests/tender.py @@ -11,9 +11,12 @@ from openprocurement.auctions.dgf.constants import ( MINIMAL_PERIOD_FROM_RECTIFICATION_END ) -from openprocurement.auctions.dgf.models import DGFOtherAssets, DGFFinancialAssets, DGF_ID_REQUIRED_FROM, CLASSIFICATION_PRECISELY_FROM, DGF_ADDRESS_REQUIRED_FROM +from openprocurement.auctions.dgf.models import DGFOtherAssets, DGFFinancialAssets, DGF_ID_REQUIRED_FROM from openprocurement.auctions.dgf.tests.base import test_auction_maximum_data, test_auction_data, test_financial_auction_data, test_organization, test_financial_organization, BaseWebTest, BaseAuctionWebTest, DEFAULT_ACCELERATION, test_bids, test_financial_bids - +from openprocurement.auctions.core.constants import ( + DGF_CDB2_CLASSIFICATION_PRECISELY_FROM as CLASSIFICATION_PRECISELY_FROM, + DGF_CDB2_ADDRESS_REQUIRED_FROM as DGF_ADDRESS_REQUIRED_FROM +) class AuctionTest(BaseWebTest): auction = DGFOtherAssets diff --git a/openprocurement/auctions/dgf/views/other/cancellation.py b/openprocurement/auctions/dgf/views/other/cancellation.py index fe7dcd21..5fac8d97 100644 --- a/openprocurement/auctions/dgf/views/other/cancellation.py +++ b/openprocurement/auctions/dgf/views/other/cancellation.py @@ -8,7 +8,6 @@ from openprocurement.auctions.core.utils import ( apply_patch, save_auction, - # add_next_award, opresource, ) @@ -49,7 +48,7 @@ def cancel_lot(self, cancellation=None): for i in self.request.validated['auction'].lots if i.numberOfBids > 1 and i.status == 'active' ]): - add_next_award(self.request) + self.request.content_configurator.start_awarding() @json_view(content_type="application/json", validators=(validate_cancellation_data,), permission='edit_auction') def collection_post(self): From e5d90dcd788f4e0f8e63d6209368aec9c4568a3c Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 15 Mar 2018 16:14:49 +0200 Subject: [PATCH 13/45] Move models(Item, Document, Complaint) to core.models --- openprocurement/auctions/dgf/models.py | 237 +++---------------------- 1 file changed, 20 insertions(+), 217 deletions(-) diff --git a/openprocurement/auctions/dgf/models.py b/openprocurement/auctions/dgf/models.py index 324b5e01..83103623 100644 --- a/openprocurement/auctions/dgf/models.py +++ b/openprocurement/auctions/dgf/models.py @@ -21,27 +21,34 @@ from openprocurement.auctions.core.models import IAuction from openprocurement.auctions.flash.models import ( - Auction as BaseAuction, Document as BaseDocument, Bid as BaseBid, - Complaint as BaseComplaint, Cancellation as BaseCancellation, - Contract as BaseContract, Award as BaseAward, Lot, edit_role, + Auction as BaseAuction, Bid as BaseBid, + Cancellation as BaseCancellation, + Lot, edit_role, calc_auction_end_time, COMPLAINT_STAND_STILL_TIME, - Organization as BaseOrganization, Item as BaseItem, ProcuringEntity as BaseProcuringEntity, Question as BaseQuestion, get_auction, Administrator_role ) + +from openprocurement.auctions.core.models import ( + dgfCDB2Document as Document, + dgfCDB2Item as Item, + dgfOrganization as Organization, + dgfCDB2Complaint as Complaint, + Identifier +) + +from openprocurement.auctions.core.plugins.awarding.v2_1.models import Award +from openprocurement.auctions.core.plugins.contracting.v2_1.models import Contract + from .utils import calculate_enddate, get_auction_creation_date, generate_rectificationPeriod from .constants import ( - AWARD_PAYMENT_TIME, CONTRACT_SIGNING_TIME, - VERIFY_AUCTION_PROTOCOL_TIME, DOCUMENT_TYPE_OFFLINE, - DOCUMENT_TYPE_URL_ONLY, CLASSIFICATION_PRECISELY_FROM, - DGF_ID_REQUIRED_FROM, CAVPS_CODES, - CPVS_CODES, ORA_CODES, MINIMAL_EXPOSITION_PERIOD, + DOCUMENT_TYPE_OFFLINE, + DOCUMENT_TYPE_URL_ONLY, + DGF_ID_REQUIRED_FROM, + ORA_CODES, MINIMAL_EXPOSITION_PERIOD, MINIMAL_EXPOSITION_REQUIRED_FROM, - CPV_NON_SPECIFIC_LOCATION_UNITS, - CAV_NON_SPECIFIC_LOCATION_UNITS, - DGF_ADDRESS_REQUIRED_FROM, MINIMAL_PERIOD_FROM_RECTIFICATION_END ) @@ -75,139 +82,11 @@ def validator(klass, data, value): return validator -class CPVCAVClassification(Classification): - scheme = StringType(required=True, default=u'CPV', choices=[u'CPV', u'CAV-PS']) - id = StringType(required=True) - - def validate_id(self, data, code): - auction = get_auction(data['__parent__']) - if data.get('scheme') == u'CPV' and code not in CPV_CODES: - raise ValidationError(BaseType.MESSAGES['choices'].format(unicode(CPV_CODES))) - elif data.get('scheme') == u'CAV-PS' and code not in CAVPS_CODES: - raise ValidationError(BaseType.MESSAGES['choices'].format(unicode(CAVPS_CODES))) - if code.find("00000-") > 0 and get_auction_creation_date(data) > CLASSIFICATION_PRECISELY_FROM: - raise ValidationError('At least {} classification class (XXXX0000-Y) should be specified more precisely'.format(data.get('scheme'))) - - -class AdditionalClassification(Classification): - def validate_id(self, data, code): - if data.get('scheme') == u'CPVS' and code not in CPVS_CODES: - raise ValidationError(BaseType.MESSAGES['choices'].format(unicode(CPVS_CODES))) - - -class Item(BaseItem): - """A good, service, or work to be contracted.""" - class Options: - roles = { - 'create': blacklist('deliveryLocation', 'deliveryAddress'), - 'edit_active.tendering': blacklist('deliveryLocation', 'deliveryAddress'), - } - classification = ModelType(CPVCAVClassification, required=True) - additionalClassifications = ListType(ModelType(AdditionalClassification), default=list()) - address = ModelType(Address) - location = ModelType(Location) - deliveryDate = None - - def validate_address(self, data, address): - import pdb; pdb.set_trace() - if not address: - if get_auction_creation_date(data) > DGF_ADDRESS_REQUIRED_FROM: - non_specific_location_cav = data['classification']['scheme'] == u'CAV-PS' and not data['classification']['id'].startswith(CAV_NON_SPECIFIC_LOCATION_UNITS) - non_specific_location_cpv = data['classification']['scheme'] == u'CPV' and not data['classification']['id'].startswith(CPV_NON_SPECIFIC_LOCATION_UNITS) - if non_specific_location_cav or non_specific_location_cpv: - raise ValidationError(u'This field is required.') - - -class Identifier(BaseIdentifier): - scheme = StringType(required=True, choices=ORA_CODES) - - -class Organization(BaseOrganization): - identifier = ModelType(Identifier, required=True) - additionalIdentifiers = ListType(ModelType(Identifier)) - - class ProcuringEntity(BaseProcuringEntity): identifier = ModelType(Identifier, required=True) additionalIdentifiers = ListType(ModelType(Identifier)) -class Document(BaseDocument): - format = StringType(regex='^[-\w]+/[-\.\w\+]+$') - url = StringType() - index = IntType() - accessDetails = StringType() - documentType = StringType(choices=[ - 'auctionNotice', 'awardNotice', 'contractNotice', - 'notice', 'biddingDocuments', 'technicalSpecifications', - 'evaluationCriteria', 'clarifications', 'shortlistedFirms', - 'riskProvisions', 'billOfQuantity', 'bidders', 'conflictOfInterest', - 'debarments', 'evaluationReports', 'winningBid', 'complaints', - 'contractSigned', 'contractArrangements', 'contractSchedule', - 'contractAnnexe', 'contractGuarantees', 'subContract', - 'eligibilityCriteria', 'contractProforma', 'commercialProposal', - 'qualificationDocuments', 'eligibilityDocuments', 'tenderNotice', - 'illustration', 'auctionProtocol', 'x_dgfAssetFamiliarization', - 'x_presentation', 'x_nda' - ]) - - @serializable(serialized_name="url", serialize_when_none=False) - def download_url(self): - url = self.url - if not url or '?download=' not in url: - return url - doc_id = parse_qs(urlparse(url).query)['download'][-1] - root = self.__parent__ - parents = [] - while root.__parent__ is not None: - parents[0:0] = [root] - root = root.__parent__ - request = root.request - if not request.registry.docservice_url: - return url - if 'status' in parents[0] and parents[0].status in type(parents[0])._options.roles: - role = parents[0].status - for index, obj in enumerate(parents): - if obj.id != url.split('/')[(index - len(parents)) * 2 - 1]: - break - field = url.split('/')[(index - len(parents)) * 2] - if "_" in field: - field = field[0] + field.title().replace("_", "")[1:] - roles = type(obj)._options.roles - if roles[role if role in roles else 'default'](field, []): - return url - from openprocurement.api.utils import generate_docservice_url - if not self.hash: - path = [i for i in urlparse(url).path.split('/') if len(i) == 32 and not set(i).difference(hexdigits)] - return generate_docservice_url(request, doc_id, False, '{}/{}'.format(path[0], path[-1])) - return generate_docservice_url(request, doc_id, False) - - def validate_hash(self, data, hash_): - doc_type = data.get('documentType') - if doc_type in (DOCUMENT_TYPE_URL_ONLY + DOCUMENT_TYPE_OFFLINE) and hash_: - raise ValidationError(u'This field is not required.') - - def validate_format(self, data, format_): - doc_type = data.get('documentType') - if doc_type not in (DOCUMENT_TYPE_URL_ONLY + DOCUMENT_TYPE_OFFLINE) and not format_: - raise ValidationError(u'This field is required.') - if doc_type in DOCUMENT_TYPE_URL_ONLY and format_: - raise ValidationError(u'This field is not required.') - - def validate_url(self, data, url): - doc_type = data.get('documentType') - if doc_type in DOCUMENT_TYPE_URL_ONLY: - URLType().validate(url) - if doc_type in DOCUMENT_TYPE_OFFLINE and url: - raise ValidationError(u'This field is not required.') - if doc_type not in DOCUMENT_TYPE_OFFLINE and not url: - raise ValidationError(u'This field is required.') - - def validate_accessDetails(self, data, accessDetails): - if data.get('documentType') in DOCUMENT_TYPE_OFFLINE and not accessDetails: - raise ValidationError(u'This field is required.') - - class Bid(BaseBid): class Options: roles = { @@ -227,86 +106,10 @@ class Question(BaseQuestion): author = ModelType(Organization, required=True) -class Complaint(BaseComplaint): - author = ModelType(Organization, required=True) - documents = ListType(ModelType(Document), default=list()) - - class Cancellation(BaseCancellation): documents = ListType(ModelType(Document), default=list()) -class Contract(BaseContract): - items = ListType(ModelType(Item)) - suppliers = ListType(ModelType(Organization), min_size=1, max_size=1) - complaints = ListType(ModelType(Complaint), default=list()) - documents = ListType(ModelType(Document), default=list()) - - -class Award(BaseAward): - class Options: - roles = { - 'create': blacklist('id', 'status', 'date', 'documents', 'complaints', 'complaintPeriod', 'verificationPeriod', 'paymentPeriod', 'signingPeriod'), - 'Administrator': whitelist('verificationPeriod', 'paymentPeriod', 'signingPeriod'), - } - - def __local_roles__(self): - auction = get_auction(self) - for bid in auction.bids: - if bid.id == self.bid_id: - bid_owner = bid.owner - bid_owner_token = bid.owner_token - return dict([('{}_{}'.format(bid_owner, bid_owner_token), 'bid_owner')]) - - def __acl__(self): - auction = get_auction(self) - for bid in auction.bids: - if bid.id == self.bid_id: - bid_owner = bid.owner - bid_owner_token = bid.owner_token - return [(Allow, '{}_{}'.format(bid_owner, bid_owner_token), 'edit_auction_award')] - - # pending status is deprecated. Only for backward compatibility with awarding 1.0 - status = StringType(required=True, choices=['pending.waiting', 'pending.verification', 'pending.payment', 'unsuccessful', 'active', 'cancelled', 'pending'], default='pending.verification') - suppliers = ListType(ModelType(Organization), min_size=1, max_size=1) - complaints = ListType(ModelType(Complaint), default=list()) - documents = ListType(ModelType(Document), default=list()) - items = ListType(ModelType(Item)) - verificationPeriod = ModelType(Period) - paymentPeriod = ModelType(Period) - signingPeriod = ModelType(Period) - - @serializable(serialized_name="verificationPeriod", serialize_when_none=False) - def award_verificationPeriod(self): - period = self.verificationPeriod - if not period: - return - if not period.endDate: - auction = get_auction(self) - calculate_enddate(auction, period, VERIFY_AUCTION_PROTOCOL_TIME) - return period.to_primitive() - - @serializable(serialized_name="paymentPeriod", serialize_when_none=False) - def award_paymentPeriod(self): - period = self.paymentPeriod - if not period: - return - if not period.endDate: - auction = get_auction(self) - calculate_enddate(auction, period, AWARD_PAYMENT_TIME) - return period.to_primitive() - - @serializable(serialized_name="signingPeriod", serialize_when_none=False) - def award_signingPeriod(self): - period = self.signingPeriod - if not period: - return - if not period.endDate: - auction = get_auction(self) - calculate_enddate(auction, period, CONTRACT_SIGNING_TIME) - return period.to_primitive() - - def validate_not_available(items, *args): if items: raise ValidationError(u"Option not available in this procurementMethodType") @@ -490,7 +293,7 @@ def validate_ua_fin(items, *args): raise ValidationError(u"One of additional classifications should be UA-FIN.") -class FinantialOrganization(BaseOrganization): +class FinantialOrganization(Organization): identifier = ModelType(Identifier, required=True) additionalIdentifiers = ListType(ModelType(Identifier), required=True, validators=[validate_ua_fin]) From cfa2e5aa67f22302c29ff80f6fda6ff12f3eb4ee Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 15 Mar 2018 16:15:37 +0200 Subject: [PATCH 14/45] Move functionality to core.plugins --- openprocurement/auctions/dgf/utils.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/openprocurement/auctions/dgf/utils.py b/openprocurement/auctions/dgf/utils.py index 266d8d48..61fd2349 100644 --- a/openprocurement/auctions/dgf/utils.py +++ b/openprocurement/auctions/dgf/utils.py @@ -57,23 +57,7 @@ def check_bids(request): auction.status = 'unsuccessful' elif auction.numberOfBids == 1: auction.auctionPeriod.startDate = None - request.content_configurator.start_awarding(request) - - -def check_auction_status(request): - auction = request.validated['auction'] - if auction.awards: - awards_statuses = set([award.status for award in auction.awards]) - else: - awards_statuses = set([""]) - if not awards_statuses.difference(set(['unsuccessful', 'cancelled'])): - LOGGER.info('Switched auction {} to {}'.format(auction.id, 'unsuccessful'), - extra=context_unpack(request, {'MESSAGE_ID': 'switched_auction_unsuccessful'})) - auction.status = 'unsuccessful' - if auction.contracts and auction.contracts[-1].status == 'active': - LOGGER.info('Switched auction {} to {}'.format(auction.id, 'complete'), - extra=context_unpack(request, {'MESSAGE_ID': 'switched_auction_complete'})) - auction.status = 'complete' + request.content_configurator.start_awarding() def check_auction_protocol(award): From 001d67a873caea72b3a37c58a4b61a82ea8b03e4 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 15 Mar 2018 16:15:49 +0200 Subject: [PATCH 15/45] Fix migration --- openprocurement/auctions/dgf/migration.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openprocurement/auctions/dgf/migration.py b/openprocurement/auctions/dgf/migration.py index 115b837c..76872e6e 100644 --- a/openprocurement/auctions/dgf/migration.py +++ b/openprocurement/auctions/dgf/migration.py @@ -26,7 +26,9 @@ def set_db_schema_version(db, version): def migrate_data(registry, destination=None): - if registry.settings.get('plugins') and 'auctions.dgf' not in registry.settings['plugins'].split(','): # pragma: no cover + existing_plugins = (dgf in registry.settings['plugins'].split(',') for dgf in + ('auctions.dgf.other', 'auctions.dgf.financial')) + if registry.settings.get('plugins') and not any(existing_plugins): return cur_version = get_db_schema_version(registry.db) if cur_version == SCHEMA_VERSION: From 21aafb428adb7e6a0b9655b9c3cfb216f900f321 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 21 Mar 2018 13:15:15 +0200 Subject: [PATCH 16/45] Fix constants --- openprocurement/auctions/dgf/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openprocurement/auctions/dgf/constants.py b/openprocurement/auctions/dgf/constants.py index dc5f43d6..996a5b0f 100644 --- a/openprocurement/auctions/dgf/constants.py +++ b/openprocurement/auctions/dgf/constants.py @@ -16,7 +16,7 @@ def read_json(name): DOCUMENT_TYPE_URL_ONLY = ['virtualDataRoom'] #requiremnt periods -MINIMAL_EXPOSITION_PERIOD = timedelta(days=7) +MINIMAL_EXPOSITION_PERIOD = timedelta(days=6) MINIMAL_PERIOD_FROM_RECTIFICATION_END = timedelta(days=5) VERIFY_AUCTION_PROTOCOL_TIME = timedelta(days=6) AWARD_PAYMENT_TIME = timedelta(days=20) From eac5eccc3a246fa512641398672a925a1bb1e959 Mon Sep 17 00:00:00 2001 From: Andrew Leitsius Date: Thu, 22 Mar 2018 12:58:07 +0200 Subject: [PATCH 17/45] Update buildout.cfg --- buildout.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/buildout.cfg b/buildout.cfg index dd3fd4cb..f3719d11 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -21,6 +21,6 @@ eggs = [sources] -openprocurement.api = git https://github.com/prozorro-sale/openprocurement.api.git -openprocurement.auctions.flash = git https://github.com/prozorro-sale/openprocurement.auctions.flash.git -openprocurement.auctions.core = git https://github.com/prozorro-sale/openprocurement.auctions.core.git +openprocurement.api = git ${remotes:gh}openprocurement/openprocurement.api.git pushurl=${remotes:gh_push}openprocurement/openprocurement.api.git branch=a499878011598746_separating_awarding +openprocurement.auctions.core = git ${remotes:gh}openprocurement/openprocurement.auctions.core.git pushurl=${remotes:gh_push}openprocurement/openprocurement.auctions.core.git branch=a499878011598746_separating_awarding +openprocurement.auctions.flash = git ${remotes:gh}openprocurement/openprocurement.auctions.flash.git pushurl=${remotes:gh_push}openprocurement/openprocurement.auctions.flash.git branch=a499878011598746_separating_awarding From d11d1b21a90a60dbf5301f4cfb330af1d9e8ecae Mon Sep 17 00:00:00 2001 From: Andrew Leitsius Date: Thu, 22 Mar 2018 13:15:31 +0200 Subject: [PATCH 18/45] Update buildout.cfg --- buildout.cfg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/buildout.cfg b/buildout.cfg index f3719d11..dfe9bbc2 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -20,6 +20,10 @@ eggs = nose +[remotes] +gh=https://github.com/ +gh_push=git@github.com: + [sources] openprocurement.api = git ${remotes:gh}openprocurement/openprocurement.api.git pushurl=${remotes:gh_push}openprocurement/openprocurement.api.git branch=a499878011598746_separating_awarding openprocurement.auctions.core = git ${remotes:gh}openprocurement/openprocurement.auctions.core.git pushurl=${remotes:gh_push}openprocurement/openprocurement.auctions.core.git branch=a499878011598746_separating_awarding From c7ae76e646e7191dc2a8dacd7318ae8d62803163 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 15:52:39 +0200 Subject: [PATCH 19/45] Fix imports --- openprocurement/auctions/dgf/models.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/openprocurement/auctions/dgf/models.py b/openprocurement/auctions/dgf/models.py index 83103623..3bcab057 100644 --- a/openprocurement/auctions/dgf/models.py +++ b/openprocurement/auctions/dgf/models.py @@ -23,14 +23,18 @@ from openprocurement.auctions.flash.models import ( Auction as BaseAuction, Bid as BaseBid, Cancellation as BaseCancellation, - Lot, edit_role, - calc_auction_end_time, COMPLAINT_STAND_STILL_TIME, + Lot, ProcuringEntity as BaseProcuringEntity, Question as BaseQuestion, - get_auction, Administrator_role + get_auction ) from openprocurement.auctions.core.models import ( + IAuction, + calc_auction_end_time, + edit_role, + COMPLAINT_STAND_STILL_TIME, + Administrator_role, dgfCDB2Document as Document, dgfCDB2Item as Item, dgfOrganization as Organization, From 577892134d199049791d89d25cca4d91c2dccfd4 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 18:52:20 +0200 Subject: [PATCH 20/45] Move auction tests to blank use existed mixins from core --- openprocurement/auctions/dgf/tests/auction.py | 998 +----------------- .../dgf/tests/blanks/auction_blanks.py | 309 ++++++ 2 files changed, 340 insertions(+), 967 deletions(-) create mode 100644 openprocurement/auctions/dgf/tests/blanks/auction_blanks.py diff --git a/openprocurement/auctions/dgf/tests/auction.py b/openprocurement/auctions/dgf/tests/auction.py index d95a0102..874437af 100644 --- a/openprocurement/auctions/dgf/tests/auction.py +++ b/openprocurement/auctions/dgf/tests/auction.py @@ -9,278 +9,35 @@ test_financial_auction_data, test_financial_bids, test_financial_organization, test_auction_data ) +from openprocurement.auctions.core.tests.auctions import ( + AuctionAuctionResourceTestMixin, + AuctionLotAuctionResourceTestMixin, + AuctionMultipleLotAuctionResourceTestMixin +) +from openprocurement.auctions.core.tests.base import snitch + +from openprocurement.auctions.dgf.tests.blanks.auction_blanks import ( + # AuctionAuctionResourceTest + post_auction_auction, + # AuctionLotAuctionResourceTest + post_auction_auction_lot, + # AuctionMultipleLotAuctionResourceTest + post_auction_auction_2_lots, +) +from openprocurement.auctions.core.tests.blanks.auction_blanks import ( + # AuctionSameValueAuctionResourceTest + post_auction_auction_not_changed, + post_auction_auction_reversed, + # AuctionFeaturesAuctionResourceTest + get_auction_features_auction +) -class AuctionAuctionResourceTest(BaseAuctionWebTest): +class AuctionAuctionResourceTest(BaseAuctionWebTest, AuctionAuctionResourceTestMixin): #initial_data = auction_data initial_status = 'active.tendering' initial_bids = test_bids - def test_get_auction_auction_not_found(self): - response = self.app.get('/auctions/some_id/auction', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/auction', {'data': {}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.post_json('/auctions/some_id/auction', {'data': {}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_get_auction_auction(self): - response = self.app.get('/auctions/{}/auction'.format(self.auction_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't get auction info in current (active.tendering) auction status") - - self.set_status('active.auction') - - response = self.app.get('/auctions/{}/auction'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertNotEqual(auction, self.initial_data) - self.assertIn('dateModified', auction) - self.assertIn('minimalStep', auction) - self.assertNotIn("procuringEntity", auction) - self.assertNotIn("tenderers", auction["bids"][0]) - self.assertEqual(auction["bids"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) - self.assertEqual(auction["bids"][1]['value']['amount'], self.initial_bids[1]['value']['amount']) - #self.assertEqual(self.initial_data["auctionPeriod"]['startDate'], auction["auctionPeriod"]['startDate']) - - response = self.app.get('/auctions/{}/auction?opt_jsonp=callback'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/javascript') - self.assertIn('callback({"data": {"', response.body) - - response = self.app.get('/auctions/{}/auction?opt_pretty=1'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('{\n "data": {\n "', response.body) - - self.set_status('active.qualification') - - response = self.app.get('/auctions/{}/auction'.format(self.auction_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't get auction info in current (active.qualification) auction status") - - def test_post_auction_auction(self): - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.tendering) auction status") - - self.set_status('active.auction') - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} - ]) - - patch_data = { - 'bids': [ - { - "id": self.initial_bids[1]['id'], - "value": { - "amount": 419, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - ] - } - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Number of auction results did not match the number of auction bids") - - patch_data['bids'].append({ - "value": { - "amount": 409, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - }) - - patch_data['bids'][1]['id'] = "some_id" - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) - - patch_data['bids'][1]['id'] = "00000000000000000000000000000000" - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") - - patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertNotEqual(auction["bids"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) - self.assertNotEqual(auction["bids"][1]['value']['amount'], self.initial_bids[1]['value']['amount']) - self.assertEqual(auction["bids"][0]['value']['amount'], patch_data["bids"][1]['value']['amount']) - self.assertEqual(auction["bids"][1]['value']['amount'], patch_data["bids"][0]['value']['amount']) - self.assertEqual('active.qualification', auction["status"]) - for i, status in enumerate(['pending.verification', 'pending.waiting']): - self.assertIn("tenderers", auction["bids"][i]) - self.assertIn("name", auction["bids"][i]["tenderers"][0]) - # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) - self.assertEqual(auction["awards"][i]['bid_id'], patch_data["bids"][i]['id']) - self.assertEqual(auction["awards"][i]['value']['amount'], patch_data["bids"][i]['value']['amount']) - self.assertEqual(auction["awards"][i]['suppliers'], self.initial_bids[i]['tenderers']) - self.assertEqual(auction["awards"][i]['status'], status) - if status == 'pending.verification': - self.assertIn("verificationPeriod", auction["awards"][i]) - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.qualification) auction status") - - def test_patch_auction_auction(self): - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update auction urls in current (active.tendering) auction status") - - self.set_status('active.auction') - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} - ]) - - patch_data = { - 'auctionUrl': u'http://auction-sandbox.openprocurement.org/auctions/{}'.format(self.auction_id), - 'bids': [ - { - "id": self.initial_bids[1]['id'], - "participationUrl": u'http://auction-sandbox.openprocurement.org/auctions/{}?key_for_bid={}'.format(self.auction_id, self.initial_bids[1]['id']) - } - ] - } - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Number of auction results did not match the number of auction bids") - - patch_data['bids'].append({ - "participationUrl": u'http://auction-sandbox.openprocurement.org/auctions/{}?key_for_bid={}'.format(self.auction_id, self.initial_bids[0]['id']) - }) - - patch_data['bids'][1]['id'] = "some_id" - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) - - patch_data['bids'][1]['id'] = "00000000000000000000000000000000" - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") - - patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertEqual(auction["bids"][0]['participationUrl'], patch_data["bids"][1]['participationUrl']) - self.assertEqual(auction["bids"][1]['participationUrl'], patch_data["bids"][0]['participationUrl']) - - self.set_status('complete') - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update auction urls in current (complete) auction status") - - def test_post_auction_auction_document(self): - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.post('/auctions/{}/documents'.format(self.auction_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.tendering) auction status") - - self.set_status('active.auction') - - response = self.app.post('/auctions/{}/documents'.format(self.auction_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - key = response.json["data"]["url"].split('?')[-1].split('=')[-1] - - patch_data = { - 'bids': [ - { - "id": self.initial_bids[1]['id'], - "value": { - "amount": 419, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - }, - { - 'id': self.initial_bids[0]['id'], - "value": { - "amount": 409, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - ] - } - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - response = self.app.put('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), upload_files=[('file', 'name.doc', 'content_with_names')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key2 = response.json["data"]["url"].split('?')[-1].split('=')[-1] - self.assertNotEqual(key, key2) - - self.set_status('complete') - response = self.app.post('/auctions/{}/documents'.format(self.auction_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (complete) auction status") + test_post_auction_auction = snitch(post_auction_auction) class AuctionSameValueAuctionResourceTest(BaseAuctionWebTest): @@ -299,701 +56,22 @@ class AuctionSameValueAuctionResourceTest(BaseAuctionWebTest): } for i in range(3) ] - - def test_post_auction_auction_not_changed(self): - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': self.initial_bids}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertEqual('active.qualification', auction["status"]) - self.assertEqual(auction["awards"][0]['bid_id'], self.initial_bids[0]['id']) - self.assertEqual(auction["awards"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) - self.assertEqual(auction["awards"][0]['suppliers'], self.initial_bids[0]['tenderers']) - - def test_post_auction_auction_reversed(self): - self.app.authorization = ('Basic', ('auction', '')) - now = get_now() - patch_data = { - 'bids': [ - { - "id": b['id'], - "date": (now - timedelta(seconds=i)).isoformat(), - "value": b['value'] - } - for i, b in enumerate(self.initial_bids) - ] - } - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertEqual('active.qualification', auction["status"]) - self.assertEqual(auction["awards"][0]['bid_id'], self.initial_bids[2]['id']) - self.assertEqual(auction["awards"][0]['value']['amount'], self.initial_bids[2]['value']['amount']) - self.assertEqual(auction["awards"][0]['suppliers'], self.initial_bids[2]['tenderers']) + test_post_auction_auction_not_changed = snitch(post_auction_auction_not_changed) + test_post_auction_auction_reversed = snitch(post_auction_auction_reversed) @unittest.skip("option not available") -class AuctionLotAuctionResourceTest(AuctionAuctionResourceTest): +class AuctionLotAuctionResourceTest(BaseAuctionWebTest, AuctionLotAuctionResourceTestMixin): initial_lots = test_lots - def test_get_auction_auction(self): - response = self.app.get('/auctions/{}/auction'.format(self.auction_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't get auction info in current (active.tendering) auction status") - self.set_status('active.auction') - response = self.app.get('/auctions/{}/auction'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertNotEqual(auction, self.initial_data) - self.assertIn('dateModified', auction) - self.assertIn('minimalStep', auction) - self.assertIn('lots', auction) - self.assertNotIn("procuringEntity", auction) - self.assertNotIn("tenderers", auction["bids"][0]) - self.assertEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], self.initial_bids[0]['lotValues'][0]['value']['amount']) - self.assertEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], self.initial_bids[1]['lotValues'][0]['value']['amount']) - - self.set_status('active.qualification') - - response = self.app.get('/auctions/{}/auction'.format(self.auction_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't get auction info in current (active.qualification) auction status") + test_post_auction_auction_lots = snitch(post_auction_auction_lot) - def test_post_auction_auction(self): - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.tendering) auction status") - - self.set_status('active.auction') - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} - ]) - - patch_data = { - 'bids': [ - { - "id": self.initial_bids[1]['id'], - 'lotValues': [ - { - "value": { - "amount": 419, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - ] - } - ] - } - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Number of auction results did not match the number of auction bids") - - patch_data['bids'].append({ - 'lotValues': [ - { - "value": { - "amount": 409, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - ] - }) - - patch_data['bids'][1]['id'] = "some_id" - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) - - patch_data['bids'][1]['id'] = "00000000000000000000000000000000" - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") - - patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] - - for lot in self.initial_lots: - response = self.app.post_json('/auctions/{}/auction/{}'.format(self.auction_id, lot['id']), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - - self.assertNotEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], self.initial_bids[0]['lotValues'][0]['value']['amount']) - self.assertNotEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], self.initial_bids[1]['lotValues'][0]['value']['amount']) - self.assertEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], patch_data["bids"][1]['lotValues'][0]['value']['amount']) - self.assertEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], patch_data["bids"][0]['lotValues'][0]['value']['amount']) - self.assertEqual('active.qualification', auction["status"]) - for i, status in enumerate(['pending.verification', 'pending.waiting']): - self.assertIn("tenderers", auction["bids"][i]) - self.assertIn("name", auction["bids"][i]["tenderers"][0]) - # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) - self.assertEqual(auction["awards"][i]['bid_id'], patch_data["bids"][i]['id']) - self.assertEqual(auction["awards"][i]['value']['amount'], patch_data["bids"][i]['lotValues'][0]['value']['amount']) - self.assertEqual(auction["awards"][i]['suppliers'], self.initial_bids[i]['tenderers']) - self.assertEqual(auction["awards"][i]['status'], status) - if status == 'pending.verification': - self.assertIn("verificationPeriod", auction["awards"][i]) - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.qualification) auction status") - - def test_patch_auction_auction(self): - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update auction urls in current (active.tendering) auction status") - - self.set_status('active.auction') - 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.app.authorization = ('Basic', ('auction', '')) - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} - ]) - - patch_data = { - 'auctionUrl': u'http://auction-sandbox.openprocurement.org/auctions/{}'.format(self.auction_id), - 'bids': [ - { - "id": self.initial_bids[1]['id'], - "participationUrl": u'http://auction-sandbox.openprocurement.org/auctions/{}?key_for_bid={}'.format(self.auction_id, self.initial_bids[1]['id']) - } - ] - } - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [{u'participationUrl': [u'url should be posted for each lot of bid']}], u'location': u'body', u'name': u'bids'} - ]) - - del patch_data['bids'][0]["participationUrl"] - patch_data['bids'][0]['lotValues'] = [ - { - "participationUrl": u'http://auction-sandbox.openprocurement.org/auctions/{}?key_for_bid={}'.format(self.auction_id, self.initial_bids[0]['id']) - } - ] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': ["url should be posted for each lot"], u'location': u'body', u'name': u'auctionUrl'} - ]) - - patch_data['lots'] = [ - { - "auctionUrl": patch_data.pop('auctionUrl') - } - ] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Number of auction results did not match the number of auction bids") - - patch_data['bids'].append({ - 'lotValues': [ - { - "participationUrl": u'http://auction-sandbox.openprocurement.org/auctions/{}?key_for_bid={}'.format(self.auction_id, self.initial_bids[0]['id']) - } - ] - }) - - patch_data['bids'][1]['id'] = "some_id" - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) - - patch_data['bids'][1]['id'] = "00000000000000000000000000000000" - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") - - patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIsNone(response.json) - - for lot in self.initial_lots: - response = self.app.patch_json('/auctions/{}/auction/{}'.format(self.auction_id, lot['id']), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - - self.assertEqual(auction["bids"][0]['lotValues'][0]['participationUrl'], patch_data["bids"][1]['lotValues'][0]['participationUrl']) - self.assertEqual(auction["bids"][1]['lotValues'][0]['participationUrl'], patch_data["bids"][0]['lotValues'][0]['participationUrl']) - self.assertEqual(auction["lots"][0]['auctionUrl'], patch_data["lots"][0]['auctionUrl']) - - self.set_status('complete') - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update auction urls in current (complete) auction status") - - def test_post_auction_auction_document(self): - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.post('/auctions/{}/documents'.format(self.auction_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.tendering) auction status") - - self.set_status('active.auction') - - response = self.app.post('/auctions/{}/documents'.format(self.auction_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - key = response.json["data"]["url"].split('?')[-1].split('=')[-1] - - response = self.app.patch_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), {'data': {"documentOf": "lot", 'relatedItem': self.initial_lots[0]['id']}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json["data"]["documentOf"], "lot") - self.assertEqual(response.json["data"]["relatedItem"], self.initial_lots[0]['id']) - - patch_data = { - 'bids': [ - { - "id": self.initial_bids[1]['id'], - 'lotValues': [ - { - "value": { - "amount": 409, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - ] - }, - { - 'id': self.initial_bids[0]['id'], - 'lotValues': [ - { - "value": { - "amount": 419, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - ] - } - ] - } - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - response = self.app.put('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), upload_files=[('file', 'name.doc', 'content_with_names')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key2 = response.json["data"]["url"].split('?')[-1].split('=')[-1] - self.assertNotEqual(key, key2) - - self.set_status('complete') - response = self.app.post('/auctions/{}/documents'.format(self.auction_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (complete) auction status") @unittest.skip("option not available") -class AuctionMultipleLotAuctionResourceTest(AuctionAuctionResourceTest): +class AuctionMultipleLotAuctionResourceTest(BaseAuctionWebTest, AuctionMultipleLotAuctionResourceTestMixin): initial_lots = 2 * test_lots - - def test_get_auction_auction(self): - response = self.app.get('/auctions/{}/auction'.format(self.auction_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't get auction info in current (active.tendering) auction status") - - self.set_status('active.auction') - - response = self.app.get('/auctions/{}/auction'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertNotEqual(auction, self.initial_data) - self.assertIn('dateModified', auction) - self.assertIn('minimalStep', auction) - self.assertIn('lots', auction) - self.assertNotIn("procuringEntity", auction) - self.assertNotIn("tenderers", auction["bids"][0]) - self.assertEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], self.initial_bids[0]['lotValues'][0]['value']['amount']) - self.assertEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], self.initial_bids[1]['lotValues'][0]['value']['amount']) - self.assertEqual(auction["bids"][0]['lotValues'][1]['value']['amount'], self.initial_bids[0]['lotValues'][1]['value']['amount']) - self.assertEqual(auction["bids"][1]['lotValues'][1]['value']['amount'], self.initial_bids[1]['lotValues'][1]['value']['amount']) - - self.set_status('active.qualification') - - response = self.app.get('/auctions/{}/auction'.format(self.auction_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't get auction info in current (active.qualification) auction status") - - def test_post_auction_auction(self): - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.tendering) auction status") - - self.set_status('active.auction') - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} - ]) - - patch_data = { - 'bids': [ - { - "id": self.initial_bids[1]['id'], - 'lotValues': [ - { - "value": { - "amount": 419, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - ] - } - ] - } - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Number of auction results did not match the number of auction bids") - - patch_data['bids'].append({ - 'lotValues': [ - { - "value": { - "amount": 409, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - ] - }) - - patch_data['bids'][1]['id'] = "some_id" - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) - - patch_data['bids'][1]['id'] = "00000000000000000000000000000000" - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") - - patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], [{"lotValues": ["Number of lots of auction results did not match the number of auction lots"]}]) - - for bid in patch_data['bids']: - bid['lotValues'] = [bid['lotValues'][0].copy() for i in self.initial_lots] - - patch_data['bids'][0]['lotValues'][1]['relatedLot'] = self.initial_bids[0]['lotValues'][0]['relatedLot'] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], [{u'lotValues': [{u'relatedLot': [u'relatedLot should be one of lots of bid']}]}]) - - patch_data['bids'][0]['lotValues'][1]['relatedLot'] = self.initial_bids[0]['lotValues'][1]['relatedLot'] - - for lot in self.initial_lots: - response = self.app.post_json('/auctions/{}/auction/{}'.format(self.auction_id, lot['id']), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - - self.assertNotEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], self.initial_bids[0]['lotValues'][0]['value']['amount']) - self.assertNotEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], self.initial_bids[1]['lotValues'][0]['value']['amount']) - self.assertEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], patch_data["bids"][1]['lotValues'][0]['value']['amount']) - self.assertEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], patch_data["bids"][0]['lotValues'][0]['value']['amount']) - self.assertEqual('active.qualification', auction["status"]) - for i, status in enumerate(['pending.verification', 'pending.waiting']): - self.assertIn("tenderers", auction["bids"][i]) - self.assertIn("name", auction["bids"][i]["tenderers"][0]) - # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) - self.assertEqual(auction["awards"][i]['bid_id'], patch_data["bids"][i]['id']) - self.assertEqual(auction["awards"][i]['value']['amount'], patch_data["bids"][i]['lotValues'][0]['value']['amount']) - self.assertEqual(auction["awards"][i]['suppliers'], self.initial_bids[i]['tenderers']) - self.assertEqual(auction["awards"][i]['status'], status) - if status == 'pending.verification': - self.assertIn("verificationPeriod", auction["awards"][i]) - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.qualification) auction status") - - def test_patch_auction_auction(self): - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update auction urls in current (active.tendering) auction status") - - self.set_status('active.auction') - 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.app.authorization = ('Basic', ('auction', '')) - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} - ]) - - patch_data = { - 'auctionUrl': u'http://auction-sandbox.openprocurement.org/auctions/{}'.format(self.auction_id), - 'bids': [ - { - "id": self.initial_bids[1]['id'], - "participationUrl": u'http://auction-sandbox.openprocurement.org/auctions/{}?key_for_bid={}'.format(self.auction_id, self.initial_bids[1]['id']) - } - ] - } - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [{u'participationUrl': [u'url should be posted for each lot of bid']}], u'location': u'body', u'name': u'bids'} - ]) - - del patch_data['bids'][0]["participationUrl"] - patch_data['bids'][0]['lotValues'] = [ - { - "participationUrl": u'http://auction-sandbox.openprocurement.org/auctions/{}?key_for_bid={}'.format(self.auction_id, self.initial_bids[0]['id']) - } - ] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': ["url should be posted for each lot"], u'location': u'body', u'name': u'auctionUrl'} - ]) - - patch_data['lots'] = [ - { - "auctionUrl": patch_data.pop('auctionUrl') - } - ] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Number of auction results did not match the number of auction bids") - - patch_data['bids'].append({ - 'lotValues': [ - { - "participationUrl": u'http://auction-sandbox.openprocurement.org/auctions/{}?key_for_bid={}'.format(self.auction_id, self.initial_bids[0]['id']) - } - ] - }) - - patch_data['bids'][1]['id'] = "some_id" - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) - - patch_data['bids'][1]['id'] = "00000000000000000000000000000000" - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") - - patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], u'Number of lots did not match the number of auction lots') - - patch_data['lots'] = [patch_data['lots'][0].copy() for i in self.initial_lots] - patch_data['lots'][1]['id'] = "00000000000000000000000000000000" - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], u'Auction lots should be identical to the auction lots') - - patch_data['lots'][1]['id'] = self.initial_lots[1]['id'] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], [{"lotValues": ["Number of lots of auction results did not match the number of auction lots"]}]) - - for bid in patch_data['bids']: - bid['lotValues'] = [bid['lotValues'][0].copy() for i in self.initial_lots] - - patch_data['bids'][0]['lotValues'][1]['relatedLot'] = self.initial_bids[0]['lotValues'][0]['relatedLot'] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], [{u'lotValues': [{u'relatedLot': [u'relatedLot should be one of lots of bid']}]}]) - - patch_data['bids'][0]['lotValues'][1]['relatedLot'] = self.initial_bids[0]['lotValues'][1]['relatedLot'] - - response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIsNone(response.json) - - for lot in self.initial_lots: - response = self.app.patch_json('/auctions/{}/auction/{}'.format(self.auction_id, lot['id']), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - - self.assertEqual(auction["bids"][0]['lotValues'][0]['participationUrl'], patch_data["bids"][1]['lotValues'][0]['participationUrl']) - self.assertEqual(auction["bids"][1]['lotValues'][0]['participationUrl'], patch_data["bids"][0]['lotValues'][0]['participationUrl']) - self.assertEqual(auction["lots"][0]['auctionUrl'], patch_data["lots"][0]['auctionUrl']) - - self.app.authorization = ('Basic', ('token', '')) - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.patch_json('/auctions/{}/auction/{}'.format(self.auction_id, self.initial_lots[0]['id']), {'data': patch_data}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update auction urls only in active lot status") - - def test_post_auction_auction_document(self): - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.post('/auctions/{}/documents'.format(self.auction_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.tendering) auction status") - - self.set_status('active.auction') - - response = self.app.post('/auctions/{}/documents'.format(self.auction_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - key = response.json["data"]["url"].split('?')[-1].split('=')[-1] - - response = self.app.patch_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), {'data': {"documentOf": "lot", 'relatedItem': self.initial_lots[0]['id']}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json["data"]["documentOf"], "lot") - self.assertEqual(response.json["data"]["relatedItem"], self.initial_lots[0]['id']) - - patch_data = { - 'bids': [ - { - "id": self.initial_bids[1]['id'], - 'lotValues': [ - { - "value": { - "amount": 409, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - for i in self.initial_lots - ] - }, - { - 'id': self.initial_bids[0]['id'], - 'lotValues': [ - { - "value": { - "amount": 419, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - for i in self.initial_lots - ] - } - ] - } - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - response = self.app.put('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), upload_files=[('file', 'name.doc', 'content_with_names')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key2 = response.json["data"]["url"].split('?')[-1].split('=')[-1] - self.assertNotEqual(key, key2) - - self.set_status('complete') - response = self.app.post('/auctions/{}/documents'.format(self.auction_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (complete) auction status") + test_post_auction_auction_2_lots = snitch(post_auction_auction_2_lots) @unittest.skip("option not available") @@ -1038,21 +116,7 @@ class AuctionFeaturesAuctionResourceTest(BaseAuctionWebTest): } ] - def test_get_auction_auction(self): - response = self.app.get('/auctions/{}/auction'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertNotEqual(auction, self.initial_data) - self.assertIn('dateModified', auction) - self.assertIn('minimalStep', auction) - self.assertNotIn("procuringEntity", auction) - self.assertNotIn("tenderers", auction["bids"][0]) - self.assertEqual(auction["bids"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) - self.assertEqual(auction["bids"][1]['value']['amount'], self.initial_bids[1]['value']['amount']) - self.assertIn('features', auction) - self.assertIn('parameters', auction["bids"][0]) - + test_get_auction_features_auction = snitch(get_auction_features_auction) class FinancialAuctionAuctionResourceTest(AuctionAuctionResourceTest): initial_bids = test_financial_bids diff --git a/openprocurement/auctions/dgf/tests/blanks/auction_blanks.py b/openprocurement/auctions/dgf/tests/blanks/auction_blanks.py new file mode 100644 index 00000000..78a4a310 --- /dev/null +++ b/openprocurement/auctions/dgf/tests/blanks/auction_blanks.py @@ -0,0 +1,309 @@ +# -*- coding: utf-8 -*- + +def post_auction_auction(self): + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], + "Can't report auction results in current (active.tendering) auction status") + + self.set_status('active.auction') + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), + {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [ + {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} + ]) + + patch_data = { + 'bids': [ + { + "id": self.initial_bids[1]['id'], + "value": { + "amount": 419, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + } + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], + "Number of auction results did not match the number of auction bids") + + patch_data['bids'].append({ + "value": { + "amount": 409, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + }) + + patch_data['bids'][1]['id'] = "some_id" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) + + patch_data['bids'][1]['id'] = "00000000000000000000000000000000" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") + + patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertNotEqual(auction["bids"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) + self.assertNotEqual(auction["bids"][1]['value']['amount'], self.initial_bids[1]['value']['amount']) + self.assertEqual(auction["bids"][0]['value']['amount'], patch_data["bids"][1]['value']['amount']) + self.assertEqual(auction["bids"][1]['value']['amount'], patch_data["bids"][0]['value']['amount']) + self.assertEqual('active.qualification', auction["status"]) + for i, status in enumerate(['pending.verification', 'pending.waiting']): + self.assertIn("tenderers", auction["bids"][i]) + self.assertIn("name", auction["bids"][i]["tenderers"][0]) + # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) + self.assertEqual(auction["awards"][i]['bid_id'], patch_data["bids"][i]['id']) + self.assertEqual(auction["awards"][i]['value']['amount'], patch_data["bids"][i]['value']['amount']) + self.assertEqual(auction["awards"][i]['suppliers'], self.initial_bids[i]['tenderers']) + self.assertEqual(auction["awards"][i]['status'], status) + if status == 'pending.verification': + self.assertIn("verificationPeriod", auction["awards"][i]) + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], + "Can't report auction results in current (active.qualification) auction status") + + +def post_auction_auction_lot(self): + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.tendering) auction status") + + self.set_status('active.auction') + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [ + {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} + ]) + + patch_data = { + 'bids': [ + { + "id": self.initial_bids[1]['id'], + 'lotValues': [ + { + "value": { + "amount": 419, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + } + ] + } + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Number of auction results did not match the number of auction bids") + + patch_data['bids'].append({ + 'lotValues': [ + { + "value": { + "amount": 409, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + }) + + patch_data['bids'][1]['id'] = "some_id" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) + + patch_data['bids'][1]['id'] = "00000000000000000000000000000000" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") + + patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] + + for lot in self.initial_lots: + response = self.app.post_json('/auctions/{}/auction/{}'.format(self.auction_id, lot['id']), {'data': patch_data}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + + self.assertNotEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], self.initial_bids[0]['lotValues'][0]['value']['amount']) + self.assertNotEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], self.initial_bids[1]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], patch_data["bids"][1]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], patch_data["bids"][0]['lotValues'][0]['value']['amount']) + self.assertEqual('active.qualification', auction["status"]) + for i, status in enumerate(['pending.verification', 'pending.waiting']): + self.assertIn("tenderers", auction["bids"][i]) + self.assertIn("name", auction["bids"][i]["tenderers"][0]) + # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) + self.assertEqual(auction["awards"][i]['bid_id'], patch_data["bids"][i]['id']) + self.assertEqual(auction["awards"][i]['value']['amount'], patch_data["bids"][i]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["awards"][i]['suppliers'], self.initial_bids[i]['tenderers']) + self.assertEqual(auction["awards"][i]['status'], status) + if status == 'pending.verification': + self.assertIn("verificationPeriod", auction["awards"][i]) + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.qualification) auction status") + + +def post_auction_auction_2_lots(self): + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.tendering) auction status") + + self.set_status('active.auction') + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': [{'invalid_field': 'invalid_value'}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [ + {u'description': {u'invalid_field': u'Rogue field'}, u'location': u'body', u'name': u'bids'} + ]) + + patch_data = { + 'bids': [ + { + "id": self.initial_bids[1]['id'], + 'lotValues': [ + { + "value": { + "amount": 419, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + } + ] + } + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Number of auction results did not match the number of auction bids") + + patch_data['bids'].append({ + 'lotValues': [ + { + "value": { + "amount": 409, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + }) + + patch_data['bids'][1]['id'] = "some_id" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], {u'id': [u'Hash value is wrong length.']}) + + patch_data['bids'][1]['id'] = "00000000000000000000000000000000" + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Auction bids should be identical to the auction bids") + + patch_data['bids'][1]['id'] = self.initial_bids[0]['id'] + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], [{"lotValues": ["Number of lots of auction results did not match the number of auction lots"]}]) + + for bid in patch_data['bids']: + bid['lotValues'] = [bid['lotValues'][0].copy() for i in self.initial_lots] + + patch_data['bids'][0]['lotValues'][1]['relatedLot'] = self.initial_bids[0]['lotValues'][0]['relatedLot'] + + response = self.app.patch_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], [{u'lotValues': [{u'relatedLot': [u'relatedLot should be one of lots of bid']}]}]) + + patch_data['bids'][0]['lotValues'][1]['relatedLot'] = self.initial_bids[0]['lotValues'][1]['relatedLot'] + + for lot in self.initial_lots: + response = self.app.post_json('/auctions/{}/auction/{}'.format(self.auction_id, lot['id']), {'data': patch_data}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + + self.assertNotEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], self.initial_bids[0]['lotValues'][0]['value']['amount']) + self.assertNotEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], self.initial_bids[1]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["bids"][0]['lotValues'][0]['value']['amount'], patch_data["bids"][1]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["bids"][1]['lotValues'][0]['value']['amount'], patch_data["bids"][0]['lotValues'][0]['value']['amount']) + self.assertEqual('active.qualification', auction["status"]) + for i, status in enumerate(['pending.verification', 'pending.waiting']): + self.assertIn("tenderers", auction["bids"][i]) + self.assertIn("name", auction["bids"][i]["tenderers"][0]) + # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) + self.assertEqual(auction["awards"][i]['bid_id'], patch_data["bids"][i]['id']) + self.assertEqual(auction["awards"][i]['value']['amount'], patch_data["bids"][i]['lotValues'][0]['value']['amount']) + self.assertEqual(auction["awards"][i]['suppliers'], self.initial_bids[i]['tenderers']) + self.assertEqual(auction["awards"][i]['status'], status) + if status == 'pending.verification': + self.assertIn("verificationPeriod", auction["awards"][i]) + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': patch_data}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't report auction results in current (active.qualification) auction status") + + +def get_auction_auction_features(self): + response = self.app.get('/auctions/{}/auction'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertNotEqual(auction, self.initial_data) + self.assertIn('dateModified', auction) + self.assertIn('minimalStep', auction) + self.assertNotIn("procuringEntity", auction) + self.assertNotIn("tenderers", auction["bids"][0]) + self.assertEqual(auction["bids"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) + self.assertEqual(auction["bids"][1]['value']['amount'], self.initial_bids[1]['value']['amount']) + self.assertIn('features', auction) + self.assertIn('parameters', auction["bids"][0]) From 66c617c9e19a95624d4234ed08ddd5ee3309c68d Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 18:52:48 +0200 Subject: [PATCH 21/45] Move bidder tests to blank use existed mixins from core --- openprocurement/auctions/dgf/tests/bidder.py | 1257 +---------------- .../dgf/tests/blanks/bidder_blanks.py | 682 +++++++++ 2 files changed, 740 insertions(+), 1199 deletions(-) create mode 100644 openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py diff --git a/openprocurement/auctions/dgf/tests/bidder.py b/openprocurement/auctions/dgf/tests/bidder.py index f9694854..327bfe7b 100644 --- a/openprocurement/auctions/dgf/tests/bidder.py +++ b/openprocurement/auctions/dgf/tests/bidder.py @@ -13,406 +13,49 @@ test_organization ) +from openprocurement.auctions.dgf.tests.blanks.bidder_blanks import ( + # AuctionBidderResourceTest + create_auction_bidder_invalid, + patch_auction_bidder, + get_auction_bidder, + delete_auction_bidder, + get_auction_auctioners, + bid_Administrator_change, + # AuctionBidInvalidationAuctionResourceTest + post_auction_all_invalid_bids, + post_auction_one_invalid_bid, + post_auction_one_valid_bid, + # AuctionBidderProcessTest + reactivate_invalidated_bids, + # AuctionBidderFeaturesResourceTest + features_bidder, + # AuctionBidderDocumentResourceTest + create_auction_bidder_document_nopending +) +from openprocurement.auctions.core.tests.blanks.bidder_blanks import ( + # AuctionBidderResourceTest + create_auction_bidder, + # AuctionBidderFeaturesResourceTest + features_bidder_invalid +) +from openprocurement.auctions.core.tests.bidder import ( + AuctionBidderDocumentResourceTestMixin, + AuctionBidderDocumentWithDSResourceTestMixin +) +from openprocurement.auctions.core.tests.base import snitch + class AuctionBidderResourceTest(BaseAuctionWebTest): initial_status = 'active.tendering' + test_financial_organization = test_financial_organization - def test_create_auction_bidder_invalid(self): - response = self.app.post_json('/auctions/some_id/bids', { - 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - request_path = '/auctions/{}/bids'.format(self.auction_id) - response = self.app.post(request_path, 'data', status=415) - self.assertEqual(response.status, '415 Unsupported Media Type') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': - u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} - ]) - - response = self.app.post( - request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, 'data', 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json( - request_path, {'not_data': {}}, 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'data': { - 'invalid_field': 'invalid_value'}}, 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'Rogue field', u'location': - u'body', u'name': u'invalid_field'} - ]) - - response = self.app.post_json(request_path, { - 'data': {'tenderers': [{'identifier': 'invalid_value'}]}}, 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'identifier': [ - u'Please use a mapping for this field or Identifier instance instead of unicode.']}, u'location': u'body', u'name': u'tenderers'} - ]) - - response = self.app.post_json(request_path, { - 'data': {'tenderers': [{'identifier': {}}]}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertIn({u"location": u"body", u"name": u"qualified", u"description": [u"This field is required."]}, response.json['errors']) - if self.initial_organization == test_financial_organization: - self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'eligible'}, response.json['errors']) - self.assertIn({u'description': [{u'additionalIdentifiers': [u'This field is required.'], u'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.']}, u'name': [u'This field is required.'], u'address': [u'This field is required.']}], u'location': u'body', u'name': u'tenderers'}, response.json['errors']) - else: - self.assertIn({u'description': [{u'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.']}, u'name': [u'This field is required.'], u'address': [u'This field is required.']}], u'location': u'body', u'name': u'tenderers'}, response.json['errors']) - - response = self.app.post_json(request_path, {'data': {'tenderers': [{ - 'name': 'name', 'identifier': {'uri': 'invalid_value'}}]}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertIn({u"location": u"body", u"name": u"qualified", u"description": [u"This field is required."]}, response.json['errors']) - if self.initial_organization == test_financial_organization: - self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'eligible'}, response.json['errors']) - self.assertIn({u'description': [{u'additionalIdentifiers': [u'This field is required.'], u'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.'], u'uri': [u'Not a well formed URL.']}, u'address': [u'This field is required.']}], u'location': u'body', u'name': u'tenderers'}, response.json['errors']) - else: - self.assertIn({u'description': [{u'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.'], u'uri': [u'Not a well formed URL.']}, u'address': [u'This field is required.']}], u'location': u'body', u'name': u'tenderers'}, response.json['errors']) - - if self.initial_organization == test_financial_organization: - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'qualified': True, 'eligible': True}}, status=422) - else: - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'qualified': True}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'value'}, response.json['errors']) - - if self.initial_organization == test_financial_organization: - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'valueAddedTaxIncluded': False}, 'qualified': True, 'eligible': True}}, status=422) - else: - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'valueAddedTaxIncluded': False}, 'qualified': True}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertIn({u'description': [u'valueAddedTaxIncluded of bid should be identical to valueAddedTaxIncluded of value of auction'], u'location': u'body', u'name': u'value'}, response.json['errors']) - - if self.initial_organization == test_financial_organization: - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'currency': "USD"}, 'qualified': True, 'eligible': True}}, status=422) - else: - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'currency': "USD"}, 'qualified': True}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertIn({u'description': [u'currency of bid should be identical to currency of value of auction'], u'location': u'body', u'name': u'value'}, response.json['errors']) - - if self.initial_organization == test_financial_organization: - response = self.app.post_json(request_path, {'data': {'tenderers': self.initial_organization, "value": {"amount": 500}, 'qualified': True, 'eligible': True}}, status=422) - else: - response = self.app.post_json(request_path, {'data': {'tenderers': self.initial_organization, "value": {"amount": 500}, 'qualified': True}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - if self.initial_organization == test_financial_organization: - self.assertIn({u'description': u"invalid literal for int() with base 10: 'additionalIdentifiers'", u'location': u'body', u'name': u'data'}, response.json['errors']) - else: - self.assertIn({u'description': u"invalid literal for int() with base 10: 'contactPoint'", u'location': u'body', u'name': u'data'}, response.json['errors']) - - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}}}, status=422) - else: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'qualified'}, response.json['errors']) - - def test_create_auction_bidder(self): - dateModified = self.db.get(self.auction_id).get('dateModified') - - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) - else: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - bidder = response.json['data'] - self.assertEqual(bidder['tenderers'][0]['name'], self.initial_organization['name']) - self.assertIn('id', bidder) - self.assertIn(bidder['id'], response.headers['Location']) - - self.assertEqual(self.db.get(self.auction_id).get('dateModified'), dateModified) - - self.set_status('complete') - - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}, status=403) - else: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add bid in current (complete) auction status") - - def test_patch_auction_bidder(self): - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "status": "draft", "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) - else: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "status": "draft", "value": {"amount": 500}, 'qualified': True}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - bidder = response.json['data'] - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"status": "active", "value": {"amount": 60}}}, 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'value of bid should be greater than value of auction'], u'location': u'body', u'name': u'value'} - ]) - - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {'tenderers': [{"name": u"Державне управління управлінням справами"}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['date'], bidder['date']) - self.assertNotEqual(response.json['data']['tenderers'][0]['name'], bidder['tenderers'][0]['name']) - - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"value": {"amount": 500}, 'tenderers': [self.initial_organization]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['date'], bidder['date']) - self.assertEqual(response.json['data']['tenderers'][0]['name'], bidder['tenderers'][0]['name']) - - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"value": {"amount": 400}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["value"]["amount"], 400) - self.assertNotEqual(response.json['data']['date'], bidder['date']) - - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - self.assertNotEqual(response.json['data']['date'], bidder['date']) - - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"status": "draft"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can\'t update bid to (draft) status") - - response = self.app.patch_json('/auctions/{}/bids/some_id'.format(self.auction_id), {"data": {"value": {"amount": 400}}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'bid_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/bids/some_id', {"data": {"value": {"amount": 400}}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - self.set_status('complete') - - response = self.app.get('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["value"]["amount"], 400) - - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"value": {"amount": 400}}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update bid in current (complete) auction status") - - def test_get_auction_bidder(self): - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) - else: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - bidder = response.json['data'] - bid_token = response.json['access']['token'] - - response = self.app.get('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't view bid in current (active.tendering) auction status") - - response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bidder['id'], bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], bidder) - - self.set_status('active.qualification') - - response = self.app.get('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - bidder_data = response.json['data'] - #self.assertIn(u'participationUrl', bidder_data) - #bidder_data.pop(u'participationUrl') - self.assertEqual(bidder_data, bidder) - - response = self.app.get('/auctions/{}/bids/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'bid_id'} - ]) - - response = self.app.get('/auctions/some_id/bids/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.delete('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't delete bid in current (active.qualification) auction status") - - def test_delete_auction_bidder(self): - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) - else: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - bidder = response.json['data'] - - response = self.app.delete('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], bidder) - - revisions = self.db.get(self.auction_id).get('revisions') - self.assertTrue(any([i for i in revisions[-2][u'changes'] if i['op'] == u'remove' and i['path'] == u'/bids'])) - self.assertTrue(any([i for i in revisions[-1][u'changes'] if i['op'] == u'add' and i['path'] == u'/bids'])) - - response = self.app.delete('/auctions/{}/bids/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'bid_id'} - ]) - - response = self.app.delete('/auctions/some_id/bids/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_get_auction_auctioners(self): - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) - else: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - bidder = response.json['data'] - - response = self.app.get('/auctions/{}/bids'.format(self.auction_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't view bids in current (active.tendering) auction status") - - self.set_status('active.qualification') - - response = self.app.get('/auctions/{}/bids'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][0], bidder) - - response = self.app.get('/auctions/some_id/bids', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_bid_Administrator_change(self): - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) - else: - response = self.app.post_json('/auctions/{}/bids'.format( - self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - bidder = response.json['data'] - - self.app.authorization = ('Basic', ('administrator', '')) - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": { - 'tenderers': [{"identifier": {"id": "00000000"}}], - "value": {"amount": 400} - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotEqual(response.json['data']["value"]["amount"], 400) - self.assertEqual(response.json['data']["tenderers"][0]["identifier"]["id"], "00000000") + test_create_auction_bidded = snitch(create_auction_bidder) + test_create_auction_bidder_invalid = snitch(create_auction_bidder_invalid) + test_patch_auction_bidder = snitch(patch_auction_bidder) + test_get_auction_bidder = snitch(get_auction_bidder) + test_delete_auction_bidder = snitch(delete_auction_bidder) + test_get_auction_auctioners = snitch(get_auction_auctioners) + test_bid_Administrator_change = snitch(bid_Administrator_change) class AuctionBidInvalidationAuctionResourceTest(BaseAuctionWebTest): @@ -432,156 +75,16 @@ class AuctionBidInvalidationAuctionResourceTest(BaseAuctionWebTest): } for i in range(3) ] - - def test_post_auction_all_invalid_bids(self): - self.app.authorization = ('Basic', ('auction', '')) - - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), - {'data': {'bids': self.initial_bids}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - - self.assertEqual(auction["bids"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) - self.assertEqual(auction["bids"][1]['value']['amount'], self.initial_bids[1]['value']['amount']) - self.assertEqual(auction["bids"][2]['value']['amount'], self.initial_bids[2]['value']['amount']) - - value_threshold = auction['value']['amount'] + auction['minimalStep']['amount'] - self.assertLess(auction["bids"][0]['value']['amount'], value_threshold) - self.assertLess(auction["bids"][1]['value']['amount'], value_threshold) - self.assertLess(auction["bids"][2]['value']['amount'], value_threshold) - self.assertEqual(auction["bids"][0]['status'], 'invalid') - self.assertEqual(auction["bids"][1]['status'], 'invalid') - self.assertEqual(auction["bids"][2]['status'], 'invalid') - self.assertEqual('unsuccessful', auction["status"]) - - def test_post_auction_one_invalid_bid(self): - self.app.authorization = ('Basic', ('auction', '')) - - bids = deepcopy(self.initial_bids) - bids[0]['value']['amount'] = bids[0]['value']['amount'] * 3 - bids[1]['value']['amount'] = bids[1]['value']['amount'] * 2 - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': bids}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - - self.assertEqual(auction["bids"][0]['value']['amount'], bids[0]['value']['amount']) - self.assertEqual(auction["bids"][1]['value']['amount'], bids[1]['value']['amount']) - self.assertEqual(auction["bids"][2]['value']['amount'], bids[2]['value']['amount']) - - value_threshold = auction['value']['amount'] + auction['minimalStep']['amount'] - - self.assertGreater(auction["bids"][0]['value']['amount'], value_threshold) - self.assertGreater(auction["bids"][1]['value']['amount'], value_threshold) - self.assertLess(auction["bids"][2]['value']['amount'], value_threshold) - - self.assertEqual(auction["bids"][0]['status'], 'active') - self.assertEqual(auction["bids"][1]['status'], 'active') - self.assertEqual(auction["bids"][2]['status'], 'invalid') - - self.assertEqual('active.qualification', auction["status"]) - - for i, status in enumerate(['pending.verification', 'pending.waiting']): - self.assertIn("tenderers", auction["bids"][i]) - self.assertIn("name", auction["bids"][i]["tenderers"][0]) - # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) - self.assertEqual(auction["awards"][i]['bid_id'], bids[i]['id']) - self.assertEqual(auction["awards"][i]['value']['amount'], bids[i]['value']['amount']) - self.assertEqual(auction["awards"][i]['suppliers'], bids[i]['tenderers']) - self.assertEqual(auction["awards"][i]['status'], status) - if status == 'pending.verification': - self.assertIn("verificationPeriod", auction["awards"][i]) - - def test_post_auction_one_valid_bid(self): - self.app.authorization = ('Basic', ('auction', '')) - - bids = deepcopy(self.initial_bids) - bids[0]['value']['amount'] = bids[0]['value']['amount'] * 2 - response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': bids}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - - self.assertEqual(auction["bids"][0]['value']['amount'], bids[0]['value']['amount']) - self.assertEqual(auction["bids"][1]['value']['amount'], bids[1]['value']['amount']) - self.assertEqual(auction["bids"][2]['value']['amount'], bids[2]['value']['amount']) - - value_threshold = auction['value']['amount'] + auction['minimalStep']['amount'] - - self.assertGreater(auction["bids"][0]['value']['amount'], value_threshold) - self.assertLess(auction["bids"][1]['value']['amount'], value_threshold) - self.assertLess(auction["bids"][2]['value']['amount'], value_threshold) - - self.assertEqual(auction["bids"][0]['status'], 'active') - self.assertEqual(auction["bids"][1]['status'], 'invalid') - self.assertEqual(auction["bids"][2]['status'], 'invalid') - - self.assertEqual('active.qualification', auction["status"]) - - for i, status in enumerate(['pending.verification', 'unsuccessful']): - self.assertIn("tenderers", auction["bids"][i]) - self.assertIn("name", auction["bids"][i]["tenderers"][0]) - # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) - self.assertEqual(auction["awards"][i]['bid_id'], bids[i]['id']) - self.assertEqual(auction["awards"][i]['value']['amount'], bids[i]['value']['amount']) - self.assertEqual(auction["awards"][i]['suppliers'], bids[i]['tenderers']) - self.assertEqual(auction["awards"][i]['status'], status) - if status == 'pending.verification': - self.assertIn("verificationPeriod", auction["awards"][i]) + test_post_auction_all_invalid_bids = snitch(post_auction_all_invalid_bids) + test_post_auction_one_invalid_bid = snitch(post_auction_one_invalid_bid) + test_post_auction_one_valid_bid = snitch(post_auction_one_valid_bid) class AuctionBidderProcessTest(BaseAuctionWebTest): initial_data = test_auction_data initial_bids = test_bids - def test_reactivate_invalidated_bids(self): - - bid1_id = self.initial_bids[0]['id'] - bid2_id = self.initial_bids[1]['id'] - bid1_token = self.initial_bids_tokens[self.initial_bids[0]['id']] - bid2_token = self.initial_bids_tokens[self.initial_bids[1]['id']] - - # patch - - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(self.auction_id, self.auction_token), {'data': {'value': {'amount': 540}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token)) - self.assertEqual(response.json['data']["status"], "invalid") - response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token)) - self.assertEqual(response.json['data']["status"], "invalid") - - # reactivate bids invalid bid value.amount - - response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token), - {'data': {"status": "active"}}, status=422) - self.assertEqual(response.json['errors'], [ - {u'description': [u'value of bid should be greater than value of auction'], u'location': u'body', u'name': u'value'} - ]) - response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token), - {'data': {"status": "active"}}, status=422) - self.assertEqual(response.json['errors'], [ - {u'description': [u'value of bid should be greater than value of auction'], u'location': u'body', u'name': u'value'} - ]) - - # set bid value.amount above auction value.amount - - response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token), - {"data": {"value": {"amount": 800}}}) - response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token), - {"data": {"value": {"amount": 900}}}) - - # reactivate bids - - response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token), - {'data': {"status": "active"}}) - self.assertEqual(response.json['data']["status"], "active") - - response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token), - {'data': {"status": "active"}}) - self.assertEqual(response.json['data']["status"], "active") + test_reactivate_invalidated_bids = snitch(reactivate_invalidated_bids) @unittest.skip("option not available") @@ -589,109 +92,13 @@ class AuctionBidderFeaturesResourceTest(BaseAuctionWebTest): initial_data = test_features_auction_data initial_status = 'active.tendering' - def test_features_bidder(self): - test_features_bids = [ - { - "parameters": [ - { - "code": i["code"], - "value": 0.1, - } - for i in self.initial_data['features'] - ], - "status": "active", - "tenderers": [ - self.initial_organization - ], - "value": { - "amount": 469, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - }, - { - "parameters": [ - { - "code": i["code"], - "value": 0.15, - } - for i in self.initial_data['features'] - ], - "tenderers": [ - self.initial_organization - ], - "status": "draft", - "value": { - "amount": 479, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - ] - for i in test_features_bids: - response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), {'data': i}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - bid = response.json['data'] - bid.pop(u'date') - bid.pop(u'id') - self.assertEqual(bid, i) + test_features_bidder = snitch(features_bidder) + test_features_bidder_invalid = snitch(features_bidder_invalid) - def test_features_bidder_invalid(self): - data = { - "tenderers": [ - self.initial_organization - ], - "value": { - "amount": 469, - "currency": "UAH", - "valueAddedTaxIncluded": True - } - } - response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), {'data': data}, 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'This field is required.'], u'location': u'body', u'name': u'parameters'} - ]) - data["parameters"] = [ - { - "code": "OCDS-123454-AIR-INTAKE", - "value": 0.1, - } - ] - response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), {'data': data}, 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'All features parameters is required.'], u'location': u'body', u'name': u'parameters'} - ]) - data["parameters"].append({ - "code": "OCDS-123454-AIR-INTAKE", - "value": 0.1, - }) - response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), {'data': data}, 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'Parameter code should be uniq for all parameters'], u'location': u'body', u'name': u'parameters'} - ]) - data["parameters"][1]["code"] = "OCDS-123454-YEARS" - data["parameters"][1]["value"] = 0.2 - response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), {'data': data}, 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'value': [u'value should be one of feature value.']}], u'location': u'body', u'name': u'parameters'} - ]) - -class AuctionBidderDocumentResourceTest(BaseAuctionWebTest): +class AuctionBidderDocumentResourceTest(BaseAuctionWebTest, AuctionBidderDocumentResourceTestMixin): initial_status = 'active.tendering' + test_create_auction_bidder_document_nopending = snitch(create_auction_bidder_document_nopending) def setUp(self): super(AuctionBidderDocumentResourceTest, self).setUp() @@ -706,355 +113,17 @@ def setUp(self): self.bid_id = bid['id'] self.bid_token = response.json['access']['token'] - def test_not_found(self): - response = self.app.post('/auctions/some_id/bids/some_id/documents', status=404, upload_files=[ - ('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.post('/auctions/{}/bids/some_id/documents'.format(self.auction_id), status=404, upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'bid_id'} - ]) - - response = self.app.post('/auctions/{}/bids/{}/documents'.format(self.auction_id, self.bid_id), status=404, upload_files=[ - ('invalid_value', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.get('/auctions/some_id/bids/some_id/documents', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/bids/some_id/documents'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'bid_id'} - ]) - - response = self.app.get('/auctions/some_id/bids/some_id/documents/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/bids/some_id/documents/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'bid_id'} - ]) - - response = self.app.get('/auctions/{}/bids/{}/documents/some_id'.format(self.auction_id, self.bid_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'document_id'} - ]) - - response = self.app.put('/auctions/some_id/bids/some_id/documents/some_id', status=404, - upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.put('/auctions/{}/bids/some_id/documents/some_id'.format(self.auction_id), status=404, upload_files=[ - ('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'bid_id'} - ]) - - response = self.app.put('/auctions/{}/bids/{}/documents/some_id'.format( - self.auction_id, self.bid_id), status=404, upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'document_id'} - ]) - - self.app.authorization = ('Basic', ('invalid', '')) - response = self.app.put('/auctions/{}/bids/{}/documents/some_id'.format( - self.auction_id, self.bid_id), status=404, upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'document_id'} - ]) - - def test_create_auction_bidder_document(self): - response = self.app.post('/auctions/{}/bids/{}/documents'.format( - self.auction_id, self.bid_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - key = response.json["data"]["url"].split('?')[-1].split('=')[-1] - - response = self.app.get('/auctions/{}/bids/{}/documents'.format(self.auction_id, self.bid_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't view bid documents in current (active.tendering) auction status") - - response = self.app.get('/auctions/{}/bids/{}/documents?acc_token={}'.format(self.auction_id, self.bid_id, self.bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/bids/{}/documents?all=true&acc_token={}'.format(self.auction_id, self.bid_id, self.bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?download=some_id&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, self.bid_token), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?download={}'.format( - self.auction_id, self.bid_id, doc_id, key), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't view bid document in current (active.tendering) auction status") - - if self.docservice: - response = self.app.get('/auctions/{}/bids/{}/documents/{}?download={}&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, key, self.bid_token)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertIn('Expires=', response.location) - else: - response = self.app.get('/auctions/{}/bids/{}/documents/{}?download={}&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, key, self.bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 7) - self.assertEqual(response.body, 'content') - - response = self.app.get('/auctions/{}/bids/{}/documents/{}'.format( - self.auction_id, self.bid_id, doc_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't view bid document in current (active.tendering) auction status") - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, self.bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - self.set_status('active.awarded', {'status': 'active.tendering'}) - response = self.app.post('/auctions/{}/bids/{}/documents'.format( - self.auction_id, self.bid_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertIn("Document can be added only during the tendering period: from", response.json['errors'][0]["description"]) - - self.set_status('active.awarded') - - response = self.app.post('/auctions/{}/bids/{}/documents'.format( - self.auction_id, self.bid_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.awarded) auction status") - - response = self.app.get('/auctions/{}/bids/{}/documents/{}'.format(self.auction_id, self.bid_id, doc_id)) - self.assertEqual(response.status, '200 OK') - if self.docservice: - self.assertIn('http://localhost/get/', response.json['data']['url']) - self.assertIn('Signature=', response.json['data']['url']) - self.assertIn('KeyID=', response.json['data']['url']) - self.assertNotIn('Expires=', response.json['data']['url']) - else: - self.assertIn('download=', response.json['data']['url']) - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?download={}&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, key, self.bid_token)) - if self.docservice: - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertIn('Expires=', response.location) - else: - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 7) - self.assertEqual(response.body, 'content') - - def test_put_auction_bidder_document(self): - response = self.app.post('/auctions/{}/bids/{}/documents'.format( - self.auction_id, self.bid_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put('/auctions/{}/bids/{}/documents/{}'.format(self.auction_id, self.bid_id, doc_id), - status=404, - upload_files=[('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/{}/bids/{}/documents/{}'.format( - self.auction_id, self.bid_id, doc_id), upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?{}&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, key, self.bid_token)) - if self.docservice: - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertIn('Expires=', response.location) - else: - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content2') - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, self.bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.put('/auctions/{}/bids/{}/documents/{}'.format( - self.auction_id, self.bid_id, doc_id), 'content3', content_type='application/msword') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?{}&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, key, self.bid_token)) - if self.docservice: - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertIn('Expires=', response.location) - else: - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content3') - - self.set_status('active.awarded') - - response = self.app.put('/auctions/{}/bids/{}/documents/{}'.format( - self.auction_id, self.bid_id, doc_id), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (active.awarded) auction status") - - def test_patch_auction_bidder_document(self): - response = self.app.post('/auctions/{}/bids/{}/documents'.format( - self.auction_id, self.bid_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.patch_json('/auctions/{}/bids/{}/documents/{}'.format(self.auction_id, self.bid_id, doc_id), {"data": { - "documentOf": "lot" - }}, 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'This field is required.'], u'location': u'body', u'name': u'relatedItem'}, - ]) - - response = self.app.patch_json('/auctions/{}/bids/{}/documents/{}'.format(self.auction_id, self.bid_id, doc_id), {"data": { - "documentOf": "lot", - "relatedItem": '0' * 32 - }}, 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'relatedItem should be one of lots'], u'location': u'body', u'name': u'relatedItem'} - ]) - - response = self.app.patch_json('/auctions/{}/bids/{}/documents/{}'.format(self.auction_id, self.bid_id, doc_id), {"data": {"description": "document description"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, self.bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('document description', response.json["data"]["description"]) - - self.set_status('active.awarded') - - response = self.app.patch_json('/auctions/{}/bids/{}/documents/{}'.format(self.auction_id, self.bid_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (active.awarded) auction status") +class AuctionBidderDocumentWithDSResourceTest(BaseAuctionWebTest, + AuctionBidderDocumentResourceTestMixin, + AuctionBidderDocumentWithDSResourceTestMixin): + initial_status = 'active.tendering' + docservice = True + test_create_auction_bidder_document_nopending = snitch(create_auction_bidder_document_nopending) - def test_create_auction_bidder_document_nopending(self): + def setUp(self): + super(AuctionBidderDocumentWithDSResourceTest, self).setUp() + # Create bid if self.initial_organization == test_financial_organization: response = self.app.post_json('/auctions/{}/bids'.format( self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) @@ -1062,218 +131,8 @@ def test_create_auction_bidder_document_nopending(self): response = self.app.post_json('/auctions/{}/bids'.format( self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) bid = response.json['data'] - bid_id = bid['id'] - - response = self.app.post('/auctions/{}/bids/{}/documents'.format( - self.auction_id, bid_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - self.set_status('active.qualification') - - response = self.app.patch_json('/auctions/{}/bids/{}/documents/{}'.format( - self.auction_id, bid_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document because award of bid is not in pending state") - - response = self.app.put('/auctions/{}/bids/{}/documents/{}'.format( - self.auction_id, bid_id, doc_id), 'content3', content_type='application/msword', status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document because award of bid is not in pending state") - - response = self.app.post('/auctions/{}/bids/{}/documents'.format( - self.auction_id, bid_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document because award of bid is not in pending state") - - -class AuctionBidderDocumentWithDSResourceTest(AuctionBidderDocumentResourceTest): - docservice = True - - def test_create_auction_bidder_document_json(self): - response = self.app.post_json('/auctions/{}/bids/{}/documents'.format(self.auction_id, self.bid_id), - {'data': { - 'title': 'name.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - key = response.json["data"]["url"].split('?')[-1].split('=')[-1] - - response = self.app.get('/auctions/{}/bids/{}/documents'.format(self.auction_id, self.bid_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't view bid documents in current (active.tendering) auction status") - - response = self.app.get('/auctions/{}/bids/{}/documents?acc_token={}'.format(self.auction_id, self.bid_id, self.bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/bids/{}/documents?all=true&acc_token={}'.format(self.auction_id, self.bid_id, self.bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?download=some_id&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, self.bid_token), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?download={}'.format( - self.auction_id, self.bid_id, doc_id, key), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't view bid document in current (active.tendering) auction status") - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?download={}&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, key, self.bid_token)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertIn('Expires=', response.location) - - response = self.app.get('/auctions/{}/bids/{}/documents/{}'.format( - self.auction_id, self.bid_id, doc_id), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't view bid document in current (active.tendering) auction status") - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, self.bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.post_json('/auctions/{}/bids/{}/documents'.format(self.auction_id, self.bid_id), - {'data': { - 'title': 'name.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - self.assertIn(response.json["data"]['id'], response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - - self.set_status('active.awarded') - - response = self.app.post_json('/auctions/{}/bids/{}/documents'.format(self.auction_id, self.bid_id), - {'data': { - 'title': 'name.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.awarded) auction status") - - response = self.app.get('/auctions/{}/bids/{}/documents/{}'.format(self.auction_id, self.bid_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertIn('http://localhost/get/', response.json['data']['url']) - self.assertIn('Signature=', response.json['data']['url']) - self.assertIn('KeyID=', response.json['data']['url']) - self.assertNotIn('Expires=', response.json['data']['url']) - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?download={}&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, key, self.bid_token)) - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertIn('Expires=', response.location) - - def test_put_auction_bidder_document_json(self): - response = self.app.post_json('/auctions/{}/bids/{}/documents'.format(self.auction_id, self.bid_id), - {'data': { - 'title': 'name.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put_json('/auctions/{}/bids/{}/documents/{}'.format(self.auction_id, self.bid_id, doc_id), - {'data': { - 'title': 'name.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?{}&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, key, self.bid_token)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertIn('Expires=', response.location) - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, self.bid_token)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.put_json('/auctions/{}/bids/{}/documents/{}'.format(self.auction_id, self.bid_id, doc_id), - {'data': { - 'title': 'name.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/bids/{}/documents/{}?{}&acc_token={}'.format( - self.auction_id, self.bid_id, doc_id, key, self.bid_token)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertIn('Expires=', response.location) - - self.set_status('active.awarded') - - response = self.app.put_json('/auctions/{}/bids/{}/documents/{}'.format(self.auction_id, self.bid_id, doc_id), - {'data': { - 'title': 'name.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (active.awarded) auction status") + self.bid_id = bid['id'] + self.bid_token = response.json['access']['token'] class FinancialAuctionBidderResourceTest(AuctionBidderResourceTest): diff --git a/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py b/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py new file mode 100644 index 00000000..7b8451af --- /dev/null +++ b/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py @@ -0,0 +1,682 @@ +# -*- coding: utf-8 -*- +from copy import deepcopy + +from openprocurement.auctions.dgf.tests.base import ( + test_auction_data, + test_features_auction_data, + test_financial_organization, + test_financial_auction_data, + test_bids, + test_financial_bids, + test_organization +) + + +# AuctionBidderResourceTest + +def create_auction_bidder_invalid(self): + response = self.app.post_json('/auctions/some_id/bids', { + 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}, status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'auction_id'} + ]) + + request_path = '/auctions/{}/bids'.format(self.auction_id) + response = self.app.post(request_path, 'data', status=415) + self.assertEqual(response.status, '415 Unsupported Media Type') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': + u"Content-Type header should be one of ['application/json']", u'location': u'header', + u'name': u'Content-Type'} + ]) + + response = self.app.post( + request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, 'data', 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'Data not available', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json( + request_path, {'not_data': {}}, 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'Data not available', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, {'data': { + 'invalid_field': 'invalid_value'}}, 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'Rogue field', u'location': + u'body', u'name': u'invalid_field'} + ]) + + response = self.app.post_json(request_path, { + 'data': {'tenderers': [{'identifier': 'invalid_value'}]}}, 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'identifier': [ + u'Please use a mapping for this field or Identifier instance instead of unicode.']}, u'location': u'body', + u'name': u'tenderers'} + ]) + + response = self.app.post_json(request_path, { + 'data': {'tenderers': [{'identifier': {}}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u"location": u"body", u"name": u"qualified", u"description": [u"This field is required."]}, + response.json['errors']) + if self.initial_organization == test_financial_organization: + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'eligible'}, + response.json['errors']) + self.assertIn({u'description': [ + {u'additionalIdentifiers': [u'This field is required.'], u'contactPoint': [u'This field is required.'], + u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.']}, + u'name': [u'This field is required.'], u'address': [u'This field is required.']}], u'location': u'body', + u'name': u'tenderers'}, response.json['errors']) + else: + self.assertIn({u'description': [{u'contactPoint': [u'This field is required.'], + u'identifier': {u'scheme': [u'This field is required.'], + u'id': [u'This field is required.']}, + u'name': [u'This field is required.'], + u'address': [u'This field is required.']}], u'location': u'body', + u'name': u'tenderers'}, response.json['errors']) + + response = self.app.post_json(request_path, {'data': {'tenderers': [{ + 'name': 'name', 'identifier': {'uri': 'invalid_value'}}]}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u"location": u"body", u"name": u"qualified", u"description": [u"This field is required."]}, + response.json['errors']) + if self.initial_organization == test_financial_organization: + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'eligible'}, + response.json['errors']) + self.assertIn({u'description': [ + {u'additionalIdentifiers': [u'This field is required.'], u'contactPoint': [u'This field is required.'], + u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.'], + u'uri': [u'Not a well formed URL.']}, u'address': [u'This field is required.']}], + u'location': u'body', u'name': u'tenderers'}, response.json['errors']) + else: + self.assertIn({u'description': [{u'contactPoint': [u'This field is required.'], + u'identifier': {u'scheme': [u'This field is required.'], + u'id': [u'This field is required.'], + u'uri': [u'Not a well formed URL.']}, + u'address': [u'This field is required.']}], u'location': u'body', + u'name': u'tenderers'}, response.json['errors']) + + if self.initial_organization == test_financial_organization: + response = self.app.post_json(request_path, { + 'data': {'tenderers': [self.initial_organization], 'qualified': True, 'eligible': True}}, status=422) + else: + response = self.app.post_json(request_path, + {'data': {'tenderers': [self.initial_organization], 'qualified': True}}, + status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'value'}, + response.json['errors']) + + if self.initial_organization == test_financial_organization: + response = self.app.post_json(request_path, { + 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'valueAddedTaxIncluded': False}, + 'qualified': True, 'eligible': True}}, status=422) + else: + response = self.app.post_json(request_path, { + 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'valueAddedTaxIncluded': False}, + 'qualified': True}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u'description': [ + u'valueAddedTaxIncluded of bid should be identical to valueAddedTaxIncluded of value of auction'], + u'location': u'body', u'name': u'value'}, response.json['errors']) + + if self.initial_organization == test_financial_organization: + response = self.app.post_json(request_path, { + 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'currency': "USD"}, + 'qualified': True, 'eligible': True}}, status=422) + else: + response = self.app.post_json(request_path, { + 'data': {'tenderers': [self.initial_organization], "value": {"amount": 500, 'currency': "USD"}, + 'qualified': True}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn( + {u'description': [u'currency of bid should be identical to currency of value of auction'], u'location': u'body', + u'name': u'value'}, response.json['errors']) + + if self.initial_organization == test_financial_organization: + response = self.app.post_json(request_path, { + 'data': {'tenderers': self.initial_organization, "value": {"amount": 500}, 'qualified': True, + 'eligible': True}}, status=422) + else: + response = self.app.post_json(request_path, { + 'data': {'tenderers': self.initial_organization, "value": {"amount": 500}, 'qualified': True}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + if self.initial_organization == test_financial_organization: + self.assertIn( + {u'description': u"invalid literal for int() with base 10: 'additionalIdentifiers'", u'location': u'body', + u'name': u'data'}, response.json['errors']) + else: + self.assertIn({u'description': u"invalid literal for int() with base 10: 'contactPoint'", u'location': u'body', + u'name': u'data'}, response.json['errors']) + + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}}}, + status=422) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}}}, + status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'qualified'}, + response.json['errors']) + + +def patch_auction_bidder(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "status": "draft", "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "status": "draft", "value": {"amount": 500}, 'qualified': True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bidder = response.json['data'] + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"status": "active", "value": {"amount": 60}}}, 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'value of bid should be greater than value of auction'], u'location': u'body', u'name': u'value'} + ]) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {'tenderers': [{"name": u"Державне управління управлінням справами"}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['date'], bidder['date']) + self.assertNotEqual(response.json['data']['tenderers'][0]['name'], bidder['tenderers'][0]['name']) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"value": {"amount": 500}, 'tenderers': [self.initial_organization]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['date'], bidder['date']) + self.assertEqual(response.json['data']['tenderers'][0]['name'], bidder['tenderers'][0]['name']) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"value": {"amount": 400}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["value"]["amount"], 400) + self.assertNotEqual(response.json['data']['date'], bidder['date']) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], "active") + self.assertNotEqual(response.json['data']['date'], bidder['date']) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"status": "draft"}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can\'t update bid to (draft) status") + + response = self.app.patch_json('/auctions/{}/bids/some_id'.format(self.auction_id), {"data": {"value": {"amount": 400}}}, status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'bid_id'} + ]) + + response = self.app.patch_json('/auctions/some_id/bids/some_id', {"data": {"value": {"amount": 400}}}, status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'auction_id'} + ]) + + self.set_status('complete') + + response = self.app.get('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id'])) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["value"]["amount"], 400) + + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {"value": {"amount": 400}}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update bid in current (complete) auction status") + + +def get_auction_bidder(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bidder = response.json['data'] + bid_token = response.json['access']['token'] + + response = self.app.get('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't view bid in current (active.tendering) auction status") + + response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bidder['id'], bid_token)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data'], bidder) + + self.set_status('active.qualification') + + response = self.app.get('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id'])) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + bidder_data = response.json['data'] + #self.assertIn(u'participationUrl', bidder_data) + #bidder_data.pop(u'participationUrl') + self.assertEqual(bidder_data, bidder) + + response = self.app.get('/auctions/{}/bids/some_id'.format(self.auction_id), status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'bid_id'} + ]) + + response = self.app.get('/auctions/some_id/bids/some_id', status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'auction_id'} + ]) + + response = self.app.delete('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't delete bid in current (active.qualification) auction status") + + +def delete_auction_bidder(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bidder = response.json['data'] + + response = self.app.delete('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id'])) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data'], bidder) + + revisions = self.db.get(self.auction_id).get('revisions') + self.assertTrue(any([i for i in revisions[-2][u'changes'] if i['op'] == u'remove' and i['path'] == u'/bids'])) + self.assertTrue(any([i for i in revisions[-1][u'changes'] if i['op'] == u'add' and i['path'] == u'/bids'])) + + response = self.app.delete('/auctions/{}/bids/some_id'.format(self.auction_id), status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'bid_id'} + ]) + + response = self.app.delete('/auctions/some_id/bids/some_id', status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'auction_id'} + ]) + + +def get_auction_auctioners(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bidder = response.json['data'] + + response = self.app.get('/auctions/{}/bids'.format(self.auction_id), status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't view bids in current (active.tendering) auction status") + + self.set_status('active.qualification') + + response = self.app.get('/auctions/{}/bids'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data'][0], bidder) + + response = self.app.get('/auctions/some_id/bids', status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': + u'url', u'name': u'auction_id'} + ]) + + +def bid_Administrator_change(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bidder = response.json['data'] + + self.app.authorization = ('Basic', ('administrator', '')) + response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": { + 'tenderers': [{"identifier": {"id": "00000000"}}], + "value": {"amount": 400} + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']["value"]["amount"], 400) + self.assertEqual(response.json['data']["tenderers"][0]["identifier"]["id"], "00000000") + + +# AuctionBidInvalidationAuctionResourceTest + + +def post_auction_all_invalid_bids(self): + self.app.authorization = ('Basic', ('auction', '')) + + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), + {'data': {'bids': self.initial_bids}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + + self.assertEqual(auction["bids"][0]['value']['amount'], self.initial_bids[0]['value']['amount']) + self.assertEqual(auction["bids"][1]['value']['amount'], self.initial_bids[1]['value']['amount']) + self.assertEqual(auction["bids"][2]['value']['amount'], self.initial_bids[2]['value']['amount']) + + value_threshold = auction['value']['amount'] + auction['minimalStep']['amount'] + self.assertLess(auction["bids"][0]['value']['amount'], value_threshold) + self.assertLess(auction["bids"][1]['value']['amount'], value_threshold) + self.assertLess(auction["bids"][2]['value']['amount'], value_threshold) + self.assertEqual(auction["bids"][0]['status'], 'invalid') + self.assertEqual(auction["bids"][1]['status'], 'invalid') + self.assertEqual(auction["bids"][2]['status'], 'invalid') + self.assertEqual('unsuccessful', auction["status"]) + + +def post_auction_one_invalid_bid(self): + self.app.authorization = ('Basic', ('auction', '')) + + bids = deepcopy(self.initial_bids) + bids[0]['value']['amount'] = bids[0]['value']['amount'] * 3 + bids[1]['value']['amount'] = bids[1]['value']['amount'] * 2 + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': bids}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + + self.assertEqual(auction["bids"][0]['value']['amount'], bids[0]['value']['amount']) + self.assertEqual(auction["bids"][1]['value']['amount'], bids[1]['value']['amount']) + self.assertEqual(auction["bids"][2]['value']['amount'], bids[2]['value']['amount']) + + value_threshold = auction['value']['amount'] + auction['minimalStep']['amount'] + + self.assertGreater(auction["bids"][0]['value']['amount'], value_threshold) + self.assertGreater(auction["bids"][1]['value']['amount'], value_threshold) + self.assertLess(auction["bids"][2]['value']['amount'], value_threshold) + + self.assertEqual(auction["bids"][0]['status'], 'active') + self.assertEqual(auction["bids"][1]['status'], 'active') + self.assertEqual(auction["bids"][2]['status'], 'invalid') + + self.assertEqual('active.qualification', auction["status"]) + + for i, status in enumerate(['pending.verification', 'pending.waiting']): + self.assertIn("tenderers", auction["bids"][i]) + self.assertIn("name", auction["bids"][i]["tenderers"][0]) + # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) + self.assertEqual(auction["awards"][i]['bid_id'], bids[i]['id']) + self.assertEqual(auction["awards"][i]['value']['amount'], bids[i]['value']['amount']) + self.assertEqual(auction["awards"][i]['suppliers'], bids[i]['tenderers']) + self.assertEqual(auction["awards"][i]['status'], status) + if status == 'pending.verification': + self.assertIn("verificationPeriod", auction["awards"][i]) + + +def post_auction_one_valid_bid(self): + self.app.authorization = ('Basic', ('auction', '')) + + bids = deepcopy(self.initial_bids) + bids[0]['value']['amount'] = bids[0]['value']['amount'] * 2 + response = self.app.post_json('/auctions/{}/auction'.format(self.auction_id), {'data': {'bids': bids}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + + self.assertEqual(auction["bids"][0]['value']['amount'], bids[0]['value']['amount']) + self.assertEqual(auction["bids"][1]['value']['amount'], bids[1]['value']['amount']) + self.assertEqual(auction["bids"][2]['value']['amount'], bids[2]['value']['amount']) + + value_threshold = auction['value']['amount'] + auction['minimalStep']['amount'] + + self.assertGreater(auction["bids"][0]['value']['amount'], value_threshold) + self.assertLess(auction["bids"][1]['value']['amount'], value_threshold) + self.assertLess(auction["bids"][2]['value']['amount'], value_threshold) + + self.assertEqual(auction["bids"][0]['status'], 'active') + self.assertEqual(auction["bids"][1]['status'], 'invalid') + self.assertEqual(auction["bids"][2]['status'], 'invalid') + + self.assertEqual('active.qualification', auction["status"]) + + for i, status in enumerate(['pending.verification', 'unsuccessful']): + self.assertIn("tenderers", auction["bids"][i]) + self.assertIn("name", auction["bids"][i]["tenderers"][0]) + # self.assertIn(auction["awards"][0]["id"], response.headers['Location']) + self.assertEqual(auction["awards"][i]['bid_id'], bids[i]['id']) + self.assertEqual(auction["awards"][i]['value']['amount'], bids[i]['value']['amount']) + self.assertEqual(auction["awards"][i]['suppliers'], bids[i]['tenderers']) + self.assertEqual(auction["awards"][i]['status'], status) + if status == 'pending.verification': + self.assertIn("verificationPeriod", auction["awards"][i]) + + +# AuctionBidderProcessTest + + +def reactivate_invalidated_bids(self): + + bid1_id = self.initial_bids[0]['id'] + bid2_id = self.initial_bids[1]['id'] + bid1_token = self.initial_bids_tokens[self.initial_bids[0]['id']] + bid2_token = self.initial_bids_tokens[self.initial_bids[1]['id']] + + # patch + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(self.auction_id, self.auction_token), {'data': {'value': {'amount': 540}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token)) + self.assertEqual(response.json['data']["status"], "invalid") + response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token)) + self.assertEqual(response.json['data']["status"], "invalid") + + # reactivate bids invalid bid value.amount + + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token), + {'data': {"status": "active"}}, status=422) + self.assertEqual(response.json['errors'], [ + {u'description': [u'value of bid should be greater than value of auction'], u'location': u'body', u'name': u'value'} + ]) + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token), + {'data': {"status": "active"}}, status=422) + self.assertEqual(response.json['errors'], [ + {u'description': [u'value of bid should be greater than value of auction'], u'location': u'body', u'name': u'value'} + ]) + + # set bid value.amount above auction value.amount + + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token), + {"data": {"value": {"amount": 800}}}) + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token), + {"data": {"value": {"amount": 900}}}) + + # reactivate bids + + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid1_id, bid1_token), + {'data': {"status": "active"}}) + self.assertEqual(response.json['data']["status"], "active") + + response = self.app.patch_json('/auctions/{}/bids/{}?acc_token={}'.format(self.auction_id, bid2_id, bid2_token), + {'data': {"status": "active"}}) + self.assertEqual(response.json['data']["status"], "active") + +# AuctionBidderFeaturesResourceTest + + +def features_bidder(self): + test_features_bids = [ + { + "parameters": [ + { + "code": i["code"], + "value": 0.1, + } + for i in self.initial_data['features'] + ], + "status": "active", + "tenderers": [ + self.initial_organization + ], + "value": { + "amount": 469, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + }, + { + "parameters": [ + { + "code": i["code"], + "value": 0.15, + } + for i in self.initial_data['features'] + ], + "tenderers": [ + self.initial_organization + ], + "status": "draft", + "value": { + "amount": 479, + "currency": "UAH", + "valueAddedTaxIncluded": True + } + } + ] + for i in test_features_bids: + response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), {'data': i}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + bid = response.json['data'] + bid.pop(u'date') + bid.pop(u'id') + self.assertEqual(bid, i) + +# AuctionBidderDocumentResourceTest + + +def create_auction_bidder_document_nopending(self): + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format( + self.auction_id), {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + bid = response.json['data'] + bid_id = bid['id'] + + response = self.app.post('/auctions/{}/bids/{}/documents'.format( + self.auction_id, bid_id), upload_files=[('file', 'name.doc', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + + self.set_status('active.qualification') + + response = self.app.patch_json('/auctions/{}/bids/{}/documents/{}'.format( + self.auction_id, bid_id, doc_id), {"data": {"description": "document description"}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update document because award of bid is not in pending state") + + response = self.app.put('/auctions/{}/bids/{}/documents/{}'.format( + self.auction_id, bid_id, doc_id), 'content3', content_type='application/msword', status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update document because award of bid is not in pending state") + + response = self.app.post('/auctions/{}/bids/{}/documents'.format( + self.auction_id, bid_id), upload_files=[('file', 'name.doc', 'content')], status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't add document because award of bid is not in pending state") From 0719a2e4be71156712e6be518fc8bc23f555e31d Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 18:54:21 +0200 Subject: [PATCH 22/45] Refactor cancellation. Use existed mixins from core --- .../auctions/dgf/tests/cancellation.py | 648 +----------------- 1 file changed, 10 insertions(+), 638 deletions(-) diff --git a/openprocurement/auctions/dgf/tests/cancellation.py b/openprocurement/auctions/dgf/tests/cancellation.py index b16714c9..0fda6527 100644 --- a/openprocurement/auctions/dgf/tests/cancellation.py +++ b/openprocurement/auctions/dgf/tests/cancellation.py @@ -2,416 +2,34 @@ import unittest from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_lots, test_bids, test_financial_auction_data, test_financial_bids +from openprocurement.auctions.core.tests.cancellation import ( + AuctionCancellationResourceTestMixin, + AuctionLotCancellationResourceTestMixin, + AuctionLotsCancellationResourceTestMixin, + AuctionCancellationDocumentResourceTestMixin +) -class AuctionCancellationResourceTest(BaseAuctionWebTest): +class AuctionCancellationResourceTest(BaseAuctionWebTest, AuctionCancellationResourceTestMixin): initial_status = 'active.tendering' initial_bids = test_bids - def test_create_auction_cancellation_invalid(self): - response = self.app.post_json('/auctions/some_id/cancellations', { - 'data': {'reason': 'cancellation reason'}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'auction_id'} - ]) - - request_path = '/auctions/{}/cancellations'.format(self.auction_id) - - response = self.app.post(request_path, 'data', status=415) - self.assertEqual(response.status, '415 Unsupported Media Type') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': - u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} - ]) - - response = self.app.post( - request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, 'data', 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json( - request_path, {'not_data': {}}, 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'data': {}}, 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'This field is required.'], u'location': u'body', u'name': u'reason'}, - ]) - - response = self.app.post_json(request_path, {'data': { - 'invalid_field': 'invalid_value'}}, 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'Rogue field', u'location': - u'body', u'name': u'invalid_field'} - ]) - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - "cancellationOf": "lot" - }}, 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'This field is required.'], u'location': u'body', u'name': u'relatedLot'} - ]) - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - "cancellationOf": "lot", - "relatedLot": '0' * 32 - }}, 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'relatedLot should be one of lots'], u'location': u'body', u'name': u'relatedLot'} - ]) - - def test_create_auction_cancellation(self): - response = self.app.post_json('/auctions/{}/cancellations'.format( - self.auction_id), {'data': {'reason': 'cancellation reason'}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - self.assertEqual(cancellation['reason'], 'cancellation reason') - self.assertIn('id', cancellation) - self.assertIn(cancellation['id'], response.headers['Location']) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], 'active.tendering') - - response = self.app.post_json('/auctions/{}/cancellations'.format( - self.auction_id), {'data': {'reason': 'cancellation reason', 'status': 'active'}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - self.assertEqual(cancellation['reason'], 'cancellation reason') - self.assertEqual(cancellation['status'], 'active') - self.assertIn('id', cancellation) - self.assertIn(cancellation['id'], response.headers['Location']) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], 'cancelled') - self.assertNotIn("bids", response.json['data']) - - response = self.app.post_json('/auctions/{}/cancellations'.format( - self.auction_id), {'data': {'reason': 'cancellation reason'}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add cancellation in current (cancelled) auction status") - - def test_patch_auction_cancellation(self): - response = self.app.post_json('/auctions/{}/cancellations'.format( - self.auction_id), {'data': {'reason': 'cancellation reason'}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - - response = self.app.patch_json('/auctions/{}/cancellations/{}'.format(self.auction_id, cancellation['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], 'cancelled') - self.assertNotIn("bids", response.json['data']) - - response = self.app.patch_json('/auctions/{}/cancellations/{}'.format(self.auction_id, cancellation['id']), {"data": {"status": "pending"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update cancellation in current (cancelled) auction status") - - response = self.app.patch_json('/auctions/{}/cancellations/some_id'.format(self.auction_id), {"data": {"status": "active"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'cancellation_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/cancellations/some_id', {"data": {"status": "active"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/cancellations/{}'.format(self.auction_id, cancellation['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - self.assertEqual(response.json['data']["reason"], "cancellation reason") - - def test_get_auction_cancellation(self): - response = self.app.post_json('/auctions/{}/cancellations'.format( - self.auction_id), {'data': {'reason': 'cancellation reason'}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - - response = self.app.get('/auctions/{}/cancellations/{}'.format(self.auction_id, cancellation['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], cancellation) - - response = self.app.get('/auctions/{}/cancellations/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'cancellation_id'} - ]) - - response = self.app.get('/auctions/some_id/cancellations/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_get_auction_cancellations(self): - response = self.app.post_json('/auctions/{}/cancellations'.format( - self.auction_id), {'data': {'reason': 'cancellation reason'}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - - response = self.app.get('/auctions/{}/cancellations'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][0], cancellation) - - response = self.app.get('/auctions/some_id/cancellations', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - @unittest.skip("option not available") -class AuctionLotCancellationResourceTest(BaseAuctionWebTest): +class AuctionLotCancellationResourceTest(BaseAuctionWebTest, AuctionLotCancellationResourceTestMixin): initial_status = 'active.tendering' initial_lots = test_lots initial_bids = test_bids - def test_create_auction_cancellation(self): - lot_id = self.initial_lots[0]['id'] - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - "cancellationOf": "lot", - "relatedLot": lot_id - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - self.assertEqual(cancellation['reason'], 'cancellation reason') - self.assertIn('id', cancellation) - self.assertIn(cancellation['id'], response.headers['Location']) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['lots'][0]["status"], 'active') - self.assertEqual(response.json['data']["status"], 'active.tendering') - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": lot_id - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - self.assertEqual(cancellation['reason'], 'cancellation reason') - self.assertEqual(cancellation['status'], 'active') - self.assertIn('id', cancellation) - self.assertIn(cancellation['id'], response.headers['Location']) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['lots'][0]["status"], 'cancelled') - self.assertEqual(response.json['data']["status"], 'cancelled') - - response = self.app.post_json('/auctions/{}/cancellations'.format( - self.auction_id), {'data': {'reason': 'cancellation reason'}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add cancellation in current (cancelled) auction status") - - def test_patch_auction_cancellation(self): - lot_id = self.initial_lots[0]['id'] - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - "cancellationOf": "lot", - "relatedLot": lot_id - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - - response = self.app.patch_json('/auctions/{}/cancellations/{}'.format(self.auction_id, cancellation['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['lots'][0]["status"], 'cancelled') - self.assertEqual(response.json['data']["status"], 'cancelled') - - response = self.app.patch_json('/auctions/{}/cancellations/{}'.format(self.auction_id, cancellation['id']), {"data": {"status": "pending"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update cancellation in current (cancelled) auction status") - - response = self.app.get('/auctions/{}/cancellations/{}'.format(self.auction_id, cancellation['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - self.assertEqual(response.json['data']["reason"], "cancellation reason") - @unittest.skip("option not available") -class AuctionLotsCancellationResourceTest(BaseAuctionWebTest): +class AuctionLotsCancellationResourceTest(BaseAuctionWebTest, AuctionLotsCancellationResourceTestMixin): initial_status = 'active.tendering' initial_lots = 2 * test_lots initial_bids = test_bids - def test_create_auction_cancellation(self): - lot_id = self.initial_lots[0]['id'] - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - "cancellationOf": "lot", - "relatedLot": lot_id - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - self.assertEqual(cancellation['reason'], 'cancellation reason') - self.assertIn('id', cancellation) - self.assertIn(cancellation['id'], response.headers['Location']) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['lots'][0]["status"], 'active') - self.assertEqual(response.json['data']["status"], 'active.tendering') - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": lot_id - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - self.assertEqual(cancellation['reason'], 'cancellation reason') - self.assertEqual(cancellation['status'], 'active') - self.assertIn('id', cancellation) - self.assertIn(cancellation['id'], response.headers['Location']) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['lots'][0]["status"], 'cancelled') - self.assertNotEqual(response.json['data']["status"], 'cancelled') - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": lot_id - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add cancellation only in active lot status") - - def test_patch_auction_cancellation(self): - lot_id = self.initial_lots[0]['id'] - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - "cancellationOf": "lot", - "relatedLot": lot_id - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - cancellation = response.json['data'] - - response = self.app.patch_json('/auctions/{}/cancellations/{}'.format(self.auction_id, cancellation['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['lots'][0]["status"], 'cancelled') - self.assertNotEqual(response.json['data']["status"], 'cancelled') - - response = self.app.patch_json('/auctions/{}/cancellations/{}'.format(self.auction_id, cancellation['id']), {"data": {"status": "pending"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update cancellation only in active lot status") - response = self.app.get('/auctions/{}/cancellations/{}'.format(self.auction_id, cancellation['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - self.assertEqual(response.json['data']["reason"], "cancellation reason") - - -class AuctionCancellationDocumentResourceTest(BaseAuctionWebTest): +class AuctionCancellationDocumentResourceTest(BaseAuctionWebTest, AuctionCancellationDocumentResourceTestMixin): def setUp(self): super(AuctionCancellationDocumentResourceTest, self).setUp() @@ -421,252 +39,6 @@ def setUp(self): cancellation = response.json['data'] self.cancellation_id = cancellation['id'] - def test_not_found(self): - response = self.app.post('/auctions/some_id/cancellations/some_id/documents', status=404, upload_files=[ - ('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.post('/auctions/{}/cancellations/some_id/documents'.format(self.auction_id), status=404, upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'cancellation_id'} - ]) - - response = self.app.post('/auctions/{}/cancellations/{}/documents'.format(self.auction_id, self.cancellation_id), status=404, upload_files=[ - ('invalid_value', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.get('/auctions/some_id/cancellations/some_id/documents', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/cancellations/some_id/documents'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'cancellation_id'} - ]) - - response = self.app.get('/auctions/some_id/cancellations/some_id/documents/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/cancellations/some_id/documents/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'cancellation_id'} - ]) - - response = self.app.get('/auctions/{}/cancellations/{}/documents/some_id'.format(self.auction_id, self.cancellation_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'document_id'} - ]) - - response = self.app.put('/auctions/some_id/cancellations/some_id/documents/some_id', status=404, - upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.put('/auctions/{}/cancellations/some_id/documents/some_id'.format(self.auction_id), status=404, upload_files=[ - ('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'cancellation_id'} - ]) - - response = self.app.put('/auctions/{}/cancellations/{}/documents/some_id'.format( - self.auction_id, self.cancellation_id), status=404, upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'document_id'} - ]) - - def test_create_auction_cancellation_document(self): - response = self.app.post('/auctions/{}/cancellations/{}/documents'.format( - self.auction_id, self.cancellation_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/cancellations/{}/documents'.format(self.auction_id, self.cancellation_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/cancellations/{}/documents?all=true'.format(self.auction_id, self.cancellation_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/cancellations/{}/documents/{}?download=some_id'.format( - self.auction_id, self.cancellation_id, doc_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/cancellations/{}/documents/{}?{}'.format( - self.auction_id, self.cancellation_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 7) - self.assertEqual(response.body, 'content') - - response = self.app.get('/auctions/{}/cancellations/{}/documents/{}'.format( - self.auction_id, self.cancellation_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - self.set_status('complete') - - response = self.app.post('/auctions/{}/cancellations/{}/documents'.format( - self.auction_id, self.cancellation_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (complete) auction status") - - def test_put_auction_cancellation_document(self): - response = self.app.post('/auctions/{}/cancellations/{}/documents'.format( - self.auction_id, self.cancellation_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put('/auctions/{}/cancellations/{}/documents/{}'.format(self.auction_id, self.cancellation_id, doc_id), - status=404, - upload_files=[('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/{}/cancellations/{}/documents/{}'.format( - self.auction_id, self.cancellation_id, doc_id), upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/cancellations/{}/documents/{}?{}'.format( - self.auction_id, self.cancellation_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content2') - - response = self.app.get('/auctions/{}/cancellations/{}/documents/{}'.format( - self.auction_id, self.cancellation_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.put('/auctions/{}/cancellations/{}/documents/{}'.format( - self.auction_id, self.cancellation_id, doc_id), 'content3', content_type='application/msword') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/cancellations/{}/documents/{}?{}'.format( - self.auction_id, self.cancellation_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content3') - - self.set_status('complete') - - response = self.app.put('/auctions/{}/cancellations/{}/documents/{}'.format( - self.auction_id, self.cancellation_id, doc_id), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") - - def test_patch_auction_cancellation_document(self): - response = self.app.post('/auctions/{}/cancellations/{}/documents'.format( - self.auction_id, self.cancellation_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.patch_json('/auctions/{}/cancellations/{}/documents/{}'.format(self.auction_id, self.cancellation_id, doc_id), {"data": {"description": "document description"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - - response = self.app.get('/auctions/{}/cancellations/{}/documents/{}'.format( - self.auction_id, self.cancellation_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('document description', response.json["data"]["description"]) - - self.set_status('complete') - - response = self.app.patch_json('/auctions/{}/cancellations/{}/documents/{}'.format(self.auction_id, self.cancellation_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") - class FinancialAuctionCancellationResourceTest(AuctionCancellationResourceTest): initial_bids = test_financial_bids From e6b4f800898c4f583ef6db682fe9aefa7c258403 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 18:55:24 +0200 Subject: [PATCH 23/45] Move chronograph tests to blank, use existed mixins from core --- .../dgf/tests/blanks/chronograph_blanks.py | 184 ++++++++++ .../auctions/dgf/tests/chronograph.py | 330 ++---------------- 2 files changed, 217 insertions(+), 297 deletions(-) create mode 100644 openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py diff --git a/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py b/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py new file mode 100644 index 00000000..74c693c7 --- /dev/null +++ b/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +from datetime import datetime, timedelta + +from openprocurement.api.models import get_now + + +# AuctionSwitchQualificationResourceTest + + +def switch_to_qualification1(self): + response = self.set_status('active.auction', {'status': self.initial_status}) + 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.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], "unsuccessful") + self.assertNotIn("awards", response.json['data']) + + +def switch_to_qualification(self): + auction = self.db.get(self.auction_id) + auction['minNumberOfQualifiedBids'] = 1 + self.db.save(auction) + response = self.set_status('active.auction', {'status': self.initial_status}) + 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.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], "active.qualification") + self.assertEqual(len(response.json['data']["awards"]), 1) + + +# AuctionAuctionPeriodResourceTest + + +def set_auction_period(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') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], 'active.tendering') + if self.initial_lots: + item = response.json['data']["lots"][0] + else: + item = response.json['data'] + self.assertIn('auctionPeriod', item) + self.assertIn('shouldStartAfter', item['auctionPeriod']) + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertIn('T00:00:00+', item['auctionPeriod']['shouldStartAfter']) + self.assertEqual(response.json['data']['next_check'], response.json['data']['tenderPeriod']['endDate']) + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00+00:00"}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00+00:00"}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(item['auctionPeriod']['startDate'], '9999-01-01T00:00:00+00:00') + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": None}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": None}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertNotIn('startDate', item['auctionPeriod']) + +def reset_auction_period(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') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], 'active.tendering') + if self.initial_lots: + item = response.json['data']["lots"][0] + else: + item = response.json['data'] + self.assertIn('auctionPeriod', item) + self.assertIn('shouldStartAfter', item['auctionPeriod']) + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertEqual(response.json['data']['next_check'], response.json['data']['tenderPeriod']['endDate']) + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) + + self.set_status('active.auction', {'status': 'active.tendering'}) + 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.auction') + item = response.json['data']["lots"][0] if self.initial_lots else response.json['data'] + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.json['data']["status"], 'active.auction') + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) + self.assertIn('9999-01-01T00:00:00', response.json['data']['next_check']) + + now = get_now().isoformat() + auction = self.db.get(self.auction_id) + if self.initial_lots: + auction['lots'][0]['auctionPeriod']['startDate'] = now + else: + auction['auctionPeriod']['startDate'] = now + self.db.save(auction) + + 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.auction') + item = response.json['data']["lots"][0] if self.initial_lots else response.json['data'] + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertGreater(response.json['data']['next_check'], item['auctionPeriod']['startDate']) + self.assertEqual(response.json['data']['next_check'], self.db.get(self.auction_id)['next_check']) + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": response.json['data']['tenderPeriod']['endDate']}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": response.json['data']['tenderPeriod']['endDate']}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.json['data']["status"], 'active.auction') + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertNotIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) + self.assertGreater(response.json['data']['next_check'], response.json['data']['tenderPeriod']['endDate']) + + auction = self.db.get(self.auction_id) + self.assertGreater(auction['next_check'], response.json['data']['tenderPeriod']['endDate']) + auction['tenderPeriod']['endDate'] = auction['tenderPeriod']['startDate'] + auction['tenderPeriod']['startDate'] = (datetime.strptime(auction['tenderPeriod']['endDate'][:19], "%Y-%m-%dT%H:%M:%S") - timedelta(days=10)).isoformat() + auction['enquiryPeriod']['startDate'] = auction['tenderPeriod']['startDate'] + auction['enquiryPeriod']['endDate'] = auction['tenderPeriod']['endDate'] + auction['rectificationPeriod']['startDate'] = (datetime.strptime(auction['tenderPeriod']['endDate'][:19], "%Y-%m-%dT%H:%M:%S") - timedelta(days=10)).isoformat() + auction['rectificationPeriod']['endDate'] = (datetime.strptime(auction['tenderPeriod']['endDate'][:19], "%Y-%m-%dT%H:%M:%S") - timedelta(days=5)).isoformat() + if self.initial_lots: + auction['lots'][0]['auctionPeriod']['startDate'] = auction['tenderPeriod']['endDate'] + else: + auction['auctionPeriod']['startDate'] = auction['tenderPeriod']['endDate'] + self.db.save(auction) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + if self.initial_lots: + item = response.json['data']["lots"][0] + else: + item = response.json['data'] + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertNotIn('next_check', response.json['data']) + self.assertNotIn('next_check', self.db.get(self.auction_id)) + shouldStartAfter = item['auctionPeriod']['shouldStartAfter'] + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) + if self.initial_lots: + item = response.json['data']["lots"][0] + else: + item = response.json['data'] + self.assertEqual(item['auctionPeriod']['shouldStartAfter'], shouldStartAfter) + self.assertNotIn('next_check', response.json['data']) + + if self.initial_lots: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}]}}) + item = response.json['data']["lots"][0] + else: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}}) + item = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.json['data']["status"], 'active.auction') + self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) + self.assertIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) + self.assertIn('9999-01-01T00:00:00', response.json['data']['next_check']) diff --git a/openprocurement/auctions/dgf/tests/chronograph.py b/openprocurement/auctions/dgf/tests/chronograph.py index da51d09e..2670a55b 100644 --- a/openprocurement/auctions/dgf/tests/chronograph.py +++ b/openprocurement/auctions/dgf/tests/chronograph.py @@ -1,58 +1,47 @@ # -*- coding: utf-8 -*- import unittest from datetime import datetime, timedelta + +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.tests.blanks.chronograph_blanks import ( + # AuctionSwitchAuctionResourceTest + switch_to_auction, + # AuctionSwitchUnsuccessfulResourceTest + switch_to_unsuccessful, + # AuctionComplaintSwitchResourceTest + switch_to_pending, + switch_to_complaint, + # AuctionAwardComplaintSwitchResourceTest + switch_to_pending_award, + switch_to_complaint_award, +) from openprocurement.api.models import get_now from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_lots, test_bids, test_financial_auction_data, test_financial_organization, test_financial_bids, test_organization +from openprocurement.auctions.dgf.tests.blanks.chronograph_blanks import ( + # AuctionSwitchQualificationResourceTest + switch_to_qualification, + switch_to_qualification1, + # AuctionAuctionPeriodResourceTest + set_auction_period, + reset_auction_period +) class AuctionSwitchQualificationResourceTest(BaseAuctionWebTest): initial_bids = test_bids[:1] - - def test_switch_to_qualification1(self): - response = self.set_status('active.auction', {'status': self.initial_status}) - 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.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "unsuccessful") - self.assertNotIn("awards", response.json['data']) - - def test_switch_to_qualification(self): - auction = self.db.get(self.auction_id) - auction['minNumberOfQualifiedBids'] = 1 - self.db.save(auction) - response = self.set_status('active.auction', {'status': self.initial_status}) - 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.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active.qualification") - self.assertEqual(len(response.json['data']["awards"]), 1) + test_switch_to_qualification1 = snitch(switch_to_qualification1) + test_switch_to_qualification = snitch(switch_to_qualification) class AuctionSwitchAuctionResourceTest(BaseAuctionWebTest): initial_bids = test_bids - def test_switch_to_auction(self): - response = self.set_status('active.auction', {'status': self.initial_status}) - 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.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active.auction") + test_switch_to_auction = snitch(switch_to_auction) class AuctionSwitchUnsuccessfulResourceTest(BaseAuctionWebTest): - def test_switch_to_unsuccessful(self): - response = self.set_status('active.auction', {'status': self.initial_status}) - 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.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "unsuccessful") - if self.initial_lots: - self.assertEqual(set([i['status'] for i in response.json['data']["lots"]]), set(["unsuccessful"])) + test_switch_to_unsuccessful = snitch(switch_to_unsuccessful) @unittest.skip("option not available") @@ -73,209 +62,14 @@ class AuctionLotSwitchUnsuccessfulResourceTest(AuctionSwitchUnsuccessfulResource class AuctionAuctionPeriodResourceTest(BaseAuctionWebTest): initial_bids = test_bids - def test_set_auction_period(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') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], 'active.tendering') - if self.initial_lots: - item = response.json['data']["lots"][0] - else: - item = response.json['data'] - self.assertIn('auctionPeriod', item) - self.assertIn('shouldStartAfter', item['auctionPeriod']) - self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) - self.assertIn('T00:00:00+', item['auctionPeriod']['shouldStartAfter']) - self.assertEqual(response.json['data']['next_check'], response.json['data']['tenderPeriod']['endDate']) - - if self.initial_lots: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00+00:00"}}]}}) - item = response.json['data']["lots"][0] - else: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00+00:00"}}}) - item = response.json['data'] - self.assertEqual(response.status, '200 OK') - self.assertEqual(item['auctionPeriod']['startDate'], '9999-01-01T00:00:00+00:00') - - if self.initial_lots: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": None}}]}}) - item = response.json['data']["lots"][0] - else: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": None}}}) - item = response.json['data'] - self.assertEqual(response.status, '200 OK') - self.assertNotIn('startDate', item['auctionPeriod']) - - def test_reset_auction_period(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') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], 'active.tendering') - if self.initial_lots: - item = response.json['data']["lots"][0] - else: - item = response.json['data'] - self.assertIn('auctionPeriod', item) - self.assertIn('shouldStartAfter', item['auctionPeriod']) - self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) - self.assertEqual(response.json['data']['next_check'], response.json['data']['tenderPeriod']['endDate']) - - if self.initial_lots: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}]}}) - item = response.json['data']["lots"][0] - else: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}}) - item = response.json['data'] - self.assertEqual(response.status, '200 OK') - self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) - self.assertIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) - - self.set_status('active.auction', {'status': 'active.tendering'}) - 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.auction') - item = response.json['data']["lots"][0] if self.initial_lots else response.json['data'] - self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) - - if self.initial_lots: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}]}}) - item = response.json['data']["lots"][0] - else: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}}) - item = response.json['data'] - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], 'active.auction') - self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) - self.assertIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) - self.assertIn('9999-01-01T00:00:00', response.json['data']['next_check']) - - now = get_now().isoformat() - auction = self.db.get(self.auction_id) - if self.initial_lots: - auction['lots'][0]['auctionPeriod']['startDate'] = now - else: - auction['auctionPeriod']['startDate'] = now - self.db.save(auction) - - 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.auction') - item = response.json['data']["lots"][0] if self.initial_lots else response.json['data'] - self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) - self.assertGreater(response.json['data']['next_check'], item['auctionPeriod']['startDate']) - self.assertEqual(response.json['data']['next_check'], self.db.get(self.auction_id)['next_check']) - - if self.initial_lots: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": response.json['data']['tenderPeriod']['endDate']}}]}}) - item = response.json['data']["lots"][0] - else: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": response.json['data']['tenderPeriod']['endDate']}}}) - item = response.json['data'] - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], 'active.auction') - self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) - self.assertNotIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) - self.assertGreater(response.json['data']['next_check'], response.json['data']['tenderPeriod']['endDate']) - - auction = self.db.get(self.auction_id) - self.assertGreater(auction['next_check'], response.json['data']['tenderPeriod']['endDate']) - auction['tenderPeriod']['endDate'] = auction['tenderPeriod']['startDate'] - auction['tenderPeriod']['startDate'] = (datetime.strptime(auction['tenderPeriod']['endDate'][:19], "%Y-%m-%dT%H:%M:%S") - timedelta(days=10)).isoformat() - auction['enquiryPeriod']['startDate'] = auction['tenderPeriod']['startDate'] - auction['enquiryPeriod']['endDate'] = auction['tenderPeriod']['endDate'] - auction['rectificationPeriod']['startDate'] = (datetime.strptime(auction['tenderPeriod']['endDate'][:19], "%Y-%m-%dT%H:%M:%S") - timedelta(days=10)).isoformat() - auction['rectificationPeriod']['endDate'] = (datetime.strptime(auction['tenderPeriod']['endDate'][:19], "%Y-%m-%dT%H:%M:%S") - timedelta(days=5)).isoformat() - if self.initial_lots: - auction['lots'][0]['auctionPeriod']['startDate'] = auction['tenderPeriod']['endDate'] - else: - auction['auctionPeriod']['startDate'] = auction['tenderPeriod']['endDate'] - self.db.save(auction) - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) - if self.initial_lots: - item = response.json['data']["lots"][0] - else: - item = response.json['data'] - self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) - self.assertNotIn('next_check', response.json['data']) - self.assertNotIn('next_check', self.db.get(self.auction_id)) - shouldStartAfter = item['auctionPeriod']['shouldStartAfter'] - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'id': self.auction_id}}) - if self.initial_lots: - item = response.json['data']["lots"][0] - else: - item = response.json['data'] - self.assertEqual(item['auctionPeriod']['shouldStartAfter'], shouldStartAfter) - self.assertNotIn('next_check', response.json['data']) - - if self.initial_lots: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"lots": [{"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}]}}) - item = response.json['data']["lots"][0] - else: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {"auctionPeriod": {"startDate": "9999-01-01T00:00:00"}}}) - item = response.json['data'] - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], 'active.auction') - self.assertGreaterEqual(item['auctionPeriod']['shouldStartAfter'], response.json['data']['tenderPeriod']['endDate']) - self.assertIn('9999-01-01T00:00:00', item['auctionPeriod']['startDate']) - self.assertIn('9999-01-01T00:00:00', response.json['data']['next_check']) + test_set_auction_period = snitch(set_auction_period) + test_reset_auction_period = snitch(reset_auction_period) class AuctionComplaintSwitchResourceTest(BaseAuctionWebTest): - def test_switch_to_pending(self): - response = self.app.post_json('/auctions/{}/complaints'.format(self.auction_id), {'data': { - 'title': 'complaint title', - 'description': 'complaint description', - 'author': self.initial_organization, - 'status': 'claim' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.json['data']['status'], 'claim') - - auction = self.db.get(self.auction_id) - auction['complaints'][0]['dateSubmitted'] = (get_now() - timedelta(days=1 if 'procurementMethodDetails' in auction else 4)).isoformat() - self.db.save(auction) - - 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']["complaints"][0]['status'], 'pending') - - def test_switch_to_complaint(self): - for status in ['invalid', 'resolved', 'declined']: - self.app.authorization = ('Basic', ('token', '')) - response = self.app.post_json('/auctions/{}/complaints'.format(self.auction_id), {'data': { - 'title': 'complaint title', - 'description': 'complaint description', - 'author': self.initial_organization, - 'status': 'claim' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.json['data']['status'], 'claim') - complaint = response.json['data'] - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolution": status * 4, - "resolutionType": status - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], status) - - auction = self.db.get(self.auction_id) - auction['complaints'][-1]['dateAnswered'] = (get_now() - timedelta(days=1 if 'procurementMethodDetails' in auction else 4)).isoformat() - self.db.save(auction) - - 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']["complaints"][-1]['status'], status) + test_switch_to_pending = snitch(switch_to_pending) + test_switch_to_complaint = snitch(switch_to_complaint) @unittest.skip("option not available") @@ -288,6 +82,9 @@ class AuctionAwardComplaintSwitchResourceTest(BaseAuctionWebTest): initial_status = 'active.qualification' initial_bids = test_bids + test_switch_to_pending_award = snitch(switch_to_pending_award) + test_switch_to_complaint_award = snitch(switch_to_complaint_award) + def setUp(self): super(AuctionAwardComplaintSwitchResourceTest, self).setUp() # Create award @@ -296,67 +93,6 @@ def setUp(self): award = response.json['data'] self.award_id = award['id'] - def test_switch_to_pending(self): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format(self.auction_id, self.award_id), {'data': { - 'title': 'complaint title', - 'description': 'complaint description', - 'author': self.initial_organization, - 'status': 'claim' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.json['data']['status'], 'claim') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - - auction = self.db.get(self.auction_id) - auction['awards'][0]['complaints'][0]['dateSubmitted'] = (get_now() - timedelta(days=1 if 'procurementMethodDetails' in auction else 4)).isoformat() - self.db.save(auction) - - 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']['awards'][0]["complaints"][0]['status'], 'pending') - - def test_switch_to_complaint(self): - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - - for status in ['invalid', 'resolved', 'declined']: - self.app.authorization = ('Basic', ('token', '')) - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format(self.auction_id, self.award_id), {'data': { - 'title': 'complaint title', - 'description': 'complaint description', - 'author': self.initial_organization, - 'status': 'claim' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.json['data']['status'], 'claim') - complaint = response.json['data'] - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolution": status * 4, - "resolutionType": status - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], status) - - auction = self.db.get(self.auction_id) - auction['awards'][0]['complaints'][-1]['dateAnswered'] = (get_now() - timedelta(days=1 if 'procurementMethodDetails' in auction else 4)).isoformat() - self.db.save(auction) - - 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']['awards'][0]["complaints"][-1]['status'], status) - @unittest.skip("option not available") class AuctionLotAwardComplaintSwitchResourceTest(AuctionAwardComplaintSwitchResourceTest): From c25b90c56b8716d50d9cf49442063ac8747a4659 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 18:55:54 +0200 Subject: [PATCH 24/45] Refactor complaint tests. Use existed mixins from core --- .../auctions/dgf/tests/complaint.py | 765 +----------------- 1 file changed, 13 insertions(+), 752 deletions(-) diff --git a/openprocurement/auctions/dgf/tests/complaint.py b/openprocurement/auctions/dgf/tests/complaint.py index 971c42ef..2435b4a2 100644 --- a/openprocurement/auctions/dgf/tests/complaint.py +++ b/openprocurement/auctions/dgf/tests/complaint.py @@ -1,489 +1,35 @@ # -*- coding: utf-8 -*- import unittest +from openprocurement.auctions.core.tests.complaint import ( + AuctionComplaintResourceTestMixin, + InsiderAuctionComplaintDocumentResourceTestMixin +) +from openprocurement.auctions.core.tests.blanks.complaint_blanks import ( + # AuctionLotAwardComplaintResourceTest + create_auction_complaint_lot +) +from openprocurement.auctions.core.tests.base import snitch from openprocurement.auctions.dgf.tests.base import ( BaseAuctionWebTest, test_auction_data, test_lots, test_financial_auction_data, test_financial_organization ) -class AuctionComplaintResourceTest(BaseAuctionWebTest): - - def test_create_auction_complaint_invalid(self): - response = self.app.post_json('/auctions/some_id/complaints', { - 'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'auction_id'} - ]) - - request_path = '/auctions/{}/complaints'.format(self.auction_id) - - response = self.app.post(request_path, 'data', status=415) - self.assertEqual(response.status, '415 Unsupported Media Type') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': - u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} - ]) - - response = self.app.post( - request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, 'data', 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json( - request_path, {'not_data': {}}, 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'data': {}}, 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'This field is required.'], u'location': u'body', u'name': u'title'}, - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'author'}, - ]) - - response = self.app.post_json(request_path, {'data': { - 'invalid_field': 'invalid_value'}}, 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'Rogue field', u'location': - u'body', u'name': u'invalid_field'} - ]) - - response = self.app.post_json(request_path, { - 'data': {'author': {'identifier': 'invalid_value'}}}, 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'identifier': [ - u'Please use a mapping for this field or Identifier instance instead of unicode.']}, u'location': u'body', u'name': u'author'} - ]) - - response = self.app.post_json(request_path, { - 'data': {'title': 'complaint title', 'description': 'complaint description', 'author': {'identifier': {}}}}, 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'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.']}, u'name': [u'This field is required.'], u'address': [u'This field is required.']}, u'location': u'body', u'name': u'author'} - ]) - - response = self.app.post_json(request_path, {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': { - 'name': 'name', 'identifier': {'uri': 'invalid_value'}}}}, 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'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.'], u'uri': [u'Not a well formed URL.']}, u'address': [u'This field is required.']}, u'location': u'body', u'name': u'author'} - ]) - - response = self.app.post_json(request_path, {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization, 'relatedLot': '0' * 32}}, 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'relatedLot should be one of lots'], u'location': u'body', u'name': u'relatedLot'} - ]) - - def test_create_auction_complaint(self): - response = self.app.post_json('/auctions/{}/complaints'.format( - self.auction_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization, 'status': 'claim'}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - status_date = response.json['data']['date'] - owner_token = response.json['access']['token'] - self.assertEqual(complaint['author']['name'], self.initial_organization['name']) - self.assertIn('id', complaint) - self.assertIn(complaint['id'], response.headers['Location']) - - auction = self.db.get(self.auction_id) - auction['status'] = 'active.awarded' - auction['awardPeriod'] = {'endDate': '2014-01-01'} - self.db.save(auction) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], self.auction_token), {"data": { - "status": "answered" - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'resolutionType'}, - ]) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "invalid", - "resolution": "spam 100% " * 3 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertNotEqual(response.json['data']['date'], status_date) - status_date = response.json['data']['date'] - self.assertEqual(response.json['data']["resolutionType"], "invalid") - self.assertEqual(response.json['data']["resolution"], "spam 100% " * 3) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "satisfied": True, - "status": "resolved" - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "resolved") - self.assertNotEqual(response.json['data']['date'], status_date) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": {"status": "cancelled", "cancellationReason": "reason"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update complaint in current (resolved) status") - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], 'active.awarded') - - self.set_status('unsuccessful') - - response = self.app.post_json('/auctions/{}/complaints'.format( - self.auction_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add complaint in current (unsuccessful) auction status") - - def test_patch_auction_complaint(self): - response = self.app.post_json('/auctions/{}/complaints'.format( - self.auction_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - owner_token = response.json['access']['token'] - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], self.auction_token), {"data": { - "status": "cancelled", - "cancellationReason": "reason" - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Forbidden") - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "title": "claim title", - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["title"], "claim title") - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "status": "claim", - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], "claim") - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], self.auction_token), {"data": { - "resolution": "changing rules " * 2 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["resolution"], "changing rules " * 2) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "resolved", - "resolution": "resolution text " * 2 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], "resolved") - self.assertEqual(response.json['data']["resolution"], "resolution text " * 2) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "satisfied": False - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["satisfied"], False) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "status": "resolved" - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update complaint") - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "status": "pending" - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "pending") - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "status": "cancelled" - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'cancellationReason'}, - ]) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "status": "cancelled", - "cancellationReason": "reason" - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "cancelled") - self.assertEqual(response.json['data']["cancellationReason"], "reason") - - response = self.app.patch_json('/auctions/{}/complaints/some_id'.format(self.auction_id), {"data": {"status": "resolved", "resolution": "resolution text"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/complaints/some_id', {"data": {"status": "resolved", "resolution": "resolution text"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/complaints/{}'.format(self.auction_id, complaint['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "cancelled") - self.assertEqual(response.json['data']["cancellationReason"], "reason") - self.assertEqual(response.json['data']["resolutionType"], "resolved") - self.assertEqual(response.json['data']["resolution"], "resolution text " * 2) - - response = self.app.post_json('/auctions/{}/complaints'.format( - self.auction_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - owner_token = response.json['access']['token'] - - self.set_status('complete') - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "status": "claim", - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update complaint in current (complete) auction status") - - def test_review_auction_complaint(self): - complaints = [] - for i in range(3): - response = self.app.post_json('/auctions/{}/complaints'.format(self.auction_id), {'data': { - 'title': 'complaint title', - 'description': 'complaint description', - 'author': self.initial_organization, - 'status': 'claim' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - owner_token = response.json['access']['token'] - complaints.append(complaint) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "resolved", - "resolution": "resolution text " * 2 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], "resolved") - self.assertEqual(response.json['data']["resolution"], "resolution text " * 2) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "satisfied": False, - "status": "pending" - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "pending") - - self.app.authorization = ('Basic', ('reviewer', '')) - for complaint, status in zip(complaints, ['invalid', 'resolved', 'declined']): - response = self.app.patch_json('/auctions/{}/complaints/{}'.format(self.auction_id, complaint['id']), {"data": { - "decision": '{} complaint'.format(status) - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["decision"], '{} complaint'.format(status)) - - response = self.app.patch_json('/auctions/{}/complaints/{}'.format(self.auction_id, complaint['id']), {"data": { - "status": status - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], status) - - def test_get_auction_complaint(self): - response = self.app.post_json('/auctions/{}/complaints'.format( - self.auction_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - del complaint['author'] - response = self.app.get('/auctions/{}/complaints/{}'.format(self.auction_id, complaint['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], complaint) +class AuctionComplaintResourceTest(BaseAuctionWebTest, AuctionComplaintResourceTestMixin): + pass - response = self.app.get('/auctions/{}/complaints/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.get('/auctions/some_id/complaints/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_get_auction_complaints(self): - response = self.app.post_json('/auctions/{}/complaints'.format( - self.auction_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - del complaint['author'] - - response = self.app.get('/auctions/{}/complaints'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][0], complaint) - - response = self.app.get('/auctions/some_id/complaints', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) @unittest.skip("option not available") class AuctionLotAwardComplaintResourceTest(BaseAuctionWebTest): initial_lots = test_lots - def test_create_auction_complaint(self): - response = self.app.post_json('/auctions/{}/complaints'.format(self.auction_id), {'data': { - 'title': 'complaint title', - 'description': 'complaint description', - 'author': self.initial_organization, - 'relatedLot': self.initial_lots[0]['id'], - 'status': 'claim' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - owner_token = response.json['access']['token'] - self.assertEqual(complaint['author']['name'], self.initial_organization['name']) - self.assertIn('id', complaint) - self.assertIn(complaint['id'], response.headers['Location']) + test_create_auction_complaint_lot = snitch(create_auction_complaint_lot) - auction = self.db.get(self.auction_id) - auction['status'] = 'active.awarded' - auction['awardPeriod'] = {'endDate': '2014-01-01'} - self.db.save(auction) - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], self.auction_token), {"data": { - "status": "answered" - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'resolutionType'}, - ]) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "invalid", - "resolution": "spam 100% " * 3 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], "invalid") - self.assertEqual(response.json['data']["resolution"], "spam 100% " * 3) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": { - "satisfied": True, - "status": "resolved" - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "resolved") - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, complaint['id'], owner_token), {"data": {"status": "cancelled", "cancellationReason": "reason"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update complaint in current (resolved) status") - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], 'active.awarded') - - self.set_status('unsuccessful') - - response = self.app.post_json('/auctions/{}/complaints'.format( - self.auction_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add complaint in current (unsuccessful) auction status") - - -class AuctionComplaintDocumentResourceTest(BaseAuctionWebTest): +class AuctionComplaintDocumentResourceTest(BaseAuctionWebTest, InsiderAuctionComplaintDocumentResourceTestMixin): def setUp(self): super(AuctionComplaintDocumentResourceTest, self).setUp() @@ -494,291 +40,6 @@ def setUp(self): self.complaint_id = complaint['id'] self.complaint_owner_token = response.json['access']['token'] - def test_not_found(self): - response = self.app.post('/auctions/some_id/complaints/some_id/documents', status=404, upload_files=[ - ('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.post('/auctions/{}/complaints/some_id/documents'.format(self.auction_id), status=404, upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.post('/auctions/{}/complaints/{}/documents'.format(self.auction_id, self.complaint_id), status=404, upload_files=[ - ('invalid_value', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.get('/auctions/some_id/complaints/some_id/documents', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/complaints/some_id/documents'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.get('/auctions/some_id/complaints/some_id/documents/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/complaints/some_id/documents/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.get('/auctions/{}/complaints/{}/documents/some_id'.format(self.auction_id, self.complaint_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'document_id'} - ]) - - response = self.app.put('/auctions/some_id/complaints/some_id/documents/some_id', status=404, - upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.put('/auctions/{}/complaints/some_id/documents/some_id'.format(self.auction_id), status=404, upload_files=[ - ('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.put('/auctions/{}/complaints/{}/documents/some_id'.format( - self.auction_id, self.complaint_id), status=404, upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'document_id'} - ]) - - def test_create_auction_complaint_document(self): - response = self.app.post('/auctions/{}/complaints/{}/documents'.format( - self.auction_id, self.complaint_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (draft) complaint status") - - response = self.app.post('/auctions/{}/complaints/{}/documents?acc_token={}'.format( - self.auction_id, self.complaint_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/complaints/{}/documents'.format(self.auction_id, self.complaint_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/complaints/{}/documents?all=true'.format(self.auction_id, self.complaint_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/complaints/{}/documents/{}?download=some_id'.format( - self.auction_id, self.complaint_id, doc_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/complaints/{}/documents/{}?{}'.format( - self.auction_id, self.complaint_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 7) - self.assertEqual(response.body, 'content') - - response = self.app.get('/auctions/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.complaint_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - self.set_status('complete') - - response = self.app.post('/auctions/{}/complaints/{}/documents'.format( - self.auction_id, self.complaint_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (complete) auction status") - - def test_put_auction_complaint_document(self): - response = self.app.post('/auctions/{}/complaints/{}/documents?acc_token={}'.format( - self.auction_id, self.complaint_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put('/auctions/{}/complaints/{}/documents/{}'.format(self.auction_id, self.complaint_id, doc_id), - status=404, - upload_files=[('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.complaint_id, doc_id), upload_files=[('file', 'name.doc', 'content2')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only author") - - response = self.app.put('/auctions/{}/complaints/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.complaint_id, doc_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/complaints/{}/documents/{}?{}'.format( - self.auction_id, self.complaint_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content2') - - response = self.app.get('/auctions/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.complaint_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.put('/auctions/{}/complaints/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.complaint_id, doc_id, self.complaint_owner_token), 'content3', content_type='application/msword') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/complaints/{}/documents/{}?{}'.format( - self.auction_id, self.complaint_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content3') - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.complaint_id, self.complaint_owner_token), {"data": { - "status": "claim", - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], "claim") - - response = self.app.put('/auctions/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.complaint_id, doc_id, self.complaint_owner_token), 'content', content_type='application/msword', status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (claim) complaint status") - - self.set_status('complete') - - response = self.app.put('/auctions/{}/complaints/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.complaint_id, doc_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") - - def test_patch_auction_complaint_document(self): - response = self.app.post('/auctions/{}/complaints/{}/documents?acc_token={}'.format( - self.auction_id, self.complaint_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.patch_json('/auctions/{}/complaints/{}/documents/{}'.format(self.auction_id, self.complaint_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only author") - - response = self.app.patch_json('/auctions/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.complaint_id, doc_id, self.complaint_owner_token), {"data": {"description": "document description"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - - response = self.app.get('/auctions/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.complaint_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('document description', response.json["data"]["description"]) - - response = self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.complaint_id, self.complaint_owner_token), {"data": { - "status": "claim", - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], "claim") - - response = self.app.patch_json('/auctions/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.complaint_id, doc_id, self.complaint_owner_token), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (claim) complaint status") - - self.set_status('complete') - - response = self.app.patch_json('/auctions/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.complaint_id, doc_id, self.complaint_owner_token), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") - class FinancialAuctionComplaintResourceTest(BaseAuctionWebTest): initial_data = test_financial_auction_data From f18c8bbe84e4608e225e97a356cf0a1fc8a5e05c Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 18:56:19 +0200 Subject: [PATCH 25/45] Add init file --- openprocurement/auctions/dgf/tests/blanks/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 openprocurement/auctions/dgf/tests/blanks/__init__.py diff --git a/openprocurement/auctions/dgf/tests/blanks/__init__.py b/openprocurement/auctions/dgf/tests/blanks/__init__.py new file mode 100644 index 00000000..e69de29b From 54a20f63f969d822f0356753650a3491a1efe148 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 18:57:21 +0200 Subject: [PATCH 26/45] Move document tests to blank, use existed mixins from core --- .../dgf/tests/blanks/document_blanks.py | 223 ++++ .../auctions/dgf/tests/document.py | 1120 +---------------- 2 files changed, 258 insertions(+), 1085 deletions(-) create mode 100644 openprocurement/auctions/dgf/tests/blanks/document_blanks.py diff --git a/openprocurement/auctions/dgf/tests/blanks/document_blanks.py b/openprocurement/auctions/dgf/tests/blanks/document_blanks.py new file mode 100644 index 00000000..22c64d9d --- /dev/null +++ b/openprocurement/auctions/dgf/tests/blanks/document_blanks.py @@ -0,0 +1,223 @@ +# -*- coding: utf-8 -*- + +def create_auction_document(self): + response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json, {"data": []}) + + response = self.app.post('/auctions/{}/documents'.format( + self.auction_id), upload_files=[('file', u'укр.doc', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + self.assertEqual(u'укр.doc', response.json["data"]["title"]) + if self.docservice: + self.assertIn('Signature=', response.json["data"]["url"]) + self.assertIn('KeyID=', response.json["data"]["url"]) + self.assertNotIn('Expires=', response.json["data"]["url"]) + key = response.json["data"]["url"].split('/')[-1].split('?')[0] + auction = self.db.get(self.auction_id) + self.assertIn(key, auction['documents'][-1]["url"]) + self.assertIn('Signature=', auction['documents'][-1]["url"]) + self.assertIn('KeyID=', auction['documents'][-1]["url"]) + self.assertNotIn('Expires=', auction['documents'][-1]["url"]) + else: + key = response.json["data"]["url"].split('?')[-1].split('=')[-1] + + response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"][0]["id"]) + self.assertEqual(u'укр.doc', response.json["data"][0]["title"]) + + response = self.app.get('/auctions/{}/documents/{}?download=some_id'.format( + self.auction_id, doc_id), status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': u'url', u'name': u'download'} + ]) + + if self.docservice: + response = self.app.get('/auctions/{}/documents/{}?download={}'.format( + self.auction_id, doc_id, key)) + self.assertEqual(response.status, '302 Moved Temporarily') + self.assertIn('http://localhost/get/', response.location) + self.assertIn('Signature=', response.location) + self.assertIn('KeyID=', response.location) + self.assertNotIn('Expires=', response.location) + else: + response = self.app.get('/auctions/{}/documents/{}?download=some_id'.format( + self.auction_id, doc_id), status=404) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not Found', u'location': u'url', u'name': u'download'} + ]) + + response = self.app.get('/auctions/{}/documents/{}?download={}'.format( + self.auction_id, doc_id, key)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/msword') + self.assertEqual(response.content_length, 7) + self.assertEqual(response.body, 'content') + + response = self.app.get('/auctions/{}/documents/{}'.format( + self.auction_id, doc_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"]["id"]) + self.assertEqual(u'укр.doc', response.json["data"]["title"]) + + response = self.app.post('/auctions/{}/documents?acc_token=acc_token'.format( + self.auction_id), upload_files=[('file', u'укр.doc'.encode("ascii", "xmlcharrefreplace"), 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(u'укр.doc', response.json["data"]["title"]) + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + self.assertNotIn('acc_token', response.headers['Location']) + + self.set_status('active.auction') + + response = self.app.post('/auctions/{}/documents'.format( + self.auction_id), upload_files=[('file', u'укр.doc', 'content')], status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.auction) auction status") + + +def put_auction_offline_document(self): + response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), + {'data': { + 'title': u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' + }}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + self.assertEqual(u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', response.json["data"]["title"]) + self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"]["accessDetails"]) + self.assertEqual('offline/on-site-examination', response.json["data"]["format"]) + self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) + dateModified = response.json["data"]['dateModified'] + datePublished = response.json["data"]['datePublished'] + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'Новий порядок ознайомлення', + 'documentType': 'x_dgfAssetFamiliarization', + }}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [ + {u'description': [u'This field is required.'], u'location': u'body', u'name': u'accessDetails'} + ]) + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'Новий порядок ознайомлення', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', + 'hash': 'md5:' + '0' * 32, + }}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [{'description': [u'This field is not required.'], u'location': u'body', u'name': u'hash'}]) + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'Порядок ознайомлення з майном #2', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"]["id"]) + self.assertEqual(u'Порядок ознайомлення з майном #2', response.json["data"]["title"]) + self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"]["accessDetails"]) + self.assertEqual('offline/on-site-examination', response.json["data"]["format"]) + self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) + + auction = self.db.get(self.auction_id) + self.assertEqual(u'Порядок ознайомлення з майном #2', auction['documents'][-1]["title"]) + self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', auction['documents'][-1]["accessDetails"]) + self.assertEqual('offline/on-site-examination', auction['documents'][-1]["format"]) + self.assertEqual('x_dgfAssetFamiliarization', auction['documents'][-1]["documentType"]) + + response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"][-1]["id"]) + self.assertEqual(u'Порядок ознайомлення з майном #2', response.json["data"][-1]["title"]) + self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"][-1]["accessDetails"]) + self.assertEqual('offline/on-site-examination', response.json["data"][-1]["format"]) + self.assertEqual('x_dgfAssetFamiliarization', response.json["data"][-1]["documentType"]) + + response = self.app.get('/auctions/{}/documents/{}'.format(self.auction_id, doc_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"]["id"]) + self.assertEqual(u'Порядок ознайомлення з майном #2', response.json["data"]["title"]) + dateModified2 = response.json["data"]['dateModified'] + self.assertTrue(dateModified < dateModified2) + self.assertEqual(dateModified, response.json["data"]["previousVersions"][0]['dateModified']) + self.assertEqual(response.json["data"]['datePublished'], datePublished) + + response = self.app.get('/auctions/{}/documents?all=true'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(dateModified, response.json["data"][0]['dateModified']) + self.assertEqual(dateModified2, response.json["data"][1]['dateModified']) + + response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), + {'data': { + 'title': u'Порядок ознайомлення з майном #3', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' + }}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + dateModified = response.json["data"]['dateModified'] + self.assertIn(doc_id, response.headers['Location']) + + response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(dateModified2, response.json["data"][0]['dateModified']) + self.assertEqual(dateModified, response.json["data"][1]['dateModified']) + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'Порядок ознайомлення з майном #4', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(doc_id, response.json["data"]["id"]) + self.assertEqual(u'Порядок ознайомлення з майном #4', response.json["data"]["title"]) + self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) + + auction = self.db.get(self.auction_id) + self.assertEqual(u'Порядок ознайомлення з майном #4', auction['documents'][-1]["title"]) + self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) + + self.set_status('active.auction') + + response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), + {'data': { + 'title': u'Порядок ознайомлення з майном #5', + 'documentType': 'x_dgfAssetFamiliarization', + 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' + }}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (active.auction) auction status") \ No newline at end of file diff --git a/openprocurement/auctions/dgf/tests/document.py b/openprocurement/auctions/dgf/tests/document.py index a88be277..201e5bb3 100644 --- a/openprocurement/auctions/dgf/tests/document.py +++ b/openprocurement/auctions/dgf/tests/document.py @@ -1,898 +1,46 @@ # -*- coding: utf-8 -*- import unittest -from email.header import Header -from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_financial_auction_data - - -class AuctionDocumentResourceTest(BaseAuctionWebTest): - docservice = False - - def test_not_found(self): - response = self.app.get('/auctions/some_id/documents', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.post('/auctions/some_id/documents', status=404, upload_files=[ - ('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.post('/auctions/{}/documents'.format(self.auction_id), status=404, upload_files=[ - ('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/some_id/documents/some_id', status=404, upload_files=[ - ('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.put('/auctions/{}/documents/some_id'.format( - self.auction_id), status=404, upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'document_id'} - ]) - - response = self.app.get('/auctions/some_id/documents/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/documents/some_id'.format( - self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'document_id'} - ]) - - def test_create_auction_document(self): - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json, {"data": []}) - - response = self.app.post('/auctions/{}/documents'.format( - self.auction_id), upload_files=[('file', u'укр.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual(u'укр.doc', response.json["data"]["title"]) - if self.docservice: - self.assertIn('Signature=', response.json["data"]["url"]) - self.assertIn('KeyID=', response.json["data"]["url"]) - self.assertNotIn('Expires=', response.json["data"]["url"]) - key = response.json["data"]["url"].split('/')[-1].split('?')[0] - auction = self.db.get(self.auction_id) - self.assertIn(key, auction['documents'][-1]["url"]) - self.assertIn('Signature=', auction['documents'][-1]["url"]) - self.assertIn('KeyID=', auction['documents'][-1]["url"]) - self.assertNotIn('Expires=', auction['documents'][-1]["url"]) - else: - key = response.json["data"]["url"].split('?')[-1].split('=')[-1] - - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual(u'укр.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/documents/{}?download=some_id'.format( - self.auction_id, doc_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - if self.docservice: - response = self.app.get('/auctions/{}/documents/{}?download={}'.format( - self.auction_id, doc_id, key)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertNotIn('Expires=', response.location) - else: - response = self.app.get('/auctions/{}/documents/{}?download=some_id'.format( - self.auction_id, doc_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/documents/{}?download={}'.format( - self.auction_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 7) - self.assertEqual(response.body, 'content') - - response = self.app.get('/auctions/{}/documents/{}'.format( - self.auction_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual(u'укр.doc', response.json["data"]["title"]) - - response = self.app.post('/auctions/{}/documents?acc_token=acc_token'.format( - self.auction_id), upload_files=[('file', u'укр.doc'.encode("ascii", "xmlcharrefreplace"), 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(u'укр.doc', response.json["data"]["title"]) - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertNotIn('acc_token', response.headers['Location']) - - self.set_status('active.auction') - - response = self.app.post('/auctions/{}/documents'.format( - self.auction_id), upload_files=[('file', u'укр.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.auction) auction status") - - def test_put_auction_document(self): - from six import BytesIO - from urllib import quote - body = u'''--BOUNDARY\nContent-Disposition: form-data; name="file"; filename={}\nContent-Type: application/msword\n\ncontent\n'''.format(u'\uff07') - environ = self.app._make_environ() - environ['CONTENT_TYPE'] = 'multipart/form-data; boundary=BOUNDARY' - environ['REQUEST_METHOD'] = 'POST' - req = self.app.RequestClass.blank(self.app._remove_fragment('/auctions/{}/documents'.format(self.auction_id)), environ) - req.environ['wsgi.input'] = BytesIO(body.encode('utf8')) - req.content_length = len(body) - response = self.app.do_request(req, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "could not decode params") - - body = u'''--BOUNDARY\nContent-Disposition: form-data; name="file"; filename*=utf-8''{}\nContent-Type: application/msword\n\ncontent\n'''.format(quote('укр.doc')) - environ = self.app._make_environ() - environ['CONTENT_TYPE'] = 'multipart/form-data; boundary=BOUNDARY' - environ['REQUEST_METHOD'] = 'POST' - req = self.app.RequestClass.blank(self.app._remove_fragment('/auctions/{}/documents'.format(self.auction_id)), environ) - req.environ['wsgi.input'] = BytesIO(body.encode(req.charset or 'utf8')) - req.content_length = len(body) - response = self.app.do_request(req) - #response = self.app.post('/auctions/{}/documents'.format( - #self.auction_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(u'укр.doc', response.json["data"]["title"]) - doc_id = response.json["data"]['id'] - dateModified = response.json["data"]['dateModified'] - datePublished = response.json["data"]['datePublished'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put('/auctions/{}/documents/{}'.format( - self.auction_id, doc_id), upload_files=[('file', 'name name.doc', 'content2')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - if self.docservice: - self.assertIn('Signature=', response.json["data"]["url"]) - self.assertIn('KeyID=', response.json["data"]["url"]) - self.assertNotIn('Expires=', response.json["data"]["url"]) - key = response.json["data"]["url"].split('/')[-1].split('?')[0] - auction = self.db.get(self.auction_id) - self.assertIn(key, auction['documents'][-1]["url"]) - self.assertIn('Signature=', auction['documents'][-1]["url"]) - self.assertIn('KeyID=', auction['documents'][-1]["url"]) - self.assertNotIn('Expires=', auction['documents'][-1]["url"]) - else: - key = response.json["data"]["url"].split('?')[-1].split('=')[-1] - - if self.docservice: - response = self.app.get('/auctions/{}/documents/{}?download={}'.format( - self.auction_id, doc_id, key)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertNotIn('Expires=', response.location) - else: - response = self.app.get('/auctions/{}/documents/{}?download={}'.format( - self.auction_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content2') - - response = self.app.get('/auctions/{}/documents/{}'.format( - self.auction_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name name.doc', response.json["data"]["title"]) - dateModified2 = response.json["data"]['dateModified'] - self.assertTrue(dateModified < dateModified2) - self.assertEqual(dateModified, response.json["data"]["previousVersions"][0]['dateModified']) - self.assertEqual(response.json["data"]['datePublished'], datePublished) - - response = self.app.get('/auctions/{}/documents?all=true'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(dateModified, response.json["data"][0]['dateModified']) - self.assertEqual(dateModified2, response.json["data"][1]['dateModified']) - - response = self.app.post('/auctions/{}/documents'.format( - self.auction_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - dateModified = response.json["data"]['dateModified'] - self.assertIn(doc_id, response.headers['Location']) - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(dateModified2, response.json["data"][0]['dateModified']) - self.assertEqual(dateModified, response.json["data"][1]['dateModified']) +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.tests.blanks.document_blanks import ( + # AuctionDocumentResourceTest + not_found, + put_auction_document, + patch_auction_document, + # AuctionDocumentWithDSResourceTest + create_auction_document_json_invalid, + create_auction_document_json, + put_auction_document_json, + create_auction_offline_document, + # FinancialAuctionDocumentWithDSResourceTest + create_auction_document_vdr, + put_auction_document_vdr +) - response = self.app.put('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), status=404, upload_files=[ - ('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/{}/documents/{}'.format( - self.auction_id, doc_id), 'content3', content_type='application/msword') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - if self.docservice: - self.assertIn('Signature=', response.json["data"]["url"]) - self.assertIn('KeyID=', response.json["data"]["url"]) - self.assertNotIn('Expires=', response.json["data"]["url"]) - key = response.json["data"]["url"].split('/')[-1].split('?')[0] - auction = self.db.get(self.auction_id) - self.assertIn(key, auction['documents'][-1]["url"]) - self.assertIn('Signature=', auction['documents'][-1]["url"]) - self.assertIn('KeyID=', auction['documents'][-1]["url"]) - self.assertNotIn('Expires=', auction['documents'][-1]["url"]) - else: - key = response.json["data"]["url"].split('?')[-1].split('=')[-1] - - if self.docservice: - response = self.app.get('/auctions/{}/documents/{}?download={}'.format( - self.auction_id, doc_id, key)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertNotIn('Expires=', response.location) - else: - response = self.app.get('/auctions/{}/documents/{}?download={}'.format( - self.auction_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content3') - - self.set_status('active.auction') - - response = self.app.put('/auctions/{}/documents/{}'.format( - self.auction_id, doc_id), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (active.auction) auction status") - - def test_patch_auction_document(self): - response = self.app.post('/auctions/{}/documents'.format( - self.auction_id), upload_files=[('file', str(Header(u'укр.doc', 'utf-8')), 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - #dateModified = response.json["data"]['dateModified'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual(u'укр.doc', response.json["data"]["title"]) - self.assertNotIn("documentType", response.json["data"]) - - response = self.app.patch_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), {"data": { - "documentOf": "lot" - }}, 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'This field is required.'], u'location': u'body', u'name': u'relatedItem'}, - ]) - - response = self.app.patch_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), {"data": { - "documentOf": "lot", - "relatedItem": '0' * 32 - }}, 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'relatedItem should be one of lots'], u'location': u'body', u'name': u'relatedItem'} - ]) - - response = self.app.patch_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), {"data": { - "documentOf": "item", - "relatedItem": '0' * 32 - }}, 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'relatedItem should be one of items'], u'location': u'body', u'name': u'relatedItem'} - ]) - - response = self.app.patch_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), {"data": { - "description": "document description", - "documentType": 'auctionNotice' - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertIn("documentType", response.json["data"]) - self.assertEqual(response.json["data"]["documentType"], 'auctionNotice') - - response = self.app.patch_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), {"data": { - "documentType": None - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertNotIn("documentType", response.json["data"]) +from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_financial_auction_data +from openprocurement.auctions.dgf.tests.blanks.document_blanks import ( + create_auction_document, + put_auction_offline_document +) - response = self.app.get('/auctions/{}/documents/{}'.format(self.auction_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('document description', response.json["data"]["description"]) - #self.assertTrue(dateModified < response.json["data"]["dateModified"]) +class AuctionDocumentResourceTestMixin(object): + test_not_found = snitch(not_found) + test_create_auction_document = snitch(create_auction_document) + test_put_auction_document = snitch(put_auction_document) + test_patch_auction_document = snitch(patch_auction_document) - self.set_status('active.auction') - response = self.app.patch_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (active.auction) auction status") +class AuctionDocumentResourceTest(BaseAuctionWebTest, AuctionDocumentResourceTestMixin): + docservice = False -class AuctionDocumentWithDSResourceTest(AuctionDocumentResourceTest): +class AuctionDocumentWithDSResourceTest(BaseAuctionWebTest, AuctionDocumentResourceTestMixin): docservice = True - - def test_create_auction_document_json_invalid(self): - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url(), - 'format': 'application/msword', - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "This field is required.") - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url(), - 'hash': '0' * 32, - 'format': 'application/msword', - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [u'Hash type is not supported.'], u'location': u'body', u'name': u'hash'} - ]) - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url(), - 'hash': 'sha2048:' + '0' * 32, - 'format': 'application/msword', - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [u'Hash type is not supported.'], u'location': u'body', u'name': u'hash'} - ]) - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url(), - 'hash': 'sha512:' + '0' * 32, - 'format': 'application/msword', - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [u'Hash value is wrong length.'], u'location': u'body', u'name': u'hash'} - ]) - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + 'O' * 32, - 'format': 'application/msword', - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [u'Hash value is not hexadecimal.'], u'location': u'body', u'name': u'hash'} - ]) - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': 'http://invalid.docservice.url/get/uuid', - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add document only from document service.") - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': '/'.join(self.generate_docservice_url().split('/')[:4]), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add document only from document service.") - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url().split('?')[0], - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add document only from document service.") - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url().replace(self.app.app.registry.keyring.keys()[-1], '0' * 8), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Document url expired.") - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url().replace("Signature=", "Signature=ABC"), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Document url signature invalid.") - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url().replace("Signature=", "Signature=bw%3D%3D"), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Document url invalid.") - - def test_create_auction_document_json(self): - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual(u'укр.doc', response.json["data"]["title"]) - self.assertIn('Signature=', response.json["data"]["url"]) - self.assertIn('KeyID=', response.json["data"]["url"]) - self.assertNotIn('Expires=', response.json["data"]["url"]) - key = response.json["data"]["url"].split('/')[-1].split('?')[0] - auction = self.db.get(self.auction_id) - self.assertIn(key, auction['documents'][-1]["url"]) - self.assertIn('Signature=', auction['documents'][-1]["url"]) - self.assertIn('KeyID=', auction['documents'][-1]["url"]) - self.assertNotIn('Expires=', auction['documents'][-1]["url"]) - - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual(u'укр.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/documents/{}?download=some_id'.format( - self.auction_id, doc_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/documents/{}?download={}'.format( - self.auction_id, doc_id, key)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertNotIn('Expires=', response.location) - - response = self.app.get('/auctions/{}/documents/{}'.format( - self.auction_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual(u'укр.doc', response.json["data"]["title"]) - - self.set_status('active.auction') - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.auction) auction status") - - def test_put_auction_document_json(self): - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(u'укр.doc', response.json["data"]["title"]) - doc_id = response.json["data"]['id'] - dateModified = response.json["data"]['dateModified'] - datePublished = response.json["data"]['datePublished'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'name.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertIn('Signature=', response.json["data"]["url"]) - self.assertIn('KeyID=', response.json["data"]["url"]) - self.assertNotIn('Expires=', response.json["data"]["url"]) - key = response.json["data"]["url"].split('/')[-1].split('?')[0] - auction = self.db.get(self.auction_id) - self.assertIn(key, auction['documents'][-1]["url"]) - self.assertIn('Signature=', auction['documents'][-1]["url"]) - self.assertIn('KeyID=', auction['documents'][-1]["url"]) - self.assertNotIn('Expires=', auction['documents'][-1]["url"]) - - response = self.app.get('/auctions/{}/documents/{}?download={}'.format( - self.auction_id, doc_id, key)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertNotIn('Expires=', response.location) - - response = self.app.get('/auctions/{}/documents/{}'.format( - self.auction_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual(u'name.doc', response.json["data"]["title"]) - dateModified2 = response.json["data"]['dateModified'] - self.assertTrue(dateModified < dateModified2) - self.assertEqual(dateModified, response.json["data"]["previousVersions"][0]['dateModified']) - self.assertEqual(response.json["data"]['datePublished'], datePublished) - - response = self.app.get('/auctions/{}/documents?all=true'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(dateModified, response.json["data"][0]['dateModified']) - self.assertEqual(dateModified2, response.json["data"][1]['dateModified']) - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id, doc_id), - {'data': { - 'title': 'name.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - dateModified = response.json["data"]['dateModified'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(dateModified2, response.json["data"][0]['dateModified']) - self.assertEqual(dateModified, response.json["data"][1]['dateModified']) - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertIn('Signature=', response.json["data"]["url"]) - self.assertIn('KeyID=', response.json["data"]["url"]) - self.assertNotIn('Expires=', response.json["data"]["url"]) - key = response.json["data"]["url"].split('/')[-1].split('?')[0] - auction = self.db.get(self.auction_id) - self.assertIn(key, auction['documents'][-1]["url"]) - self.assertIn('Signature=', auction['documents'][-1]["url"]) - self.assertIn('KeyID=', auction['documents'][-1]["url"]) - self.assertNotIn('Expires=', auction['documents'][-1]["url"]) - - response = self.app.get('/auctions/{}/documents/{}?download={}'.format( - self.auction_id, doc_id, key)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertIn('http://localhost/get/', response.location) - self.assertIn('Signature=', response.location) - self.assertIn('KeyID=', response.location) - self.assertNotIn('Expires=', response.location) - - self.set_status('active.auction') - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'укр.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (active.auction) auction status") - - def test_create_auction_offline_document(self): - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', - 'documentType': 'x_dgfAssetFamiliarization', - 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual(u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', response.json["data"]["title"]) - self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"]["accessDetails"]) - self.assertEqual('offline/on-site-examination', response.json["data"]["format"]) - self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) - - auction = self.db.get(self.auction_id) - self.assertEqual(u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', auction['documents'][-1]["title"]) - self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', auction['documents'][-1]["accessDetails"]) - self.assertEqual('offline/on-site-examination', auction['documents'][-1]["format"]) - self.assertEqual('x_dgfAssetFamiliarization', auction['documents'][-1]["documentType"]) - - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][-1]["id"]) - self.assertEqual(u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', response.json["data"][-1]["title"]) - self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"][-1]["accessDetails"]) - self.assertEqual('offline/on-site-examination', response.json["data"][-1]["format"]) - self.assertEqual('x_dgfAssetFamiliarization', response.json["data"][-1]["documentType"]) - - - response = self.app.get('/auctions/{}/documents/{}'.format( - self.auction_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual(u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', response.json["data"]["title"]) - self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"]["accessDetails"]) - self.assertEqual('offline/on-site-examination', response.json["data"]["format"]) - self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) - - self.set_status('active.auction') - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', - 'documentType': 'x_dgfAssetFamiliarization', - 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.auction) auction status") - - def test_put_auction_offline_document(self): - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', - 'documentType': 'x_dgfAssetFamiliarization', - 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual(u'Порядок ознайомлення з майном / Порядок ознайомлення з активом у кімнаті даних', response.json["data"]["title"]) - self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"]["accessDetails"]) - self.assertEqual('offline/on-site-examination', response.json["data"]["format"]) - self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) - dateModified = response.json["data"]['dateModified'] - datePublished = response.json["data"]['datePublished'] - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'Новий порядок ознайомлення', - 'documentType': 'x_dgfAssetFamiliarization', - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'accessDetails'} - ]) - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'Новий порядок ознайомлення', - 'documentType': 'x_dgfAssetFamiliarization', - 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', - 'hash': 'md5:' + '0' * 32, - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [{'description': [u'This field is not required.'], u'location': u'body', u'name': u'hash'}]) - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'Порядок ознайомлення з майном #2', - 'documentType': 'x_dgfAssetFamiliarization', - 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual(u'Порядок ознайомлення з майном #2', response.json["data"]["title"]) - self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"]["accessDetails"]) - self.assertEqual('offline/on-site-examination', response.json["data"]["format"]) - self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) - - auction = self.db.get(self.auction_id) - self.assertEqual(u'Порядок ознайомлення з майном #2', auction['documents'][-1]["title"]) - self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', auction['documents'][-1]["accessDetails"]) - self.assertEqual('offline/on-site-examination', auction['documents'][-1]["format"]) - self.assertEqual('x_dgfAssetFamiliarization', auction['documents'][-1]["documentType"]) - - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][-1]["id"]) - self.assertEqual(u'Порядок ознайомлення з майном #2', response.json["data"][-1]["title"]) - self.assertEqual(u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс', response.json["data"][-1]["accessDetails"]) - self.assertEqual('offline/on-site-examination', response.json["data"][-1]["format"]) - self.assertEqual('x_dgfAssetFamiliarization', response.json["data"][-1]["documentType"]) - - response = self.app.get('/auctions/{}/documents/{}'.format(self.auction_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual(u'Порядок ознайомлення з майном #2', response.json["data"]["title"]) - dateModified2 = response.json["data"]['dateModified'] - self.assertTrue(dateModified < dateModified2) - self.assertEqual(dateModified, response.json["data"]["previousVersions"][0]['dateModified']) - self.assertEqual(response.json["data"]['datePublished'], datePublished) - - response = self.app.get('/auctions/{}/documents?all=true'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(dateModified, response.json["data"][0]['dateModified']) - self.assertEqual(dateModified2, response.json["data"][1]['dateModified']) - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'Порядок ознайомлення з майном #3', - 'documentType': 'x_dgfAssetFamiliarization', - 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - dateModified = response.json["data"]['dateModified'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(dateModified2, response.json["data"][0]['dateModified']) - self.assertEqual(dateModified, response.json["data"][1]['dateModified']) - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'Порядок ознайомлення з майном #4', - 'documentType': 'x_dgfAssetFamiliarization', - 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual(u'Порядок ознайомлення з майном #4', response.json["data"]["title"]) - self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) - - auction = self.db.get(self.auction_id) - self.assertEqual(u'Порядок ознайомлення з майном #4', auction['documents'][-1]["title"]) - self.assertEqual('x_dgfAssetFamiliarization', response.json["data"]["documentType"]) - - self.set_status('active.auction') - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'Порядок ознайомлення з майном #5', - 'documentType': 'x_dgfAssetFamiliarization', - 'accessDetails': u'Ознайомитись з рогом єдинорога можна: 30 лютого, коли сонце зійде на заході, печера Ілона Маска, плато Азімова, Марс' - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (active.auction) auction status") + test_create_auction_document_json_invalid = snitch(create_auction_document_json_invalid) + test_create_auction_document_json = snitch(create_auction_document_json) + test_put_auction_document_json = snitch(put_auction_document_json) + test_create_auction_offline_document = snitch(create_auction_offline_document) + test_put_auction_offline_document = snitch(put_auction_offline_document) class FinancialAuctionDocumentResourceTest(AuctionDocumentResourceTest): @@ -902,206 +50,8 @@ class FinancialAuctionDocumentResourceTest(AuctionDocumentResourceTest): class FinancialAuctionDocumentWithDSResourceTest(AuctionDocumentWithDSResourceTest): initial_data = test_financial_auction_data - def test_create_auction_document_vdr(self): - vdr_url = 'http://virtial-data-room.com/id_of_room' - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'VDR for auction lot', - 'url': vdr_url, - 'documentType': 'virtualDataRoom', - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('VDR for auction lot', response.json["data"]["title"]) - self.assertEqual(vdr_url, response.json["data"]["url"]) - self.assertEqual('virtualDataRoom', response.json["data"]["documentType"]) - - auction = self.db.get(self.auction_id) - self.assertEqual('VDR for auction lot', auction['documents'][-1]["title"]) - self.assertEqual(vdr_url, auction['documents'][-1]["url"]) - self.assertEqual('virtualDataRoom', auction['documents'][-1]["documentType"]) - - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][-1]["id"]) - self.assertEqual('VDR for auction lot', response.json["data"][-1]["title"]) - self.assertEqual(vdr_url, response.json["data"][-1]["url"]) - self.assertEqual('virtualDataRoom', response.json["data"][-1]["documentType"]) - - response = self.app.get('/auctions/{}/documents/{}?download=1'.format( - self.auction_id, doc_id)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertEqual(vdr_url, response.location) - - response = self.app.get('/auctions/{}/documents/{}'.format( - self.auction_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('VDR for auction lot', response.json["data"]["title"]) - self.assertEqual(vdr_url, response.json["data"]["url"]) - self.assertEqual('virtualDataRoom', response.json["data"]["documentType"]) - - self.set_status('active.auction') - - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'VDR for auction lot', - 'url': vdr_url, - 'documentType': 'virtualDataRoom', - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (active.auction) auction status") - - def test_put_auction_document_vdr(self): - vdr_url = 'http://virtial-data-room.com/id_of_room' - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'VDR for auction lot', - 'url': vdr_url, - 'documentType': 'virtualDataRoom', - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual('VDR for auction lot', response.json["data"]["title"]) - self.assertEqual(vdr_url, response.json["data"]["url"]) - self.assertEqual('virtualDataRoom', response.json["data"]["documentType"]) - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - dateModified = response.json["data"]['dateModified'] - datePublished = response.json["data"]['datePublished'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'name.doc', - 'url': self.generate_docservice_url(), - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'format'} - ]) - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'name.doc', - 'url': self.generate_docservice_url(), - 'hash': 'md5:' + '0' * 32, - 'format': 'application/msword', - }}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {u'description': [{u'url': [u'Not a well formed URL.'], u'hash': [u'This field is not required.'], u'format': [u'This field is not required.']}], u'location': u'body', u'name': u'documents'} - ]) - - vdr_url = 'http://virtial-data-room.com/new_id_of_room' - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'VDR for auction lot #2', - 'url': vdr_url, - 'documentType': 'virtualDataRoom', - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('VDR for auction lot #2', response.json["data"]["title"]) - self.assertEqual(vdr_url, response.json["data"]["url"]) - self.assertEqual('virtualDataRoom', response.json["data"]["documentType"]) - - auction = self.db.get(self.auction_id) - self.assertEqual('VDR for auction lot #2', auction['documents'][-1]["title"]) - self.assertEqual(vdr_url, auction['documents'][-1]["url"]) - self.assertEqual('virtualDataRoom', auction['documents'][-1]["documentType"]) - - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][-1]["id"]) - self.assertEqual('VDR for auction lot #2', response.json["data"][-1]["title"]) - self.assertEqual(vdr_url, response.json["data"][-1]["url"]) - self.assertEqual('virtualDataRoom', response.json["data"][-1]["documentType"]) - - response = self.app.get('/auctions/{}/documents/{}?download=1'.format( - self.auction_id, doc_id)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertEqual(vdr_url, response.location) - - response = self.app.get('/auctions/{}/documents/{}'.format(self.auction_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('VDR for auction lot #2', response.json["data"]["title"]) - dateModified2 = response.json["data"]['dateModified'] - self.assertTrue(dateModified < dateModified2) - self.assertEqual(dateModified, response.json["data"]["previousVersions"][0]['dateModified']) - self.assertEqual(response.json["data"]['datePublished'], datePublished) - - response = self.app.get('/auctions/{}/documents?all=true'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(dateModified, response.json["data"][0]['dateModified']) - self.assertEqual(dateModified2, response.json["data"][1]['dateModified']) - - vdr_url = 'http://virtial-data-room.com/new_new_id_of_room' - response = self.app.post_json('/auctions/{}/documents'.format(self.auction_id), - {'data': { - 'title': u'VDR for auction lot #3', - 'url': vdr_url, - 'documentType': 'virtualDataRoom', - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - dateModified = response.json["data"]['dateModified'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.get('/auctions/{}/documents'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(dateModified2, response.json["data"][0]['dateModified']) - self.assertEqual(dateModified, response.json["data"][1]['dateModified']) - - vdr_url = 'http://virtial-data-room.com/new_new_new_id_of_room' - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'VDR for auction lot #4', - 'url': vdr_url, - 'documentType': 'virtualDataRoom', - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('VDR for auction lot #4', response.json["data"]["title"]) - self.assertEqual(vdr_url, response.json["data"]["url"]) - self.assertEqual('virtualDataRoom', response.json["data"]["documentType"]) - - auction = self.db.get(self.auction_id) - self.assertEqual('VDR for auction lot #4', auction['documents'][-1]["title"]) - self.assertEqual(vdr_url, auction['documents'][-1]["url"]) - self.assertEqual('virtualDataRoom', auction['documents'][-1]["documentType"]) - - response = self.app.get('/auctions/{}/documents/{}?download=1'.format( - self.auction_id, doc_id)) - self.assertEqual(response.status, '302 Moved Temporarily') - self.assertEqual(vdr_url, response.location) - - self.set_status('active.auction') - - response = self.app.put_json('/auctions/{}/documents/{}'.format(self.auction_id, doc_id), - {'data': { - 'title': u'VDR for auction lot #5', - 'url': vdr_url, - 'documentType': 'virtualDataRoom', - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (active.auction) auction status") + test_create_auction_document_vdr = snitch(create_auction_document_vdr) + test_put_auction_document_vdr = snitch(put_auction_document_vdr) def suite(): From 450e2106f6bbd0b451a408ce94ae67d01a66ee7f Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 18:58:42 +0200 Subject: [PATCH 27/45] Move lot tests to blanks. --- .../auctions/dgf/tests/blanks/lot_blanks.py | 22 + openprocurement/auctions/dgf/tests/lot.py | 1684 +---------------- 2 files changed, 56 insertions(+), 1650 deletions(-) create mode 100644 openprocurement/auctions/dgf/tests/blanks/lot_blanks.py diff --git a/openprocurement/auctions/dgf/tests/blanks/lot_blanks.py b/openprocurement/auctions/dgf/tests/blanks/lot_blanks.py new file mode 100644 index 00000000..c1c63ee7 --- /dev/null +++ b/openprocurement/auctions/dgf/tests/blanks/lot_blanks.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +def patch_auction_currency(self): + # create lot + response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + lot = response.json['data'] + self.assertEqual(lot['value']['currency'], "UAH") + + # update auction currency without mimimalStep currency change + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {"data": {"value": {"currency": "GBP"}}}, + 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'currency should be identical to currency of value of auction'], + u'location': u'body', u'name': u'minimalStep'}, + {u"description": [u"currency should be only UAH"], + u"location": u"body", u"name": u"value"} + ]) diff --git a/openprocurement/auctions/dgf/tests/lot.py b/openprocurement/auctions/dgf/tests/lot.py index c748aad7..51d91d91 100644 --- a/openprocurement/auctions/dgf/tests/lot.py +++ b/openprocurement/auctions/dgf/tests/lot.py @@ -1,611 +1,42 @@ # -*- coding: utf-8 -*- import unittest -from copy import deepcopy -from datetime import timedelta -from openprocurement.api.models import get_now -from openprocurement.auctions.dgf.tests.base import BaseWebTest, BaseAuctionWebTest, test_auction_data, test_lots, test_financial_auction_data, test_financial_bids, test_financial_organization +from openprocurement.auctions.core.tests.lot import ( + AuctionLotResourceTestMixin, + AuctionLotProcessTestMixin +) +from openprocurement.auctions.core.tests.blanks.lot_blanks import ( + # AuctionLotFeatureResourceTest + auction_value, + auction_features_invalid, + # AuctionLotBidderResourceTest + create_auction_bidder_invalid, + patch_auction_bidder, + # AuctionLotFeatureBidderResourceTest + create_auction_bidder_invalid_feature, + create_auction_bidder_feature +) +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.dgf.tests.base import BaseWebTest, BaseAuctionWebTest, test_auction_data, test_lots, test_financial_auction_data, test_financial_bids, test_financial_organization +from openprocurement.auctions.dgf.tests.blanks.lot_blanks import ( + patch_auction_currency +) @unittest.skip("option not available") -class AuctionLotResourceTest(BaseAuctionWebTest): - - def test_create_auction_lot_invalid(self): - response = self.app.post_json('/auctions/some_id/lots', {'data': {'title': 'lot title', 'description': 'lot description'}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'auction_id'} - ]) - - request_path = '/auctions/{}/lots'.format(self.auction_id) - - response = self.app.post(request_path, 'data', status=415) - self.assertEqual(response.status, '415 Unsupported Media Type') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': - u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} - ]) - - response = self.app.post( - request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, 'data', 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json( - request_path, {'not_data': {}}, 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'data': {}}, 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'This field is required.'], u'location': u'body', u'name': u'minimalStep'}, - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'value'}, - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'title'}, - ]) - - response = self.app.post_json(request_path, {'data': { - 'invalid_field': 'invalid_value'}}, 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'Rogue field', u'location': - u'body', u'name': u'invalid_field'} - ]) - - response = self.app.post_json(request_path, {'data': {'value': 'invalid_value'}}, 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'Please use a mapping for this field or Value instance instead of unicode.'], u'location': u'body', u'name': u'value'} - ]) - - response = self.app.post_json(request_path, {'data': { - 'title': 'lot title', - 'description': 'lot description', - 'value': {'amount': '100.0'}, - 'minimalStep': {'amount': '500.0'}, - }}, 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'value should be less than value of lot'], u'location': u'body', u'name': u'minimalStep'} - ]) - - response = self.app.post_json(request_path, {'data': { - 'title': 'lot title', - 'description': 'lot description', - 'value': {'amount': '500.0'}, - 'minimalStep': {'amount': '100.0', 'currency': "USD"} - }}) - self.assertEqual(response.status, '201 Created') - # but minimalStep currency stays unchanged - response = self.app.get(request_path) - self.assertEqual(response.content_type, 'application/json') - lots = response.json['data'] - self.assertEqual(len(lots), 1) - self.assertEqual(lots[0]['minimalStep']['currency'], "UAH") - self.assertEqual(lots[0]['minimalStep']['amount'], 100) - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {"data": {"items": [{'relatedLot': '0' * 32}]}}, 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'relatedLot': [u'relatedLot should be one of lots']}], u'location': u'body', u'name': u'items'} - ]) - - def test_create_auction_lot(self): - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - self.assertEqual(lot['title'], 'lot title') - self.assertEqual(lot['description'], 'lot description') - self.assertIn('id', lot) - self.assertIn(lot['id'], response.headers['Location']) - self.assertNotIn('guarantee', lot) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertNotIn('guarantee', response.json['data']) - - lot2 = deepcopy(test_lots[0]) - lot2['guarantee'] = {"amount": 100500, "currency": "USD"} - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': lot2}) - self.assertEqual(response.status, '201 Created') - data = response.json['data'] - self.assertIn('guarantee', data) - self.assertEqual(data['guarantee']['amount'], 100500) - self.assertEqual(data['guarantee']['currency'], "USD") - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 100500) - self.assertEqual(response.json['data']['guarantee']['currency'], "USD") - self.assertNotIn('guarantee', response.json['data']['lots'][0]) - - lot3 = deepcopy(test_lots[0]) - lot3['guarantee'] = {"amount": 500, "currency": "UAH"} - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': lot3}, 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'lot guarantee currency should be identical to auction guarantee currency'], u'location': u'body', u'name': u'lots'} - ]) - - lot3['guarantee'] = {"amount": 500} - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': lot3}, 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'lot guarantee currency should be identical to auction guarantee currency'], u'location': u'body', u'name': u'lots'} - ]) - - lot3['guarantee'] = {"amount": 20, "currency": "USD"} - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': lot3}) - self.assertEqual(response.status, '201 Created') - data = response.json['data'] - self.assertIn('guarantee', data) - self.assertEqual(data['guarantee']['amount'], 20) - self.assertEqual(data['guarantee']['currency'], "USD") - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 100500 + 20) - self.assertEqual(response.json['data']['guarantee']['currency'], "USD") - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {"data": {"guarantee": {"currency": "EUR"}}}) - self.assertEqual(response.json['data']['guarantee']['amount'], 100500 + 20) - self.assertEqual(response.json['data']['guarantee']['currency'], "EUR") - self.assertNotIn('guarantee', response.json['data']['lots'][0]) - self.assertEqual(response.json['data']['lots'][1]['guarantee']['amount'], 100500) - self.assertEqual(response.json['data']['lots'][1]['guarantee']['currency'], "EUR") - self.assertEqual(response.json['data']['lots'][2]['guarantee']['amount'], 20) - self.assertEqual(response.json['data']['lots'][2]['guarantee']['currency'], "EUR") - - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': lot}, 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'Lot id should be uniq for all lots'], u'location': u'body', u'name': u'lots'} - ]) - - self.set_status('active.tendering') - - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add lot in current (active.tendering) auction status") - - def test_patch_auction_lot(self): - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - - response = self.app.patch_json('/auctions/{}/lots/{}'.format(self.auction_id, lot['id']), {"data": {"title": "new title"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["title"], "new title") - - response = self.app.patch_json('/auctions/{}/lots/{}'.format(self.auction_id, lot['id']), {"data": {"guarantee": {"amount": 12}}}) - self.assertEqual(response.status, '200 OK') - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 12) - self.assertEqual(response.json['data']['guarantee']['currency'], 'UAH') - - response = self.app.patch_json('/auctions/{}/lots/{}'.format(self.auction_id, lot['id']), {"data": {"guarantee": {"currency": "USD"}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.body, 'null') - - response = self.app.patch_json('/auctions/{}/lots/some_id'.format(self.auction_id), {"data": {"title": "other title"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'lot_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/lots/some_id', {"data": {"title": "other title"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/lots/{}'.format(self.auction_id, lot['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["title"], "new title") - - self.set_status('active.tendering') - - response = self.app.patch_json('/auctions/{}/lots/{}'.format(self.auction_id, lot['id']), {"data": {"title": "other title"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update lot in current (active.tendering) auction status") - - def test_patch_auction_currency(self): - # create lot - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - self.assertEqual(lot['value']['currency'], "UAH") - - # update auction currency without mimimalStep currency change - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {"data": {"value": {"currency": "GBP"}}}, 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'currency should be identical to currency of value of auction'], - u'location': u'body', u'name': u'minimalStep'}, - {u"description": [u"currency should be only UAH"], - u"location": u"body", u"name": u"value"} - ]) - - def test_patch_auction_vat(self): - # set auction VAT - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {"data": {"value": {"valueAddedTaxIncluded": True}}}) - self.assertEqual(response.status, '200 OK') - - # create lot - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - self.assertTrue(lot['value']['valueAddedTaxIncluded']) - - # update auction VAT - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {"data": - {"value": {"valueAddedTaxIncluded": False}, - "minimalStep": {"valueAddedTaxIncluded": False}} - }) - self.assertEqual(response.status, '200 OK') - # log VAT is updated too - response = self.app.get('/auctions/{}/lots/{}'.format(self.auction_id, lot['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - self.assertFalse(lot['value']['valueAddedTaxIncluded']) - - # try to update lot VAT - response = self.app.patch_json('/auctions/{}/lots/{}'.format(self.auction_id, lot['id']), {"data": {"value": {"valueAddedTaxIncluded": True}}}) - self.assertEqual(response.status, '200 OK') - # but the value stays unchanged - response = self.app.get('/auctions/{}/lots/{}'.format(self.auction_id, lot['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - self.assertFalse(lot['value']['valueAddedTaxIncluded']) - - # try to update minimalStep VAT - response = self.app.patch_json('/auctions/{}/lots/{}'.format(self.auction_id, lot['id']), {"data": {"minimalStep": {"valueAddedTaxIncluded": True}}}) - self.assertEqual(response.status, '200 OK') - # but the value stays unchanged - response = self.app.get('/auctions/{}/lots/{}'.format(self.auction_id, lot['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - self.assertFalse(lot['minimalStep']['valueAddedTaxIncluded']) - - # try to update minimalStep VAT and value VAT in single request - response = self.app.patch_json('/auctions/{}/lots/{}'.format(self.auction_id, lot['id']), {"data": {"value": {"valueAddedTaxIncluded": True}, - "minimalStep": {"valueAddedTaxIncluded": True}}}) - self.assertEqual(response.status, '200 OK') - # but the value stays unchanged - response = self.app.get('/auctions/{}/lots/{}'.format(self.auction_id, lot['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - self.assertFalse(lot['value']['valueAddedTaxIncluded']) - self.assertEqual(lot['minimalStep']['valueAddedTaxIncluded'], lot['value']['valueAddedTaxIncluded']) - - def test_get_auction_lot(self): - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - - response = self.app.get('/auctions/{}/lots/{}'.format(self.auction_id, lot['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(set(response.json['data']), set([u'id', u'date', u'title', u'description', u'minimalStep', u'value', u'status'])) - - self.set_status('active.qualification') - - response = self.app.get('/auctions/{}/lots/{}'.format(self.auction_id, lot['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], lot) - - response = self.app.get('/auctions/{}/lots/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'lot_id'} - ]) - - response = self.app.get('/auctions/some_id/lots/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_get_auction_lots(self): - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - - response = self.app.get('/auctions/{}/lots'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(set(response.json['data'][0]), set([u'id', u'date', u'title', u'description', u'minimalStep', u'value', u'status'])) - - self.set_status('active.qualification') - - response = self.app.get('/auctions/{}/lots'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][0], lot) - - response = self.app.get('/auctions/some_id/lots', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_delete_auction_lot(self): - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - - response = self.app.delete('/auctions/{}/lots/{}'.format(self.auction_id, lot['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], lot) - - response = self.app.delete('/auctions/{}/lots/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'lot_id'} - ]) - - response = self.app.delete('/auctions/some_id/lots/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.post_json('/auctions/{}/lots'.format(self.auction_id), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - lot = response.json['data'] - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {"data": { - "items": [ - { - 'relatedLot': lot['id'] - } - ] - }}) - self.assertEqual(response.status, '200 OK') - - response = self.app.delete('/auctions/{}/lots/{}'.format(self.auction_id, lot['id']), 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'relatedLot': [u'relatedLot should be one of lots']}], u'location': u'body', u'name': u'items'} - ]) - - self.set_status('active.tendering') - - response = self.app.delete('/auctions/{}/lots/{}'.format(self.auction_id, lot['id']), status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't delete lot in current (active.tendering) auction status") - - def test_auction_lot_guarantee(self): - data = deepcopy(test_auction_data) - data['guarantee'] = {"amount": 100, "currency": "USD"} - response = self.app.post_json('/auctions', {'data': data}) - auction = response.json['data'] - self.assertEqual(response.status, '201 Created') - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 100) - self.assertEqual(response.json['data']['guarantee']['currency'], "USD") - - lot = deepcopy(test_lots[0]) - lot['guarantee'] = {"amount": 20, "currency": "USD"} - response = self.app.post_json('/auctions/{}/lots'.format(auction['id']), {'data': lot}) - self.assertEqual(response.status, '201 Created') - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 20) - self.assertEqual(response.json['data']['guarantee']['currency'], "USD") - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'guarantee': {"currency": "GBP"}}}) - self.assertEqual(response.status, '200 OK') - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 20) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") - - lot['guarantee'] = {"amount": 20, "currency": "GBP"} - response = self.app.post_json('/auctions/{}/lots'.format(auction['id']), {'data': lot}) - self.assertEqual(response.status, '201 Created') - lot_id = response.json['data']['id'] - self.assertEqual(response.json['data']['guarantee']['amount'], 20) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertEqual(response.json['data']['guarantee']['amount'], 20 + 20) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") - - lot2 = deepcopy(test_lots[0]) - lot2['guarantee'] = {"amount": 30, "currency": "GBP"} - response = self.app.post_json('/auctions/{}/lots'.format(auction['id']), {'data': lot2}) - self.assertEqual(response.status, '201 Created') - lot2_id = response.json['data']['id'] - self.assertEqual(response.json['data']['guarantee']['amount'], 30) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") - - lot2['guarantee'] = {"amount": 40, "currency": "USD"} - response = self.app.post_json('/auctions/{}/lots'.format(auction['id']), {'data': lot2}, 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'lot guarantee currency should be identical to auction guarantee currency'], u'location': u'body', u'name': u'lots'} - ]) - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 20 + 20 + 30) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {"data": {"guarantee": {"amount": 55}}}) - self.assertEqual(response.json['data']['guarantee']['amount'], 20 + 20 + 30) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") - - response = self.app.patch_json('/auctions/{}/lots/{}'.format(auction['id'], lot2_id), {'data': {'guarantee': {"amount": 35, "currency": "GBP"}}}) - self.assertEqual(response.json['data']['guarantee']['amount'], 35) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 20 + 20 + 35) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") - - for l_id in (lot_id, lot2_id): - response = self.app.patch_json('/auctions/{}/lots/{}'.format(auction['id'], l_id), {'data': {'guarantee': {"amount": 0, "currency": "GBP"}}}) - self.assertEqual(response.json['data']['guarantee']['amount'], 0) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 20) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") - - for l_id in (lot_id, lot2_id): - response = self.app.delete('/auctions/{}/lots/{}'.format(auction['id'], l_id)) - self.assertEqual(response.status, '200 OK') - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 20) - self.assertEqual(response.json['data']['guarantee']['currency'], "GBP") +class AuctionLotResourceTest(BaseAuctionWebTest, AuctionLotResourceTestMixin): + test_auction_data = test_auction_data + test_lots = test_lots + test_patch_auction_currency = snitch(patch_auction_currency) @unittest.skip("option not available") class AuctionLotFeatureResourceTest(BaseAuctionWebTest): + test_auction_data = test_auction_data initial_lots = 2 * test_lots - def test_auction_value(self): - request_path = '/auctions/{}'.format(self.auction_id) - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['value']['amount'], sum([i['value']['amount'] for i in self.initial_lots])) - self.assertEqual(response.json['data']['minimalStep']['amount'], min([i['minimalStep']['amount'] for i in self.initial_lots])) - - def test_auction_features_invalid(self): - request_path = '/auctions/{}'.format(self.auction_id) - data = test_auction_data.copy() - item = data['items'][0].copy() - item['id'] = "1" - data['items'] = [item] - data['features'] = [ - { - "featureOf": "lot", - "relatedItem": self.initial_lots[0]['id'], - "title": u"Потужність всмоктування", - "enum": [ - { - "value": 0.5, - "title": u"До 1000 Вт" - }, - { - "value": 0.15, - "title": u"Більше 1000 Вт" - } - ] - } - ] - response = self.app.patch_json(request_path, {'data': data}, 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'enum': [{u'value': [u'Float value should be less than 0.3.']}]}], u'location': u'body', u'name': u'features'} - ]) - data['features'][0]["enum"][0]["value"] = 0.1 - data['features'].append(data['features'][0].copy()) - data['features'][1]["enum"][0]["value"] = 0.2 - response = self.app.patch_json(request_path, {'data': data}, 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'Sum of max value of all features for lot should be less then or equal to 30%'], u'location': u'body', u'name': u'features'} - ]) - data['features'][1]["enum"][0]["value"] = 0.1 - data['features'].append(data['features'][0].copy()) - data['features'][2]["relatedItem"] = self.initial_lots[1]['id'] - data['features'].append(data['features'][2].copy()) - response = self.app.patch_json(request_path, {'data': data}) - self.assertEqual(response.status, '200 OK') + test_auction_value = snitch(auction_value) + test_auction_features_invalid = snitch(auction_features_invalid) @unittest.skip("option not available") @@ -613,114 +44,15 @@ class AuctionLotBidderResourceTest(BaseAuctionWebTest): initial_status = 'active.tendering' initial_lots = test_lots - def test_create_auction_bidder_invalid(self): - request_path = '/auctions/{}/bids'.format(self.auction_id) - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization]}}, 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'This field is required.'], u'location': u'body', u'name': u'lotValues'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}}]}}, 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'relatedLot': [u'This field is required.']}], u'location': u'body', u'name': u'lotValues'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}, 'relatedLot': "0" * 32}]}}, 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'relatedLot': [u'relatedLot should be one of lots']}], u'location': u'body', u'name': u'lotValues'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 50}, 'relatedLot': self.initial_lots[0]['id']}]}}, 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'value': [u'value of bid should be greater than value of lot']}], u'location': u'body', u'name': u'lotValues'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500, 'valueAddedTaxIncluded': False}, 'relatedLot': self.initial_lots[0]['id']}]}}, 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'value': [u'valueAddedTaxIncluded of bid should be identical to valueAddedTaxIncluded of value of lot']}], u'location': u'body', u'name': u'lotValues'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500, 'currency': "USD"}, 'relatedLot': self.initial_lots[0]['id']}]}}, 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'value': [u'currency of bid should be identical to currency of value of lot']}], u'location': u'body', u'name': u'lotValues'}, - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'lotValues': [{"value": {"amount": 500}, 'relatedLot': self.initial_lots[0]['id']}]}}, 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'value should be posted for each lot of bid'], u'location': u'body', u'name': u'value'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': self.initial_organization, 'lotValues': [{"value": {"amount": 500}, 'relatedLot': self.initial_lots[0]['id']}]}}, 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"invalid literal for int() with base 10: 'contactPoint'", u'location': u'body', u'name': u'data'}, - ]) - - def test_patch_auction_bidder(self): - lot_id = self.initial_lots[0]['id'] - response = self.app.post_json('/auctions/{}/bids'.format(self.auction_id), {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}, 'relatedLot': lot_id}]}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - bidder = response.json['data'] - lot = bidder['lotValues'][0] - - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {'tenderers': [{"name": u"Державне управління управлінням справами"}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['lotValues'][0]['date'], lot['date']) - self.assertNotEqual(response.json['data']['tenderers'][0]['name'], bidder['tenderers'][0]['name']) - - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {'lotValues': [{"value": {"amount": 500}, 'relatedLot': lot_id}], 'tenderers': [self.initial_organization]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['lotValues'][0]['date'], lot['date']) - self.assertEqual(response.json['data']['tenderers'][0]['name'], bidder['tenderers'][0]['name']) - - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {'lotValues': [{"value": {"amount": 400}, 'relatedLot': lot_id}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['lotValues'][0]["value"]["amount"], 400) - self.assertNotEqual(response.json['data']['lotValues'][0]['date'], lot['date']) - - self.set_status('complete') - - response = self.app.get('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['lotValues'][0]["value"]["amount"], 400) - - response = self.app.patch_json('/auctions/{}/bids/{}'.format(self.auction_id, bidder['id']), {"data": {'lotValues': [{"value": {"amount": 500}, 'relatedLot': lot_id}]}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update bid in current (complete) auction status") + create_auction_bidder_invalid = snitch(create_auction_bidder_invalid) + patch_auction_bidder = snitch(patch_auction_bidder) @unittest.skip("option not available") class AuctionLotFeatureBidderResourceTest(BaseAuctionWebTest): initial_lots = test_lots + test_create_auction_bidder_invalid_feature = snitch(create_auction_bidder_invalid_feature) + test_create_auction_bidder_feature = snitch(create_auction_bidder_feature) def setUp(self): super(AuctionLotFeatureBidderResourceTest, self).setUp() @@ -787,960 +119,12 @@ def setUp(self): self.assertEqual(response.json['data']['items'][0]['relatedLot'], self.lot_id) self.set_status('active.tendering') - def test_create_auction_bidder_invalid(self): - request_path = '/auctions/{}/bids'.format(self.auction_id) - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization]}}, 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'All features parameters is required.'], u'location': u'body', u'name': u'parameters'}, - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'lotValues'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}}]}}, 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'relatedLot': [u'This field is required.']}], u'location': u'body', u'name': u'lotValues'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}, 'relatedLot': "0" * 32}]}}, 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'relatedLot': [u'relatedLot should be one of lots']}], u'location': u'body', u'name': u'lotValues'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 50}, 'relatedLot': self.lot_id}]}}, 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'value': [u'value of bid should be greater than value of lot']}], u'location': u'body', u'name': u'lotValues'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500, 'valueAddedTaxIncluded': False}, 'relatedLot': self.lot_id}]}}, 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'value': [u'valueAddedTaxIncluded of bid should be identical to valueAddedTaxIncluded of value of lot']}], u'location': u'body', u'name': u'lotValues'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500, 'currency': "USD"}, 'relatedLot': self.lot_id}]}}, 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'value': [u'currency of bid should be identical to currency of value of lot']}], u'location': u'body', u'name': u'lotValues'}, - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': self.initial_organization, 'lotValues': [{"value": {"amount": 500}, 'relatedLot': self.lot_id}]}}, 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"invalid literal for int() with base 10: 'contactPoint'", u'location': u'body', u'name': u'data'}, - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}, 'relatedLot': self.lot_id}]}}, 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'All features parameters is required.'], u'location': u'body', u'name': u'parameters'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}, 'relatedLot': self.lot_id}], 'parameters': [{"code": "code_item", "value": 0.01}]}}, 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'All features parameters is required.'], u'location': u'body', u'name': u'parameters'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}, 'relatedLot': self.lot_id}], 'parameters': [{"code": "code_invalid", "value": 0.01}]}}, 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'code': [u'code should be one of feature code.']}], u'location': u'body', u'name': u'parameters'} - ]) - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}, 'relatedLot': self.lot_id}], 'parameters': [ - {"code": "code_item", "value": 0.01}, - {"code": "code_tenderer", "value": 0}, - {"code": "code_lot", "value": 0.01}, - ]}}, 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'value': [u'value should be one of feature value.']}], u'location': u'body', u'name': u'parameters'} - ]) - - def test_create_auction_bidder(self): - request_path = '/auctions/{}/bids'.format(self.auction_id) - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}, 'relatedLot': self.lot_id}], 'parameters': [ - {"code": "code_item", "value": 0.01}, - {"code": "code_tenderer", "value": 0.01}, - {"code": "code_lot", "value": 0.01}, - ]}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - bidder = response.json['data'] - self.assertEqual(bidder['tenderers'][0]['name'], self.initial_organization['name']) - self.assertIn('id', bidder) - self.assertIn(bidder['id'], response.headers['Location']) - - self.set_status('complete') - - response = self.app.post_json(request_path, {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}, 'relatedLot': self.lot_id}], 'parameters': [ - {"code": "code_item", "value": 0.01}, - {"code": "code_tenderer", "value": 0.01}, - {"code": "code_lot", "value": 0.01}, - ]}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add bid in current (complete) auction status") - @unittest.skip("option not available") -class AuctionLotProcessTest(BaseAuctionWebTest): +class AuctionLotProcessTest(BaseAuctionWebTest, AuctionLotProcessTestMixin): setUp = BaseWebTest.setUp - - def test_1lot_0bid(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lot_id = response.json['data']['id'] - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': lot_id}]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [{"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}}]}) - self.assertIn("auctionPeriod", response.json['data']['lots'][0]) - # switch to unsuccessful - response = self.set_status('active.auction', {"lots": [{"auctionPeriod": {"startDate": None}}], 'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - self.assertEqual(response.json['data']["lots"][0]['status'], 'unsuccessful') - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_1lot_1bid(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lot_id = response.json['data']['id'] - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': lot_id}]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [{"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}}]}) - self.assertIn("auctionPeriod", response.json['data']['lots'][0]) - # create bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 500}, 'relatedLot': lot_id}]}}) - # switch to active.qualification - response = self.set_status('active.auction', {"lots": [{"auctionPeriod": {"startDate": None}}], 'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending'][0] - # set award as active - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) - # get contract id - response = self.app.get('/auctions/{}'.format(auction_id)) - contract_id = response.json['data']['contracts'][-1]['id'] - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # sign contract - self.app.authorization = ('Basic', ('broker', '')) - self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertEqual(response.json['data']["lots"][0]['status'], 'complete') - self.assertEqual(response.json['data']['status'], 'complete') - - def test_1lot_2bid(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lot_id = response.json['data']['id'] - self.initial_lots = [response.json['data']] - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': lot_id}]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [{"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}}]}) - self.assertIn("auctionPeriod", response.json['data']['lots'][0]) - # create bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 450}, 'relatedLot': lot_id}]}}) - bid_id = response.json['data']['id'] - bid_token = response.json['access']['token'] - # create second bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], 'lotValues': [{"value": {"amount": 475}, 'relatedLot': lot_id}]}}) - # switch to active.auction - self.set_status('active.auction') - # get auction info - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.get('/auctions/{}/auction'.format(auction_id)) - auction_bids_data = response.json['data']['bids'] - # posting auction urls - response = self.app.patch_json('/auctions/{}/auction/{}'.format(auction_id, lot_id), { - 'data': { - 'lots': [ - { - 'id': i['id'], - 'auctionUrl': 'https://auction.auction.url' - } - for i in response.json['data']['lots'] - ], - 'bids': [ - { - 'id': i['id'], - 'lotValues': [ - { - 'relatedLot': j['relatedLot'], - 'participationUrl': 'https://auction.auction.url/for_bid/{}'.format(i['id']) - } - for j in i['lotValues'] - ], - } - for i in auction_bids_data - ] - } - }) - # view bid participationUrl - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(auction_id, bid_id, bid_token)) - self.assertEqual(response.json['data']['lotValues'][0]['participationUrl'], 'https://auction.auction.url/for_bid/{}'.format(bid_id)) - # posting auction results - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.post_json('/auctions/{}/auction/{}'.format(auction_id, lot_id), {'data': {'bids': auction_bids_data}}) - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending'][0] - # set award as active - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) - # get contract id - response = self.app.get('/auctions/{}'.format(auction_id)) - contract_id = response.json['data']['contracts'][-1]['id'] - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # sign contract - self.app.authorization = ('Basic', ('broker', '')) - self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertEqual(response.json['data']["lots"][0]['status'], 'complete') - self.assertEqual(response.json['data']['status'], 'complete') - - def test_2lot_0bid(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - lots = [] - for lot in 2 * test_lots: - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lots.append(response.json['data']['id']) - # add item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [test_auction_data['items'][0] for i in lots]}}) - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': i} for i in lots]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [ - {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}} - for i in lots - ]}) - self.assertTrue(all(["auctionPeriod" in i for i in response.json['data']['lots']])) - # switch to unsuccessful - response = self.set_status('active.auction', { - "lots": [ - {"auctionPeriod": {"startDate": None}} - for i in lots - ], - 'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - self.assertTrue(all([i['status'] == 'unsuccessful' for i in response.json['data']['lots']])) - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_2lot_2can(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - lots = [] - for lot in 2 * test_lots: - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lots.append(response.json['data']['id']) - # add item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [test_auction_data['items'][0] for i in lots]}}) - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': i} for i in lots]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [ - {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}} - for i in lots - ]}) - self.assertTrue(all(["auctionPeriod" in i for i in response.json['data']['lots']])) - # cancel every lot - for lot_id in lots: - response = self.app.post_json('/auctions/{}/cancellations?acc_token={}'.format(auction_id, owner_token), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": lot_id - }}) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertTrue(all([i['status'] == 'cancelled' for i in response.json['data']['lots']])) - self.assertEqual(response.json['data']['status'], 'cancelled') - - def test_2lot_2bid_0com_1can_before_auction(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - lots = [] - for lot in 2 * test_lots: - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), - {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lots.append(response.json['data']['id']) - # add item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), - {"data": {"items": [test_auction_data['items'][0] for i in lots]}}) - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), - {"data": {"items": [{'relatedLot': i} for i in lots]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [ - {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}} - for i in lots - ]}) - # create bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], 'lotValues': [ - {"value": {"amount": 500}, 'relatedLot': lot_id} - for lot_id in lots - ]}}) - # for first lot - lot_id = lots[0] - # create bid #2 for 1 lot - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], 'lotValues': [ - {"value": {"amount": 500}, 'relatedLot': lot_id} - ]}}) - # cancel lot - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/cancellations?acc_token={}'.format(auction_id, owner_token), - {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": lot_id - }}) - # switch to active.qualification - response = self.set_status('active.auction', {'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - self.assertEqual(response.json['data']['status'], 'active.qualification') - # for second lot - lot_id = lots[1] - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as unsuccessful - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), - {"data": {"status": "unsuccessful"}}) - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - tender = self.db.get(auction_id) - for i in tender.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(tender) - # check tender status - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertEqual([i['status'] for i in response.json['data']['lots']], [u'cancelled', u'unsuccessful']) - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_2lot_1bid_0com_1can(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - lots = [] - for lot in 2 * test_lots: - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lots.append(response.json['data']['id']) - # add item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [test_auction_data['items'][0] for i in lots]}}) - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': i} for i in lots]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [ - {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}} - for i in lots - ]}) - # create bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), {'data': {'tenderers': [self.initial_organization], 'lotValues': [ - {"value": {"amount": 500}, 'relatedLot': lot_id} - for lot_id in lots - ]}}) - # switch to active.qualification - response = self.set_status('active.auction', { - "lots": [ - {"auctionPeriod": {"startDate": None}} - for i in lots - ], - 'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - # for first lot - lot_id = lots[0] - # cancel lot - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/cancellations?acc_token={}'.format(auction_id, owner_token), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": lot_id - }}) - # for second lot - lot_id = lots[1] - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as unsuccessful - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "unsuccessful"}}) - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # check auction status - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertEqual([i['status'] for i in response.json['data']['lots']], [u'cancelled', u'unsuccessful']) - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_2lot_1bid_2com_1win(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - lots = [] - for lot in 2 * test_lots: - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lots.append(response.json['data']['id']) - # add item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [test_auction_data['items'][0] for i in lots]}}) - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': i} for i in lots]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [ - {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}} - for i in lots - ]}) - # create bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), {'data': {'tenderers': [self.initial_organization], 'lotValues': [ - {"value": {"amount": 500}, 'relatedLot': lot_id} - for lot_id in lots - ]}}) - # switch to active.qualification - response = self.set_status('active.auction', { - "lots": [ - {"auctionPeriod": {"startDate": None}} - for i in lots - ], - 'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - for lot_id in lots: - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as active - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) - # get contract id - response = self.app.get('/auctions/{}'.format(auction_id)) - contract_id = response.json['data']['contracts'][-1]['id'] - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # sign contract - self.app.authorization = ('Basic', ('broker', '')) - self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertTrue(all([i['status'] == 'complete' for i in response.json['data']['lots']])) - self.assertEqual(response.json['data']['status'], 'complete') - - def test_2lot_1bid_0com_0win(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - lots = [] - for lot in 2 * test_lots: - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lots.append(response.json['data']['id']) - # add item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [test_auction_data['items'][0] for i in lots]}}) - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': i} for i in lots]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [ - {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}} - for i in lots - ]}) - # create bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), {'data': {'tenderers': [self.initial_organization], 'lotValues': [ - {"value": {"amount": 500}, 'relatedLot': lot_id} - for lot_id in lots - ]}}) - # switch to active.qualification - response = self.set_status('active.auction', { - "lots": [ - {"auctionPeriod": {"startDate": None}} - for i in lots - ], - 'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - # for every lot - for lot_id in lots: - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as unsuccessful - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "unsuccessful"}}) - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # check auction status - self.set_status('complete', {'status': 'active.awarded'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertTrue(all([i['status'] == 'unsuccessful' for i in response.json['data']['lots']])) - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_2lot_1bid_1com_1win(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - lots = [] - for lot in 2 * test_lots: - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lots.append(response.json['data']['id']) - # add item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [test_auction_data['items'][0] for i in lots]}}) - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': i} for i in lots]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [ - {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}} - for i in lots - ]}) - # create bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), {'data': {'tenderers': [self.initial_organization], 'lotValues': [ - {"value": {"amount": 500}, 'relatedLot': lot_id} - for lot_id in lots - ]}}) - # switch to active.qualification - response = self.set_status('active.auction', { - "lots": [ - {"auctionPeriod": {"startDate": None}} - for i in lots - ], - 'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - # for first lot - lot_id = lots[0] - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as active - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) - # get contract id - response = self.app.get('/auctions/{}'.format(auction_id)) - contract_id = response.json['data']['contracts'][-1]['id'] - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # sign contract - self.app.authorization = ('Basic', ('broker', '')) - self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) - # for second lot - lot_id = lots[1] - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as unsuccessful - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "unsuccessful"}}) - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # check auction status - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertEqual([i['status'] for i in response.json['data']['lots']], [u'complete', u'unsuccessful']) - self.assertEqual(response.json['data']['status'], 'complete') - - def test_2lot_2bid_2com_2win(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - lots = [] - for lot in 2 * test_lots: - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lots.append(response.json['data']['id']) - self.initial_lots = lots - # add item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [test_auction_data['items'][0] for i in lots]}}) - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': i} for i in lots]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [ - {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}} - for i in lots - ]}) - # create bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), {'data': {'tenderers': [self.initial_organization], 'lotValues': [ - {"value": {"amount": 500}, 'relatedLot': lot_id} - for lot_id in lots - ]}}) - # create second bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), {'data': {'tenderers': [self.initial_organization], 'lotValues': [ - {"value": {"amount": 500}, 'relatedLot': lot_id} - for lot_id in lots - ]}}) - # switch to active.auction - self.set_status('active.auction') - # get auction info - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.get('/auctions/{}/auction'.format(auction_id)) - auction_bids_data = response.json['data']['bids'] - for lot_id in lots: - # posting auction urls - response = self.app.patch_json('/auctions/{}/auction/{}'.format(auction_id, lot_id), { - 'data': { - 'lots': [ - { - 'id': i['id'], - 'auctionUrl': 'https://auction.auction.url' - } - for i in response.json['data']['lots'] - ], - 'bids': [ - { - 'id': i['id'], - 'lotValues': [ - { - 'relatedLot': j['relatedLot'], - 'participationUrl': 'https://auction.auction.url/for_bid/{}'.format(i['id']) - } - for j in i['lotValues'] - ], - } - for i in auction_bids_data - ] - } - }) - # posting auction results - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.post_json('/auctions/{}/auction/{}'.format(auction_id, lot_id), {'data': {'bids': auction_bids_data}}) - # for first lot - lot_id = lots[0] - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as active - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) - # get contract id - response = self.app.get('/auctions/{}'.format(auction_id)) - contract_id = response.json['data']['contracts'][-1]['id'] - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # sign contract - self.app.authorization = ('Basic', ('broker', '')) - self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) - # for second lot - lot_id = lots[1] - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as unsuccessful - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "unsuccessful"}}) - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as active - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) - # get contract id - response = self.app.get('/auctions/{}'.format(auction_id)) - contract_id = response.json['data']['contracts'][-1]['id'] - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # sign contract - self.app.authorization = ('Basic', ('broker', '')) - self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertTrue(all([i['status'] == 'complete' for i in response.json['data']['lots']])) - self.assertEqual(response.json['data']['status'], 'complete') - - def test_2lot_1feature_2bid_2com_2win(self): - self.app.authorization = ('Basic', ('broker', '')) - # create auction - response = self.app.post_json('/auctions', {"data": test_auction_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - lots = [] - for lot in 2 * test_lots: - # add lot - response = self.app.post_json('/auctions/{}/lots?acc_token={}'.format(auction_id, owner_token), {'data': test_lots[0]}) - self.assertEqual(response.status, '201 Created') - lots.append(response.json['data']['id']) - self.initial_lots = lots - # add item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [test_auction_data['items'][0] for i in lots]}}) - # add relatedLot for item - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"items": [{'relatedLot': i} for i in lots]}}) - # add features - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction_id, owner_token), {"data": {"features": [ - { - "code": "code_item", - "featureOf": "item", - "relatedItem": response.json['data']['items'][0]['id'], - "title": u"item feature", - "enum": [ - { - "value": 0.1, - "title": u"good" - }, - { - "value": 0.2, - "title": u"best" - } - ] - } - ]}}) - self.assertEqual(response.status, '200 OK') - # switch to active.tendering - response = self.set_status('active.tendering', {"lots": [ - {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}} - for i in lots - ]}) - # create bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), {'data': {'tenderers': [self.initial_organization], 'lotValues': [ - {"value": {"amount": 500}, 'relatedLot': lots[0]} - ], 'parameters': [{"code": "code_item", "value": 0.2}]}}) - # create second bid - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), {'data': {'tenderers': [self.initial_organization], 'lotValues': [ - {"value": {"amount": 500}, 'relatedLot': lots[1]} - ]}}) - # switch to active.qualification - response = self.set_status('active.auction', {'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - # for first lot - lot_id = lots[0] - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as active - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) - # get contract id - response = self.app.get('/auctions/{}'.format(auction_id)) - contract_id = response.json['data']['contracts'][-1]['id'] - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # sign contract - self.app.authorization = ('Basic', ('broker', '')) - self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) - # for second lot - lot_id = lots[1] - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending' and i['lotID'] == lot_id][0] - # set award as active - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) - # get contract id - response = self.app.get('/auctions/{}'.format(auction_id)) - contract_id = response.json['data']['contracts'][-1]['id'] - # after stand slill period - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # sign contract - self.app.authorization = ('Basic', ('broker', '')) - self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertTrue(all([i['status'] == 'complete' for i in response.json['data']['lots']])) - self.assertEqual(response.json['data']['status'], 'complete') + test_auction_data = test_auction_data + test_lots = test_lots @unittest.skip("option not available") From 8894101b936951fd2934e08ebfb1c9806709c3e9 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 18:59:18 +0200 Subject: [PATCH 28/45] Move migration tests to blanks --- .../dgf/tests/blanks/migration_blanks.py | 1175 ++++++++++++++++ .../auctions/dgf/tests/migration.py | 1201 +---------------- 2 files changed, 1220 insertions(+), 1156 deletions(-) create mode 100644 openprocurement/auctions/dgf/tests/blanks/migration_blanks.py diff --git a/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py b/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py new file mode 100644 index 00000000..974bcac3 --- /dev/null +++ b/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py @@ -0,0 +1,1175 @@ +# -*- coding: utf-8 -*- + +from openprocurement.api.models import get_now +from datetime import timedelta +from uuid import uuid4 +from copy import deepcopy + +from openprocurement.auctions.dgf.migration import migrate_data +# MigrateTestFrom1To2Bids + +def migrate_one_pending(self): + auction = self.db.get(self.auction_id) + award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + auction['awards'] = [award] + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + self.assertEqual(auction['bids'][0]['status'], 'active') + self.assertEqual(auction['bids'][1]['status'], 'active') + self.assertEqual(auction['status'], 'active.qualification') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.qualification') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'pending.payment') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + pending_award = response.json['data'][0] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), + {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.qualification') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data'][1]['status'], u'pending.verification') + + +def migrate_one_active(self): + auction = self.db.get(self.auction_id) + now = get_now() + award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][1]['id'], + 'suppliers': auction['bids'][1]['tenderers'], + 'value': auction['bids'][1]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + auction['awards'] = [award] + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=7)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + contract_id = uuid4().hex + auction['contracts'] = [{ + 'awardID': award['id'], + 'id': contract_id, + 'suppliers': award['suppliers'], + 'value': award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'active') + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertIn('signingPeriod', auction['awards'][0]) + self.assertEqual(auction['bids'][0]['status'], 'active') + self.assertEqual(auction['bids'][1]['status'], 'active') + self.assertEqual(auction['contracts'][0]['status'], 'pending') + self.assertEqual(auction['status'], 'active.awarded') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'active') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + active_award = response.json['data'][0] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, active_award['id']), + {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.qualification') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data'][1]['status'], u'pending.verification') + + +def migrate_unsuccessful_pending(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + unsuccessful_award = deepcopy(pending_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + pending_award['bid_id'] = auction['bids'][0]['id'] + auction['awards'] = [unsuccessful_award, pending_award] + auction.update(auction) + + self.db.save(auction) + + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['bids'][0]['status'], 'active') + self.assertEqual(auction['bids'][1]['status'], 'active') + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'pending.payment') + self.assertEqual(auction['status'], 'active.qualification') + + +def migrate_unsuccessful_active(self): + auction = self.db.get(self.auction_id) + + now = get_now() + + active_award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][1]['id'], + 'suppliers': auction['bids'][1]['tenderers'], + 'value': auction['bids'][1]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + unsuccessful_award = deepcopy(active_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + active_award['bid_id'] = auction['bids'][0]['id'] + + auction['awards'] = [unsuccessful_award, active_award] + + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + auction['contracts'] = [{ + 'awardID': active_award['id'], + 'suppliers': active_award['suppliers'], + 'value': active_award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['bids'][0]['status'], 'active') + self.assertEqual(auction['bids'][1]['status'], 'active') + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'active') + self.assertEqual(auction['contracts'][0]['status'], 'pending') + self.assertEqual(auction['status'], 'active.awarded') + +# MigrateTestFrom1To2WithTwoBids + + +def migrate_pending_to_unsuccesful(self): + auction = self.db.get(self.auction_id) + award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + auction['awards'] = [award] + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.qualification') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'pending.payment') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + pending_award = response.json['data'][0] + waiting_award = response.json['data'][1] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + +def migrate_pending_to_complete(self): + auction = self.db.get(self.auction_id) + award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + auction['awards'] = [award] + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.qualification') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'pending.payment') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + pending_award = response.json['data'][0] + waiting_award = response.json['data'][1] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, waiting_award['id'], self.auction_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, waiting_award['id'], doc_id, self.auction_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "pending.payment"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'pending.payment') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + contract = response.json['data']['contracts'][0] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'complete') + + +def migrate_active_to_unsuccessful(self): + auction = self.db.get(self.auction_id) + now = get_now() + award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][1]['id'], + 'suppliers': auction['bids'][1]['tenderers'], + 'value': auction['bids'][1]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + auction['awards'] = [award] + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=7)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + contract_id = uuid4().hex + auction['contracts'] = [{ + 'awardID': award['id'], + 'id': contract_id, + 'suppliers': award['suppliers'], + 'value': award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + auction.update(auction) + self.db.save(auction) + + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'active') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertIn('signingPeriod', auction['awards'][0]) + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'active') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + active_award = response.json['data'][0] + waiting_award = response.json['data'][1] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, active_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + +def migrate_active_to_complete(self): + auction = self.db.get(self.auction_id) + now = get_now() + award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][1]['id'], + 'suppliers': auction['bids'][1]['tenderers'], + 'value': auction['bids'][1]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + auction['awards'] = [award] + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=7)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + contract_id = uuid4().hex + auction['contracts'] = [{ + 'awardID': award['id'], + 'id': contract_id, + 'suppliers': award['suppliers'], + 'value': award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + auction.update(auction) + self.db.save(auction) + + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'active') + self.assertIn('verificationPeriod', auction['awards'][0]) + self.assertIn('paymentPeriod', auction['awards'][0]) + self.assertIn('signingPeriod', auction['awards'][0]) + self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(auction['status'], u'active.awarded') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'active') + self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract_id), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'complete') + + +def migrate_cancelled_pending_to_complete(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + cancelled_award = deepcopy(pending_award) + cancelled_award['id'] = uuid4().hex + cancelled_award['status'] = 'cancelled' + cancelled_award['complaintPeriod']['endDate'] = get_now().isoformat() + auction['awards'] = [cancelled_award, pending_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.qualification') + self.assertEqual(len(auction['awards']), 3) + self.assertEqual(auction['awards'][0]['status'], 'cancelled') + self.assertEqual(auction['awards'][1]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][1]) + self.assertIn('paymentPeriod', auction['awards'][1]) + self.assertIn('signingPeriod', auction['awards'][1]) + self.assertEqual(auction['awards'][2]['status'], 'pending.waiting') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 3) + self.assertEqual(response.json['data'][0]['status'], u'cancelled') + self.assertEqual(response.json['data'][1]['status'], u'pending.payment') + self.assertEqual(response.json['data'][2]['status'], u'pending.waiting') + pending_award = response.json['data'][1] + waiting_award = response.json['data'][2] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, waiting_award['id'], self.auction_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, waiting_award['id'], doc_id, self.auction_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "pending.payment"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'pending.payment') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + contract = response.json['data']['contracts'][0] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'complete') + + +def migrate_unsuccessful_pending_to_complete(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][0]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + unsuccessful_award = deepcopy(pending_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + pending_award['bid_id'] = auction['bids'][1]['id'] + auction['awards'] = [unsuccessful_award, pending_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.qualification') + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][1]) + self.assertIn('paymentPeriod', auction['awards'][1]) + self.assertIn('signingPeriod', auction['awards'][1]) + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'unsuccessful') + self.assertEqual(response.json['data'][1]['status'], u'pending.payment') + pending_award = response.json['data'][1] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + contract = response.json['data']['contracts'][0] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'complete') + +def migrate_unsuccessful_active_to_complete(self): + auction = self.db.get(self.auction_id) + + now = get_now() + + active_award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][0]['id'], + 'suppliers': auction['bids'][0]['tenderers'], + 'value': auction['bids'][0]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + unsuccessful_award = deepcopy(active_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + active_award['bid_id'] = auction['bids'][1]['id'] + + auction['awards'] = [unsuccessful_award, active_award] + + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=9)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + auction['contracts'] = [{ + 'awardID': active_award['id'], + 'suppliers': active_award['suppliers'], + 'value': active_award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.awarded') + self.assertEqual(len(auction['awards']), 2) + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'active') + self.assertIn('verificationPeriod', auction['awards'][1]) + self.assertIn('paymentPeriod', auction['awards'][1]) + self.assertIn('signingPeriod', auction['awards'][1]) + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 2) + self.assertEqual(response.json['data'][0]['status'], u'unsuccessful') + self.assertEqual(response.json['data'][1]['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + contract = response.json['data']['contracts'][0] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'complete') + +def migrate_cancelled_unsuccessful_pending(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + unsuccessful_award = deepcopy(pending_award) + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + cancelled_award = deepcopy(unsuccessful_award) + cancelled_award['id'] = uuid4().hex + cancelled_award['status'] = 'cancelled' + + pending_award['bid_id'] = auction['bids'][0]['id'] + + auction['awards'] = [cancelled_award, unsuccessful_award, pending_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.qualification') + self.assertEqual(len(auction['awards']), 3) + self.assertEqual(auction['awards'][0]['status'], 'cancelled') + self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][2]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][2]) + self.assertIn('paymentPeriod', auction['awards'][2]) + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 3) + self.assertEqual(response.json['data'][0]['status'], u'cancelled') + self.assertEqual(response.json['data'][1]['status'], u'unsuccessful') + self.assertEqual(response.json['data'][2]['status'], u'pending.payment') + pending_award = response.json['data'][2] + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + contract = response.json['data']['contracts'][0] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'complete') + +def migrate_cancelled_unsuccessful_cancelled_pending_to_unsuccessful(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + unsuccessful_award = deepcopy(pending_award) + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + cancelled_award = deepcopy(unsuccessful_award) + cancelled_award['id'] = uuid4().hex + cancelled_award['status'] = 'cancelled' + + cancelled_award2 = deepcopy(cancelled_award) + cancelled_award2['bid_id'] = pending_award['bid_id'] = auction['bids'][0]['id'] + + auction['awards'] = [cancelled_award, unsuccessful_award, cancelled_award2, pending_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.qualification') + self.assertEqual(len(auction['awards']), 4) + self.assertEqual(auction['awards'][0]['status'], 'cancelled') + self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][2]['status'], 'cancelled') + self.assertEqual(auction['awards'][3]['status'], 'pending.payment') + self.assertIn('verificationPeriod', auction['awards'][3]) + self.assertIn('paymentPeriod', auction['awards'][3]) + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "active"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'active.awarded') + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']['awards']), 4) + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 4) + self.assertEqual(response.json['data'][0]['status'], u'cancelled') + self.assertEqual(response.json['data'][1]['status'], u'unsuccessful') + self.assertEqual(response.json['data'][2]['status'], u'cancelled') + self.assertEqual(response.json['data'][3]['status'], u'unsuccessful') + +def migrate_cancelled_unsuccessful_cancelled_active_to_unsuccessful(self): + auction = self.db.get(self.auction_id) + + now = get_now() + + active_award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][1]['id'], + 'suppliers': auction['bids'][1]['tenderers'], + 'value': auction['bids'][1]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + unsuccessful_award = deepcopy(active_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + cancelled_award = deepcopy(unsuccessful_award) + cancelled_award['id'] = uuid4().hex + cancelled_award['status'] = 'cancelled' + + cancelled_award2 = deepcopy(cancelled_award) + cancelled_award2['bid_id'] = active_award['bid_id'] = auction['bids'][0]['id'] + + auction['awards'] = [cancelled_award, unsuccessful_award, cancelled_award2, active_award] + + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=7)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=15)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + auction['contracts'] = [{ + 'awardID': active_award['id'], + 'suppliers': active_award['suppliers'], + 'value': active_award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(auction['status'], u'active.awarded') + self.assertEqual(len(auction['awards']), 4) + self.assertEqual(auction['awards'][0]['status'], 'cancelled') + self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][2]['status'], 'cancelled') + self.assertEqual(auction['awards'][3]['status'], 'active') + self.assertIn('verificationPeriod', auction['awards'][3]) + self.assertIn('paymentPeriod', auction['awards'][3]) + self.assertIn('signingPeriod', auction['awards'][3]) + + response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, active_award['id']), {"data": {"status": "unsuccessful"}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']['awards']), 4) + self.assertEqual(response.json['data']['status'], u'unsuccessful') + + response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(len(response.json['data']), 4) + self.assertEqual(response.json['data'][0]['status'], u'cancelled') + self.assertEqual(response.json['data'][1]['status'], u'unsuccessful') + self.assertEqual(response.json['data'][2]['status'], u'cancelled') + self.assertEqual(response.json['data'][3]['status'], u'unsuccessful') + +def migrate_awards_number(self): + auction = self.db.get(self.auction_id) + award_1 = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][0]['id'], + "status": "active", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + award_2 = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][0]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + award_3 = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][1]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + auction['awards'] = [award_1, award_2, award_3] + auction.update(auction) + awards_num = len(auction['awards']) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] + migrated_awards_num = len(auction['awards']) + self.assertEqual(awards_num, migrated_awards_num) + +# MigrateTestFrom1To2WithThreeBids + +def migrate_unsuccessful_unsuccessful_pending(self): + auction = self.db.get(self.auction_id) + + pending_award = { + 'id': uuid4().hex, + "date": get_now().isoformat(), + "bid_id": auction['bids'][0]['id'], + "status": "pending", + "complaintPeriod": { + "startDate": get_now().isoformat(), + } + } + unsuccessful_award = deepcopy(pending_award) + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + + unsuccessful_award2 = deepcopy(unsuccessful_award) + unsuccessful_award['bid_id'] = auction['bids'][2]['id'] + unsuccessful_award2['bid_id'] = auction['bids'][1]['id'] + + auction['awards'] = [unsuccessful_award, unsuccessful_award2, pending_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(auction['status'], u'active.qualification') + self.assertEqual(len(auction['awards']), 3) + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][2]['status'], 'pending.payment') + +def migrate_unsuccessful_unsuccessful_active(self): + auction = self.db.get(self.auction_id) + + now = get_now() + + active_award = { + 'id': uuid4().hex, + "date": now.isoformat(), + "bid_id": auction['bids'][0]['id'], + 'suppliers': auction['bids'][0]['tenderers'], + 'value': auction['bids'][0]['value'], + "status": "active", + "complaintPeriod": { + "startDate": now.isoformat(), + "endDate": now.isoformat() + } + } + unsuccessful_award = deepcopy(active_award) + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + + auction.update({ + "enquiryPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "tenderPeriod": { + "startDate": (now - timedelta(days=8)).isoformat(), + "endDate": (now - timedelta(days=1)).isoformat() + }, + "auctionPeriod": { + "startDate": (now - timedelta(days=1)).isoformat(), + "endDate": (now).isoformat() + }, + "awardPeriod": { + "startDate": (now).isoformat(), + "endDate": (now).isoformat() + } + }) + auction['contracts'] = [{ + 'awardID': active_award['id'], + 'suppliers': active_award['suppliers'], + 'value': active_award['value'], + 'date': now.isoformat(), + 'items': auction['items'], + 'contractID': '{}-11'.format(auction['auctionID'])}] + auction['status'] = 'active.awarded' + + unsuccessful_award = deepcopy(active_award) + unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() + unsuccessful_award['id'] = uuid4().hex + unsuccessful_award['status'] = 'unsuccessful' + + unsuccessful_award2 = deepcopy(unsuccessful_award) + unsuccessful_award['bid_id'] = auction['bids'][2]['id'] + unsuccessful_award2['bid_id'] = auction['bids'][1]['id'] + + auction['awards'] = [unsuccessful_award, unsuccessful_award2, active_award] + + auction.update(auction) + self.db.save(auction) + migrate_data(self.app.app.registry, 1) + + response = self.app.get('/auctions/{}'.format(self.auction_id)) + auction = response.json['data'] + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(auction['status'], u'active.awarded') + self.assertEqual(len(auction['awards']), 3) + self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') + self.assertEqual(auction['awards'][2]['status'], 'active') + self.assertEqual(auction['contracts'][0]['status'], 'pending') diff --git a/openprocurement/auctions/dgf/tests/migration.py b/openprocurement/auctions/dgf/tests/migration.py index 3e770ff3..40f61681 100644 --- a/openprocurement/auctions/dgf/tests/migration.py +++ b/openprocurement/auctions/dgf/tests/migration.py @@ -1,15 +1,37 @@ # -*- coding: utf-8 -*- import unittest -from openprocurement.api.models import get_now - -from openprocurement.auctions.dgf.migration import migrate_data, get_db_schema_version, set_db_schema_version, SCHEMA_VERSION -from openprocurement.auctions.dgf.tests.base import BaseWebTest, BaseAuctionWebTest, test_bids - from datetime import timedelta from uuid import uuid4 from copy import deepcopy +from openprocurement.api.models import get_now +from openprocurement.auctions.core.tests.base import snitch + +from openprocurement.auctions.dgf.migration import migrate_data, get_db_schema_version, set_db_schema_version, SCHEMA_VERSION +from openprocurement.auctions.dgf.tests.base import BaseWebTest, BaseAuctionWebTest, test_bids +from openprocurement.auctions.dgf.tests.blanks.migration_blanks import ( + # MigrateTestFrom1To2Bids + migrate_one_pending, + migrate_one_active, + migrate_unsuccessful_active, + migrate_unsuccessful_pending, + # MigrateTestFrom1To2WithTwoBids + migrate_pending_to_unsuccesful, + migrate_pending_to_complete, + migrate_active_to_unsuccessful, + migrate_active_to_complete, + migrate_cancelled_pending_to_complete, + migrate_unsuccessful_pending_to_complete, + migrate_unsuccessful_active_to_complete, + migrate_cancelled_unsuccessful_pending, + migrate_cancelled_unsuccessful_cancelled_pending_to_unsuccessful, + migrate_cancelled_unsuccessful_cancelled_active_to_unsuccessful, + migrate_awards_number, + # MigrateTestFrom1To2WithThreeBids + migrate_unsuccessful_unsuccessful_pending, + migrate_unsuccessful_unsuccessful_active +) class MigrateTest(BaseWebTest): @@ -26,6 +48,10 @@ def test_migrate(self): class MigrateTestFrom1To2Bids(BaseAuctionWebTest): initial_status = 'active.qualification' initial_bids = test_bids + test_migrate_one_pending = snitch(migrate_one_pending) + test_migrate_one_active = snitch(migrate_one_active) + test_migrate_unsuccessful_active = snitch(migrate_unsuccessful_active) + test_migrate_unsuccessful_pending = snitch(migrate_unsuccessful_pending) def setUp(self): super(MigrateTestFrom1To2Bids, self).setUp() @@ -35,1060 +61,34 @@ def setUp(self): auction['bids'][0]['value']['amount'] = auction['value']['amount'] self.db.save(auction) - def test_migrate_one_pending(self): - auction = self.db.get(self.auction_id) - award = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][1]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - auction['awards'] = [award] - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] - self.assertEqual(len(auction['awards']), 2) - self.assertEqual(auction['awards'][0]['status'], 'pending.payment') - self.assertIn('verificationPeriod', auction['awards'][0]) - self.assertIn('paymentPeriod', auction['awards'][0]) - self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') - self.assertEqual(auction['bids'][0]['status'], 'active') - self.assertEqual(auction['bids'][1]['status'], 'active') - self.assertEqual(auction['status'], 'active.qualification') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.qualification') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - self.assertEqual(response.json['data'][0]['status'], u'pending.payment') - self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') - pending_award = response.json['data'][0] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.qualification') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][1]['status'], u'pending.verification') - - def test_migrate_one_active(self): - auction = self.db.get(self.auction_id) - now = get_now() - award = { - 'id': uuid4().hex, - "date": now.isoformat(), - "bid_id": auction['bids'][1]['id'], - 'suppliers': auction['bids'][1]['tenderers'], - 'value': auction['bids'][1]['value'], - "status": "active", - "complaintPeriod": { - "startDate": now.isoformat(), - "endDate": now.isoformat() - } - } - auction['awards'] = [award] - auction.update({ - "enquiryPeriod": { - "startDate": (now - timedelta(days=15)).isoformat(), - "endDate": (now - timedelta(days=7)).isoformat() - }, - "tenderPeriod": { - "startDate": (now - timedelta(days=15)).isoformat(), - "endDate": (now - timedelta(days=1)).isoformat() - }, - "auctionPeriod": { - "startDate": (now - timedelta(days=1)).isoformat(), - "endDate": (now).isoformat() - }, - "awardPeriod": { - "startDate": (now).isoformat(), - "endDate": (now).isoformat() - } - }) - contract_id = uuid4().hex - auction['contracts'] = [{ - 'awardID': award['id'], - 'id': contract_id, - 'suppliers': award['suppliers'], - 'value': award['value'], - 'date': now.isoformat(), - 'items': auction['items'], - 'contractID': '{}-11'.format(auction['auctionID'])}] - auction['status'] = 'active.awarded' - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] - self.assertEqual(len(auction['awards']), 2) - self.assertEqual(auction['awards'][0]['status'], 'active') - self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') - self.assertIn('verificationPeriod', auction['awards'][0]) - self.assertIn('paymentPeriod', auction['awards'][0]) - self.assertIn('signingPeriod', auction['awards'][0]) - self.assertEqual(auction['bids'][0]['status'], 'active') - self.assertEqual(auction['bids'][1]['status'], 'active') - self.assertEqual(auction['contracts'][0]['status'], 'pending') - self.assertEqual(auction['status'], 'active.awarded') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - self.assertEqual(response.json['data'][0]['status'], u'active') - self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') - active_award = response.json['data'][0] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, active_award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.qualification') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][1]['status'], u'pending.verification') - - def test_migrate_unsuccessful_pending(self): - auction = self.db.get(self.auction_id) - - pending_award = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][1]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - unsuccessful_award = deepcopy(pending_award) - unsuccessful_award['id'] = uuid4().hex - unsuccessful_award['status'] = 'unsuccessful' - unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() - pending_award['bid_id'] = auction['bids'][0]['id'] - auction['awards'] = [unsuccessful_award, pending_award] - auction.update(auction) - - self.db.save(auction) - - migrate_data(self.app.app.registry, 1) - auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] - self.assertEqual(len(auction['awards']), 2) - self.assertEqual(auction['bids'][0]['status'], 'active') - self.assertEqual(auction['bids'][1]['status'], 'active') - self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][1]['status'], 'pending.payment') - self.assertEqual(auction['status'], 'active.qualification') - - def test_migrate_unsuccessful_active(self): - auction = self.db.get(self.auction_id) - - now = get_now() - - active_award = { - 'id': uuid4().hex, - "date": now.isoformat(), - "bid_id": auction['bids'][1]['id'], - 'suppliers': auction['bids'][1]['tenderers'], - 'value': auction['bids'][1]['value'], - "status": "active", - "complaintPeriod": { - "startDate": now.isoformat(), - "endDate": now.isoformat() - } - } - unsuccessful_award = deepcopy(active_award) - unsuccessful_award['id'] = uuid4().hex - unsuccessful_award['status'] = 'unsuccessful' - active_award['bid_id'] = auction['bids'][0]['id'] - - auction['awards'] = [unsuccessful_award, active_award] - - auction.update({ - "enquiryPeriod": { - "startDate": (now - timedelta(days=8)).isoformat(), - "endDate": (now - timedelta(days=1)).isoformat() - }, - "tenderPeriod": { - "startDate": (now - timedelta(days=8)).isoformat(), - "endDate": (now - timedelta(days=1)).isoformat() - }, - "auctionPeriod": { - "startDate": (now - timedelta(days=1)).isoformat(), - "endDate": (now).isoformat() - }, - "awardPeriod": { - "startDate": (now).isoformat(), - "endDate": (now).isoformat() - } - }) - auction['contracts'] = [{ - 'awardID': active_award['id'], - 'suppliers': active_award['suppliers'], - 'value': active_award['value'], - 'date': now.isoformat(), - 'items': auction['items'], - 'contractID': '{}-11'.format(auction['auctionID'])}] - auction['status'] = 'active.awarded' - - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - - auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] - self.assertEqual(len(auction['awards']), 2) - self.assertEqual(auction['bids'][0]['status'], 'active') - self.assertEqual(auction['bids'][1]['status'], 'active') - self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][1]['status'], 'active') - self.assertEqual(auction['contracts'][0]['status'], 'pending') - self.assertEqual(auction['status'], 'active.awarded') - class MigrateTestFrom1To2WithTwoBids(BaseAuctionWebTest): initial_status = 'active.qualification' initial_bids = test_bids + test_migrate_pending_to_unsuccesful = snitch(migrate_pending_to_unsuccesful) + test_migrate_pending_to_complete = snitch(migrate_pending_to_complete) + test_migrate_active_to_unsuccessful= snitch(migrate_active_to_unsuccessful) + test_migrate_active_to_complete = snitch(migrate_active_to_complete) + test_migrate_cancelled_pending_to_complete = snitch(migrate_cancelled_pending_to_complete) + test_migrate_unsuccessful_pending_to_complete = snitch(migrate_unsuccessful_pending_to_complete) + test_migrate_unsuccessful_active_to_complete = snitch(migrate_unsuccessful_active_to_complete) + test_migrate_cancelled_unsuccessful_pending = snitch(migrate_cancelled_unsuccessful_pending) + test_migrate_cancelled_unsuccessful_cancelled_pending_to_unsuccessful = snitch(migrate_cancelled_unsuccessful_cancelled_pending_to_unsuccessful) + test_migrate_cancelled_unsuccessful_cancelled_active_to_unsuccessful = snitch(migrate_cancelled_unsuccessful_cancelled_active_to_unsuccessful) + test_migrate_awards_number = snitch(migrate_awards_number) + def setUp(self): super(MigrateTestFrom1To2WithTwoBids, self).setUp() migrate_data(self.app.app.registry) set_db_schema_version(self.db, 0) - def test_migrate_pending_to_unsuccesful(self): - auction = self.db.get(self.auction_id) - award = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][1]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - auction['awards'] = [award] - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] - self.assertEqual(len(auction['awards']), 2) - self.assertEqual(auction['awards'][0]['status'], 'pending.payment') - self.assertIn('verificationPeriod', auction['awards'][0]) - self.assertIn('paymentPeriod', auction['awards'][0]) - self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.qualification') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - self.assertEqual(response.json['data'][0]['status'], u'pending.payment') - self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') - pending_award = response.json['data'][0] - waiting_award = response.json['data'][1] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - def test_migrate_pending_to_complete(self): - auction = self.db.get(self.auction_id) - award = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][1]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - auction['awards'] = [award] - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] - self.assertEqual(len(auction['awards']), 2) - self.assertEqual(auction['awards'][0]['status'], 'pending.payment') - self.assertIn('verificationPeriod', auction['awards'][0]) - self.assertIn('paymentPeriod', auction['awards'][0]) - self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.qualification') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - self.assertEqual(response.json['data'][0]['status'], u'pending.payment') - self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') - pending_award = response.json['data'][0] - waiting_award = response.json['data'][1] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( - self.auction_id, waiting_award['id'], self.auction_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - - response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, waiting_award['id'], doc_id, self.auction_token), {"data": { - "description": "auction protocol", - "documentType": 'auctionProtocol' - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "pending.payment"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'pending.payment') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - contract = response.json['data']['contracts'][0] - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'complete') - - def test_migrate_active_to_unsuccessful(self): - auction = self.db.get(self.auction_id) - now = get_now() - award = { - 'id': uuid4().hex, - "date": now.isoformat(), - "bid_id": auction['bids'][1]['id'], - 'suppliers': auction['bids'][1]['tenderers'], - 'value': auction['bids'][1]['value'], - "status": "active", - "complaintPeriod": { - "startDate": now.isoformat(), - "endDate": now.isoformat() - } - } - auction['awards'] = [award] - auction.update({ - "enquiryPeriod": { - "startDate": (now - timedelta(days=15)).isoformat(), - "endDate": (now - timedelta(days=7)).isoformat() - }, - "tenderPeriod": { - "startDate": (now - timedelta(days=15)).isoformat(), - "endDate": (now - timedelta(days=1)).isoformat() - }, - "auctionPeriod": { - "startDate": (now - timedelta(days=1)).isoformat(), - "endDate": (now).isoformat() - }, - "awardPeriod": { - "startDate": (now).isoformat(), - "endDate": (now).isoformat() - } - }) - contract_id = uuid4().hex - auction['contracts'] = [{ - 'awardID': award['id'], - 'id': contract_id, - 'suppliers': award['suppliers'], - 'value': award['value'], - 'date': now.isoformat(), - 'items': auction['items'], - 'contractID': '{}-11'.format(auction['auctionID'])}] - auction['status'] = 'active.awarded' - auction.update(auction) - self.db.save(auction) - - migrate_data(self.app.app.registry, 1) - auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] - self.assertEqual(len(auction['awards']), 2) - self.assertEqual(auction['awards'][0]['status'], 'active') - self.assertIn('verificationPeriod', auction['awards'][0]) - self.assertIn('paymentPeriod', auction['awards'][0]) - self.assertIn('signingPeriod', auction['awards'][0]) - self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - self.assertEqual(response.json['data'][0]['status'], u'active') - self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') - active_award = response.json['data'][0] - waiting_award = response.json['data'][1] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, active_award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - def test_migrate_active_to_complete(self): - auction = self.db.get(self.auction_id) - now = get_now() - award = { - 'id': uuid4().hex, - "date": now.isoformat(), - "bid_id": auction['bids'][1]['id'], - 'suppliers': auction['bids'][1]['tenderers'], - 'value': auction['bids'][1]['value'], - "status": "active", - "complaintPeriod": { - "startDate": now.isoformat(), - "endDate": now.isoformat() - } - } - auction['awards'] = [award] - auction.update({ - "enquiryPeriod": { - "startDate": (now - timedelta(days=15)).isoformat(), - "endDate": (now - timedelta(days=7)).isoformat() - }, - "tenderPeriod": { - "startDate": (now - timedelta(days=15)).isoformat(), - "endDate": (now - timedelta(days=1)).isoformat() - }, - "auctionPeriod": { - "startDate": (now - timedelta(days=1)).isoformat(), - "endDate": (now).isoformat() - }, - "awardPeriod": { - "startDate": (now).isoformat(), - "endDate": (now).isoformat() - } - }) - contract_id = uuid4().hex - auction['contracts'] = [{ - 'awardID': award['id'], - 'id': contract_id, - 'suppliers': award['suppliers'], - 'value': award['value'], - 'date': now.isoformat(), - 'items': auction['items'], - 'contractID': '{}-11'.format(auction['auctionID'])}] - auction['status'] = 'active.awarded' - auction.update(auction) - self.db.save(auction) - - migrate_data(self.app.app.registry, 1) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - auction = response.json['data'] - self.assertEqual(len(auction['awards']), 2) - self.assertEqual(auction['awards'][0]['status'], 'active') - self.assertIn('verificationPeriod', auction['awards'][0]) - self.assertIn('paymentPeriod', auction['awards'][0]) - self.assertIn('signingPeriod', auction['awards'][0]) - self.assertEqual(auction['awards'][1]['status'], 'pending.waiting') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(auction['status'], u'active.awarded') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - self.assertEqual(response.json['data'][0]['status'], u'active') - self.assertEqual(response.json['data'][1]['status'], u'pending.waiting') - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract_id), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'complete') - - def test_migrate_cancelled_pending_to_complete(self): - auction = self.db.get(self.auction_id) - - pending_award = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][1]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - cancelled_award = deepcopy(pending_award) - cancelled_award['id'] = uuid4().hex - cancelled_award['status'] = 'cancelled' - cancelled_award['complaintPeriod']['endDate'] = get_now().isoformat() - auction['awards'] = [cancelled_award, pending_award] - - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - auction = response.json['data'] - self.assertEqual(auction['status'], u'active.qualification') - self.assertEqual(len(auction['awards']), 3) - self.assertEqual(auction['awards'][0]['status'], 'cancelled') - self.assertEqual(auction['awards'][1]['status'], 'pending.payment') - self.assertIn('verificationPeriod', auction['awards'][1]) - self.assertIn('paymentPeriod', auction['awards'][1]) - self.assertIn('signingPeriod', auction['awards'][1]) - self.assertEqual(auction['awards'][2]['status'], 'pending.waiting') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(response.json['data'][0]['status'], u'cancelled') - self.assertEqual(response.json['data'][1]['status'], u'pending.payment') - self.assertEqual(response.json['data'][2]['status'], u'pending.waiting') - pending_award = response.json['data'][1] - waiting_award = response.json['data'][2] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( - self.auction_id, waiting_award['id'], self.auction_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - - response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, waiting_award['id'], doc_id, self.auction_token), {"data": { - "description": "auction protocol", - "documentType": 'auctionProtocol' - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "pending.payment"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'pending.payment') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, waiting_award['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - contract = response.json['data']['contracts'][0] - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'complete') - - def test_migrate_unsuccessful_pending_to_complete(self): - auction = self.db.get(self.auction_id) - - pending_award = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][0]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - unsuccessful_award = deepcopy(pending_award) - unsuccessful_award['id'] = uuid4().hex - unsuccessful_award['status'] = 'unsuccessful' - unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() - pending_award['bid_id'] = auction['bids'][1]['id'] - auction['awards'] = [unsuccessful_award, pending_award] - - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - auction = response.json['data'] - self.assertEqual(auction['status'], u'active.qualification') - self.assertEqual(len(auction['awards']), 2) - self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][1]['status'], 'pending.payment') - self.assertIn('verificationPeriod', auction['awards'][1]) - self.assertIn('paymentPeriod', auction['awards'][1]) - self.assertIn('signingPeriod', auction['awards'][1]) - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - self.assertEqual(response.json['data'][0]['status'], u'unsuccessful') - self.assertEqual(response.json['data'][1]['status'], u'pending.payment') - pending_award = response.json['data'][1] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - contract = response.json['data']['contracts'][0] - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'complete') - - def test_migrate_unsuccessful_active_to_complete(self): - auction = self.db.get(self.auction_id) - - now = get_now() - - active_award = { - 'id': uuid4().hex, - "date": now.isoformat(), - "bid_id": auction['bids'][0]['id'], - 'suppliers': auction['bids'][0]['tenderers'], - 'value': auction['bids'][0]['value'], - "status": "active", - "complaintPeriod": { - "startDate": now.isoformat(), - "endDate": now.isoformat() - } - } - unsuccessful_award = deepcopy(active_award) - unsuccessful_award['id'] = uuid4().hex - unsuccessful_award['status'] = 'unsuccessful' - active_award['bid_id'] = auction['bids'][1]['id'] - - auction['awards'] = [unsuccessful_award, active_award] - - auction.update({ - "enquiryPeriod": { - "startDate": (now - timedelta(days=15)).isoformat(), - "endDate": (now - timedelta(days=9)).isoformat() - }, - "tenderPeriod": { - "startDate": (now - timedelta(days=15)).isoformat(), - "endDate": (now - timedelta(days=1)).isoformat() - }, - "auctionPeriod": { - "startDate": (now - timedelta(days=1)).isoformat(), - "endDate": (now).isoformat() - }, - "awardPeriod": { - "startDate": (now).isoformat(), - "endDate": (now).isoformat() - } - }) - auction['contracts'] = [{ - 'awardID': active_award['id'], - 'suppliers': active_award['suppliers'], - 'value': active_award['value'], - 'date': now.isoformat(), - 'items': auction['items'], - 'contractID': '{}-11'.format(auction['auctionID'])}] - auction['status'] = 'active.awarded' - - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - auction = response.json['data'] - self.assertEqual(auction['status'], u'active.awarded') - self.assertEqual(len(auction['awards']), 2) - self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][1]['status'], 'active') - self.assertIn('verificationPeriod', auction['awards'][1]) - self.assertIn('paymentPeriod', auction['awards'][1]) - self.assertIn('signingPeriod', auction['awards'][1]) - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - self.assertEqual(response.json['data'][0]['status'], u'unsuccessful') - self.assertEqual(response.json['data'][1]['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - contract = response.json['data']['contracts'][0] - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'complete') - - def test_migrate_cancelled_unsuccessful_pending(self): - auction = self.db.get(self.auction_id) - - pending_award = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][1]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - unsuccessful_award = deepcopy(pending_award) - unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() - unsuccessful_award['id'] = uuid4().hex - unsuccessful_award['status'] = 'unsuccessful' - cancelled_award = deepcopy(unsuccessful_award) - cancelled_award['id'] = uuid4().hex - cancelled_award['status'] = 'cancelled' - - pending_award['bid_id'] = auction['bids'][0]['id'] - - auction['awards'] = [cancelled_award, unsuccessful_award, pending_award] - - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - auction = response.json['data'] - self.assertEqual(auction['status'], u'active.qualification') - self.assertEqual(len(auction['awards']), 3) - self.assertEqual(auction['awards'][0]['status'], 'cancelled') - self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][2]['status'], 'pending.payment') - self.assertIn('verificationPeriod', auction['awards'][2]) - self.assertIn('paymentPeriod', auction['awards'][2]) - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(response.json['data'][0]['status'], u'cancelled') - self.assertEqual(response.json['data'][1]['status'], u'unsuccessful') - self.assertEqual(response.json['data'][2]['status'], u'pending.payment') - pending_award = response.json['data'][2] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - contract = response.json['data']['contracts'][0] - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'complete') - - def test_migrate_cancelled_unsuccessful_cancelled_pending_to_unsuccessful(self): - auction = self.db.get(self.auction_id) - - pending_award = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][1]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - unsuccessful_award = deepcopy(pending_award) - unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() - unsuccessful_award['id'] = uuid4().hex - unsuccessful_award['status'] = 'unsuccessful' - cancelled_award = deepcopy(unsuccessful_award) - cancelled_award['id'] = uuid4().hex - cancelled_award['status'] = 'cancelled' - - cancelled_award2 = deepcopy(cancelled_award) - cancelled_award2['bid_id'] = pending_award['bid_id'] = auction['bids'][0]['id'] - - auction['awards'] = [cancelled_award, unsuccessful_award, cancelled_award2, pending_award] - - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - auction = response.json['data'] - self.assertEqual(auction['status'], u'active.qualification') - self.assertEqual(len(auction['awards']), 4) - self.assertEqual(auction['awards'][0]['status'], 'cancelled') - self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][2]['status'], 'cancelled') - self.assertEqual(auction['awards'][3]['status'], 'pending.payment') - self.assertIn('verificationPeriod', auction['awards'][3]) - self.assertIn('paymentPeriod', auction['awards'][3]) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, pending_award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']['awards']), 4) - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 4) - self.assertEqual(response.json['data'][0]['status'], u'cancelled') - self.assertEqual(response.json['data'][1]['status'], u'unsuccessful') - self.assertEqual(response.json['data'][2]['status'], u'cancelled') - self.assertEqual(response.json['data'][3]['status'], u'unsuccessful') - - def test_migrate_cancelled_unsuccessful_cancelled_active_to_unsuccessful(self): - auction = self.db.get(self.auction_id) - - now = get_now() - - active_award = { - 'id': uuid4().hex, - "date": now.isoformat(), - "bid_id": auction['bids'][1]['id'], - 'suppliers': auction['bids'][1]['tenderers'], - 'value': auction['bids'][1]['value'], - "status": "active", - "complaintPeriod": { - "startDate": now.isoformat(), - "endDate": now.isoformat() - } - } - unsuccessful_award = deepcopy(active_award) - unsuccessful_award['id'] = uuid4().hex - unsuccessful_award['status'] = 'unsuccessful' - cancelled_award = deepcopy(unsuccessful_award) - cancelled_award['id'] = uuid4().hex - cancelled_award['status'] = 'cancelled' - - cancelled_award2 = deepcopy(cancelled_award) - cancelled_award2['bid_id'] = active_award['bid_id'] = auction['bids'][0]['id'] - - auction['awards'] = [cancelled_award, unsuccessful_award, cancelled_award2, active_award] - - auction.update({ - "enquiryPeriod": { - "startDate": (now - timedelta(days=15)).isoformat(), - "endDate": (now - timedelta(days=7)).isoformat() - }, - "tenderPeriod": { - "startDate": (now - timedelta(days=15)).isoformat(), - "endDate": (now - timedelta(days=1)).isoformat() - }, - "auctionPeriod": { - "startDate": (now - timedelta(days=1)).isoformat(), - "endDate": (now).isoformat() - }, - "awardPeriod": { - "startDate": (now).isoformat(), - "endDate": (now).isoformat() - } - }) - auction['contracts'] = [{ - 'awardID': active_award['id'], - 'suppliers': active_award['suppliers'], - 'value': active_award['value'], - 'date': now.isoformat(), - 'items': auction['items'], - 'contractID': '{}-11'.format(auction['auctionID'])}] - auction['status'] = 'active.awarded' - - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - auction = response.json['data'] - self.assertEqual(auction['status'], u'active.awarded') - self.assertEqual(len(auction['awards']), 4) - self.assertEqual(auction['awards'][0]['status'], 'cancelled') - self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][2]['status'], 'cancelled') - self.assertEqual(auction['awards'][3]['status'], 'active') - self.assertIn('verificationPeriod', auction['awards'][3]) - self.assertIn('paymentPeriod', auction['awards'][3]) - self.assertIn('signingPeriod', auction['awards'][3]) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, active_award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']['awards']), 4) - self.assertEqual(response.json['data']['status'], u'unsuccessful') - - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 4) - self.assertEqual(response.json['data'][0]['status'], u'cancelled') - self.assertEqual(response.json['data'][1]['status'], u'unsuccessful') - self.assertEqual(response.json['data'][2]['status'], u'cancelled') - self.assertEqual(response.json['data'][3]['status'], u'unsuccessful') - - def test_migrate_awards_number(self): - auction = self.db.get(self.auction_id) - award_1 = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][0]['id'], - "status": "active", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - award_2 = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][0]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - award_3 = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][1]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - auction['awards'] = [award_1, award_2, award_3] - auction.update(auction) - awards_num = len(auction['awards']) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - auction = self.app.get('/auctions/{}'.format(self.auction_id)).json['data'] - migrated_awards_num = len(auction['awards']) - self.assertEqual(awards_num, migrated_awards_num) - class MigrateTestFrom1To2WithThreeBids(BaseAuctionWebTest): initial_status = 'active.qualification' initial_bids = test_bids + test_migrate_unsuccessful_unsuccessful_pending = snitch(migrate_unsuccessful_unsuccessful_pending) + test_migrate_unsuccessful_unsuccessful_active = snitch(migrate_unsuccessful_unsuccessful_active) def setUp(self): super(MigrateTestFrom1To2WithThreeBids, self).setUp() @@ -1099,117 +99,6 @@ def setUp(self): auction['bids'][-1]['id'] = uuid4().hex self.db.save(auction) - def test_migrate_unsuccessful_unsuccessful_pending(self): - auction = self.db.get(self.auction_id) - - pending_award = { - 'id': uuid4().hex, - "date": get_now().isoformat(), - "bid_id": auction['bids'][0]['id'], - "status": "pending", - "complaintPeriod": { - "startDate": get_now().isoformat(), - } - } - unsuccessful_award = deepcopy(pending_award) - unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() - unsuccessful_award['id'] = uuid4().hex - unsuccessful_award['status'] = 'unsuccessful' - - unsuccessful_award2 = deepcopy(unsuccessful_award) - unsuccessful_award['bid_id'] = auction['bids'][2]['id'] - unsuccessful_award2['bid_id'] = auction['bids'][1]['id'] - - auction['awards'] = [unsuccessful_award, unsuccessful_award2, pending_award] - - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - auction = response.json['data'] - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(auction['status'], u'active.qualification') - self.assertEqual(len(auction['awards']), 3) - self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][2]['status'], 'pending.payment') - - def test_migrate_unsuccessful_unsuccessful_active(self): - auction = self.db.get(self.auction_id) - - now = get_now() - - active_award = { - 'id': uuid4().hex, - "date": now.isoformat(), - "bid_id": auction['bids'][0]['id'], - 'suppliers': auction['bids'][0]['tenderers'], - 'value': auction['bids'][0]['value'], - "status": "active", - "complaintPeriod": { - "startDate": now.isoformat(), - "endDate": now.isoformat() - } - } - unsuccessful_award = deepcopy(active_award) - unsuccessful_award['id'] = uuid4().hex - unsuccessful_award['status'] = 'unsuccessful' - - auction.update({ - "enquiryPeriod": { - "startDate": (now - timedelta(days=8)).isoformat(), - "endDate": (now - timedelta(days=1)).isoformat() - }, - "tenderPeriod": { - "startDate": (now - timedelta(days=8)).isoformat(), - "endDate": (now - timedelta(days=1)).isoformat() - }, - "auctionPeriod": { - "startDate": (now - timedelta(days=1)).isoformat(), - "endDate": (now).isoformat() - }, - "awardPeriod": { - "startDate": (now).isoformat(), - "endDate": (now).isoformat() - } - }) - auction['contracts'] = [{ - 'awardID': active_award['id'], - 'suppliers': active_award['suppliers'], - 'value': active_award['value'], - 'date': now.isoformat(), - 'items': auction['items'], - 'contractID': '{}-11'.format(auction['auctionID'])}] - auction['status'] = 'active.awarded' - - unsuccessful_award = deepcopy(active_award) - unsuccessful_award['complaintPeriod']['endDate'] = get_now().isoformat() - unsuccessful_award['id'] = uuid4().hex - unsuccessful_award['status'] = 'unsuccessful' - - unsuccessful_award2 = deepcopy(unsuccessful_award) - unsuccessful_award['bid_id'] = auction['bids'][2]['id'] - unsuccessful_award2['bid_id'] = auction['bids'][1]['id'] - - auction['awards'] = [unsuccessful_award, unsuccessful_award2, active_award] - - auction.update(auction) - self.db.save(auction) - migrate_data(self.app.app.registry, 1) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - auction = response.json['data'] - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(auction['status'], u'active.awarded') - self.assertEqual(len(auction['awards']), 3) - self.assertEqual(auction['awards'][0]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][1]['status'], 'unsuccessful') - self.assertEqual(auction['awards'][2]['status'], 'active') - self.assertEqual(auction['contracts'][0]['status'], 'pending') - def suite(): suite = unittest.TestSuite() From 0feb4cef4337604ab011af9ecfd7442ec775eb93 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 18:59:40 +0200 Subject: [PATCH 29/45] Use mixins for question tests --- .../auctions/dgf/tests/question.py | 355 +----------------- 1 file changed, 13 insertions(+), 342 deletions(-) diff --git a/openprocurement/auctions/dgf/tests/question.py b/openprocurement/auctions/dgf/tests/question.py index 445ff2ef..c45254b2 100644 --- a/openprocurement/auctions/dgf/tests/question.py +++ b/openprocurement/auctions/dgf/tests/question.py @@ -1,357 +1,28 @@ # -*- coding: utf-8 -*- import unittest -from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_lots, test_financial_auction_data, test_financial_organization - - -class AuctionQuestionResourceTest(BaseAuctionWebTest): - - def test_create_auction_question_invalid(self): - response = self.app.post_json('/auctions/some_id/questions', { - 'data': {'title': 'question title', 'description': 'question description', 'author': self.initial_organization}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'auction_id'} - ]) - - request_path = '/auctions/{}/questions'.format(self.auction_id) - - response = self.app.post(request_path, 'data', status=415) - self.assertEqual(response.status, '415 Unsupported Media Type') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': - u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} - ]) - - response = self.app.post( - request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, 'data', 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json( - request_path, {'not_data': {}}, 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'data': {}}, 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'This field is required.'], u'location': u'body', u'name': u'title'}, - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'author'}, - ]) - - response = self.app.post_json(request_path, {'data': { - 'invalid_field': 'invalid_value'}}, 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'Rogue field', u'location': - u'body', u'name': u'invalid_field'} - ]) - - response = self.app.post_json(request_path, { - 'data': {'author': {'identifier': 'invalid_value'}}}, 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'identifier': [u'Please use a mapping for this field or Identifier instance instead of unicode.']}, u'location': u'body', u'name': u'author'} - ]) - - response = self.app.post_json(request_path, { - 'data': {'title': 'question title', 'description': 'question description', 'author': {'identifier': {}}}}, 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'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.']}, u'name': [u'This field is required.'], u'address': [u'This field is required.']}, u'location': u'body', u'name': u'author'} - ]) - - response = self.app.post_json(request_path, {'data': {'title': 'question title', 'description': 'question description', 'author': { - 'name': 'name', 'identifier': {'uri': 'invalid_value'}}}}, 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'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.'], u'uri': [u'Not a well formed URL.']}, u'address': [u'This field is required.']}, u'location': u'body', u'name': u'author'} - ]) - - response = self.app.post_json('/auctions/{}/questions'.format(self.auction_id), {'data': { - 'title': 'question title', - 'description': 'question description', - 'author': self.initial_organization, - "questionOf": "lot" - }}, 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'This field is required.'], u'location': u'body', u'name': u'relatedItem'} - ]) - - response = self.app.post_json('/auctions/{}/questions'.format(self.auction_id), {'data': { - 'title': 'question title', - 'description': 'question description', - 'author': self.initial_organization, - "questionOf": "lot", - "relatedItem": '0' * 32 - }}, 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'relatedItem should be one of lots'], u'location': u'body', u'name': u'relatedItem'} - ]) - - response = self.app.post_json('/auctions/{}/questions'.format(self.auction_id), {'data': { - 'title': 'question title', - 'description': 'question description', - 'author': self.initial_organization, - "questionOf": "item", - "relatedItem": '0' * 32 - }}, 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'relatedItem should be one of items'], u'location': u'body', u'name': u'relatedItem'} - ]) - - def test_create_auction_question(self): - response = self.app.post_json('/auctions/{}/questions'.format( - self.auction_id), {'data': {'title': 'question title', 'description': 'question description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - question = response.json['data'] - self.assertEqual(question['author']['name'], self.initial_organization['name']) - self.assertIn('id', question) - self.assertIn(question['id'], response.headers['Location']) - - self.set_status('active.auction') - - response = self.app.post_json('/auctions/{}/questions'.format( - self.auction_id), {'data': {'title': 'question title', 'description': 'question description', 'author': self.initial_organization}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add question only in enquiryPeriod") - - def test_patch_auction_question(self): - response = self.app.post_json('/auctions/{}/questions'.format( - self.auction_id), {'data': {'title': 'question title', 'description': 'question description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - question = response.json['data'] - - response = self.app.patch_json('/auctions/{}/questions/{}'.format(self.auction_id, question['id']), {"data": {"answer": "answer"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["answer"], "answer") +from openprocurement.auctions.core.tests.question import ( + AuctionQuestionResourceTestMixin +) +from openprocurement.auctions.core.tests.blanks.question_blanks import ( + create_auction_question_lot, + patch_auction_question_lot +) +from openprocurement.auctions.core.tests.base import snitch - response = self.app.patch_json('/auctions/{}/questions/some_id'.format(self.auction_id), {"data": {"answer": "answer"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'question_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/questions/some_id', {"data": {"answer": "answer"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/questions/{}'.format(self.auction_id, question['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["answer"], "answer") - - self.set_status('active.auction') - - response = self.app.patch_json('/auctions/{}/questions/{}'.format(self.auction_id, question['id']), {"data": {"answer": "answer"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update question in current (active.auction) auction status") - - def test_get_auction_question(self): - response = self.app.post_json('/auctions/{}/questions'.format( - self.auction_id), {'data': {'title': 'question title', 'description': 'question description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - question = response.json['data'] - - response = self.app.get('/auctions/{}/questions/{}'.format(self.auction_id, question['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(set(response.json['data']), set([u'id', u'date', u'title', u'description', u'questionOf'])) - - self.set_status('active.qualification') - - response = self.app.get('/auctions/{}/questions/{}'.format(self.auction_id, question['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], question) - - response = self.app.get('/auctions/{}/questions/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'question_id'} - ]) - - response = self.app.get('/auctions/some_id/questions/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_get_auction_questions(self): - response = self.app.post_json('/auctions/{}/questions'.format( - self.auction_id), {'data': {'title': 'question title', 'description': 'question description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - question = response.json['data'] - - response = self.app.get('/auctions/{}/questions'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(set(response.json['data'][0]), set([u'id', u'date', u'title', u'description', u'questionOf'])) - - self.set_status('active.qualification') +from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_lots, test_financial_auction_data, test_financial_organization - response = self.app.get('/auctions/{}/questions'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][0], question) - response = self.app.get('/auctions/some_id/questions', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) +class AuctionQuestionResourceTest(BaseAuctionWebTest, AuctionQuestionResourceTestMixin): + pass @unittest.skip("option not available") class AuctionLotQuestionResourceTest(BaseAuctionWebTest): initial_lots = 2 * test_lots + create_auction_question_lot = snitch(create_auction_question_lot) + patch_auction_question_lot = snitch(patch_auction_question_lot) - def test_create_auction_question(self): - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.post_json('/auctions/{}/questions'.format(self.auction_id), {'data': { - 'title': 'question title', - 'description': 'question description', - "questionOf": "lot", - "relatedItem": self.initial_lots[0]['id'], - 'author': self.initial_organization - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add question only in active lot status") - - response = self.app.post_json('/auctions/{}/questions'.format(self.auction_id), {'data': { - 'title': 'question title', - 'description': 'question description', - "questionOf": "lot", - "relatedItem": self.initial_lots[1]['id'], - 'author': self.initial_organization - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - question = response.json['data'] - self.assertEqual(question['author']['name'], self.initial_organization['name']) - self.assertIn('id', question) - self.assertIn(question['id'], response.headers['Location']) - - def test_patch_auction_question(self): - response = self.app.post_json('/auctions/{}/questions'.format(self.auction_id), {'data': { - 'title': 'question title', - 'description': 'question description', - "questionOf": "lot", - "relatedItem": self.initial_lots[0]['id'], - 'author': self.initial_organization - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - question = response.json['data'] - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.patch_json('/auctions/{}/questions/{}'.format(self.auction_id, question['id']), {"data": {"answer": "answer"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update question only in active lot status") - - response = self.app.post_json('/auctions/{}/questions'.format(self.auction_id), {'data': { - 'title': 'question title', - 'description': 'question description', - "questionOf": "lot", - "relatedItem": self.initial_lots[1]['id'], - 'author': self.initial_organization - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - question = response.json['data'] - - response = self.app.patch_json('/auctions/{}/questions/{}'.format(self.auction_id, question['id']), {"data": {"answer": "answer"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["answer"], "answer") - - response = self.app.get('/auctions/{}/questions/{}'.format(self.auction_id, question['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["answer"], "answer") class FinancialAuctionQuestionResourceTest(AuctionQuestionResourceTest): From f3d25efc58dfda1d80ee959c644b6b1d2f19c9c6 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 22 Mar 2018 19:00:17 +0200 Subject: [PATCH 30/45] Move tender tests to blanks --- .../dgf/tests/blanks/tender_blanks.py | 1356 +++++++++++ openprocurement/auctions/dgf/tests/tender.py | 2045 +---------------- 2 files changed, 1446 insertions(+), 1955 deletions(-) create mode 100644 openprocurement/auctions/dgf/tests/blanks/tender_blanks.py diff --git a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py new file mode 100644 index 00000000..c8b02473 --- /dev/null +++ b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py @@ -0,0 +1,1356 @@ +# -*- coding: utf-8 -*- +import unittest +from datetime import timedelta, time +from copy import deepcopy +from iso8601 import parse_date + +from openprocurement.auctions.core.constants import ( + DGF_CDB2_CLASSIFICATION_PRECISELY_FROM as CLASSIFICATION_PRECISELY_FROM, + DGF_CDB2_ADDRESS_REQUIRED_FROM as DGF_ADDRESS_REQUIRED_FROM +) +from openprocurement.api.models import get_now, SANDBOX_MODE, TZ +from openprocurement.auctions.dgf.tests.base import ( + test_auction_maximum_data, + test_auction_data, + test_financial_auction_data, + test_organization, + test_financial_organization, + BaseWebTest, + BaseAuctionWebTest, + DEFAULT_ACCELERATION, + test_bids, + test_financial_bids +) +from openprocurement.auctions.dgf.models import ( + DGFOtherAssets, + DGFFinancialAssets, + DGF_ID_REQUIRED_FROM +) +from openprocurement.auctions.dgf.constants import ( + MINIMAL_PERIOD_FROM_RECTIFICATION_END +) + +# AuctionTest + + +def create_role(self): + fields = set([ + 'awardCriteriaDetails', 'awardCriteriaDetails_en', 'awardCriteriaDetails_ru', + 'description', 'description_en', 'description_ru', 'dgfID', 'tenderAttempts', + 'features', 'guarantee', 'hasEnquiries', 'items', 'lots', 'minimalStep', 'mode', + 'procurementMethodRationale', 'procurementMethodRationale_en', 'procurementMethodRationale_ru', + 'procurementMethodType', 'procuringEntity', 'minNumberOfQualifiedBids', + 'submissionMethodDetails', 'submissionMethodDetails_en', 'submissionMethodDetails_ru', + 'title', 'title_en', 'title_ru', 'value', 'auctionPeriod', 'rectificationPeriod' + ]) + if SANDBOX_MODE: + fields.add('procurementMethodDetails') + self.assertEqual(set(self.auction._fields) - self.auction._options.roles['create'].fields, fields) + + +def edit_role(self): + fields = set([ + 'description', 'description_en', 'description_ru', + 'features', 'hasEnquiries', 'items', 'procuringEntity', + 'value', 'minimalStep', 'guarantee', 'tenderAttempts', 'title_en', 'dgfID', 'title_ru', + 'title' + ]) + if SANDBOX_MODE: + fields.add('procurementMethodDetails') + self.assertEqual(set(self.auction._fields) - self.auction._options.roles['edit_active.tendering'].fields, fields) + + +# AuctionResourceTest + + +def create_auction_validation_accelerated(self): + request_path = '/auctions' + now = get_now() + data = self.initial_data.copy() + auction_data = deepcopy(self.initial_data) + if SANDBOX_MODE: + startDate = (now + timedelta(days=8, hours=4) / DEFAULT_ACCELERATION).isoformat() + else: + startDate = (now + timedelta(days=8, hours=4)).isoformat() + auction_data['auctionPeriod'] = {'startDate': startDate} + response = self.app.post_json(request_path, {'data': auction_data}, status=201) + auction = response.json['data'] + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + tender_period_startDate = parse_date(auction['tenderPeriod']['startDate'], None) + if not tender_period_startDate.tzinfo: + tender_period_startDate = TZ.localize(tender_period_startDate) + tender_period_endDate = parse_date(auction['tenderPeriod']['endDate'], None) + if not tender_period_endDate.tzinfo: + tender_period_endDate = TZ.localize(tender_period_endDate) + if SANDBOX_MODE: + self.assertLess((tender_period_endDate - tender_period_startDate), timedelta(days=8, hours=4) / DEFAULT_ACCELERATION) + else: + self.assertLess((tender_period_endDate - tender_period_startDate), timedelta(days=8, hours=4)) + + +def create_auction_invalid(self): + request_path = '/auctions' + response = self.app.post(request_path, 'data', status=415) + self.assertEqual(response.status, '415 Unsupported Media Type') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': + u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} + ]) + + response = self.app.post( + request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, 'data', 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'Data not available', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, {'not_data': {}}, 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'Data not available', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, {'data': []}, 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'Data not available', + u'location': u'body', u'name': u'data'} + ]) + + response = self.app.post_json(request_path, {'data': {'procurementMethodType': 'invalid_value'}}, status=415) + self.assertEqual(response.status, '415 Unsupported Media Type') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertEqual(response.json['errors'], [ + {u'description': u'Not implemented', u'location': u'data', u'name': u'procurementMethodType'} + ]) + + response = self.app.post_json(request_path, {'data': {'invalid_field': 'invalid_value', 'procurementMethodType': self.initial_data['procurementMethodType']}}, 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'Rogue field', u'location': + u'body', u'name': u'invalid_field'} + ]) + + response = self.app.post_json(request_path, {'data': {'value': 'invalid_value', 'procurementMethodType': self.initial_data['procurementMethodType']}}, 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'Please use a mapping for this field or Value instance instead of unicode.'], u'location': u'body', u'name': u'value'} + ]) + + response = self.app.post_json(request_path, {'data': {'procurementMethod': 'invalid_value', 'procurementMethodType': self.initial_data['procurementMethodType']}}, status=422) + self.assertEqual(response.status, '422 Unprocessable Entity') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['status'], 'error') + self.assertIn({u'description': [u"Value must be one of ['open', 'selective', 'limited']."], u'location': u'body', u'name': u'procurementMethod'}, response.json['errors']) + #self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'tenderPeriod'}, response.json['errors']) + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'minimalStep'}, response.json['errors']) + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'items'}, response.json['errors']) + #self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'enquiryPeriod'}, response.json['errors']) + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'value'}, response.json['errors']) + self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'items'}, response.json['errors']) + + response = self.app.post_json(request_path, {'data': {'enquiryPeriod': {'endDate': 'invalid_value'}, 'procurementMethodType': self.initial_data['procurementMethodType']}}, 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'endDate': [u"Could not parse invalid_value. Should be ISO8601."]}, u'location': u'body', u'name': u'enquiryPeriod'} + ]) + + response = self.app.post_json(request_path, {'data': {'enquiryPeriod': {'endDate': '9999-12-31T23:59:59.999999'}, 'procurementMethodType': self.initial_data['procurementMethodType']}}, 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'endDate': [u'date value out of range']}, u'location': u'body', u'name': u'enquiryPeriod'} + ]) + + self.initial_data['tenderPeriod'] = self.initial_data.pop('auctionPeriod') + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data['auctionPeriod'] = self.initial_data.pop('tenderPeriod') + 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 is required.']}, u'location': u'body', u'name': u'auctionPeriod'} + ]) + + self.initial_data['tenderPeriod'] = {'startDate': '2014-10-31T00:00:00', 'endDate': '2014-10-01T00:00:00'} + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data.pop('tenderPeriod') + 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'period should begin before its end']}, u'location': u'body', u'name': u'tenderPeriod'} + ]) + + #data = self.initial_data['tenderPeriod'] + #self.initial_data['tenderPeriod'] = {'startDate': '2014-10-31T00:00:00', 'endDate': '2015-10-01T00:00:00'} + #response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + #self.initial_data['tenderPeriod'] = data + #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'period should begin after enquiryPeriod'], u'location': u'body', u'name': u'tenderPeriod'} + #]) + + now = get_now() + #self.initial_data['awardPeriod'] = {'startDate': now.isoformat(), 'endDate': now.isoformat()} + #response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + #del self.initial_data['awardPeriod'] + #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'period should begin after tenderPeriod'], u'location': u'body', u'name': u'awardPeriod'} + #]) + + data = self.initial_data['auctionPeriod'] + self.initial_data['auctionPeriod'] = {'startDate': (now + timedelta(days=15)).isoformat(), 'endDate': (now + timedelta(days=15)).isoformat()} + self.initial_data['awardPeriod'] = {'startDate': (now + timedelta(days=14)).isoformat(), 'endDate': (now + timedelta(days=14)).isoformat()} + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data['auctionPeriod'] = data + del self.initial_data['awardPeriod'] + 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'period should begin after auctionPeriod'], u'location': u'body', u'name': u'awardPeriod'} + ]) + + auction_data = deepcopy(self.initial_data) + if SANDBOX_MODE: + auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=5) / DEFAULT_ACCELERATION).isoformat()} + else: + auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=5)).isoformat()} + response = self.app.post_json(request_path, {'data': auction_data}, 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'rectificationPeriod.endDate should come at least 5 working days earlier than tenderPeriod.endDate'], u'location': u'body', u'name': u'rectificationPeriod'}, + {u'description': [u'tenderPeriod should be greater than 6 days'], u'location': u'body', u'name': u'tenderPeriod'} + ]) + + if SANDBOX_MODE: + auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=10) / DEFAULT_ACCELERATION).isoformat()} + auction_data['rectificationPeriod'] = {'endDate': (now + timedelta(days=9) / DEFAULT_ACCELERATION).isoformat()} + else: + auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=10)).isoformat()} + auction_data['rectificationPeriod'] = {'endDate': (now + timedelta(days=9)).isoformat()} + response = self.app.post_json(request_path, {'data': auction_data}, 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'rectificationPeriod.endDate should come at least 5 working days earlier than tenderPeriod.endDate'], u'location': u'body', u'name': u'rectificationPeriod'}]) + + data = self.initial_data['minimalStep'] + self.initial_data['minimalStep'] = {'amount': '1000.0'} + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data['minimalStep'] = data + 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'value should be less than value of auction'], u'location': u'body', u'name': u'minimalStep'} + ]) + + data = self.initial_data['minimalStep'] + self.initial_data['minimalStep'] = {'amount': '100.0', 'valueAddedTaxIncluded': False} + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data['minimalStep'] = data + 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'valueAddedTaxIncluded should be identical to valueAddedTaxIncluded of value of auction'], u'location': u'body', u'name': u'minimalStep'} + ]) + + data = self.initial_data['minimalStep'] + self.initial_data['minimalStep'] = {'amount': '100.0', 'currency': "USD"} + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data['minimalStep'] = data + 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'currency should be identical to currency of value of auction'], u'location': u'body', u'name': u'minimalStep'} + ]) + + auction_data = deepcopy(self.initial_data) + auction_data['value'] = {'amount': '100.0', 'currency': "USD"} + auction_data['minimalStep'] = {'amount': '5.0', 'currency': "USD"} + response = self.app.post_json(request_path, {'data': auction_data}, 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'currency should be only UAH'], u'location': u'body', u'name': u'value'} + ]) + + data = self.initial_data["procuringEntity"]["contactPoint"]["telephone"] + del self.initial_data["procuringEntity"]["contactPoint"]["telephone"] + response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) + self.initial_data["procuringEntity"]["contactPoint"]["telephone"] = data + 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'contactPoint': {u'email': [u'telephone or email should be present']}}, u'location': u'body', u'name': u'procuringEntity'} + ]) + + +@unittest.skipIf(get_now() < DGF_ID_REQUIRED_FROM, "Can`t create auction without dgfID only from {}".format(DGF_ID_REQUIRED_FROM)) +def required_dgf_id(self): + data = self.initial_data.copy() + del data['dgfID'] + response = self.app.post_json('/auctions', {'data': data}, 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'], [{"location": "body", "name": "dgfID", "description": ["This field is required."]}]) + + data['dgfID'] = self.initial_data['dgfID'] + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertIn('dgfID', auction) + self.assertEqual(data['dgfID'], auction['dgfID']) + + +@unittest.skipIf(get_now() < DGF_ADDRESS_REQUIRED_FROM, "Can`t create auction without item.address only from {}".format(DGF_ADDRESS_REQUIRED_FROM)) +def required_dgf_item_address(self): + auction_data = deepcopy(self.initial_data) + del auction_data['items'][0]['address'] + + address = { + "countryName": u"Україна", + "postalCode": "79000", + "region": u"м. Київ", + "locality": u"м. Київ", + "streetAddress": u"вул. Банкова 1" + } + + # CAV-PS specific location code test (address is required) + auction_data['items'][0]['classification'] = { + "scheme": u"CAV-PS", + "id": u"04210000-3", + "description": u"Промислова нерухомість" + } + response = self.app.post_json('/auctions', {'data': auction_data}, 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'], [{"location": "body", "name": "items", "description": [{"address": ["This field is required."]}]}]) + + auction_data['items'][0]["address"] = address + + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + + del auction_data['items'][0]['address'] + + # CPV specific location code test (address is required) + auction_data['items'][0]['classification'] = { + "scheme": u"CPV", + "id": u"34965000-9", + "description": u"Всебічно направлений далекомірний радіомаяк" + } + response = self.app.post_json('/auctions', {'data': auction_data}, 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'], [{"location": "body", "name": "items", "description": [{"address": ["This field is required."]}]}]) + + auction_data['items'][0]["address"] = address + + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + + del auction_data['items'][0]["address"] + + # CAV-PS/CPV non specific location code test (address is not required) + auction_data['items'][0]['classification'] = { + "scheme": u"CPV", + "id": u"90470000-2", + "description": u"Послуги з чищення каналізаційних колекторів" + } + item = deepcopy(auction_data['items'][0]) + item['classification'] = { + "scheme": u"CAV-PS", + "id": u"07227000-6", + "description": u"Застава - Інше" + } + auction_data['items'].append(item) + + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + + auction_data['items'][0]["address"] = address + + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + + +def create_auction_auctionPeriod(self): + data = self.initial_data.copy() + #tenderPeriod = data.pop('tenderPeriod') + #data['auctionPeriod'] = {'startDate': tenderPeriod['endDate']} + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertIn('tenderPeriod', auction) + self.assertIn('auctionPeriod', auction) + self.assertNotIn('startDate', auction['auctionPeriod']) + self.assertEqual(parse_date(data['auctionPeriod']['startDate']).date(), parse_date(auction['auctionPeriod']['shouldStartAfter'], TZ).date()) + if SANDBOX_MODE: + auction_startDate = parse_date(data['auctionPeriod']['startDate'], None) + if not auction_startDate.tzinfo: + auction_startDate = TZ.localize(auction_startDate) + tender_endDate = parse_date(auction['tenderPeriod']['endDate'], None) + if not tender_endDate.tzinfo: + tender_endDate = TZ.localize(tender_endDate) + self.assertLessEqual((auction_startDate - tender_endDate).total_seconds(), 70) + else: + self.assertEqual(parse_date(auction['tenderPeriod']['endDate']).date(), parse_date(data['auctionPeriod']['startDate'], TZ).date() - timedelta(days=1)) + self.assertEqual(parse_date(auction['tenderPeriod']['endDate']).time(), time(20, 0)) + + +def create_auction_rectificationPeriod_generated(self): + response = self.app.post_json('/auctions', {'data': self.initial_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + self.assertIn('tenderPeriod', auction) + self.assertIn('enquiryPeriod', auction) + self.assertIn('rectificationPeriod', auction) + self.assertIn('auctionPeriod', auction) + self.assertNotIn('startDate', auction['auctionPeriod']) + self.assertEqual(parse_date(self.initial_data['auctionPeriod']['startDate']).date(), parse_date(auction['auctionPeriod']['shouldStartAfter'], TZ).date()) + timedelta_during_periods_ends = parse_date(auction['tenderPeriod']['endDate']) - parse_date(auction['rectificationPeriod']['endDate']) + if not SANDBOX_MODE: + self.assertEqual(timedelta_during_periods_ends, MINIMAL_PERIOD_FROM_RECTIFICATION_END) + else: + self.assertEqual(timedelta_during_periods_ends, (MINIMAL_PERIOD_FROM_RECTIFICATION_END / DEFAULT_ACCELERATION)) + + +def create_auction_rectificationPeriod_set(self): + now = get_now() + auction_data = deepcopy(self.initial_data) + auction_data['rectificationPeriod'] = {'endDate' : (get_now() + timedelta(days=2)).isoformat()} + auction_data['auctionPeriod'] = {'startDate' : (get_now() + timedelta(days=10)).isoformat()} + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + self.assertIn('rectificationPeriod', auction) + timedelta_during_set_periods_ends = parse_date(auction['tenderPeriod']['endDate']) - parse_date(auction_data['rectificationPeriod']['endDate']) + self.assertGreaterEqual(timedelta_during_set_periods_ends, MINIMAL_PERIOD_FROM_RECTIFICATION_END) + self.assertEqual(timedelta_during_set_periods_ends, parse_date(auction['tenderPeriod']['endDate']) - parse_date(auction['rectificationPeriod']['endDate'])) + + +def create_auction_generated(self): + data = self.initial_data.copy() + #del data['awardPeriod'] + data.update({'id': 'hash', 'doc_id': 'hash2', 'auctionID': 'hash3'}) + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + if 'procurementMethodDetails' in auction: + auction.pop('procurementMethodDetails') + self.assertEqual(set(auction), set([ + u'procurementMethodType', u'id', u'date', u'dateModified', u'auctionID', u'status', u'enquiryPeriod', + u'tenderPeriod', u'minimalStep', u'items', u'value', u'procuringEntity', u'next_check', u'dgfID', + u'procurementMethod', u'awardCriteria', u'submissionMethod', u'title', u'owner', u'auctionPeriod', + u'tenderAttempts', u'rectificationPeriod' + ])) + self.assertNotEqual(data['id'], auction['id']) + self.assertNotEqual(data['doc_id'], auction['id']) + self.assertNotEqual(data['auctionID'], auction['auctionID']) + + +def create_auction(self): + 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": self.initial_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + auction = response.json['data'] + if self.initial_organization == test_financial_organization: + self.assertEqual(set(auction) - set(self.initial_data), set([ + u'id', u'dateModified', u'auctionID', u'date', u'status', u'procurementMethod', u'rectificationPeriod', + u'awardCriteria', u'submissionMethod', u'next_check', u'owner', u'enquiryPeriod', u'tenderPeriod', + u'eligibilityCriteria_en', u'eligibilityCriteria', u'eligibilityCriteria_ru' + ])) + else: + self.assertEqual(set(auction) - set(self.initial_data), set([ + u'id', u'dateModified', u'auctionID', u'date', u'status', u'procurementMethod', u'rectificationPeriod', + u'awardCriteria', u'submissionMethod', u'next_check', u'owner', u'enquiryPeriod', u'tenderPeriod', + ])) + self.assertIn(auction['id'], response.headers['Location']) + + response = self.app.get('/auctions/{}'.format(auction['id'])) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(set(response.json['data']), set(auction)) + self.assertEqual(response.json['data'], auction) + + response = self.app.post_json('/auctions?opt_jsonp=callback', {"data": self.initial_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/javascript') + self.assertIn('callback({"', response.body) + + response = self.app.post_json('/auctions?opt_pretty=1', {"data": self.initial_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + self.assertIn('{\n "', response.body) + + response = self.app.post_json('/auctions', {"data": self.initial_data, "options": {"pretty": True}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + self.assertIn('{\n "', response.body) + + auction_data = deepcopy(self.initial_data) + auction_data['guarantee'] = {"amount": 100500, "currency": "USD"} + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + data = response.json['data'] + self.assertIn('guarantee', data) + self.assertEqual(data['guarantee']['amount'], 100500) + self.assertEqual(data['guarantee']['currency'], "USD") + + +def additionalClassifications(self): + auction_data = deepcopy(self.initial_data) + # CAV-PS classification test + auction_data['items'][0]['classification'] = { + "scheme" : u"CAV-PS", + "id": u"04210000-3", + "description": u"Промислова нерухомість" + } + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + data = response.json['data'] + self.assertEqual(data['items'][0]['classification']['scheme'], 'CAV-PS') + self.assertEqual(data['items'][0]['classification']['id'], '04210000-3') + + # CAV-PS and CPV classification in different items + auction_data = deepcopy(self.initial_data) + item = deepcopy(auction_data['items'][0]) + item['classification'] = { + "scheme" : u"CAV-PS", + "id": u"04210000-3", + "description": u"Промислова нерухомість" + } + auction_data['items'].append(item) + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + data = response.json['data'] + self.assertEqual(data['items'][1]['classification']['scheme'], 'CAV-PS') + self.assertEqual(data['items'][1]['classification']['id'], '04210000-3') + self.assertEqual(data['items'][0]['classification']['scheme'], 'CPV') + self.assertEqual(data['items'][0]['classification']['id'], '66113000-5') + + # Additional Classification + + auction_data['items'][0]['additionalClassifications'] = [{ + "scheme" : u"CPVS", + "id": u"PA01-7", + "description": u"Найм" + }] + response = self.app.post_json('/auctions', {'data': auction_data}, status=201) + data = response.json['data'] + self.assertEqual(data['items'][0]['additionalClassifications'][0]['scheme'], 'CPVS') + self.assertEqual(data['items'][0]['additionalClassifications'][0]['id'], 'PA01-7') + + # CAV-PS classification fail test + auction_data['items'][0]['classification'] = { + "scheme" : u"CAV-PS", + "id": u"07227000-3", # last number is wrong + "description": u"Застава - Інше" + } + response = self.app.post_json('/auctions', {'data': auction_data}, status=422) + self.assertTrue(response.json['errors'][0]['description'][0]['classification']) + + # Bad classification + auction_data['items'][0]['classification'] = { + "scheme" : u"CAE", # wrong scheme + "id": u"07227000-6", + "description": u"Застава - Інше" + } + response = self.app.post_json('/auctions', {'data': auction_data}, status=422) + self.assertEqual(response.json['errors'], [{u'description': [{u'classification': {u'scheme': [u"Value must be one of [u'CPV', u'CAV-PS']."]}}], u'location': u'body', u'name': u'items'}]) + + # Additional Classification wrong id + auction_data['items'][0]['additionalClassifications'] = [{ + "scheme" : u"CPVS", + "id": u"PA01-2", # Wrong ID + "description": u"Найм" + }] + response = self.app.post_json('/auctions', {'data': auction_data}, status=422) + self.assertRegexpMatches(response.json['errors'][0]['description'][0]['additionalClassifications'][0]['id'][0], "Value must be one of*") + + +@unittest.skipIf(get_now() < CLASSIFICATION_PRECISELY_FROM, "Can`t setup precisely classification from {}".format(CLASSIFICATION_PRECISELY_FROM)) +def cavps_cpvs_classifications(self): + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + self.assertEqual(len(response.json['data']), 0) + + data = deepcopy(self.initial_data) + data['guarantee'] = {"amount": 100, "currency": "UAH"} + + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"classification": { + "scheme": u"CPV", + "id": u"19212310-1", + "description": u"Нерухоме майно" + }}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"classification": { + "scheme": u"CPV", + "id": u"03100000-2", + "description": u"Нерухоме майно" + }}]}}, status=422) + self.assertEqual(response.json['errors'], [{u'description': [{u'classification': {u'id': [u'At least CPV classification class (XXXX0000-Y) should be specified more precisely']}}], u'location': u'body', u'name': u'items'}]) + + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"additionalClassifications": [auction['items'][0]["classification"]]}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + +def patch_auction(self): + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + self.assertEqual(len(response.json['data']), 0) + + data = deepcopy(self.initial_data) + data['guarantee'] = {"amount": 100, "currency": "UAH"} + + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + owner_token = response.json['access']['token'] + dateModified = auction.pop('dateModified') + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {'data': {'status': 'cancelled'}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['status'], 'cancelled') + + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'status': 'cancelled'}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['status'], 'cancelled') + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {'data': {'procuringEntity': {'kind': 'defense'}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotIn('kind', response.json['data']['procuringEntity']) + + #response = self.app.patch_json('/auctions/{}'.format( + #auction['id']), {'data': {'tenderPeriod': {'startDate': None}}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + #self.assertNotIn('startDate', response.json['data']['tenderPeriod']) + + #response = self.app.patch_json('/auctions/{}'.format( + #auction['id']), {'data': {'tenderPeriod': {'startDate': auction['enquiryPeriod']['endDate']}}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + #self.assertIn('startDate', response.json['data']['tenderPeriod']) + + response = self.app.patch_json('/auctions/{}'.format( + auction['id']), {'data': {'procurementMethodRationale': 'Open'}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + new_auction = response.json['data'] + new_dateModified = new_auction.pop('dateModified') + new_auction['rectificationPeriod'].pop('invalidationDate') + self.assertEqual(auction, new_auction) + self.assertNotEqual(dateModified, new_dateModified) + + response = self.app.patch_json('/auctions/{}'.format( + auction['id']), {'data': {'dateModified': new_dateModified}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + new_auction2 = response.json['data'] + new_dateModified2 = new_auction2.pop('dateModified') + new_auction2['rectificationPeriod'].pop('invalidationDate') + self.assertEqual(new_auction, new_auction2) + self.assertEqual(new_dateModified, new_dateModified2) + + revisions = self.db.get(auction['id']).get('revisions') + + response = self.app.patch_json('/auctions/{}'.format( + auction['id']), {'data': {'items': [self.initial_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': [{}, self.initial_data['items'][0]]}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + #item0 = response.json['data']['items'][0] + #item1 = response.json['data']['items'][1] + #self.assertNotEqual(item0.pop('id'), item1.pop('id')) + #self.assertEqual(item0, item1) + + #response = self.app.patch_json('/auctions/{}'.format( + #auction['id']), {'data': {'items': [{}]}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + #self.assertEqual(len(response.json['data']['items']), 1) + + #response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"classification": { + #"scheme": u"CAV", + #"id": u"04000000-8", + #"description": u"Нерухоме майно" + #}}]}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + + #response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"additionalClassifications": [auction['items'][0]["classification"]]}]}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + + response = self.app.patch_json('/auctions/{}'.format( + auction['id']), {'data': {'enquiryPeriod': {'endDate': new_dateModified2}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + new_auction = response.json['data'] + self.assertIn('startDate', new_auction['enquiryPeriod']) + + #response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"guarantee": {"amount": 12, "valueAddedTaxIncluded": True}}}, status=422) + #self.assertEqual(response.status, '422 Unprocessable Entity') + #self.assertEqual(response.json['errors'][0], {u'description': {u'valueAddedTaxIncluded': u'Rogue field'}, u'location': u'body', u'name': u'guarantee'}) + + #response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"guarantee": {"amount": 12}}}) + #self.assertEqual(response.status, '200 OK') + #self.assertIn('guarantee', response.json['data']) + #self.assertEqual(response.json['data']['guarantee']['amount'], 12) + #self.assertEqual(response.json['data']['guarantee']['currency'], 'UAH') + + #response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"guarantee": {"currency": "USD"}}}) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.json['data']['guarantee']['currency'], 'USD') + + #response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'status': 'active.auction'}}) + #self.assertEqual(response.status, '200 OK') + + #response = self.app.get('/auctions/{}'.format(auction['id'])) + #self.assertEqual(response.status, '200 OK') + #self.assertEqual(response.content_type, 'application/json') + #self.assertIn('auctionUrl', response.json['data']) + + # Check availability of value, minimalStep, guarantee + response = self.app.get('/auctions/{}'.format(auction['id'])) + self.assertIn('value', response.json['data']) + self.assertIn('guarantee', response.json['data']) + self.assertIn('minimalStep', response.json['data']) + + value = response.json['data']['value'] + + # 422 very low amount + response = self.app.patch_json('/auctions/{}'.format(auction['id']),{'data': {'value': {'amount': auction['value']['amount'] - 80}}}, status=422) + self.assertEqual(response.json['errors'], [{'location': 'body', 'name': 'minimalStep', 'description': [u'value should be less than value of auction']}]) + + auction_data = self.db.get(auction['id']) + auction_data['status'] = 'complete' + self.db.save(auction_data) + + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'status': 'active.auction'}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update auction in current (complete) status") + + +def patch_auction_rectificationPeriod_invalidationDate(self): + + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + self.assertEqual(len(response.json['data']), 0) + + data = deepcopy(self.initial_data) + data['guarantee'] = {"amount": 100, "currency": "UAH"} + + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + self.assertNotIn('invalidationDate', response.json['data']['rectificationPeriod']) + auction = response.json['data'] + owner_token = response.json['access']['token'] + + # patch one of main auction field by auction owner + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"value": {"amount": 120}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertIn('invalidationDate', response.json['data']['rectificationPeriod']) + + +def patch_old_auction_rectificationPeriod_invalidationDate(self): + + response = self.app.get('/auctions') + self.assertEqual(response.status, '200 OK') + self.assertEqual(len(response.json['data']), 0) + + data = deepcopy(self.initial_data) + data['auctionPeriod']['startDate'] = (get_now().date() + timedelta(days=8)).isoformat() + data['guarantee'] = {"amount": 100, "currency": "UAH"} + + response = self.app.post_json('/auctions', {'data': data}) + self.assertEqual(response.status, '201 Created') + self.assertNotIn('invalidationDate', response.json['data']['rectificationPeriod']) + auction = response.json['data'] + owner_token = response.json['access']['token'] + + db_auction = self.db.get(auction['id']) + del db_auction['rectificationPeriod'] + self.db.save(db_auction) + + # patch one of main auction field by auction owner + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"value": {"amount": 120}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertIn('invalidationDate', response.json['data']['rectificationPeriod']) + + +def auction_Administrator_change(self): + response = self.app.post_json('/auctions', {'data': self.initial_data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + + response = self.app.post_json('/auctions/{}/questions'.format(auction['id']), {'data': {'title': 'question title', 'description': 'question description', 'author': self.initial_organization}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + question = response.json['data'] + + authorization = self.app.authorization + self.app.authorization = ('Basic', ('administrator', '')) + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'mode': u'test', 'procuringEntity': {"identifier": {"id": "00000000"}}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['mode'], u'test') + self.assertEqual(response.json['data']["procuringEntity"]["identifier"]["id"], "00000000") + + response = self.app.patch_json('/auctions/{}/questions/{}'.format(auction['id'], question['id']), {"data": {"answer": "answer"}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'], [ + {"location": "url", "name": "role", "description": "Forbidden"} + ]) + self.app.authorization = authorization + + response = self.app.post_json('/auctions', {'data': self.initial_data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + + response = self.app.post_json('/auctions/{}/cancellations'.format(auction['id']), {'data': {'reason': 'cancellation reason', 'status': 'active'}}) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + + self.app.authorization = ('Basic', ('administrator', '')) + response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'mode': u'test'}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['mode'], u'test') + + self.app.authorization = authorization + auction_data = deepcopy(self.initial_data) + auction_data['guarantee'] = {"amount": 100500, "currency": "USD"} + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + + self.app.authorization = ('Basic', ('administrator', '')) + + # Check availability of value, minimalStep, guarantee + + response = self.app.get('/auctions/{}'.format(auction['id'])) + self.assertIn('value', response.json['data']) + self.assertIn('guarantee', response.json['data']) + self.assertIn('minimalStep', response.json['data']) + + # 422 very low amount + response = self.app.patch_json('/auctions/{}'.format(auction['id']),{'data': {'value': {'amount': auction['value']['amount'] - 80}}}, status=422) + self.assertEqual(response.json['errors'], [{'location': 'body', 'name': 'minimalStep', 'description': [u'value should be less than value of auction']}]) + + +# AuctionFieldsEditingTest + + +def patch_auction_denied(self): + + # patch auction during rectificationPeriod + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'value': {'amount': 80}}}, + status=200) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['value']['amount'], 80) + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'minimalStep': {'amount': 20}}}, status=200) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['minimalStep']['amount'], 20) + + self.go_to_rectificationPeriod_end() + + # patch auction after the rectificationPeriod.endDate + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'value': {'amount': 80}}}, + status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertIn(u'Auction can be edited only during the rectification period', + response.json['errors'][0][u'description']) + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'minimalStep': {'amount': 20}}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertIn(u'Auction can be edited only during the rectification period', + response.json['errors'][0][u'description']) + +def patch_auction_during_rectification_period(self): + auction_data = deepcopy(self.initial_maximum_data) + classification_data_edited = { + "scheme": "CAV-PS", + "description": "Edited field", + "id": "06125000-4" + } + unit_data_edited = { + "code": "44617100-0", + "name": "edited item" + } + address_data_edited = auction_data["procuringEntity"]["address"] + response = self.app.post_json('/auctions', {'data': auction_data}) + self.assertEqual(response.status, '201 Created') + auction = response.json['data'] + + for param in ['title', 'title_en', 'title_ru']: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {param: auction[param] + u' EDITED'}}, status=200) + self.assertNotEqual(response.json['data'][param], auction[param]) + self.assertEqual(response.json['data'][param], auction[param] + u' EDITED') + + for param in ['description', 'description_en', 'description_ru']: + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'items': [{param: auction[param] + u' EDITED'}]}}, status=200) + self.assertNotEqual(response.json['data']['items'][0][param], auction['items'][0][param]) + self.assertEqual(response.json['data']['items'][0][param], auction[param] + u' EDITED') + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'items': [{"address": address_data_edited}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['items'][0]['address'], auction['items'][0]['address']) + self.assertEqual(response.json['data']['items'][0]['address'], address_data_edited) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'items': [{"classification": classification_data_edited}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['items'][0]['classification'], auction['items'][0]['classification']) + self.assertEqual(response.json['data']['items'][0]['classification'], classification_data_edited) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'items': [{"unit": unit_data_edited}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['items'][0]['unit'], auction['items'][0]['unit']) + self.assertEqual(response.json['data']['items'][0]['unit'], unit_data_edited) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'items': [{"quantity": auction['items'][0]['quantity'] + 1}]}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['items'][0]['quantity'], auction['items'][0]['quantity']) + self.assertEqual(response.json['data']['items'][0]['quantity'], auction['items'][0]['quantity'] + 1) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'tenderAttempts': auction['tenderAttempts'] + 1}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['tenderAttempts'], auction['tenderAttempts']) + self.assertEqual(response.json['data']['tenderAttempts'], auction['tenderAttempts'] + 1) + + response = self.app.patch_json('/auctions/{}'.format(self.auction_id), + {'data': {'dgfID': auction['dgfID'] + u'EDITED'}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertNotEqual(response.json['data']['dgfID'], auction['dgfID']) + self.assertEqual(response.json['data']['dgfID'], auction['dgfID'] + u'EDITED') + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(self.auction_id, self.auction_token), { + 'data': {'value': {'valueAddedTaxIncluded': False, 'amount': auction['value']['amount']}, + 'minimalStep': {'valueAddedTaxIncluded': False}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['data']['value']['valueAddedTaxIncluded'], False) + self.assertEqual(response.json['data']['minimalStep']['valueAddedTaxIncluded'], False) + + +def invalidate_bids_auction_unsuccessful(self): + + # patch auction already created + + response = self.app.patch_json('/auctions/{}?acc_token={}'.format(self.auction_id, self.auction_token), + {'data': {'value': {'amount': 80}}}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + + # switch to active.auction + + response = self.set_status('active.auction', {'status': self.initial_status}) + 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.content_type, 'application/json') + self.assertEqual(response.json['data']["status"], "unsuccessful") + self.assertNotIn("awards", response.json['data']) + self.assertNotIn("bids", response.json['data']) + + +# AuctionProcessTest + + +def one_valid_bid_auction(self): + self.app.authorization = ('Basic', ('broker', '')) + # empty auctions listing + response = self.app.get('/auctions') + self.assertEqual(response.json['data'], []) + # create auction + + data = deepcopy(self.initial_data) + data['minNumberOfQualifiedBids'] = 1 + + response = self.app.post_json('/auctions', + {"data": data}) + auction_id = self.auction_id = response.json['data']['id'] + owner_token = response.json['access']['token'] + # switch to active.tendering + response = self.set_status('active.tendering', {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}}) + self.assertIn("auctionPeriod", response.json['data']) + # create bid + self.app.authorization = ('Basic', ('broker', '')) + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) + # switch to active.qualification + self.set_status('active.auction', {'status': 'active.tendering'}) + self.app.authorization = ('Basic', ('chronograph', '')) + response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) + self.assertNotIn('auctionPeriod', response.json['data']) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) + # get pending.verification award + award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending.verification'][0] + award_date = [i['date'] for i in response.json['data'] if i['status'] == 'pending.verification'][0] + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id, owner_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + self.assertEqual('auction_protocol.pdf', response.json["data"]["title"]) + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, award_id, doc_id, owner_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + self.assertEqual(response.json["data"]["author"], 'auction_owner') + + # set award as pending.payment + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "pending.payment"}}) + self.assertNotEqual(response.json['data']['date'], award_date) + # set award as active + self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) + # get contract id + response = self.app.get('/auctions/{}'.format(auction_id)) + contract_id = response.json['data']['contracts'][-1]['id'] + # after stand slill period + self.app.authorization = ('Basic', ('chronograph', '')) + self.set_status('complete', {'status': 'active.awarded'}) + # time travel + auction = self.db.get(auction_id) + for i in auction.get('awards', []): + i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] + self.db.save(auction) + # sign contract + self.app.authorization = ('Basic', ('broker', '')) + self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) + # check status + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}'.format(auction_id)) + self.assertEqual(response.json['data']['status'], 'complete') + +def one_invalid_bid_auction(self): + self.app.authorization = ('Basic', ('broker', '')) + # empty auctions listing + response = self.app.get('/auctions') + self.assertEqual(response.json['data'], []) + # create auction + data = deepcopy(self.initial_data) + data['minNumberOfQualifiedBids'] = 1 + + response = self.app.post_json('/auctions', + {"data": data}) + auction_id = self.auction_id = response.json['data']['id'] + owner_token = response.json['access']['token'] + # switch to active.tendering + self.set_status('active.tendering') + # create bid + self.app.authorization = ('Basic', ('broker', '')) + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True}}) + # switch to active.qualification + self.set_status('active.auction', {"auctionPeriod": {"startDate": None}, 'status': 'active.tendering'}) + self.app.authorization = ('Basic', ('chronograph', '')) + response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) + # get pending award + award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending.verification'][0] + # set award as unsuccessful + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), + {"data": {"status": "unsuccessful"}}) + + response = self.app.get('/auctions/{}'.format(auction_id)) + self.assertEqual(response.json['data']['status'], 'unsuccessful') + + +def first_bid_auction(self): + self.app.authorization = ('Basic', ('broker', '')) + # empty auctions listing + response = self.app.get('/auctions') + self.assertEqual(response.json['data'], []) + # create auction + response = self.app.post_json('/auctions', + {"data": self.initial_data}) + auction_id = self.auction_id = response.json['data']['id'] + owner_token = response.json['access']['token'] + # switch to active.tendering + self.set_status('active.tendering') + # create bid + self.app.authorization = ('Basic', ('broker', '')) + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True}}) + bid_id = response.json['data']['id'] + bid_token = response.json['access']['token'] + bids_tokens = {bid_id: bid_token} + # create second bid + self.app.authorization = ('Basic', ('broker', '')) + if self.initial_organization == test_financial_organization: + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True, 'eligible': True}}) + else: + response = self.app.post_json('/auctions/{}/bids'.format(auction_id), + {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True}}) + bids_tokens[response.json['data']['id']] = response.json['access']['token'] + # switch to active.auction + self.set_status('active.auction') + + # get auction info + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.get('/auctions/{}/auction'.format(auction_id)) + auction_bids_data = response.json['data']['bids'] + # posting auction urls + response = self.app.patch_json('/auctions/{}/auction'.format(auction_id), + { + 'data': { + 'auctionUrl': 'https://auction.auction.url', + 'bids': [ + { + 'id': i['id'], + 'participationUrl': 'https://auction.auction.url/for_bid/{}'.format(i['id']) + } + for i in auction_bids_data + ] + } + }) + # view bid participationUrl + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(auction_id, bid_id, bid_token)) + self.assertEqual(response.json['data']['participationUrl'], 'https://auction.auction.url/for_bid/{}'.format(bid_id)) + + # posting auction results + self.app.authorization = ('Basic', ('auction', '')) + response = self.app.post_json('/auctions/{}/auction'.format(auction_id), + {'data': {'bids': auction_bids_data}}) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) + # get pending.verification award + award = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] + award_id = award['id'] + # Upload auction protocol + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id, owner_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, award_id, doc_id, owner_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + self.assertEqual(response.json["data"]["author"], 'auction_owner') + # set award as unsuccessful + response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), + {"data": {"status": "unsuccessful"}}) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) + # get pending award + award2 = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] + award2_id = award2['id'] + self.assertNotEqual(award_id, award2_id) + # create first award complaint + # self.app.authorization = ('Basic', ('broker', '')) + # response = self.app.post_json('/auctions/{}/awards/{}/complaints?acc_token={}'.format(auction_id, award_id, bid_token), + # {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization, 'status': 'claim'}}) + # complaint_id = response.json['data']['id'] + # complaint_owner_token = response.json['access']['token'] + # # create first award complaint #2 + # response = self.app.post_json('/auctions/{}/awards/{}/complaints?acc_token={}'.format(auction_id, award_id, bid_token), + # {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) + # # answering claim + # self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(auction_id, award_id, complaint_id, owner_token), {"data": { + # "status": "answered", + # "resolutionType": "resolved", + # "resolution": "resolution text " * 2 + # }}) + # # satisfying resolution + # self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(auction_id, award_id, complaint_id, complaint_owner_token), {"data": { + # "satisfied": True, + # "status": "resolved" + # }}) + # get awards + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) + # get pending award + award = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] + award_id = award['id'] + # Upload auction protocol + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( + self.auction_id, award_id, owner_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + + response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, award_id, doc_id, owner_token), {"data": { + "description": "auction protocol", + "documentType": 'auctionProtocol' + }}) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') + self.assertEqual(response.json["data"]["author"], 'auction_owner') + # set award as "pending.payment + self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "pending.payment"}}) + # set award as active + self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) + # get contract id + response = self.app.get('/auctions/{}'.format(auction_id)) + contract_id = response.json['data']['contracts'][-1]['id'] + # create auction contract document for test + response = self.app.post('/auctions/{}/contracts/{}/documents?acc_token={}'.format(auction_id, contract_id, owner_token), upload_files=[('file', 'name.doc', 'content')], status=201) + self.assertEqual(response.status, '201 Created') + self.assertEqual(response.content_type, 'application/json') + doc_id = response.json["data"]['id'] + self.assertIn(doc_id, response.headers['Location']) + # after stand slill period + self.app.authorization = ('Basic', ('chronograph', '')) + self.set_status('complete', {'status': 'active.awarded'}) + # time travel + auction = self.db.get(auction_id) + for i in auction.get('awards', []): + i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] + self.db.save(auction) + # sign contract + self.app.authorization = ('Basic', ('broker', '')) + self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) + # check status + self.app.authorization = ('Basic', ('broker', '')) + response = self.app.get('/auctions/{}'.format(auction_id)) + self.assertEqual(response.json['data']['status'], 'complete') + + response = self.app.post('/auctions/{}/contracts/{}/documents?acc_token={}'.format(auction_id, contract_id, owner_token), upload_files=[('file', 'name.doc', 'content')], status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (complete) auction status") + + response = self.app.patch_json('/auctions/{}/contracts/{}/documents/{}?acc_token={}'.format(auction_id, contract_id, doc_id, owner_token), {"data": {"description": "document description"}}, status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") + + response = self.app.put('/auctions/{}/contracts/{}/documents/{}?acc_token={}'.format(auction_id, contract_id, doc_id, owner_token), upload_files=[('file', 'name.doc', 'content3')], status=403) + self.assertEqual(response.status, '403 Forbidden') + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") diff --git a/openprocurement/auctions/dgf/tests/tender.py b/openprocurement/auctions/dgf/tests/tender.py index 8bb7df5d..c41ab9ac 100644 --- a/openprocurement/auctions/dgf/tests/tender.py +++ b/openprocurement/auctions/dgf/tests/tender.py @@ -17,1524 +17,97 @@ DGF_CDB2_CLASSIFICATION_PRECISELY_FROM as CLASSIFICATION_PRECISELY_FROM, DGF_CDB2_ADDRESS_REQUIRED_FROM as DGF_ADDRESS_REQUIRED_FROM ) +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.tests.blanks.tender_blanks import ( + simple_add_auction +) +from openprocurement.auctions.core.tests.blanks.tender_blanks import ( + # AuctionResourceTest + auction_features_invalid, + auction_features, + patch_tender_jsonpatch, + dateModified_auction, + guarantee, + empty_listing, + listing, + listing_changes, + listing_draft, + create_auction_draft, + get_auction, + auction_not_found, + invalid_auction_conditions +) +from openprocurement.auctions.dgf.tests.blanks.tender_blanks import ( + # AuctionTest + create_role, + edit_role, + # AuctionResourceTest + create_auction_validation_accelerated, + create_auction_invalid, + required_dgf_id, + required_dgf_item_address, + create_auction_auctionPeriod, + create_auction_rectificationPeriod_generated, + create_auction_rectificationPeriod_set, + create_auction_generated, + create_auction, + additionalClassifications, + cavps_cpvs_classifications, + patch_auction, + patch_auction_rectificationPeriod_invalidationDate, + patch_old_auction_rectificationPeriod_invalidationDate, + auction_Administrator_change, + # AuctionFieldsEditingTest + patch_auction_denied, + patch_auction_during_rectification_period, + invalidate_bids_auction_unsuccessful, + # AuctionProcessTest + one_valid_bid_auction, + one_invalid_bid_auction, + first_bid_auction, +) + class AuctionTest(BaseWebTest): auction = DGFOtherAssets initial_data = test_auction_data - - def test_simple_add_auction(self): - - u = self.auction(self.initial_data) - u.auctionID = "UA-EA-X" - - assert u.id is None - assert u.rev is None - - u.store(self.db) - - assert u.id is not None - assert u.rev is not None - - fromdb = self.db.get(u.id) - - assert u.auctionID == fromdb['auctionID'] - assert u.doc_type == "Auction" - - u.delete_instance(self.db) - - def test_create_role(self): - fields = set([ - 'awardCriteriaDetails', 'awardCriteriaDetails_en', 'awardCriteriaDetails_ru', - 'description', 'description_en', 'description_ru', 'dgfID', 'tenderAttempts', - 'features', 'guarantee', 'hasEnquiries', 'items', 'lots', 'minimalStep', 'mode', - 'procurementMethodRationale', 'procurementMethodRationale_en', 'procurementMethodRationale_ru', - 'procurementMethodType', 'procuringEntity', 'minNumberOfQualifiedBids', - 'submissionMethodDetails', 'submissionMethodDetails_en', 'submissionMethodDetails_ru', - 'title', 'title_en', 'title_ru', 'value', 'auctionPeriod', 'rectificationPeriod' - ]) - if SANDBOX_MODE: - fields.add('procurementMethodDetails') - self.assertEqual(set(self.auction._fields) - self.auction._options.roles['create'].fields, fields) - - def test_edit_role(self): - fields = set([ - 'description', 'description_en', 'description_ru', - 'features', 'hasEnquiries', 'items', 'procuringEntity', - 'value', 'minimalStep', 'guarantee', 'tenderAttempts', 'title_en', 'dgfID', 'title_ru', - 'title' - ]) - if SANDBOX_MODE: - fields.add('procurementMethodDetails') - self.assertEqual(set(self.auction._fields) - self.auction._options.roles['edit_active.tendering'].fields, fields) + test_simple_add_auction = snitch(simple_add_auction) + test_create_role = snitch(create_role) + test_edit_role = snitch(edit_role) class AuctionResourceTest(BaseWebTest): initial_data = test_auction_data initial_organization = test_organization - - def test_empty_listing(self): - response = self.app.get('/auctions') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], []) - self.assertNotIn('{\n "', response.body) - self.assertNotIn('callback({', response.body) - self.assertEqual(response.json['next_page']['offset'], '') - self.assertNotIn('prev_page', response.json) - - response = self.app.get('/auctions?opt_jsonp=callback') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/javascript') - self.assertNotIn('{\n "', response.body) - self.assertIn('callback({', response.body) - - response = self.app.get('/auctions?opt_pretty=1') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('{\n "', response.body) - self.assertNotIn('callback({', response.body) - - response = self.app.get('/auctions?opt_jsonp=callback&opt_pretty=1') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/javascript') - self.assertIn('{\n "', response.body) - self.assertIn('callback({', response.body) - - response = self.app.get('/auctions?offset=2015-01-01T00:00:00+02:00&descending=1&limit=10') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], []) - self.assertIn('descending=1', response.json['next_page']['uri']) - self.assertIn('limit=10', response.json['next_page']['uri']) - self.assertNotIn('descending=1', response.json['prev_page']['uri']) - self.assertIn('limit=10', response.json['prev_page']['uri']) - - response = self.app.get('/auctions?feed=changes') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], []) - self.assertEqual(response.json['next_page']['offset'], '') - self.assertNotIn('prev_page', response.json) - - response = self.app.get('/auctions?feed=changes&offset=0', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Offset expired/invalid', u'location': u'params', u'name': u'offset'} - ]) - - response = self.app.get('/auctions?feed=changes&descending=1&limit=10') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], []) - self.assertIn('descending=1', response.json['next_page']['uri']) - self.assertIn('limit=10', response.json['next_page']['uri']) - self.assertNotIn('descending=1', response.json['prev_page']['uri']) - self.assertIn('limit=10', response.json['prev_page']['uri']) - - def test_listing(self): - response = self.app.get('/auctions') - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 0) - - auctions = [] - - for i in range(3): - offset = get_now().isoformat() - response = self.app.post_json('/auctions', {'data': self.initial_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - auctions.append(response.json['data']) - - ids = ','.join([i['id'] for i in auctions]) - - while True: - response = self.app.get('/auctions') - self.assertTrue(ids.startswith(','.join([i['id'] for i in response.json['data']]))) - if len(response.json['data']) == 3: - break - - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(set(response.json['data'][0]), set([u'id', u'dateModified'])) - self.assertEqual(set([i['id'] for i in response.json['data']]), set([i['id'] for i in auctions])) - self.assertEqual(set([i['dateModified'] for i in response.json['data']]), set([i['dateModified'] for i in auctions])) - self.assertEqual([i['dateModified'] for i in response.json['data']], sorted([i['dateModified'] for i in auctions])) - - while True: - response = self.app.get('/auctions?offset={}'.format(offset)) - self.assertEqual(response.status, '200 OK') - if len(response.json['data']) == 1: - break - self.assertEqual(len(response.json['data']), 1) - - response = self.app.get('/auctions?limit=2') - self.assertEqual(response.status, '200 OK') - self.assertNotIn('prev_page', response.json) - self.assertEqual(len(response.json['data']), 2) - - response = self.app.get(response.json['next_page']['path'].replace(ROUTE_PREFIX, '')) - self.assertEqual(response.status, '200 OK') - self.assertIn('descending=1', response.json['prev_page']['uri']) - self.assertEqual(len(response.json['data']), 1) - - response = self.app.get(response.json['next_page']['path'].replace(ROUTE_PREFIX, '')) - self.assertEqual(response.status, '200 OK') - self.assertIn('descending=1', response.json['prev_page']['uri']) - self.assertEqual(len(response.json['data']), 0) - - response = self.app.get('/auctions', params=[('opt_fields', 'status')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(set(response.json['data'][0]), set([u'id', u'dateModified', u'status'])) - self.assertIn('opt_fields=status', response.json['next_page']['uri']) - - response = self.app.get('/auctions', params=[('opt_fields', 'status,enquiryPeriod')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(set(response.json['data'][0]), set([u'id', u'dateModified', u'status', u'enquiryPeriod'])) - self.assertIn('opt_fields=status%2CenquiryPeriod', response.json['next_page']['uri']) - - response = self.app.get('/auctions?descending=1') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(set(response.json['data'][0]), set([u'id', u'dateModified'])) - self.assertEqual(set([i['id'] for i in response.json['data']]), set([i['id'] for i in auctions])) - self.assertEqual([i['dateModified'] for i in response.json['data']], sorted([i['dateModified'] for i in auctions], reverse=True)) - - response = self.app.get('/auctions?descending=1&limit=2') - self.assertEqual(response.status, '200 OK') - self.assertNotIn('descending=1', response.json['prev_page']['uri']) - self.assertEqual(len(response.json['data']), 2) - - response = self.app.get(response.json['next_page']['path'].replace(ROUTE_PREFIX, '')) - self.assertEqual(response.status, '200 OK') - self.assertNotIn('descending=1', response.json['prev_page']['uri']) - self.assertEqual(len(response.json['data']), 1) - - response = self.app.get(response.json['next_page']['path'].replace(ROUTE_PREFIX, '')) - self.assertEqual(response.status, '200 OK') - self.assertNotIn('descending=1', response.json['prev_page']['uri']) - self.assertEqual(len(response.json['data']), 0) - - test_auction_data2 = self.initial_data.copy() - test_auction_data2['mode'] = 'test' - response = self.app.post_json('/auctions', {'data': test_auction_data2}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - - while True: - response = self.app.get('/auctions?mode=test') - self.assertEqual(response.status, '200 OK') - if len(response.json['data']) == 1: - break - self.assertEqual(len(response.json['data']), 1) - - response = self.app.get('/auctions?mode=_all_') - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 4) - - def test_listing_changes(self): - response = self.app.get('/auctions?feed=changes') - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 0) - - auctions = [] - - for i in range(3): - response = self.app.post_json('/auctions', {'data': self.initial_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - auctions.append(response.json['data']) - - ids = ','.join([i['id'] for i in auctions]) - - while True: - response = self.app.get('/auctions?feed=changes') - self.assertTrue(ids.startswith(','.join([i['id'] for i in response.json['data']]))) - if len(response.json['data']) == 3: - break - - self.assertEqual(','.join([i['id'] for i in response.json['data']]), ids) - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(set(response.json['data'][0]), set([u'id', u'dateModified'])) - self.assertEqual(set([i['id'] for i in response.json['data']]), set([i['id'] for i in auctions])) - self.assertEqual(set([i['dateModified'] for i in response.json['data']]), set([i['dateModified'] for i in auctions])) - self.assertEqual([i['dateModified'] for i in response.json['data']], sorted([i['dateModified'] for i in auctions])) - - response = self.app.get('/auctions?feed=changes&limit=2') - self.assertEqual(response.status, '200 OK') - self.assertNotIn('prev_page', response.json) - self.assertEqual(len(response.json['data']), 2) - - response = self.app.get(response.json['next_page']['path'].replace(ROUTE_PREFIX, '')) - self.assertEqual(response.status, '200 OK') - self.assertIn('descending=1', response.json['prev_page']['uri']) - self.assertEqual(len(response.json['data']), 1) - - response = self.app.get(response.json['next_page']['path'].replace(ROUTE_PREFIX, '')) - self.assertEqual(response.status, '200 OK') - self.assertIn('descending=1', response.json['prev_page']['uri']) - self.assertEqual(len(response.json['data']), 0) - - response = self.app.get('/auctions?feed=changes', params=[('opt_fields', 'status')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(set(response.json['data'][0]), set([u'id', u'dateModified', u'status'])) - self.assertIn('opt_fields=status', response.json['next_page']['uri']) - - response = self.app.get('/auctions?feed=changes', params=[('opt_fields', 'status,enquiryPeriod')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(set(response.json['data'][0]), set([u'id', u'dateModified', u'status', u'enquiryPeriod'])) - self.assertIn('opt_fields=status%2CenquiryPeriod', response.json['next_page']['uri']) - - response = self.app.get('/auctions?feed=changes&descending=1') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(set(response.json['data'][0]), set([u'id', u'dateModified'])) - self.assertEqual(set([i['id'] for i in response.json['data']]), set([i['id'] for i in auctions])) - self.assertEqual([i['dateModified'] for i in response.json['data']], sorted([i['dateModified'] for i in auctions], reverse=True)) - - response = self.app.get('/auctions?feed=changes&descending=1&limit=2') - self.assertEqual(response.status, '200 OK') - self.assertNotIn('descending=1', response.json['prev_page']['uri']) - self.assertEqual(len(response.json['data']), 2) - - response = self.app.get(response.json['next_page']['path'].replace(ROUTE_PREFIX, '')) - self.assertEqual(response.status, '200 OK') - self.assertNotIn('descending=1', response.json['prev_page']['uri']) - self.assertEqual(len(response.json['data']), 1) - - response = self.app.get(response.json['next_page']['path'].replace(ROUTE_PREFIX, '')) - self.assertEqual(response.status, '200 OK') - self.assertNotIn('descending=1', response.json['prev_page']['uri']) - self.assertEqual(len(response.json['data']), 0) - - test_auction_data2 = self.initial_data.copy() - test_auction_data2['mode'] = 'test' - response = self.app.post_json('/auctions', {'data': test_auction_data2}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - - while True: - response = self.app.get('/auctions?feed=changes&mode=test') - self.assertEqual(response.status, '200 OK') - if len(response.json['data']) == 1: - break - self.assertEqual(len(response.json['data']), 1) - - response = self.app.get('/auctions?feed=changes&mode=_all_') - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 4) - - def test_listing_draft(self): - response = self.app.get('/auctions') - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 0) - - auctions = [] - data = self.initial_data.copy() - data.update({'status': 'draft'}) - - for i in range(3): - response = self.app.post_json('/auctions', {'data': self.initial_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - auctions.append(response.json['data']) - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - - ids = ','.join([i['id'] for i in auctions]) - - while True: - response = self.app.get('/auctions') - self.assertTrue(ids.startswith(','.join([i['id'] for i in response.json['data']]))) - if len(response.json['data']) == 3: - break - - self.assertEqual(len(response.json['data']), 3) - self.assertEqual(set(response.json['data'][0]), set([u'id', u'dateModified'])) - self.assertEqual(set([i['id'] for i in response.json['data']]), set([i['id'] for i in auctions])) - self.assertEqual(set([i['dateModified'] for i in response.json['data']]), set([i['dateModified'] for i in auctions])) - self.assertEqual([i['dateModified'] for i in response.json['data']], sorted([i['dateModified'] for i in auctions])) - - def test_create_auction_validation_accelerated(self): - request_path = '/auctions' - now = get_now() - data = self.initial_data.copy() - auction_data = deepcopy(self.initial_data) - if SANDBOX_MODE: - startDate = (now + timedelta(days=8, hours=4) / DEFAULT_ACCELERATION).isoformat() - else: - startDate = (now + timedelta(days=8, hours=4)).isoformat() - auction_data['auctionPeriod'] = {'startDate': startDate} - response = self.app.post_json(request_path, {'data': auction_data}, status=201) - auction = response.json['data'] - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - tender_period_startDate = parse_date(auction['tenderPeriod']['startDate'], None) - if not tender_period_startDate.tzinfo: - tender_period_startDate = TZ.localize(tender_period_startDate) - tender_period_endDate = parse_date(auction['tenderPeriod']['endDate'], None) - if not tender_period_endDate.tzinfo: - tender_period_endDate = TZ.localize(tender_period_endDate) - if SANDBOX_MODE: - self.assertLess((tender_period_endDate - tender_period_startDate), timedelta(days=8, hours=4) / DEFAULT_ACCELERATION) - else: - self.assertLess((tender_period_endDate - tender_period_startDate), timedelta(days=8, hours=4)) - - def test_create_auction_invalid(self): - request_path = '/auctions' - response = self.app.post(request_path, 'data', status=415) - self.assertEqual(response.status, '415 Unsupported Media Type') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': - u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} - ]) - - response = self.app.post( - request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, 'data', 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'not_data': {}}, 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'data': []}, 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'data': {'procurementMethodType': 'invalid_value'}}, status=415) - self.assertEqual(response.status, '415 Unsupported Media Type') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not implemented', u'location': u'data', u'name': u'procurementMethodType'} - ]) - - response = self.app.post_json(request_path, {'data': {'invalid_field': 'invalid_value', 'procurementMethodType': self.initial_data['procurementMethodType']}}, 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'Rogue field', u'location': - u'body', u'name': u'invalid_field'} - ]) - - response = self.app.post_json(request_path, {'data': {'value': 'invalid_value', 'procurementMethodType': self.initial_data['procurementMethodType']}}, 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'Please use a mapping for this field or Value instance instead of unicode.'], u'location': u'body', u'name': u'value'} - ]) - - response = self.app.post_json(request_path, {'data': {'procurementMethod': 'invalid_value', 'procurementMethodType': self.initial_data['procurementMethodType']}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertIn({u'description': [u"Value must be one of ['open', 'selective', 'limited']."], u'location': u'body', u'name': u'procurementMethod'}, response.json['errors']) - #self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'tenderPeriod'}, response.json['errors']) - self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'minimalStep'}, response.json['errors']) - self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'items'}, response.json['errors']) - #self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'enquiryPeriod'}, response.json['errors']) - self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'value'}, response.json['errors']) - self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'items'}, response.json['errors']) - - response = self.app.post_json(request_path, {'data': {'enquiryPeriod': {'endDate': 'invalid_value'}, 'procurementMethodType': self.initial_data['procurementMethodType']}}, 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'endDate': [u"Could not parse invalid_value. Should be ISO8601."]}, u'location': u'body', u'name': u'enquiryPeriod'} - ]) - - response = self.app.post_json(request_path, {'data': {'enquiryPeriod': {'endDate': '9999-12-31T23:59:59.999999'}, 'procurementMethodType': self.initial_data['procurementMethodType']}}, 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'endDate': [u'date value out of range']}, u'location': u'body', u'name': u'enquiryPeriod'} - ]) - - self.initial_data['tenderPeriod'] = self.initial_data.pop('auctionPeriod') - response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) - self.initial_data['auctionPeriod'] = self.initial_data.pop('tenderPeriod') - 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 is required.']}, u'location': u'body', u'name': u'auctionPeriod'} - ]) - - self.initial_data['tenderPeriod'] = {'startDate': '2014-10-31T00:00:00', 'endDate': '2014-10-01T00:00:00'} - response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) - self.initial_data.pop('tenderPeriod') - 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'period should begin before its end']}, u'location': u'body', u'name': u'tenderPeriod'} - ]) - - #data = self.initial_data['tenderPeriod'] - #self.initial_data['tenderPeriod'] = {'startDate': '2014-10-31T00:00:00', 'endDate': '2015-10-01T00:00:00'} - #response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) - #self.initial_data['tenderPeriod'] = data - #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'period should begin after enquiryPeriod'], u'location': u'body', u'name': u'tenderPeriod'} - #]) - - now = get_now() - #self.initial_data['awardPeriod'] = {'startDate': now.isoformat(), 'endDate': now.isoformat()} - #response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) - #del self.initial_data['awardPeriod'] - #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'period should begin after tenderPeriod'], u'location': u'body', u'name': u'awardPeriod'} - #]) - - data = self.initial_data['auctionPeriod'] - self.initial_data['auctionPeriod'] = {'startDate': (now + timedelta(days=15)).isoformat(), 'endDate': (now + timedelta(days=15)).isoformat()} - self.initial_data['awardPeriod'] = {'startDate': (now + timedelta(days=14)).isoformat(), 'endDate': (now + timedelta(days=14)).isoformat()} - response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) - self.initial_data['auctionPeriod'] = data - del self.initial_data['awardPeriod'] - 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'period should begin after auctionPeriod'], u'location': u'body', u'name': u'awardPeriod'} - ]) - - auction_data = deepcopy(self.initial_data) - if SANDBOX_MODE: - auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=5) / DEFAULT_ACCELERATION).isoformat()} - else: - auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=5)).isoformat()} - response = self.app.post_json(request_path, {'data': auction_data}, 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'rectificationPeriod.endDate should come at least 5 working days earlier than tenderPeriod.endDate'], u'location': u'body', u'name': u'rectificationPeriod'}, - {u'description': [u'tenderPeriod should be greater than 6 days'], u'location': u'body', u'name': u'tenderPeriod'} - ]) - - if SANDBOX_MODE: - auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=10) / DEFAULT_ACCELERATION).isoformat()} - auction_data['rectificationPeriod'] = {'endDate': (now + timedelta(days=9) / DEFAULT_ACCELERATION).isoformat()} - else: - auction_data['auctionPeriod'] = {'startDate': (now + timedelta(days=10)).isoformat()} - auction_data['rectificationPeriod'] = {'endDate': (now + timedelta(days=9)).isoformat()} - response = self.app.post_json(request_path, {'data': auction_data}, 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'rectificationPeriod.endDate should come at least 5 working days earlier than tenderPeriod.endDate'], u'location': u'body', u'name': u'rectificationPeriod'}]) - - data = self.initial_data['minimalStep'] - self.initial_data['minimalStep'] = {'amount': '1000.0'} - response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) - self.initial_data['minimalStep'] = data - 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'value should be less than value of auction'], u'location': u'body', u'name': u'minimalStep'} - ]) - - data = self.initial_data['minimalStep'] - self.initial_data['minimalStep'] = {'amount': '100.0', 'valueAddedTaxIncluded': False} - response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) - self.initial_data['minimalStep'] = data - 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'valueAddedTaxIncluded should be identical to valueAddedTaxIncluded of value of auction'], u'location': u'body', u'name': u'minimalStep'} - ]) - - data = self.initial_data['minimalStep'] - self.initial_data['minimalStep'] = {'amount': '100.0', 'currency': "USD"} - response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) - self.initial_data['minimalStep'] = data - 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'currency should be identical to currency of value of auction'], u'location': u'body', u'name': u'minimalStep'} - ]) - - auction_data = deepcopy(self.initial_data) - auction_data['value'] = {'amount': '100.0', 'currency': "USD"} - auction_data['minimalStep'] = {'amount': '5.0', 'currency': "USD"} - response = self.app.post_json(request_path, {'data': auction_data}, 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'currency should be only UAH'], u'location': u'body', u'name': u'value'} - ]) - - data = self.initial_data["procuringEntity"]["contactPoint"]["telephone"] - del self.initial_data["procuringEntity"]["contactPoint"]["telephone"] - response = self.app.post_json(request_path, {'data': self.initial_data}, status=422) - self.initial_data["procuringEntity"]["contactPoint"]["telephone"] = data - 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'contactPoint': {u'email': [u'telephone or email should be present']}}, u'location': u'body', u'name': u'procuringEntity'} - ]) - - - - @unittest.skipIf(get_now() < DGF_ID_REQUIRED_FROM, "Can`t create auction without dgfID only from {}".format(DGF_ID_REQUIRED_FROM)) - def test_required_dgf_id(self): - data = self.initial_data.copy() - del data['dgfID'] - response = self.app.post_json('/auctions', {'data': data}, 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'], [{"location": "body", "name": "dgfID", "description": ["This field is required."]}]) - - data['dgfID'] = self.initial_data['dgfID'] - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertIn('dgfID', auction) - self.assertEqual(data['dgfID'], auction['dgfID']) - - @unittest.skipIf(get_now() < DGF_ADDRESS_REQUIRED_FROM, "Can`t create auction without item.address only from {}".format(DGF_ADDRESS_REQUIRED_FROM)) - def test_required_dgf_item_address(self): - auction_data = deepcopy(self.initial_data) - del auction_data['items'][0]['address'] - - address = { - "countryName": u"Україна", - "postalCode": "79000", - "region": u"м. Київ", - "locality": u"м. Київ", - "streetAddress": u"вул. Банкова 1" - } - - # CAV-PS specific location code test (address is required) - auction_data['items'][0]['classification'] = { - "scheme": u"CAV-PS", - "id": u"04210000-3", - "description": u"Промислова нерухомість" - } - response = self.app.post_json('/auctions', {'data': auction_data}, 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'], [{"location": "body", "name": "items", "description": [{"address": ["This field is required."]}]}]) - - auction_data['items'][0]["address"] = address - - response = self.app.post_json('/auctions', {'data': auction_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - - del auction_data['items'][0]['address'] - - # CPV specific location code test (address is required) - auction_data['items'][0]['classification'] = { - "scheme": u"CPV", - "id": u"34965000-9", - "description": u"Всебічно направлений далекомірний радіомаяк" - } - response = self.app.post_json('/auctions', {'data': auction_data}, 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'], [{"location": "body", "name": "items", "description": [{"address": ["This field is required."]}]}]) - - auction_data['items'][0]["address"] = address - - response = self.app.post_json('/auctions', {'data': auction_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - - del auction_data['items'][0]["address"] - - # CAV-PS/CPV non specific location code test (address is not required) - auction_data['items'][0]['classification'] = { - "scheme": u"CPV", - "id": u"90470000-2", - "description": u"Послуги з чищення каналізаційних колекторів" - } - item = deepcopy(auction_data['items'][0]) - item['classification'] = { - "scheme": u"CAV-PS", - "id": u"07227000-6", - "description": u"Застава - Інше" - } - auction_data['items'].append(item) - - response = self.app.post_json('/auctions', {'data': auction_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - - auction_data['items'][0]["address"] = address - - response = self.app.post_json('/auctions', {'data': auction_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - - def test_create_auction_auctionPeriod(self): - data = self.initial_data.copy() - #tenderPeriod = data.pop('tenderPeriod') - #data['auctionPeriod'] = {'startDate': tenderPeriod['endDate']} - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertIn('tenderPeriod', auction) - self.assertIn('auctionPeriod', auction) - self.assertNotIn('startDate', auction['auctionPeriod']) - self.assertEqual(parse_date(data['auctionPeriod']['startDate']).date(), parse_date(auction['auctionPeriod']['shouldStartAfter'], TZ).date()) - if SANDBOX_MODE: - auction_startDate = parse_date(data['auctionPeriod']['startDate'], None) - if not auction_startDate.tzinfo: - auction_startDate = TZ.localize(auction_startDate) - tender_endDate = parse_date(auction['tenderPeriod']['endDate'], None) - if not tender_endDate.tzinfo: - tender_endDate = TZ.localize(tender_endDate) - self.assertLessEqual((auction_startDate - tender_endDate).total_seconds(), 70) - else: - self.assertEqual(parse_date(auction['tenderPeriod']['endDate']).date(), parse_date(data['auctionPeriod']['startDate'], TZ).date() - timedelta(days=1)) - self.assertEqual(parse_date(auction['tenderPeriod']['endDate']).time(), time(20, 0)) - - def test_create_auction_rectificationPeriod_generated(self): - response = self.app.post_json('/auctions', {'data': self.initial_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertIn('tenderPeriod', auction) - self.assertIn('enquiryPeriod', auction) - self.assertIn('rectificationPeriod', auction) - self.assertIn('auctionPeriod', auction) - self.assertNotIn('startDate', auction['auctionPeriod']) - self.assertEqual(parse_date(self.initial_data['auctionPeriod']['startDate']).date(), parse_date(auction['auctionPeriod']['shouldStartAfter'], TZ).date()) - timedelta_during_periods_ends = parse_date(auction['tenderPeriod']['endDate']) - parse_date(auction['rectificationPeriod']['endDate']) - if not SANDBOX_MODE: - self.assertEqual(timedelta_during_periods_ends, MINIMAL_PERIOD_FROM_RECTIFICATION_END) - else: - self.assertEqual(timedelta_during_periods_ends, (MINIMAL_PERIOD_FROM_RECTIFICATION_END / DEFAULT_ACCELERATION)) - - def test_create_auction_rectificationPeriod_set(self): - now = get_now() - auction_data = deepcopy(self.initial_data) - auction_data['rectificationPeriod'] = {'endDate' : (get_now() + timedelta(days=2)).isoformat()} - auction_data['auctionPeriod'] = {'startDate' : (get_now() + timedelta(days=10)).isoformat()} - response = self.app.post_json('/auctions', {'data': auction_data}) - self.assertEqual(response.status, '201 Created') - auction = response.json['data'] - self.assertIn('rectificationPeriod', auction) - timedelta_during_set_periods_ends = parse_date(auction['tenderPeriod']['endDate']) - parse_date(auction_data['rectificationPeriod']['endDate']) - self.assertGreaterEqual(timedelta_during_set_periods_ends, MINIMAL_PERIOD_FROM_RECTIFICATION_END) - self.assertEqual(timedelta_during_set_periods_ends, parse_date(auction['tenderPeriod']['endDate']) - parse_date(auction['rectificationPeriod']['endDate'])) - - def test_create_auction_generated(self): - data = self.initial_data.copy() - #del data['awardPeriod'] - data.update({'id': 'hash', 'doc_id': 'hash2', 'auctionID': 'hash3'}) - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - if 'procurementMethodDetails' in auction: - auction.pop('procurementMethodDetails') - self.assertEqual(set(auction), set([ - u'procurementMethodType', u'id', u'date', u'dateModified', u'auctionID', u'status', u'enquiryPeriod', - u'tenderPeriod', u'minimalStep', u'items', u'value', u'procuringEntity', u'next_check', u'dgfID', - u'procurementMethod', u'awardCriteria', u'submissionMethod', u'title', u'owner', u'auctionPeriod', - u'tenderAttempts', u'rectificationPeriod' - ])) - self.assertNotEqual(data['id'], auction['id']) - self.assertNotEqual(data['doc_id'], auction['id']) - self.assertNotEqual(data['auctionID'], auction['auctionID']) - - def test_create_auction_draft(self): - data = self.initial_data.copy() - data.update({'status': 'draft'}) - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertEqual(auction['status'], 'draft') - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'value': {'amount': 100}}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u"Can't update auction in current (draft) status", u'location': u'body', u'name': u'data'} - ]) - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'status': 'active.tendering'}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertEqual(auction['status'], 'active.tendering') - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertEqual(auction['status'], 'active.tendering') - - def test_create_auction(self): - 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": self.initial_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - if self.initial_organization == test_financial_organization: - self.assertEqual(set(auction) - set(self.initial_data), set([ - u'id', u'dateModified', u'auctionID', u'date', u'status', u'procurementMethod', u'rectificationPeriod', - u'awardCriteria', u'submissionMethod', u'next_check', u'owner', u'enquiryPeriod', u'tenderPeriod', - u'eligibilityCriteria_en', u'eligibilityCriteria', u'eligibilityCriteria_ru' - ])) - else: - self.assertEqual(set(auction) - set(self.initial_data), set([ - u'id', u'dateModified', u'auctionID', u'date', u'status', u'procurementMethod', u'rectificationPeriod', - u'awardCriteria', u'submissionMethod', u'next_check', u'owner', u'enquiryPeriod', u'tenderPeriod', - ])) - self.assertIn(auction['id'], response.headers['Location']) - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(set(response.json['data']), set(auction)) - self.assertEqual(response.json['data'], auction) - - response = self.app.post_json('/auctions?opt_jsonp=callback', {"data": self.initial_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/javascript') - self.assertIn('callback({"', response.body) - - response = self.app.post_json('/auctions?opt_pretty=1', {"data": self.initial_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('{\n "', response.body) - - response = self.app.post_json('/auctions', {"data": self.initial_data, "options": {"pretty": True}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('{\n "', response.body) - - auction_data = deepcopy(self.initial_data) - auction_data['guarantee'] = {"amount": 100500, "currency": "USD"} - response = self.app.post_json('/auctions', {'data': auction_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - data = response.json['data'] - self.assertIn('guarantee', data) - self.assertEqual(data['guarantee']['amount'], 100500) - self.assertEqual(data['guarantee']['currency'], "USD") - - def test_get_auction(self): - 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': self.initial_data}) - self.assertEqual(response.status, '201 Created') - auction = response.json['data'] - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], auction) - - response = self.app.get('/auctions/{}?opt_jsonp=callback'.format(auction['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/javascript') - self.assertIn('callback({"data": {"', response.body) - - response = self.app.get('/auctions/{}?opt_pretty=1'.format(auction['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('{\n "data": {\n "', response.body) - - def test_additionalClassifications(self): - auction_data = deepcopy(self.initial_data) - # CAV-PS classification test - auction_data['items'][0]['classification'] = { - "scheme" : u"CAV-PS", - "id": u"04210000-3", - "description": u"Промислова нерухомість" - } - response = self.app.post_json('/auctions', {'data': auction_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - data = response.json['data'] - self.assertEqual(data['items'][0]['classification']['scheme'], 'CAV-PS') - self.assertEqual(data['items'][0]['classification']['id'], '04210000-3') - - # CAV-PS and CPV classification in different items - auction_data = deepcopy(self.initial_data) - item = deepcopy(auction_data['items'][0]) - item['classification'] = { - "scheme" : u"CAV-PS", - "id": u"04210000-3", - "description": u"Промислова нерухомість" - } - auction_data['items'].append(item) - response = self.app.post_json('/auctions', {'data': auction_data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - data = response.json['data'] - self.assertEqual(data['items'][1]['classification']['scheme'], 'CAV-PS') - self.assertEqual(data['items'][1]['classification']['id'], '04210000-3') - self.assertEqual(data['items'][0]['classification']['scheme'], 'CPV') - self.assertEqual(data['items'][0]['classification']['id'], '66113000-5') - - # Additional Classification - - auction_data['items'][0]['additionalClassifications'] = [{ - "scheme" : u"CPVS", - "id": u"PA01-7", - "description": u"Найм" - }] - response = self.app.post_json('/auctions', {'data': auction_data}, status=201) - data = response.json['data'] - self.assertEqual(data['items'][0]['additionalClassifications'][0]['scheme'], 'CPVS') - self.assertEqual(data['items'][0]['additionalClassifications'][0]['id'], 'PA01-7') - - # CAV-PS classification fail test - auction_data['items'][0]['classification'] = { - "scheme" : u"CAV-PS", - "id": u"07227000-3", # last number is wrong - "description": u"Застава - Інше" - } - response = self.app.post_json('/auctions', {'data': auction_data}, status=422) - self.assertTrue(response.json['errors'][0]['description'][0]['classification']) - - # Bad classification - auction_data['items'][0]['classification'] = { - "scheme" : u"CAE", # wrong scheme - "id": u"07227000-6", - "description": u"Застава - Інше" - } - response = self.app.post_json('/auctions', {'data': auction_data}, status=422) - self.assertEqual(response.json['errors'], [{u'description': [{u'classification': {u'scheme': [u"Value must be one of [u'CPV', u'CAV-PS']."]}}], u'location': u'body', u'name': u'items'}]) - - # Additional Classification wrong id - auction_data['items'][0]['additionalClassifications'] = [{ - "scheme" : u"CPVS", - "id": u"PA01-2", # Wrong ID - "description": u"Найм" - }] - response = self.app.post_json('/auctions', {'data': auction_data}, status=422) - self.assertRegexpMatches(response.json['errors'][0]['description'][0]['additionalClassifications'][0]['id'][0], "Value must be one of*") - - @unittest.skipIf(get_now() < CLASSIFICATION_PRECISELY_FROM, "Can`t setup precisely classification from {}".format(CLASSIFICATION_PRECISELY_FROM)) - def test_cavps_cpvs_classifications(self): - response = self.app.get('/auctions') - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 0) - - data = deepcopy(self.initial_data) - data['guarantee'] = {"amount": 100, "currency": "UAH"} - - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - auction = response.json['data'] - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"classification": { - "scheme": u"CPV", - "id": u"19212310-1", - "description": u"Нерухоме майно" - }}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"classification": { - "scheme": u"CPV", - "id": u"03100000-2", - "description": u"Нерухоме майно" - }}]}}, status=422) - self.assertEqual(response.json['errors'], [{u'description': [{u'classification': {u'id': [u'At least CPV classification class (XXXX0000-Y) should be specified more precisely']}}], u'location': u'body', u'name': u'items'}]) - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"additionalClassifications": [auction['items'][0]["classification"]]}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - - - - @unittest.skip("option not available") - def test_auction_features_invalid(self): - data = self.initial_data.copy() - item = data['items'][0].copy() - item['id'] = "1" - data['items'] = [item, item.copy()] - response = self.app.post_json('/auctions', {'data': data}, 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'Item id should be uniq for all items'], u'location': u'body', u'name': u'items'} - ]) - data['items'][0]["id"] = "0" - data['features'] = [ - { - "code": "OCDS-123454-AIR-INTAKE", - "featureOf": "lot", - "title": u"Потужність всмоктування", - "enum": [ - { - "value": 0.1, - "title": u"До 1000 Вт" - }, - { - "value": 0.15, - "title": u"Більше 1000 Вт" - } - ] - } - ] - response = self.app.post_json('/auctions', {'data': data}, 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'relatedItem': [u'This field is required.']}], u'location': u'body', u'name': u'features'} - ]) - data['features'][0]["relatedItem"] = "2" - response = self.app.post_json('/auctions', {'data': data}, 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'relatedItem': [u'relatedItem should be one of lots']}], u'location': u'body', u'name': u'features'} - ]) - data['features'][0]["featureOf"] = "item" - response = self.app.post_json('/auctions', {'data': data}, 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'relatedItem': [u'relatedItem should be one of items']}], u'location': u'body', u'name': u'features'} - ]) - data['features'][0]["relatedItem"] = "1" - data['features'][0]["enum"][0]["value"] = 0.5 - response = self.app.post_json('/auctions', {'data': data}, 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'enum': [{u'value': [u'Float value should be less than 0.3.']}]}], u'location': u'body', u'name': u'features'} - ]) - data['features'][0]["enum"][0]["value"] = 0.15 - response = self.app.post_json('/auctions', {'data': data}, 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'enum': [u'Feature value should be uniq for feature']}], u'location': u'body', u'name': u'features'} - ]) - data['features'][0]["enum"][0]["value"] = 0.1 - data['features'].append(data['features'][0].copy()) - response = self.app.post_json('/auctions', {'data': data}, 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'Feature code should be uniq for all features'], u'location': u'body', u'name': u'features'} - ]) - data['features'][1]["code"] = u"OCDS-123454-YEARS" - data['features'][1]["enum"][0]["value"] = 0.2 - response = self.app.post_json('/auctions', {'data': data}, 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'Sum of max value of all features should be less then or equal to 30%'], u'location': u'body', u'name': u'features'} - ]) - - @unittest.skip("option not available") - def test_auction_features(self): - data = self.initial_data.copy() - item = data['items'][0].copy() - item['id'] = "1" - data['items'] = [item] - data['features'] = [ - { - "code": "OCDS-123454-AIR-INTAKE", - "featureOf": "item", - "relatedItem": "1", - "title": u"Потужність всмоктування", - "title_en": u"Air Intake", - "description": u"Ефективна потужність всмоктування пилососа, в ватах (аероватах)", - "enum": [ - { - "value": 0.05, - "title": u"До 1000 Вт" - }, - { - "value": 0.1, - "title": u"Більше 1000 Вт" - } - ] - }, - { - "code": "OCDS-123454-YEARS", - "featureOf": "tenderer", - "title": u"Років на ринку", - "title_en": u"Years trading", - "description": u"Кількість років, які організація учасник працює на ринку", - "enum": [ - { - "value": 0.05, - "title": u"До 3 років" - }, - { - "value": 0.1, - "title": u"Більше 3 років" - } - ] - }, - { - "code": "OCDS-123454-POSTPONEMENT", - "featureOf": "tenderer", - "title": u"Відстрочка платежу", - "title_en": u"Postponement of payment", - "description": u"Термін відстрочки платежу", - "enum": [ - { - "value": 0.05, - "title": u"До 90 днів" - }, - { - "value": 0.1, - "title": u"Більше 90 днів" - } - ] - } - ] - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - auction = response.json['data'] - self.assertEqual(auction['features'], data['features']) - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'features': [{ - "featureOf": "tenderer", - "relatedItem": None - }, {}, {}]}}) - self.assertEqual(response.status, '200 OK') - 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}}}) - self.assertEqual(response.status, '200 OK') - self.assertIn('features', response.json['data']) - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'features': []}}) - self.assertEqual(response.status, '200 OK') - self.assertNotIn('features', response.json['data']) - - @unittest.skip("this test requires fixed version of jsonpatch library") - def test_patch_tender_jsonpatch(self): - response = self.app.post_json('/auctions', {'data': self.initial_data}) - self.assertEqual(response.status, '201 Created') - tender = response.json['data'] - owner_token = response.json['access']['token'] - dateModified = tender.pop('dateModified') - - import random - response = self.app.patch_json('/auctions/{}'.format(tender['id']), - {'data': {'items': [{"additionalClassifications": [ - { - "scheme": "ДКПП", - "id": "{}".format(i), - "description": "description #{}".format(i) - } - for i in random.sample(range(30), 25) - ]}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - response = self.app.patch_json('/auctions/{}'.format(tender['id']), - {'data': {'items': [{"additionalClassifications": [ - { - "scheme": "ДКПП", - "id": "{}".format(i), - "description": "description #{}".format(i) - } - for i in random.sample(range(30), 20) - ]}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - def test_patch_auction(self): - response = self.app.get('/auctions') - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 0) - - data = deepcopy(self.initial_data) - data['guarantee'] = {"amount": 100, "currency": "UAH"} - - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - auction = response.json['data'] - owner_token = response.json['access']['token'] - dateModified = auction.pop('dateModified') - - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {'data': {'status': 'cancelled'}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotEqual(response.json['data']['status'], 'cancelled') - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'status': 'cancelled'}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotEqual(response.json['data']['status'], 'cancelled') - - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {'data': {'procuringEntity': {'kind': 'defense'}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotIn('kind', response.json['data']['procuringEntity']) - - #response = self.app.patch_json('/auctions/{}'.format( - #auction['id']), {'data': {'tenderPeriod': {'startDate': None}}}) - #self.assertEqual(response.status, '200 OK') - #self.assertEqual(response.content_type, 'application/json') - #self.assertNotIn('startDate', response.json['data']['tenderPeriod']) - - #response = self.app.patch_json('/auctions/{}'.format( - #auction['id']), {'data': {'tenderPeriod': {'startDate': auction['enquiryPeriod']['endDate']}}}) - #self.assertEqual(response.status, '200 OK') - #self.assertEqual(response.content_type, 'application/json') - #self.assertIn('startDate', response.json['data']['tenderPeriod']) - - response = self.app.patch_json('/auctions/{}'.format( - auction['id']), {'data': {'procurementMethodRationale': 'Open'}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - new_auction = response.json['data'] - new_dateModified = new_auction.pop('dateModified') - new_auction['rectificationPeriod'].pop('invalidationDate') - self.assertEqual(auction, new_auction) - self.assertNotEqual(dateModified, new_dateModified) - - response = self.app.patch_json('/auctions/{}'.format( - auction['id']), {'data': {'dateModified': new_dateModified}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - new_auction2 = response.json['data'] - new_dateModified2 = new_auction2.pop('dateModified') - new_auction2['rectificationPeriod'].pop('invalidationDate') - self.assertEqual(new_auction, new_auction2) - self.assertEqual(new_dateModified, new_dateModified2) - - revisions = self.db.get(auction['id']).get('revisions') - - response = self.app.patch_json('/auctions/{}'.format( - auction['id']), {'data': {'items': [self.initial_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': [{}, self.initial_data['items'][0]]}}) - #self.assertEqual(response.status, '200 OK') - #self.assertEqual(response.content_type, 'application/json') - #item0 = response.json['data']['items'][0] - #item1 = response.json['data']['items'][1] - #self.assertNotEqual(item0.pop('id'), item1.pop('id')) - #self.assertEqual(item0, item1) - - #response = self.app.patch_json('/auctions/{}'.format( - #auction['id']), {'data': {'items': [{}]}}) - #self.assertEqual(response.status, '200 OK') - #self.assertEqual(response.content_type, 'application/json') - #self.assertEqual(len(response.json['data']['items']), 1) - - #response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"classification": { - #"scheme": u"CAV", - #"id": u"04000000-8", - #"description": u"Нерухоме майно" - #}}]}}) - #self.assertEqual(response.status, '200 OK') - #self.assertEqual(response.content_type, 'application/json') - - #response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'items': [{"additionalClassifications": [auction['items'][0]["classification"]]}]}}) - #self.assertEqual(response.status, '200 OK') - #self.assertEqual(response.content_type, 'application/json') - - response = self.app.patch_json('/auctions/{}'.format( - auction['id']), {'data': {'enquiryPeriod': {'endDate': new_dateModified2}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - new_auction = response.json['data'] - self.assertIn('startDate', new_auction['enquiryPeriod']) - - #response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"guarantee": {"amount": 12, "valueAddedTaxIncluded": True}}}, status=422) - #self.assertEqual(response.status, '422 Unprocessable Entity') - #self.assertEqual(response.json['errors'][0], {u'description': {u'valueAddedTaxIncluded': u'Rogue field'}, u'location': u'body', u'name': u'guarantee'}) - - #response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"guarantee": {"amount": 12}}}) - #self.assertEqual(response.status, '200 OK') - #self.assertIn('guarantee', response.json['data']) - #self.assertEqual(response.json['data']['guarantee']['amount'], 12) - #self.assertEqual(response.json['data']['guarantee']['currency'], 'UAH') - - #response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"guarantee": {"currency": "USD"}}}) - #self.assertEqual(response.status, '200 OK') - #self.assertEqual(response.json['data']['guarantee']['currency'], 'USD') - - #response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'status': 'active.auction'}}) - #self.assertEqual(response.status, '200 OK') - - #response = self.app.get('/auctions/{}'.format(auction['id'])) - #self.assertEqual(response.status, '200 OK') - #self.assertEqual(response.content_type, 'application/json') - #self.assertIn('auctionUrl', response.json['data']) - - # Check availability of value, minimalStep, guarantee - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertIn('value', response.json['data']) - self.assertIn('guarantee', response.json['data']) - self.assertIn('minimalStep', response.json['data']) - - value = response.json['data']['value'] - - # 422 very low amount - response = self.app.patch_json('/auctions/{}'.format(auction['id']),{'data': {'value': {'amount': auction['value']['amount'] - 80}}}, status=422) - self.assertEqual(response.json['errors'], [{'location': 'body', 'name': 'minimalStep', 'description': [u'value should be less than value of auction']}]) - - auction_data = self.db.get(auction['id']) - auction_data['status'] = 'complete' - self.db.save(auction_data) - - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'status': 'active.auction'}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update auction in current (complete) status") - - def test_patch_auction_rectificationPeriod_invalidationDate(self): - - response = self.app.get('/auctions') - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 0) - - data = deepcopy(self.initial_data) - data['guarantee'] = {"amount": 100, "currency": "UAH"} - - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - self.assertNotIn('invalidationDate', response.json['data']['rectificationPeriod']) - auction = response.json['data'] - owner_token = response.json['access']['token'] - - # patch one of main auction field by auction owner - - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"value": {"amount": 120}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('invalidationDate', response.json['data']['rectificationPeriod']) - - def test_patch_old_auction_rectificationPeriod_invalidationDate(self): - - response = self.app.get('/auctions') - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 0) - - data = deepcopy(self.initial_data) - data['auctionPeriod']['startDate'] = (get_now().date() + timedelta(days=8)).isoformat() - data['guarantee'] = {"amount": 100, "currency": "UAH"} - - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - self.assertNotIn('invalidationDate', response.json['data']['rectificationPeriod']) - auction = response.json['data'] - owner_token = response.json['access']['token'] - - db_auction = self.db.get(auction['id']) - del db_auction['rectificationPeriod'] - self.db.save(db_auction) - - # patch one of main auction field by auction owner - - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(auction['id'], owner_token), {"data": {"value": {"amount": 120}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('invalidationDate', response.json['data']['rectificationPeriod']) - - def test_dateModified_auction(self): - 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': self.initial_data}) - self.assertEqual(response.status, '201 Created') - auction = response.json['data'] - dateModified = auction['dateModified'] - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['dateModified'], dateModified) - - response = self.app.patch_json('/auctions/{}'.format( - auction['id']), {'data': {'procurementMethodRationale': 'Open'}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['dateModified'], dateModified) - auction = response.json['data'] - dateModified = auction['dateModified'] - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], auction) - self.assertEqual(response.json['data']['dateModified'], dateModified) - - def test_auction_not_found(self): - response = self.app.get('/auctions') - self.assertEqual(response.status, '200 OK') - self.assertEqual(len(response.json['data']), 0) - - response = self.app.get('/auctions/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'auction_id'} - ]) - - response = self.app.patch_json( - '/auctions/some_id', {'data': {}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'auction_id'} - ]) - - # put custom document object into database to check tender construction on non-Tender data - data = {'contract': 'test', '_id': uuid4().hex} - self.db.save(data) - - response = self.app.get('/auctions/{}'.format(data['_id']), status=404) - self.assertEqual(response.status, '404 Not Found') - - def test_guarantee(self): - data = deepcopy(self.initial_data) - data['guarantee'] = {"amount": 100, "currency": "UAH"} - response = self.app.post_json('/auctions', {'data': data}) - self.assertEqual(response.status, '201 Created') - self.assertIn('guarantee', response.json['data']) - self.assertEqual(response.json['data']['guarantee']['amount'], 100) - self.assertEqual(response.json['data']['guarantee']['currency'], 'UAH') - - def test_auction_Administrator_change(self): - response = self.app.post_json('/auctions', {'data': self.initial_data}) - self.assertEqual(response.status, '201 Created') - auction = response.json['data'] - - response = self.app.post_json('/auctions/{}/questions'.format(auction['id']), {'data': {'title': 'question title', 'description': 'question description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - question = response.json['data'] - - authorization = self.app.authorization - self.app.authorization = ('Basic', ('administrator', '')) - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'mode': u'test', 'procuringEntity': {"identifier": {"id": "00000000"}}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['mode'], u'test') - self.assertEqual(response.json['data']["procuringEntity"]["identifier"]["id"], "00000000") - - response = self.app.patch_json('/auctions/{}/questions/{}'.format(auction['id'], question['id']), {"data": {"answer": "answer"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {"location": "url", "name": "role", "description": "Forbidden"} - ]) - self.app.authorization = authorization - - response = self.app.post_json('/auctions', {'data': self.initial_data}) - self.assertEqual(response.status, '201 Created') - auction = response.json['data'] - - response = self.app.post_json('/auctions/{}/cancellations'.format(auction['id']), {'data': {'reason': 'cancellation reason', 'status': 'active'}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - - self.app.authorization = ('Basic', ('administrator', '')) - response = self.app.patch_json('/auctions/{}'.format(auction['id']), {'data': {'mode': u'test'}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['mode'], u'test') - - self.app.authorization = authorization - auction_data = deepcopy(self.initial_data) - auction_data['guarantee'] = {"amount": 100500, "currency": "USD"} - response = self.app.post_json('/auctions', {'data': auction_data}) - self.assertEqual(response.status, '201 Created') - auction = response.json['data'] - - self.app.authorization = ('Basic', ('administrator', '')) - - # Check availability of value, minimalStep, guarantee - - response = self.app.get('/auctions/{}'.format(auction['id'])) - self.assertIn('value', response.json['data']) - self.assertIn('guarantee', response.json['data']) - self.assertIn('minimalStep', response.json['data']) - - # 422 very low amount - response = self.app.patch_json('/auctions/{}'.format(auction['id']),{'data': {'value': {'amount': auction['value']['amount'] - 80}}}, status=422) - self.assertEqual(response.json['errors'], [{'location': 'body', 'name': 'minimalStep', 'description': [u'value should be less than value of auction']}]) + initial_status = 'active.tendering' + + test_empty_listing = snitch(empty_listing) + test_listing = snitch(listing) + test_listing_changes = snitch(listing_changes) + test_listing_draft = snitch(listing_draft) + test_create_auction_draft = snitch(create_auction_draft) + test_get_auction = snitch(get_auction) + test_auction_not_found = snitch(auction_not_found) + test_create_auction_validation_accelerated = snitch(create_auction_validation_accelerated) + test_create_auction_invalid = snitch(create_auction_invalid) + test_required_dgf_id = snitch(required_dgf_id) + test_required_dgf_item_address = snitch(required_dgf_item_address) + test_create_auction_auctionPeriod = snitch(create_auction_auctionPeriod) + test_create_auction_rectificationPeriod_generated = snitch(create_auction_rectificationPeriod_generated) + test_create_auction_rectificationPeriod_set = snitch(create_auction_rectificationPeriod_set) + test_create_auction_generated = snitch(create_auction_generated) + test_create_auction = snitch(create_auction) + test_additionalClassifications = snitch(additionalClassifications) + test_cavps_cpvs_classifications = snitch(cavps_cpvs_classifications) + test_auction_features_invalid = snitch(unittest.skip("option not available")(auction_features_invalid)) + test_auction_features = snitch(unittest.skip("option not available")(auction_features)) + test_patch_tender_jsonpatch = snitch(patch_tender_jsonpatch) + test_patch_auction = snitch(patch_auction) + test_patch_auction_rectificationPeriod_invalidationDate = snitch(patch_auction_rectificationPeriod_invalidationDate) + test_patch_old_auction_rectificationPeriod_invalidationDate = snitch(patch_old_auction_rectificationPeriod_invalidationDate) + test_dateModified_auction = snitch(dateModified_auction) + test_guarantee = snitch(guarantee) + test_auction_Administrator_change = snitch(auction_Administrator_change) class AuctionFieldsEditingTest(BaseAuctionWebTest): @@ -1542,460 +115,22 @@ class AuctionFieldsEditingTest(BaseAuctionWebTest): initial_maximum_data = test_auction_maximum_data initial_organization = test_organization initial_bids = test_bids + patch_auction_denied = snitch(patch_auction_denied) + patch_auction_during_rectification_period = snitch(patch_auction_during_rectification_period) + invalidate_bids_auction_unsuccessful = snitch(invalidate_bids_auction_unsuccessful) - def test_patch_auction_denied(self): - - # patch auction during rectificationPeriod - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'value': {'amount': 80}}}, status=200) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['value']['amount'], 80) - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'minimalStep': {'amount': 20}}}, status=200) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['minimalStep']['amount'], 20) - - self.go_to_rectificationPeriod_end() - - # patch auction after the rectificationPeriod.endDate - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'value': {'amount': 80}}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertIn(u'Auction can be edited only during the rectification period', response.json['errors'][0][u'description']) - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'minimalStep': {'amount': 20}}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertIn(u'Auction can be edited only during the rectification period', response.json['errors'][0][u'description']) - def test_patch_auction_during_rectification_period(self): - auction_data = deepcopy(self.initial_maximum_data) - classification_data_edited = { - "scheme": "CAV-PS", - "description": "Edited field", - "id": "06125000-4" - } - unit_data_edited = { - "code": "44617100-0", - "name": "edited item" - } - address_data_edited = auction_data["procuringEntity"]["address"] - response = self.app.post_json('/auctions', {'data': auction_data}) - self.assertEqual(response.status, '201 Created') - auction = response.json['data'] - - for param in ['title', 'title_en', 'title_ru']: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {param: auction[param] + u' EDITED'}}, status=200) - self.assertNotEqual(response.json['data'][param], auction[param]) - self.assertEqual(response.json['data'][param], auction[param] + u' EDITED') - - for param in ['description', 'description_en', 'description_ru']: - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'items' : [{param: auction[param] + u' EDITED'}]}}, status=200) - self.assertNotEqual(response.json['data']['items'][0][param], auction['items'][0][param]) - self.assertEqual(response.json['data']['items'][0][param], auction[param] + u' EDITED') - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'items': [{"address": address_data_edited}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotEqual(response.json['data']['items'][0]['address'], auction['items'][0]['address']) - self.assertEqual(response.json['data']['items'][0]['address'], address_data_edited) - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'items': [{"classification": classification_data_edited}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotEqual(response.json['data']['items'][0]['classification'], auction['items'][0]['classification']) - self.assertEqual(response.json['data']['items'][0]['classification'], classification_data_edited) - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'items': [{"unit": unit_data_edited}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotEqual(response.json['data']['items'][0]['unit'], auction['items'][0]['unit']) - self.assertEqual(response.json['data']['items'][0]['unit'], unit_data_edited) - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'items': [{"quantity": auction['items'][0]['quantity'] + 1}]}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotEqual(response.json['data']['items'][0]['quantity'], auction['items'][0]['quantity']) - self.assertEqual(response.json['data']['items'][0]['quantity'], auction['items'][0]['quantity'] + 1) - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'tenderAttempts': auction['tenderAttempts'] + 1} }) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotEqual(response.json['data']['tenderAttempts'], auction['tenderAttempts']) - self.assertEqual(response.json['data']['tenderAttempts'], auction['tenderAttempts'] + 1) - - response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'dgfID': auction['dgfID'] + u'EDITED'} }) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotEqual(response.json['data']['dgfID'], auction['dgfID']) - self.assertEqual(response.json['data']['dgfID'], auction['dgfID'] + u'EDITED') - - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(self.auction_id, self.auction_token), {'data': { 'value': {'valueAddedTaxIncluded': False, 'amount': auction['value']['amount']}, - 'minimalStep':{'valueAddedTaxIncluded': False}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['value']['valueAddedTaxIncluded'], False) - self.assertEqual(response.json['data']['minimalStep']['valueAddedTaxIncluded'], False) - - def test_invalidate_bids_auction_unsuccessful(self): - - # patch auction already created - - response = self.app.patch_json('/auctions/{}?acc_token={}'.format(self.auction_id, self.auction_token), {'data': {'value': {'amount': 80}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - # switch to active.auction - - response = self.set_status('active.auction', {'status': self.initial_status}) - 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.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "unsuccessful") - self.assertNotIn("awards", response.json['data']) - self.assertNotIn("bids", response.json['data']) +class AuctionProcessTest(BaseAuctionWebTest): + test_invalid_auction_conditions = snitch(unittest.skip("option not available")(invalid_auction_conditions)) + test_one_valid_bid_auction = snitch(one_valid_bid_auction) + test_one_invalid_bid_auction = snitch(one_invalid_bid_auction) + test_first_bid_auction = snitch(first_bid_auction) -class AuctionProcessTest(BaseAuctionWebTest): #setUp = BaseWebTest.setUp def setUp(self): super(AuctionProcessTest.__bases__[0], self).setUp() - @unittest.skip("option not available") - def test_invalid_auction_conditions(self): - self.app.authorization = ('Basic', ('broker', '')) - # empty auctions listing - response = self.app.get('/auctions') - self.assertEqual(response.json['data'], []) - # create auction - response = self.app.post_json('/auctions', - {"data": self.initial_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - # switch to active.tendering - self.set_status('active.tendering') - # create compaint - response = self.app.post_json('/auctions/{}/complaints'.format(auction_id), - {'data': {'title': 'invalid conditions', 'description': 'description', 'author': self.initial_organization, 'status': 'claim'}}) - complaint_id = response.json['data']['id'] - complaint_owner_token = response.json['access']['token'] - # answering claim - self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(auction_id, complaint_id, owner_token), {"data": { - "status": "answered", - "resolutionType": "resolved", - "resolution": "I will cancel the auction" - }}) - # satisfying resolution - self.app.patch_json('/auctions/{}/complaints/{}?acc_token={}'.format(auction_id, complaint_id, complaint_owner_token), {"data": { - "satisfied": True, - "status": "resolved" - }}) - # cancellation - self.app.post_json('/auctions/{}/cancellations?acc_token={}'.format(auction_id, owner_token), {'data': { - 'reason': 'invalid conditions', - 'status': 'active' - }}) - # check status - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertEqual(response.json['data']['status'], 'cancelled') - - def test_one_valid_bid_auction(self): - self.app.authorization = ('Basic', ('broker', '')) - # empty auctions listing - response = self.app.get('/auctions') - self.assertEqual(response.json['data'], []) - # create auction - - data = deepcopy(self.initial_data) - data['minNumberOfQualifiedBids'] = 1 - - response = self.app.post_json('/auctions', - {"data": data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - # switch to active.tendering - response = self.set_status('active.tendering', {"auctionPeriod": {"startDate": (get_now() + timedelta(days=10)).isoformat()}}) - self.assertIn("auctionPeriod", response.json['data']) - # create bid - self.app.authorization = ('Basic', ('broker', '')) - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True, 'eligible': True}}) - else: - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], "value": {"amount": 500}, 'qualified': True}}) - # switch to active.qualification - self.set_status('active.auction', {'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - self.assertNotIn('auctionPeriod', response.json['data']) - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending.verification award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending.verification'][0] - award_date = [i['date'] for i in response.json['data'] if i['status'] == 'pending.verification'][0] - response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( - self.auction_id, award_id, owner_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('auction_protocol.pdf', response.json["data"]["title"]) - response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, award_id, doc_id, owner_token), {"data": { - "description": "auction protocol", - "documentType": 'auctionProtocol' - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') - self.assertEqual(response.json["data"]["author"], 'auction_owner') - - # set award as pending.payment - response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "pending.payment"}}) - self.assertNotEqual(response.json['data']['date'], award_date) - # set award as active - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) - # get contract id - response = self.app.get('/auctions/{}'.format(auction_id)) - contract_id = response.json['data']['contracts'][-1]['id'] - # after stand slill period - self.app.authorization = ('Basic', ('chronograph', '')) - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # sign contract - self.app.authorization = ('Basic', ('broker', '')) - self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertEqual(response.json['data']['status'], 'complete') - - def test_one_invalid_bid_auction(self): - self.app.authorization = ('Basic', ('broker', '')) - # empty auctions listing - response = self.app.get('/auctions') - self.assertEqual(response.json['data'], []) - # create auction - data = deepcopy(self.initial_data) - data['minNumberOfQualifiedBids'] = 1 - - response = self.app.post_json('/auctions', - {"data": data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - # switch to active.tendering - self.set_status('active.tendering') - # create bid - self.app.authorization = ('Basic', ('broker', '')) - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True, 'eligible': True}}) - else: - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True}}) - # switch to active.qualification - self.set_status('active.auction', {"auctionPeriod": {"startDate": None}, 'status': 'active.tendering'}) - self.app.authorization = ('Basic', ('chronograph', '')) - response = self.app.patch_json('/auctions/{}'.format(auction_id), {"data": {"id": auction_id}}) - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award_id = [i['id'] for i in response.json['data'] if i['status'] == 'pending.verification'][0] - # set award as unsuccessful - response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), - {"data": {"status": "unsuccessful"}}) - - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_first_bid_auction(self): - self.app.authorization = ('Basic', ('broker', '')) - # empty auctions listing - response = self.app.get('/auctions') - self.assertEqual(response.json['data'], []) - # create auction - response = self.app.post_json('/auctions', - {"data": self.initial_data}) - auction_id = self.auction_id = response.json['data']['id'] - owner_token = response.json['access']['token'] - # switch to active.tendering - self.set_status('active.tendering') - # create bid - self.app.authorization = ('Basic', ('broker', '')) - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True, 'eligible': True}}) - else: - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True}}) - bid_id = response.json['data']['id'] - bid_token = response.json['access']['token'] - bids_tokens = {bid_id: bid_token} - # create second bid - self.app.authorization = ('Basic', ('broker', '')) - if self.initial_organization == test_financial_organization: - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True, 'eligible': True}}) - else: - response = self.app.post_json('/auctions/{}/bids'.format(auction_id), - {'data': {'tenderers': [self.initial_organization], "value": {"amount": 450}, 'qualified': True}}) - bids_tokens[response.json['data']['id']] = response.json['access']['token'] - # switch to active.auction - self.set_status('active.auction') - - # get auction info - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.get('/auctions/{}/auction'.format(auction_id)) - auction_bids_data = response.json['data']['bids'] - # posting auction urls - response = self.app.patch_json('/auctions/{}/auction'.format(auction_id), - { - 'data': { - 'auctionUrl': 'https://auction.auction.url', - 'bids': [ - { - 'id': i['id'], - 'participationUrl': 'https://auction.auction.url/for_bid/{}'.format(i['id']) - } - for i in auction_bids_data - ] - } - }) - # view bid participationUrl - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/bids/{}?acc_token={}'.format(auction_id, bid_id, bid_token)) - self.assertEqual(response.json['data']['participationUrl'], 'https://auction.auction.url/for_bid/{}'.format(bid_id)) - - # posting auction results - self.app.authorization = ('Basic', ('auction', '')) - response = self.app.post_json('/auctions/{}/auction'.format(auction_id), - {'data': {'bids': auction_bids_data}}) - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending.verification award - award = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] - award_id = award['id'] - # Upload auction protocol - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( - self.auction_id, award_id, owner_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - - response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, award_id, doc_id, owner_token), {"data": { - "description": "auction protocol", - "documentType": 'auctionProtocol' - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') - self.assertEqual(response.json["data"]["author"], 'auction_owner') - # set award as unsuccessful - response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), - {"data": {"status": "unsuccessful"}}) - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award2 = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] - award2_id = award2['id'] - self.assertNotEqual(award_id, award2_id) - # create first award complaint - # self.app.authorization = ('Basic', ('broker', '')) - # response = self.app.post_json('/auctions/{}/awards/{}/complaints?acc_token={}'.format(auction_id, award_id, bid_token), - # {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization, 'status': 'claim'}}) - # complaint_id = response.json['data']['id'] - # complaint_owner_token = response.json['access']['token'] - # # create first award complaint #2 - # response = self.app.post_json('/auctions/{}/awards/{}/complaints?acc_token={}'.format(auction_id, award_id, bid_token), - # {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - # # answering claim - # self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(auction_id, award_id, complaint_id, owner_token), {"data": { - # "status": "answered", - # "resolutionType": "resolved", - # "resolution": "resolution text " * 2 - # }}) - # # satisfying resolution - # self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(auction_id, award_id, complaint_id, complaint_owner_token), {"data": { - # "satisfied": True, - # "status": "resolved" - # }}) - # get awards - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}/awards?acc_token={}'.format(auction_id, owner_token)) - # get pending award - award = [i for i in response.json['data'] if i['status'] == 'pending.verification'][0] - award_id = award['id'] - # Upload auction protocol - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.post('/auctions/{}/awards/{}/documents?acc_token={}'.format( - self.auction_id, award_id, owner_token), upload_files=[('file', 'auction_protocol.pdf', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - - response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}?acc_token={}'.format(self.auction_id, award_id, doc_id, owner_token), {"data": { - "description": "auction protocol", - "documentType": 'auctionProtocol' - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json["data"]["documentType"], 'auctionProtocol') - self.assertEqual(response.json["data"]["author"], 'auction_owner') - # set award as "pending.payment - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "pending.payment"}}) - # set award as active - self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(auction_id, award_id, owner_token), {"data": {"status": "active"}}) - # get contract id - response = self.app.get('/auctions/{}'.format(auction_id)) - contract_id = response.json['data']['contracts'][-1]['id'] - # create auction contract document for test - response = self.app.post('/auctions/{}/contracts/{}/documents?acc_token={}'.format(auction_id, contract_id, owner_token), upload_files=[('file', 'name.doc', 'content')], status=201) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - # after stand slill period - self.app.authorization = ('Basic', ('chronograph', '')) - self.set_status('complete', {'status': 'active.awarded'}) - # time travel - auction = self.db.get(auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - # sign contract - self.app.authorization = ('Basic', ('broker', '')) - self.app.patch_json('/auctions/{}/contracts/{}?acc_token={}'.format(auction_id, contract_id, owner_token), {"data": {"status": "active"}}) - # check status - self.app.authorization = ('Basic', ('broker', '')) - response = self.app.get('/auctions/{}'.format(auction_id)) - self.assertEqual(response.json['data']['status'], 'complete') - - response = self.app.post('/auctions/{}/contracts/{}/documents?acc_token={}'.format(auction_id, contract_id, owner_token), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (complete) auction status") - - response = self.app.patch_json('/auctions/{}/contracts/{}/documents/{}?acc_token={}'.format(auction_id, contract_id, doc_id, owner_token), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") - - response = self.app.put('/auctions/{}/contracts/{}/documents/{}?acc_token={}'.format(auction_id, contract_id, doc_id, owner_token), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") - class FinancialAuctionTest(AuctionTest): auction = DGFFinancialAssets From 0b20e26f24cbe98164e6241d6a88ab27c7da2557 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Fri, 23 Mar 2018 11:35:58 +0200 Subject: [PATCH 31/45] Move tests to core.plugins awarding tests --- openprocurement/auctions/dgf/tests/award.py | 2548 +------------------ 1 file changed, 119 insertions(+), 2429 deletions(-) diff --git a/openprocurement/auctions/dgf/tests/award.py b/openprocurement/auctions/dgf/tests/award.py index 383deea9..10271ea4 100644 --- a/openprocurement/auctions/dgf/tests/award.py +++ b/openprocurement/auctions/dgf/tests/award.py @@ -9,6 +9,67 @@ test_financial_auction_data, test_financial_organization, ) +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.plugins.awarding.v2_1.tests.blanks.award_blanks import ( + # CreateAuctionAwardTest + create_auction_award_invalid, + create_auction_award, + # AuctionAwardProcessTest + invalid_patch_auction_award, + patch_auction_award, + patch_auction_award_admin, + complate_auction_with_second_award1, + complate_auction_with_second_award2, + complate_auction_with_second_award3, + successful_second_auction_award, + unsuccessful_auction1, + unsuccessful_auction2, + unsuccessful_auction3, + unsuccessful_auction4, + unsuccessful_auction5, + get_auction_awards, + patch_auction_award_Administrator_change, + # AuctionLotAwardResourceTest + create_auction_award_lot, + patch_auction_award_lot, + patch_auction_award_unsuccessful_lot, + # Auction2LotAwardResourceTest + create_auction_award_2_lots, + patch_auction_award_2_lots, + # AuctionAwardComplaintResourceTest + create_auction_award_complaint_invalid, + create_auction_award_complaint, + patch_auction_award_complaint, + review_auction_award_complaint, + get_auction_award_complaint, + get_auction_award_complaints, + # AuctionLotAwardComplaintResourceTest + create_auction_award_complaint_lot_complaint, + patch_auction_award_complaint_lot_complaint, + get_auction_award_complaint_lot_complaint, + get_auction_award_complaints_lot_complaint, + # Auction2LotAwardComplaintResourceTest + create_auction_award_complaint_2_lot_complaint, + patch_auction_award_complaint_2_lot_complaint, + # AuctionAwardComplaintDocumentResourceTest + not_found_award_complaint_document, + create_auction_award_complaint_document, + put_auction_award_complaint_document, + patch_auction_award_complaint_document, + # Auction2LotAwardComplaintDocumentResourceTest + create_auction_award_complaint_document_2_lots, + put_auction_award_complaint_document_2_lots, + patch_auction_award_complaint_document_2_lots, + # AuctionAwardDocumentResourceTest + not_found_award_document, + create_auction_award_document, + put_auction_award_document, + patch_auction_award_document, + # Auction2LotAwardDocumentResourceTest + create_auction_award_document_2_lots, + put_auction_award_document_2_lots, + patch_auction_award_document_2_lots, +) bid = { "tenderers": [ test_organization @@ -37,153 +98,9 @@ class CreateAuctionAwardTest(BaseAuctionWebTest): initial_bids = test_bids docservice = True - def test_create_auction_award_invalid(self): - request_path = '/auctions/{}/awards'.format(self.auction_id) - response = self.app.post(request_path, 'data', status=415) - self.assertEqual(response.status, '415 Unsupported Media Type') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': - u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} - ]) - - response = self.app.post( - request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, 'data', 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json( - request_path, {'not_data': {}}, 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'data': { - 'invalid_field': 'invalid_value'}}, 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'Rogue field', u'location': - u'body', u'name': u'invalid_field'} - ]) - - response = self.app.post_json(request_path, { - 'data': {'suppliers': [{'identifier': 'invalid_value'}]}}, 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'identifier': [ - u'Please use a mapping for this field or Identifier instance instead of unicode.']}, u'location': u'body', u'name': u'suppliers'} - ]) - - response = self.app.post_json(request_path, { - 'data': {'suppliers': [{'identifier': {'id': 0}}]}}, 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'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.']}, u'name': [u'This field is required.'], u'address': [u'This field is required.']}], u'location': u'body', u'name': u'suppliers'}, - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'bid_id'} - ]) - - response = self.app.post_json(request_path, {'data': {'suppliers': [ - {'name': 'name', 'identifier': {'uri': 'invalid_value'}}]}}, 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'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.'], u'uri': [u'Not a well formed URL.']}, u'address': [u'This field is required.']}], u'location': u'body', u'name': u'suppliers'}, - {u'description': [u'This field is required.'], u'location': u'body', u'name': u'bid_id'} - ]) - - response = self.app.post_json(request_path, {'data': { - 'suppliers': [self.initial_organization], - 'status': 'pending.verification', - 'bid_id': self.initial_bids[0]['id'], - 'lotID': '0' * 32 - }}, 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'lotID should be one of lots'], u'location': u'body', u'name': u'lotID'} - ]) - - response = self.app.post_json('/auctions/some_id/awards', {'data': { - 'suppliers': [self.initial_organization], 'bid_id': self.initial_bids[0]['id']}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/some_id/awards', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - self.set_status('complete') - - response = self.app.post_json('/auctions/{}/awards'.format( - self.auction_id), {'data': {'suppliers': [self.initial_organization], 'status': 'pending.verification', 'bid_id': self.initial_bids[0]['id']}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't create award in current (complete) auction status") - - def test_create_auction_award(self): - request_path = '/auctions/{}/awards'.format(self.auction_id) - response = self.app.post_json(request_path, {'data': {'suppliers': [self.initial_organization], 'bid_id': self.initial_bids[0]['id']}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - award = response.json['data'] - self.assertEqual(award['suppliers'][0]['name'], self.initial_organization['name']) - self.assertIn('id', award) - self.assertIn(award['id'], response.headers['Location']) - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][-1], award) - - self.upload_auction_protocol(award) + test_create_auction_award_invalid = snitch(create_auction_award_invalid) + test_create_auction_award = snitch(create_auction_award) - response = self.patch_award(award['id'], "pending.payment") - self.assertEqual(response.json['data']['status'], u'pending.payment') - - response = self.patch_award(award['id'], "active") - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') class AuctionAwardProcessTest(BaseAuctionWebTest): @@ -192,437 +109,25 @@ class AuctionAwardProcessTest(BaseAuctionWebTest): initial_bids = test_bids docservice = True + test_invalid_patch_auction_award = snitch(invalid_patch_auction_award) + test_patch_auction_award = snitch(patch_auction_award) + test_patch_auction_award_admin = snitch(patch_auction_award_admin) + test_complate_auction_with_second_award1 = snitch(complate_auction_with_second_award1) + test_complate_auction_with_second_award2 = snitch(complate_auction_with_second_award2) + test_complate_auction_with_second_award3 = snitch(complate_auction_with_second_award3) + test_successful_second_auction_award = snitch(successful_second_auction_award) + test_unsuccessful_auction1 = snitch(unsuccessful_auction1) + test_unsuccessful_auction2 = snitch(unsuccessful_auction2) + test_unsuccessful_auction3 = snitch(unsuccessful_auction3) + test_unsuccessful_auction4 = snitch(unsuccessful_auction4) + test_unsuccessful_auction5 = snitch(unsuccessful_auction5) + test_get_auction_awards = snitch(get_auction_awards) + test_patch_auction_award_Administrator_change = snitch(patch_auction_award_Administrator_change) + def setUp(self): super(AuctionAwardProcessTest, self).setUp() self.post_auction_results() - def test_invalid_patch_auction_award(self): - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.first_award_id), {"data": {"status": "pending.payment"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't switch award status to (pending.payment) before auction owner load auction protocol") - - for i in ["pending.waiting", "active", "cancelled"]: - self.forbidden_patch_award(self.first_award_id, "pending.verification", i) - - for i in ["unsuccessful", "pending.verification", "pending.payment", "active"]: - self.forbidden_patch_award(self.second_award_id, "pending.waiting", i) - - self.upload_auction_protocol(self.first_award) - - for i in ["pending.waiting", "active", "cancelled"]: - self.forbidden_patch_award(self.first_award_id, "pending.verification", i) - - for i in ["unsuccessful", "pending.verification", "pending.payment", "active"]: - self.forbidden_patch_award(self.second_award_id, "pending.waiting", i) - - response = self.patch_award(self.first_award_id, "pending.payment") - self.assertEqual(response.json['data']['status'], "pending.payment") - - for i in ["cancelled", "pending.waiting", "pending.verification"]: - self.forbidden_patch_award(self.first_award_id, "pending.payment", i) - - for i in ["unsuccessful", "pending.verification", "pending.payment", "active"]: - self.forbidden_patch_award(self.second_award_id, "pending.waiting", i) - - response = self.patch_award(self.first_award_id, "active") - self.assertEqual(response.json['data']['status'], "active") - - for i in ["cancelled", "pending.waiting", "pending.verification", "pending.payment"]: - self.forbidden_patch_award(self.first_award_id, "active", i) - - for i in ["unsuccessful", "pending.verification", "pending.payment", "active"]: - self.forbidden_patch_award(self.second_award_id, "pending.waiting", i) - - response = self.patch_award(self.first_award_id, "unsuccessful") - self.assertEqual(response.json['data']['status'], "unsuccessful") - self.assertIn('Location', response.headers) - self.assertIn(self.second_award_id, response.headers['Location']) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.first_award_id), {"data": {"status": "active"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update award in current (unsuccessful) status") - - self.upload_auction_protocol(self.second_award) - - for i in ["pending.payment", "active"]: - self.patch_award(self.second_award_id, i) - - self.set_status('complete') - - def test_patch_auction_award(self): - request_path = '/auctions/{}/awards'.format(self.auction_id) - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - - response = self.app.patch_json('/auctions/{}/awards/some_id'.format(self.auction_id), {"data": {"status": "unsuccessful"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/awards/some_id', {"data": {"status": "unsuccessful"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.first_award_id), {"data": {"awardStatus": "unsuccessful"}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {"location": "body", "name": "awardStatus", "description": "Rogue field"} - ]) - - self.upload_auction_protocol(self.first_award) - - response = self.patch_award(self.first_award_id, "unsuccessful") - self.assertIn('Location', response.headers) - new_award_location = response.headers['Location'] - self.assertIn(self.second_award_id, new_award_location) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.first_award_id), {"data": {"status": "active"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update award in current (unsuccessful) status") - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - self.assertIn(response.json['data'][1]['id'], new_award_location) - - response = self.app.patch_json('/auctions/{}/awards/{}?acc_token={}'.format(self.auction_id, self.second_award_id, self.auction_token), - {"data": {"title": "title", "description": "description"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['title'], 'title') - self.assertEqual(response.json['data']['description'], 'description') - - self.upload_auction_protocol(self.second_award) - - self.patch_award(self.second_award_id, "pending.payment") - - self.patch_award(self.second_award_id, "active") - - self.set_status('complete') - - response = self.app.get('/auctions/{}/awards/{}'.format(self.auction_id, self.second_award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["value"]["amount"], 469) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.second_award_id), {"data": {"status": "unsuccessful"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update award in current (complete) auction status") - - def test_patch_auction_award_admin(self): - request_path = '/auctions/{}/awards'.format(self.auction_id) - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - authorization = self.app.authorization - - self.app.authorization = ('Basic', ('administrator', '')) - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.first_award_id), - {"data":{ - "paymentPeriod": {'endDate': self.first_award['paymentPeriod']['startDate']}, - "verificationPeriod": {'endDate': self.first_award['verificationPeriod']['startDate']}, - "signingPeriod": {'endDate': self.first_award['signingPeriod']['startDate']} - } - }) - self.assertEqual(response.status, '200 OK') - first_award = response.json['data'] - self.assertEqual(first_award['verificationPeriod']['startDate'], first_award['verificationPeriod']['endDate']) - self.assertEqual(first_award['paymentPeriod']['startDate'], first_award['paymentPeriod']['endDate']) - self.assertEqual(first_award['signingPeriod']['startDate'], first_award['signingPeriod']['endDate']) - - response = self.app.patch_json('/auctions/{}/awards/{}?opt_pretty'.format(self.auction_id, self.first_award_id), - {"data":{ - "status": 'active', - "paymentPeriod": {'endDate': None}, - "verificationPeriod": {'endDate': None}, - "signingPeriod": {'endDate': None}} - }) - self.assertEqual(response.status, '200 OK') - first_award = response.json['data'] - self.assertNotEqual(first_award['status'], 'active') - self.assertNotEqual(first_award['paymentPeriod']['startDate'], first_award['paymentPeriod']['endDate']) - self.assertEqual(first_award['paymentPeriod']['endDate'], self.first_award['paymentPeriod']['endDate']) - self.assertNotEqual(first_award['verificationPeriod']['startDate'], first_award['verificationPeriod']['endDate']) - self.assertEqual(first_award['verificationPeriod']['endDate'], self.first_award['verificationPeriod']['endDate']) - self.assertNotEqual(first_award['signingPeriod']['startDate'], first_award['signingPeriod']['endDate']) - self.assertEqual(first_award['signingPeriod']['endDate'], self.first_award['signingPeriod']['endDate']) - - self.app.authorization = authorization - - self.upload_auction_protocol(self.first_award) - - self.patch_award(self.first_award_id, "pending.payment") - - self.patch_award(self.first_award_id, "active") - - self.set_status('complete') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], 'complete') - - def test_complate_auction_with_second_award1(self): - self.upload_auction_protocol(self.first_award) - - response = self.patch_award(self.first_award_id, "unsuccessful") - self.assertIn('Location', response.headers) - self.assertIn(self.second_award_id, response.headers['Location']) - - self.upload_auction_protocol(self.second_award) - - self.patch_award(self.second_award_id, "pending.payment") - - self.patch_award(self.second_award_id, "active") - - self.set_status('complete') - - response = self.app.get('/auctions/{}/awards/{}'.format(self.auction_id, self.second_award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["value"]["amount"], 469) - - def test_complate_auction_with_second_award2(self): - self.upload_auction_protocol(self.first_award) - - self.patch_award(self.first_award_id, "pending.payment") - - response = self.patch_award(self.first_award_id, "unsuccessful") - self.assertIn('Location', response.headers) - self.assertIn(self.second_award_id, response.headers['Location']) - - self.upload_auction_protocol(self.second_award) - - self.patch_award(self.second_award_id, "pending.payment") - - self.patch_award(self.second_award_id, "active") - - self.set_status('complete') - - response = self.app.get('/auctions/{}/awards/{}'.format(self.auction_id, self.second_award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["value"]["amount"], 469) - - def test_complate_auction_with_second_award3(self): - self.upload_auction_protocol(self.first_award) - - self.patch_award(self.first_award_id, "pending.payment") - - self.patch_award(self.first_award_id, "active") - - response = self.patch_award(self.first_award_id, "unsuccessful") - self.assertIn('Location', response.headers) - self.assertIn(self.second_award_id, response.headers['Location']) - - self.upload_auction_protocol(self.second_award) - - self.patch_award(self.second_award_id, "pending.payment") - - self.patch_award(self.second_award_id, "active") - - self.set_status('complete') - - response = self.app.get('/auctions/{}/awards/{}'.format(self.auction_id, self.second_award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["value"]["amount"], 469) - - def test_successful_second_auction_award(self): - request_path = '/auctions/{}/awards'.format(self.auction_id) - self.upload_auction_protocol(self.first_award) - - self.patch_award(self.first_award_id, "pending.payment") - - self.patch_award(self.first_award_id, "active") - - response = self.patch_award(self.first_award_id, "unsuccessful") - self.assertIn('Location', response.headers) - new_award_location = response.headers['Location'] - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - self.assertIn(response.json['data'][1]['id'], new_award_location) - new_award = response.json['data'][-1] - - self.upload_auction_protocol(self.second_award) - - self.patch_award(self.second_award_id, "pending.payment") - - self.patch_award(self.second_award_id, "active") - - self.set_status('complete') - - response = self.app.get('/auctions/{}/awards/{}'.format(self.auction_id, self.second_award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["value"]["amount"], 469) - - def test_unsuccessful_auction1(self): - response = self.app.patch_json('/auctions/{}/awards/{}?acc_token=1'.format(self.auction_id, self.second_award_id), {"data": {"status": "cancelled"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Only bid owner may cancel award in current (pending.waiting) status', u'location': - u'body', u'name': u'data'} - ]) - - bid_token = self.initial_bids_tokens[self.first_award['bid_id']] - self.patch_award(self.second_award_id, "cancelled", bid_token=bid_token) - - self.upload_auction_protocol(self.first_award) - - self.patch_award(self.first_award_id, "unsuccessful") - - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_unsuccessful_auction2(self): - bid_token = self.initial_bids_tokens[self.first_award['bid_id']] - self.patch_award(self.second_award_id, "cancelled", bid_token=bid_token) - - self.upload_auction_protocol(self.first_award) - - self.patch_award(self.first_award_id, "pending.payment") - - self.patch_award(self.first_award_id, "unsuccessful") - - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_unsuccessful_auction3(self): - bid_token = self.initial_bids_tokens[self.first_award['bid_id']] - self.patch_award(self.second_award_id, "cancelled", bid_token=bid_token) - - self.upload_auction_protocol(self.first_award) - - self.patch_award(self.first_award_id, "pending.payment") - - self.patch_award(self.first_award_id, "active") - - self.patch_award(self.first_award_id, "unsuccessful") - - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_unsuccessful_auction4(self): - self.upload_auction_protocol(self.first_award) - - self.patch_award(self.first_award_id, "pending.payment") - - bid_token = self.initial_bids_tokens[self.first_award['bid_id']] - self.patch_award(self.second_award_id, "cancelled", bid_token=bid_token) - - self.patch_award(self.first_award_id, "active") - - self.patch_award(self.first_award_id, "unsuccessful") - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_unsuccessful_auction5(self): - self.upload_auction_protocol(self.first_award) - - self.patch_award(self.first_award_id, "pending.payment") - - self.patch_award(self.first_award_id, "active") - - bid_token = self.initial_bids_tokens[self.first_award['bid_id']] - self.patch_award(self.second_award_id, "cancelled", bid_token=bid_token) - - self.patch_award(self.first_award_id, "unsuccessful") - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], 'unsuccessful') - - def test_get_auction_awards(self): - response = self.app.get('/auctions/{}/awards'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - fist_award = response.json['data'][0] - second_award = response.json['data'][1] - - response = self.app.get('/auctions/{}/awards/{}'.format(self.auction_id, fist_award['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], 'pending.verification') - self.assertIn('verificationPeriod', response.json['data']) - - response = self.app.get('/auctions/{}/awards/{}'.format(self.auction_id, second_award['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], 'pending.waiting') - - response = self.app.get('/auctions/{}/awards/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.get('/auctions/some_id/awards/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_patch_auction_award_Administrator_change(self): - response = self.app.post_json('/auctions/{}/awards'.format( - self.auction_id), {'data': {'suppliers': [self.initial_organization], 'bid_id': self.initial_bids[0]['id']}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - award = response.json['data'] - verificationPeriod = award['verificationPeriod'][u'startDate'] - authorization = self.app.authorization - self.app.authorization = ('Basic', ('administrator', '')) - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"verificationPeriod": {"endDate": award['verificationPeriod'][u'startDate']}}}) - - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn("endDate", response.json['data']['complaintPeriod']) - self.assertEqual(response.json['data']['verificationPeriod']["endDate"], verificationPeriod) @unittest.skip("option not available") class AuctionLotAwardResourceTest(BaseAuctionWebTest): @@ -630,185 +135,9 @@ class AuctionLotAwardResourceTest(BaseAuctionWebTest): initial_lots = test_lots initial_bids = test_bids - def test_create_auction_award(self): - request_path = '/auctions/{}/awards'.format(self.auction_id) - response = self.app.post_json(request_path, {'data': {'suppliers': [self.initial_organization], 'status': 'pending', 'bid_id': self.initial_bids[0]['id']}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {"location": "body", "name": "lotID", "description": ["This field is required."]} - ]) - - response = self.app.post_json(request_path, {'data': {'suppliers': [self.initial_organization], 'status': 'pending', 'bid_id': self.initial_bids[0]['id'], 'lotID': self.initial_lots[0]['id']}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - award = response.json['data'] - self.assertEqual(award['suppliers'][0]['name'], self.initial_organization['name']) - self.assertEqual(award['lotID'], self.initial_lots[0]['id']) - self.assertIn('id', award) - self.assertIn(award['id'], response.headers['Location']) - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][-1], award) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"status": "cancelled"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'cancelled') - self.assertIn('Location', response.headers) - - def test_patch_auction_award(self): - request_path = '/auctions/{}/awards'.format(self.auction_id) - response = self.app.post_json(request_path, {'data': {'suppliers': [self.initial_organization], 'status': u'pending', 'bid_id': self.initial_bids[0]['id'], 'lotID': self.initial_lots[0]['id'], "value": {"amount": 500}}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - award = response.json['data'] - - response = self.app.patch_json('/auctions/{}/awards/some_id'.format(self.auction_id), {"data": {"status": "unsuccessful"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/awards/some_id', {"data": {"status": "unsuccessful"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"awardStatus": "unsuccessful"}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'], [ - {"location": "body", "name": "awardStatus", "description": "Rogue field"} - ]) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('Location', response.headers) - new_award_location = response.headers['Location'] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"status": "pending"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update award in current (unsuccessful) status") - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 3) - self.assertIn(response.json['data'][-1]['id'], new_award_location) - new_award = response.json['data'][-1] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.second_award_id), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 3) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.second_award_id), {"data": {"status": "cancelled"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('Location', response.headers) - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 3) - - self.set_status('complete') - - response = self.app.get('/auctions/{}/awards/{}'.format(self.auction_id, award['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["value"]["amount"], 500) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"status": "unsuccessful"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update award in current (complete) auction status") - - def test_patch_auction_award_unsuccessful(self): - request_path = '/auctions/{}/awards'.format(self.auction_id) - response = self.app.post_json(request_path, {'data': {'suppliers': [self.initial_organization], 'status': u'pending', 'bid_id': self.initial_bids[0]['id'], 'lotID': self.initial_lots[0]['id'], "value": {"amount": 500}}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - award = response.json['data'] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('Location', response.headers) - new_award_location = response.headers['Location'] - - response = self.app.patch_json(new_award_location[-82:], {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotIn('Location', response.headers) - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 3) - - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format(self.auction_id, award['id']), {'data': { - 'title': 'complaint title', - 'description': 'complaint description', - 'author': self.initial_organization, - 'status': 'claim' - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.post_json('{}/complaints'.format(new_award_location[-82:]), {'data': { - 'title': 'complaint title', - 'description': 'complaint description', - 'author': self.initial_organization - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"status": "cancelled"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('Location', response.headers) - new_award_location = response.headers['Location'] - - response = self.app.patch_json(new_award_location[-82:], {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertIn('Location', response.headers) - new_award_location = response.headers['Location'] - - response = self.app.patch_json(new_award_location[-82:], {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertNotIn('Location', response.headers) - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 4) + test_create_auction_award_lot = snitch(create_auction_award_lot) + test_patch_auction_award_lot = snitch(patch_auction_award_lot) + test_patch_auction_award_unsuccessful_lot = snitch(patch_auction_award_unsuccessful_lot) @unittest.skip("option not available") @@ -817,89 +146,8 @@ class Auction2LotAwardResourceTest(BaseAuctionWebTest): initial_lots = 2 * test_lots initial_bids = test_bids - def test_create_auction_award(self): - request_path = '/auctions/{}/awards'.format(self.auction_id) - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.post_json(request_path, {'data': { - 'suppliers': [self.initial_organization], - 'status': 'pending', - 'bid_id': self.initial_bids[0]['id'], - 'lotID': self.initial_lots[0]['id'] - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can create award only in active lot status") - - response = self.app.post_json(request_path, {'data': { - 'suppliers': [self.initial_organization], - 'status': 'pending', - 'bid_id': self.initial_bids[0]['id'], - 'lotID': self.initial_lots[1]['id'] - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - award = response.json['data'] - self.assertEqual(award['suppliers'][0]['name'], self.initial_organization['name']) - self.assertEqual(award['lotID'], self.initial_lots[1]['id']) - self.assertIn('id', award) - self.assertIn(award['id'], response.headers['Location']) - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][-1], award) - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active') - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'active.awarded') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"status": "cancelled"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']['status'], u'cancelled') - self.assertIn('Location', response.headers) - - def test_patch_auction_award(self): - request_path = '/auctions/{}/awards'.format(self.auction_id) - response = self.app.post_json(request_path, {'data': {'suppliers': [self.initial_organization], 'status': u'pending', 'bid_id': self.initial_bids[0]['id'], 'lotID': self.initial_lots[0]['id'], "value": {"amount": 500}}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - award = response.json['data'] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, award['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - - response = self.app.get(request_path) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(len(response.json['data']), 2) - new_award = response.json['data'][-1] - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[1]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.second_award_id), {"data": {"status": "unsuccessful"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update award only in active lot status") + test_create_auction_award_2_lots = snitch(create_auction_award_2_lots) + test_patch_auction_award_2_lots = snitch(patch_auction_award_2_lots) @unittest.skip("option not available") @@ -908,6 +156,13 @@ class AuctionAwardComplaintResourceTest(BaseAuctionWebTest): initial_status = 'active.qualification' initial_bids = test_bids + test_create_auction_award_complaint_invalid = snitch(create_auction_award_complaint_invalid) + test_create_auction_award_complaint = snitch(create_auction_award_complaint) + test_patch_auction_award_complaint = snitch(patch_auction_award_complaint) + test_review_auction_award_complaint = snitch(review_auction_award_complaint) + test_get_auction_award_complaint = snitch(get_auction_award_complaint) + test_get_auction_award_complaints = snitch(get_auction_award_complaints) + def setUp(self): super(AuctionAwardComplaintResourceTest, self).setUp() # Create award @@ -916,389 +171,6 @@ def setUp(self): award = response.json['data'] self.award_id = award['id'] - def test_create_auction_award_complaint_invalid(self): - response = self.app.post_json('/auctions/some_id/awards/some_id/complaints', { - 'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'auction_id'} - ]) - - request_path = '/auctions/{}/awards/{}/complaints'.format(self.auction_id, self.award_id) - - response = self.app.post(request_path, 'data', status=415) - self.assertEqual(response.status, '415 Unsupported Media Type') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': - u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} - ]) - - response = self.app.post( - request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, 'data', 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json( - request_path, {'not_data': {}}, 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'data': {}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'author'}, response.json['errors']) - self.assertIn({u'description': [u'This field is required.'], u'location': u'body', u'name': u'title'}, response.json['errors']) - - response = self.app.post_json(request_path, {'data': { - 'invalid_field': 'invalid_value'}}, 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'Rogue field', u'location': - u'body', u'name': u'invalid_field'} - ]) - - response = self.app.post_json(request_path, { - 'data': {'author': {'identifier': 'invalid_value'}}}, 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'identifier': [ - u'Please use a mapping for this field or Identifier instance instead of unicode.']}, u'location': u'body', u'name': u'author'} - ]) - - response = self.app.post_json(request_path, { - 'data': {'title': 'complaint title', 'description': 'complaint description', 'author': {'identifier': {'id': 0}}}}, 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'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.']}, u'name': [u'This field is required.'], u'address': [u'This field is required.']}, u'location': u'body', u'name': u'author'} - ]) - - response = self.app.post_json(request_path, {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': { - 'name': 'name', 'identifier': {'uri': 'invalid_value'}}}}, 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'contactPoint': [u'This field is required.'], u'identifier': {u'scheme': [u'This field is required.'], u'id': [u'This field is required.'], u'uri': [u'Not a well formed URL.']}, u'address': [u'This field is required.']}, u'location': u'body', u'name': u'author'} - ]) - - def test_create_auction_award_complaint(self): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization, 'status': 'claim'}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - self.assertEqual(complaint['author']['name'], self.initial_organization['name']) - self.assertIn('id', complaint) - self.assertIn(complaint['id'], response.headers['Location']) - - self.set_status('active.awarded') - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "invalid", - "resolution": "spam 100% " * 3 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], "invalid") - self.assertEqual(response.json['data']["resolution"], "spam 100% " * 3) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], 'active.awarded') - - self.set_status('unsuccessful') - - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add complaint in current (unsuccessful) auction status") - - def test_patch_auction_award_complaint(self): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - owner_token = response.json['access']['token'] - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "status": "cancelled", - "cancellationReason": "reason" - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Forbidden") - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id, complaint['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "title": "claim title", - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["title"], "claim title") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "status": "claim", - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], "claim") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "resolution": "changing rules" - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["resolution"], "changing rules") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "resolved", - "resolution": "resolution text " * 2 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], "resolved") - self.assertEqual(response.json['data']["resolution"], "resolution text " * 2) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "satisfied": False - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["satisfied"], False) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "status": "resolved" - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update complaint") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "status": "pending" - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "pending") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "status": "cancelled", - "cancellationReason": "reason" - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "cancelled") - self.assertEqual(response.json['data']["cancellationReason"], "reason") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/some_id'.format(self.auction_id, self.award_id), {"data": {"status": "resolved", "resolution": "resolution text"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/awards/some_id/complaints/some_id', {"data": {"status": "resolved", "resolution": "resolution text"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "status": "cancelled", - "cancellationReason": "reason" - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update complaint in current (cancelled) status") - - response = self.app.patch_json('/auctions/{}/awards/some_id/complaints/some_id'.format(self.auction_id), {"data": {"status": "resolved", "resolution": "resolution text"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}'.format(self.auction_id, self.award_id, complaint['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "cancelled") - self.assertEqual(response.json['data']["cancellationReason"], "reason") - self.assertEqual(response.json['data']["resolutionType"], "resolved") - self.assertEqual(response.json['data']["resolution"], "resolution text " * 2) - - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - owner_token = response.json['access']['token'] - - self.set_status('complete') - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "status": "claim", - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update complaint in current (complete) auction status") - - def test_review_auction_award_complaint(self): - complaints = [] - for i in range(2): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format(self.auction_id, self.award_id), {'data': { - 'title': 'complaint title', - 'description': 'complaint description', - 'author': self.initial_organization, - 'status': 'claim' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - owner_token = response.json['access']['token'] - complaints.append(complaint) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "resolved", - "resolution": "resolution text " * 2 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], "resolved") - self.assertEqual(response.json['data']["resolution"], "resolution text " * 2) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "satisfied": False, - "status": "pending" - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "pending") - - self.app.authorization = ('Basic', ('reviewer', '')) - for complaint, status in zip(complaints, ['invalid', 'resolved', 'declined']): - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}'.format(self.auction_id, self.award_id, complaint['id']), {"data": { - "decision": '{} complaint'.format(status) - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["decision"], '{} complaint'.format(status)) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}'.format(self.auction_id, self.award_id, complaint['id']), {"data": { - "status": status - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], status) - - def test_get_auction_award_complaint(self): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}'.format(self.auction_id, self.award_id, complaint['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], complaint) - - response = self.app.get('/auctions/{}/awards/{}/complaints/some_id'.format(self.auction_id, self.award_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.get('/auctions/some_id/awards/some_id/complaints/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_get_auction_award_complaints(self): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - - response = self.app.get('/auctions/{}/awards/{}/complaints'.format(self.auction_id, self.award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][0], complaint) - - response = self.app.get('/auctions/some_id/awards/some_id/complaints', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - auction = self.db.get(self.auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add complaint only in complaintPeriod") - @unittest.skip("option not available") class AuctionLotAwardComplaintResourceTest(BaseAuctionWebTest): @@ -1307,6 +179,11 @@ class AuctionLotAwardComplaintResourceTest(BaseAuctionWebTest): initial_lots = test_lots initial_bids = test_bids + test_create_auction_award_complaint_lot_complaint = snitch(create_auction_award_complaint_lot_complaint) + test_patch_auction_award_complaint_lot_complaint = snitch(patch_auction_award_complaint_lot_complaint) + test_get_auction_award_complaint_lot_complaint = snitch(get_auction_award_complaint_lot_complaint) + test_get_auction_award_complaints_lot_complaint = snitch(get_auction_award_complaints_lot_complaint) + def setUp(self): super(AuctionLotAwardComplaintResourceTest, self).setUp() # Create award @@ -1316,306 +193,16 @@ def setUp(self): award = response.json['data'] self.award_id = award['id'] - def test_create_auction_award_complaint(self): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization, 'status': 'claim'}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - self.assertEqual(complaint['author']['name'], self.initial_organization['name']) - self.assertIn('id', complaint) - self.assertIn(complaint['id'], response.headers['Location']) - - self.set_status('active.awarded') - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "invalid", - "resolution": "spam 100% " * 3 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], "invalid") - self.assertEqual(response.json['data']["resolution"], "spam 100% " * 3) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], 'active.awarded') - - self.set_status('unsuccessful') - - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add complaint in current (unsuccessful) auction status") - - def test_patch_auction_award_complaint(self): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - owner_token = response.json['access']['token'] - - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id, complaint['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "status": "claim" - }}) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "resolved", - "resolution": "resolution text " * 2 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], "resolved") - self.assertEqual(response.json['data']["resolution"], "resolution text " * 2) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "satisfied": False, - "status": "pending", - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "pending") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": {"status": "cancelled", "cancellationReason": "reason"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "cancelled") - self.assertEqual(response.json['data']["cancellationReason"], "reason") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/some_id'.format(self.auction_id, self.award_id), {"data": {"status": "resolved", "resolution": "resolution text"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/awards/some_id/complaints/some_id', {"data": {"status": "resolved", "resolution": "resolution text"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "status": "cancelled", - "cancellationReason": "reason" - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update complaint in current (cancelled) status") - - response = self.app.patch_json('/auctions/{}/awards/some_id/complaints/some_id'.format(self.auction_id), {"data": {"status": "resolved", "resolution": "resolution text"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}'.format(self.auction_id, self.award_id, complaint['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "cancelled") - self.assertEqual(response.json['data']["cancellationReason"], "reason") - self.assertEqual(response.json['data']["resolutionType"], "resolved") - self.assertEqual(response.json['data']["resolution"], "resolution text " * 2) - - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - owner_token = response.json['access']['token'] - - self.set_status('complete') - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "status": "claim", - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update complaint in current (complete) auction status") - - def test_get_auction_award_complaint(self): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}'.format(self.auction_id, self.award_id, complaint['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], complaint) - - response = self.app.get('/auctions/{}/awards/{}/complaints/some_id'.format(self.auction_id, self.award_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.get('/auctions/some_id/awards/some_id/complaints/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_get_auction_award_complaints(self): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - - response = self.app.get('/auctions/{}/awards/{}/complaints'.format(self.auction_id, self.award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][0], complaint) - - response = self.app.get('/auctions/some_id/awards/some_id/complaints', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - auction = self.db.get(self.auction_id) - for i in auction.get('awards', []): - i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - self.db.save(auction) - - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add complaint only in complaintPeriod") - @unittest.skip("option not available") -class Auction2LotAwardComplaintResourceTest(AuctionLotAwardComplaintResourceTest): +class Auction2LotAwardComplaintResourceTest(BaseAuctionWebTest): initial_lots = 2 * test_lots - def test_create_auction_award_complaint(self): - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization, 'status': 'claim'}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - self.assertEqual(complaint['author']['name'], self.initial_organization['name']) - self.assertIn('id', complaint) - self.assertIn(complaint['id'], response.headers['Location']) - - self.set_status('active.awarded') - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "invalid", - "resolution": "spam 100% " * 3 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], "invalid") - self.assertEqual(response.json['data']["resolution"], "spam 100% " * 3) - - response = self.app.get('/auctions/{}'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], 'active.awarded') - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add complaint only in active lot status") - - def test_patch_auction_award_complaint(self): - response = self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "unsuccessful"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "unsuccessful") + test_create_auction_award_complaint_2_lot_complaint = snitch(create_auction_award_complaint_2_lot_complaint) + test_patch_auction_award_complaint_2_lot_complaint = snitch(patch_auction_award_complaint_2_lot_complaint) + test_get_auction_award_complaint_lot_complaint = snitch(get_auction_award_complaint_lot_complaint) + test_get_auction_award_complaints_lot_complaint = snitch(get_auction_award_complaints_lot_complaint) - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format( - self.auction_id, self.award_id), {'data': {'title': 'complaint title', 'description': 'complaint description', 'author': self.initial_organization}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - owner_token = response.json['access']['token'] - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - "status": "claim" - }}) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "resolved", - "resolution": "resolution text " * 2 - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "answered") - self.assertEqual(response.json['data']["resolutionType"], "resolved") - self.assertEqual(response.json['data']["resolution"], "resolution text " * 2) - - response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format(self.auction_id, self.award_id), {'data': { - 'title': 'complaint title', - 'description': 'complaint description', - 'author': self.initial_organization, - 'status': 'claim' - }}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - complaint = response.json['data'] - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - "status": "answered", - "resolutionType": "resolved", - "resolution": "resolution text" - }}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update complaint only in active lot status") @unittest.skip("option not available") @@ -1623,6 +210,12 @@ class AuctionAwardComplaintDocumentResourceTest(BaseAuctionWebTest): initial_status = 'active.qualification' initial_bids = test_bids + test_not_found_award_complaint_document = snitch(not_found_award_complaint_document) + test_create_auction_award_complaint_document = snitch(create_auction_award_complaint_document) + test_put_auction_award_complaint_document = snitch(put_auction_award_complaint_document) + test_patch_auction_award_complaint_document = snitch(patch_auction_award_complaint_document) + + def setUp(self): super(AuctionAwardComplaintDocumentResourceTest, self).setUp() # Create award @@ -1637,317 +230,6 @@ def setUp(self): self.complaint_id = complaint['id'] self.complaint_owner_token = response.json['access']['token'] - def test_not_found(self): - response = self.app.post('/auctions/some_id/awards/some_id/complaints/some_id/documents', status=404, upload_files=[ - ('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.post('/auctions/{}/awards/some_id/complaints/some_id/documents'.format(self.auction_id), status=404, upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.post('/auctions/{}/awards/{}/complaints/some_id/documents'.format(self.auction_id, self.award_id), status=404, upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents'.format(self.auction_id, self.award_id, self.complaint_id), status=404, upload_files=[ - ('invalid_value', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.get('/auctions/some_id/awards/some_id/complaints/some_id/documents', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/awards/some_id/complaints/some_id/documents'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/some_id/documents'.format(self.auction_id, self.award_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.get('/auctions/some_id/awards/some_id/complaints/some_id/documents/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/awards/some_id/complaints/some_id/documents/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/some_id/documents/some_id'.format(self.auction_id, self.award_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/some_id'.format(self.auction_id, self.award_id, self.complaint_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'document_id'} - ]) - - response = self.app.put('/auctions/some_id/awards/some_id/complaints/some_id/documents/some_id', status=404, - upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.put('/auctions/{}/awards/some_id/complaints/some_id/documents/some_id'.format(self.auction_id), status=404, - upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.put('/auctions/{}/awards/{}/complaints/some_id/documents/some_id'.format(self.auction_id, self.award_id), status=404, upload_files=[ - ('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'complaint_id'} - ]) - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/some_id'.format( - self.auction_id, self.award_id, self.complaint_id), status=404, upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'document_id'} - ]) - - def test_create_auction_award_complaint_document(self): - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents'.format( - self.auction_id, self.award_id, self.complaint_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (draft) complaint status") - - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents'.format(self.auction_id, self.award_id, self.complaint_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents?all=true'.format(self.auction_id, self.award_id, self.complaint_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}?download=some_id'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}?{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 7) - self.assertEqual(response.body, 'content') - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - self.set_status('complete') - - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents'.format( - self.auction_id, self.award_id, self.complaint_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (complete) auction status") - - def test_put_auction_award_complaint_document(self): - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id), - status=404, - upload_files=[('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id), upload_files=[('file', 'name.doc', 'content2')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only author") - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}?{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content2') - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), 'content3', content_type='application/msword') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}?{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content3') - - self.set_status('complete') - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") - - def test_patch_auction_award_complaint_document(self): - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only author") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), {"data": {"description": "document description"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('document description', response.json["data"]["description"]) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, self.complaint_id, self.complaint_owner_token), {"data": { - "status": "claim", - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], "claim") - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), 'content', content_type='application/msword', status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (claim) complaint status") - - self.set_status('complete') - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") - @unittest.skip("option not available") class Auction2LotAwardComplaintDocumentResourceTest(BaseAuctionWebTest): @@ -1955,6 +237,10 @@ class Auction2LotAwardComplaintDocumentResourceTest(BaseAuctionWebTest): initial_bids = test_bids initial_lots = 2 * test_lots + test_create_auction_award_complaint_document_2_lots = snitch(create_auction_award_complaint_document_2_lots) + test_put_auction_award_complaint_document_2_lots = snitch(put_auction_award_complaint_document_2_lots) + test_patch_auction_award_complaint_document_2_lots = snitch(patch_auction_award_complaint_document_2_lots) + def setUp(self): super(Auction2LotAwardComplaintDocumentResourceTest, self).setUp() # Create award @@ -1970,460 +256,20 @@ def setUp(self): self.complaint_id = complaint['id'] self.complaint_owner_token = response.json['access']['token'] - def test_create_auction_award_complaint_document(self): - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents'.format( - self.auction_id, self.award_id, self.complaint_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (draft) complaint status") - - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents'.format(self.auction_id, self.award_id, self.complaint_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents?all=true'.format(self.auction_id, self.award_id, self.complaint_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}?download=some_id'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}?{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 7) - self.assertEqual(response.body, 'content') - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents'.format( - self.auction_id, self.award_id, self.complaint_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add document only in active lot status") - - def test_put_auction_award_complaint_document(self): - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id), - status=404, - upload_files=[('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id), upload_files=[('file', 'name.doc', 'content2')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only author") - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}?{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content2') - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), 'content3', content_type='application/msword') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}?{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content3') - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, self.complaint_id, self.complaint_owner_token), {"data": { - "status": "claim", - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], "claim") - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), 'content', content_type='application/msword', status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (claim) complaint status") - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.put('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only in active lot status") - - def test_patch_auction_award_complaint_document(self): - response = self.app.post('/auctions/{}/awards/{}/complaints/{}/documents?acc_token={}'.format( - self.auction_id, self.award_id, self.complaint_id, self.complaint_owner_token), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only author") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), {"data": {"description": "document description"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - - response = self.app.get('/auctions/{}/awards/{}/complaints/{}/documents/{}'.format( - self.auction_id, self.award_id, self.complaint_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('document description', response.json["data"]["description"]) - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, self.complaint_id, self.complaint_owner_token), {"data": { - "status": "claim", - }}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']["status"], "claim") - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (claim) complaint status") - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}/documents/{}?acc_token={}'.format(self.auction_id, self.award_id, self.complaint_id, doc_id, self.complaint_owner_token), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only in active lot status") - class AuctionAwardDocumentResourceTest(BaseAuctionWebTest): initial_status = 'active.auction' initial_bids = test_bids + test_not_found_award_document = snitch(not_found_award_document) + test_create_auction_award_document = snitch(create_auction_award_document) + test_put_auction_award_document = snitch(put_auction_award_document) + test_patch_auction_award_document = snitch(patch_auction_award_document) + def setUp(self): super(AuctionAwardDocumentResourceTest, self).setUp() self.post_auction_results() - def test_not_found(self): - response = self.app.post('/auctions/some_id/awards/some_id/documents', status=404, upload_files=[ - ('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.post('/auctions/{}/awards/some_id/documents'.format(self.auction_id), status=404, upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.post('/auctions/{}/awards/{}/documents'.format(self.auction_id, self.first_award_id), status=404, upload_files=[ - ('invalid_value', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.get('/auctions/some_id/awards/some_id/documents', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/awards/some_id/documents'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.get('/auctions/some_id/awards/some_id/documents/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/awards/some_id/documents/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.get('/auctions/{}/awards/{}/documents/some_id'.format(self.auction_id, self.first_award_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'document_id'} - ]) - - response = self.app.put('/auctions/some_id/awards/some_id/documents/some_id', status=404, - upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.put('/auctions/{}/awards/some_id/documents/some_id'.format(self.auction_id), status=404, - upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'award_id'} - ]) - - response = self.app.put('/auctions/{}/awards/{}/documents/some_id'.format( - self.auction_id, self.first_award_id), status=404, upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'document_id'} - ]) - - def test_create_auction_award_document(self): - response = self.app.post('/auctions/{}/awards/{}/documents'.format( - self.auction_id, self.first_award_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/documents'.format(self.auction_id, self.first_award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/awards/{}/documents?all=true'.format(self.auction_id, self.first_award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/awards/{}/documents/{}?download=some_id'.format( - self.auction_id, self.first_award_id, doc_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/awards/{}/documents/{}?{}'.format( - self.auction_id, self.first_award_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 7) - self.assertEqual(response.body, 'content') - - response = self.app.get('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.first_award_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - self.set_status('complete') - - response = self.app.post('/auctions/{}/awards/{}/documents'.format( - self.auction_id, self.first_award_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (complete) auction status") - - def test_put_auction_award_document(self): - response = self.app.post('/auctions/{}/awards/{}/documents'.format( - self.auction_id, self.first_award_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put('/auctions/{}/awards/{}/documents/{}'.format(self.auction_id, self.first_award_id, doc_id), - status=404, - upload_files=[('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.first_award_id, doc_id), upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/documents/{}?{}'.format( - self.auction_id, self.first_award_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content2') - - response = self.app.get('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.first_award_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.put('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.first_award_id, doc_id), 'content3', content_type='application/msword') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/documents/{}?{}'.format( - self.auction_id, self.first_award_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content3') - - self.set_status('complete') - - response = self.app.put('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.first_award_id, doc_id), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") - - def test_patch_auction_award_document(self): - response = self.app.post('/auctions/{}/awards/{}/documents'.format( - self.auction_id, self.first_award_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}'.format(self.auction_id, self.first_award_id, doc_id), {"data": {"description": "document description"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - - response = self.app.get('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.first_award_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('document description', response.json["data"]["description"]) - - self.set_status('complete') - - response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}'.format(self.auction_id, self.first_award_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (complete) auction status") - @unittest.skip("option not available") class Auction2LotAwardDocumentResourceTest(BaseAuctionWebTest): @@ -2431,6 +277,10 @@ class Auction2LotAwardDocumentResourceTest(BaseAuctionWebTest): initial_bids = test_bids initial_lots = 2 * test_lots + test_create_auction_award_document_2_lots = snitch(create_auction_award_document_2_lots) + test_put_auction_award_document_2_lots = snitch(put_auction_award_document_2_lots) + test_patch_auction_award_document_2_lots = snitch(patch_auction_award_document_2_lots) + def setUp(self): super(Auction2LotAwardDocumentResourceTest, self).setUp() # Create award @@ -2440,166 +290,6 @@ def setUp(self): award = response.json['data'] self.award_id = award['id'] - def test_create_auction_award_document(self): - response = self.app.post('/auctions/{}/awards/{}/documents'.format( - self.auction_id, self.award_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/documents'.format(self.auction_id, self.award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/awards/{}/documents?all=true'.format(self.auction_id, self.award_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/awards/{}/documents/{}?download=some_id'.format( - self.auction_id, self.award_id, doc_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/awards/{}/documents/{}?{}'.format( - self.auction_id, self.award_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 7) - self.assertEqual(response.body, 'content') - - response = self.app.get('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.award_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.post('/auctions/{}/awards/{}/documents'.format( - self.auction_id, self.award_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add document only in active lot status") - - def test_put_auction_award_document(self): - response = self.app.post('/auctions/{}/awards/{}/documents'.format( - self.auction_id, self.award_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put('/auctions/{}/awards/{}/documents/{}'.format(self.auction_id, self.award_id, doc_id), - status=404, - upload_files=[('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.award_id, doc_id), upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/documents/{}?{}'.format( - self.auction_id, self.award_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content2') - - response = self.app.get('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.award_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.put('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.award_id, doc_id), 'content3', content_type='application/msword') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/awards/{}/documents/{}?{}'.format( - self.auction_id, self.award_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content3') - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.put('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.award_id, doc_id), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only in active lot status") - - def test_patch_auction_award_document(self): - response = self.app.post('/auctions/{}/awards/{}/documents'.format( - self.auction_id, self.award_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}'.format(self.auction_id, self.award_id, doc_id), {"data": {"description": "document description"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - - response = self.app.get('/auctions/{}/awards/{}/documents/{}'.format( - self.auction_id, self.award_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('document description', response.json["data"]["description"]) - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - self.assertEqual(response.status, '201 Created') - - response = self.app.patch_json('/auctions/{}/awards/{}/documents/{}'.format(self.auction_id, self.award_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only in active lot status") - class CreateFinancialAuctionAwardTest(CreateAuctionAwardTest): initial_bids = test_financial_bids From 75c559c2e7314ff85ec1bf31998e82a0df270ff5 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Fri, 23 Mar 2018 17:32:09 +0200 Subject: [PATCH 32/45] Move contracts test to core.plugins. Use existed mixins --- .../auctions/dgf/tests/contract.py | 732 +----------------- 1 file changed, 30 insertions(+), 702 deletions(-) diff --git a/openprocurement/auctions/dgf/tests/contract.py b/openprocurement/auctions/dgf/tests/contract.py index c5d3c01c..35408c5f 100644 --- a/openprocurement/auctions/dgf/tests/contract.py +++ b/openprocurement/auctions/dgf/tests/contract.py @@ -2,6 +2,24 @@ import unittest from datetime import timedelta +from openprocurement.auctions.core.tests.contract import ( + AuctionContractDocumentResourceTestMixin, + Auction2LotContractDocumentResourceTestMixin +) + +from openprocurement.auctions.core.tests.base import snitch +from openprocurement.auctions.core.plugins.contracting.v2_1.tests.blanks.contract_blanks import ( + # AuctionContractResourceTest + create_auction_contract_invalid, + create_auction_contract, + create_auction_contract_in_complete_status, + patch_auction_contract, + get_auction_contract, + get_auction_contracts, + # Auction2LotContractResourceTest + patch_auction_contract_2_lots + +) from openprocurement.api.models import get_now from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_auction_data, test_bids, test_lots, test_financial_auction_data, test_financial_bids, test_financial_organization @@ -11,6 +29,14 @@ class AuctionContractResourceTest(BaseAuctionWebTest): initial_status = 'active.auction' initial_bids = test_bids + test_create_auction_contract_invalid = snitch(create_auction_contract_invalid) + test_create_auction_contract = snitch(create_auction_contract) + test_create_auction_contract_in_complete_status = snitch(create_auction_contract_in_complete_status) + test_patch_auction_contract = snitch(patch_auction_contract) + test_get_auction_contract = snitch(get_auction_contract) + test_get_auction_contracts = snitch(get_auction_contracts) + + def setUp(self): super(AuctionContractResourceTest, self).setUp() # Create award @@ -59,325 +85,14 @@ def setUp(self): self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "active"}}) - def test_create_auction_contract_invalid(self): - response = self.app.post_json('/auctions/some_id/contracts', { - 'data': {'title': 'contract title', 'description': 'contract description', 'awardID': self.award_id}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'auction_id'} - ]) - - request_path = '/auctions/{}/contracts'.format(self.auction_id) - - response = self.app.post(request_path, 'data', status=415) - self.assertEqual(response.status, '415 Unsupported Media Type') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': - u"Content-Type header should be one of ['application/json']", u'location': u'header', u'name': u'Content-Type'} - ]) - - response = self.app.post( - request_path, 'data', content_type='application/json', 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'Expecting value: line 1 column 1 (char 0)', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, 'data', 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json( - request_path, {'not_data': {}}, 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'Data not available', - u'location': u'body', u'name': u'data'} - ]) - - response = self.app.post_json(request_path, {'data': { - 'invalid_field': 'invalid_value'}}, 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'Rogue field', u'location': - u'body', u'name': u'invalid_field'} - ]) - - response = self.app.post_json(request_path, {'data': {'awardID': 'invalid_value'}}, 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'awardID should be one of awards'], u'location': u'body', u'name': u'awardID'} - ]) - - def test_create_auction_contract(self): - response = self.app.post_json('/auctions/{}/contracts'.format( - self.auction_id), {'data': {'title': 'contract title', 'description': 'contract description', 'awardID': self.award_id, 'value': self.award_value, 'suppliers': self.award_suppliers}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - contract = response.json['data'] - self.assertIn('id', contract) - self.assertIn('value', contract) - self.assertIn('suppliers', contract) - self.assertIn(contract['id'], response.headers['Location']) - - auction = self.db.get(self.auction_id) - auction['contracts'][-1]["status"] = "terminated" - self.db.save(auction) - - self.set_status('unsuccessful') - - response = self.app.post_json('/auctions/{}/contracts'.format( - self.auction_id), {'data': {'title': 'contract title', 'description': 'contract description', 'awardID': self.award_id}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add contract in current (unsuccessful) auction status") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update contract in current (unsuccessful) auction status") - - def test_create_auction_contract_in_complete_status(self): - response = self.app.post_json('/auctions/{}/contracts'.format( - self.auction_id), {'data': {'title': 'contract title', 'description': 'contract description', 'awardID': self.award_id}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - contract = response.json['data'] - self.assertIn('id', contract) - self.assertIn(contract['id'], response.headers['Location']) - - auction = self.db.get(self.auction_id) - auction['contracts'][-1]["status"] = "terminated" - self.db.save(auction) - - self.set_status('complete') - - response = self.app.post_json('/auctions/{}/contracts'.format( - self.auction_id), {'data': {'title': 'contract title', 'description': 'contract description', 'awardID': self.award_id}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add contract in current (complete) auction status") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update contract in current (complete) auction status") - - def test_patch_auction_contract(self): - response = self.app.get('/auctions/{}/contracts'.format(self.auction_id)) - contract = response.json['data'][0] - - # response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}, status=403) - # self.assertEqual(response.status, '403 Forbidden') - # self.assertEqual(response.content_type, 'application/json') - # self.assertIn("Can't sign contract before stand-still period end (", response.json['errors'][0]["description"]) - - # self.set_status('complete', {'status': 'active.awarded'}) - - # response = self.app.post_json('/auctions/{}/awards/{}/complaints'.format(self.auction_id, self.award_id), {'data': { - # 'title': 'complaint title', - # 'description': 'complaint description', - # 'author': self.initial_organization, - # 'status': 'claim' - # }}) - # self.assertEqual(response.status, '201 Created') - # complaint = response.json['data'] - # owner_token = response.json['access']['token'] - - # auction = self.db.get(self.auction_id) - # for i in auction.get('awards', []): - # i['complaintPeriod']['endDate'] = i['complaintPeriod']['startDate'] - # self.db.save(auction) - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"contractID": "myselfID", "items": [{"description": "New Description"}], "suppliers": [{"name": "New Name"}]}}) - - response = self.app.get('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id'])) - self.assertEqual(response.json['data']['contractID'], contract['contractID']) - self.assertEqual(response.json['data']['items'], contract['items']) - self.assertEqual(response.json['data']['suppliers'], contract['suppliers']) - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"value": {"currency": "USD"}}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.json['errors'][0]["description"], "Can\'t update currency for contract value") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"value": {"valueAddedTaxIncluded": False}}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.json['errors'][0]["description"], "Can\'t update valueAddedTaxIncluded for contract value") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"value": {"amount": 99}}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.json['errors'][0]["description"], "Value amount should be greater or equal to awarded amount (479.0)") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"value": {"amount": 500}}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.json['data']['value']['amount'], 500) - - # response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"dateSigned": i['complaintPeriod']['endDate']}}, status=422) - # self.assertEqual(response.status, '422 Unprocessable Entity') - # self.assertEqual(response.json['errors'], [{u'description': [u'Contract signature date should be after award complaint period end date ({})'.format(i['complaintPeriod']['endDate'])], u'location': u'body', u'name': u'dateSigned'}]) - - one_hour_in_furure = (get_now() + timedelta(hours=1)).isoformat() - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"dateSigned": one_hour_in_furure}}, status=422) - self.assertEqual(response.status, '422 Unprocessable Entity') - self.assertEqual(response.json['errors'], [{u'description': [u"Contract signature date can't be in the future"], u'location': u'body', u'name': u'dateSigned'}]) - - custom_signature_date = get_now().isoformat() - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"dateSigned": custom_signature_date}}) - self.assertEqual(response.status, '200 OK') - - # response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}, status=403) - # self.assertEqual(response.status, '403 Forbidden') - # self.assertEqual(response.content_type, 'application/json') - # self.assertEqual(response.json['errors'][0]["description"], "Can't sign contract before reviewing all complaints") - - # response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], self.auction_token), {"data": { - # "status": "answered", - # "resolutionType": "resolved", - # "resolution": "resolution text " * 2 - # }}) - # self.assertEqual(response.status, '200 OK') - # self.assertEqual(response.content_type, 'application/json') - # self.assertEqual(response.json['data']["status"], "answered") - # self.assertEqual(response.json['data']["resolutionType"], "resolved") - # self.assertEqual(response.json['data']["resolution"], "resolution text " * 2) - - # response = self.app.patch_json('/auctions/{}/awards/{}/complaints/{}?acc_token={}'.format(self.auction_id, self.award_id, complaint['id'], owner_token), {"data": { - # "satisfied": True, - # "status": "resolved" - # }}) - # self.assertEqual(response.status, '200 OK') - # self.assertEqual(response.content_type, 'application/json') - # self.assertEqual(response.json['data']["status"], "resolved") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"value": {"amount": 232}}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.json['errors'][0]["description"], "Can't update contract in current (complete) auction status") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"contractID": "myselfID"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.json['errors'][0]["description"], "Can't update contract in current (complete) auction status") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"items": [{"description": "New Description"}]}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.json['errors'][0]["description"], "Can't update contract in current (complete) auction status") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"suppliers": [{"name": "New Name"}]}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.json['errors'][0]["description"], "Can't update contract in current (complete) auction status") - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update contract in current (complete) auction status") - - response = self.app.patch_json('/auctions/{}/contracts/some_id'.format(self.auction_id), {"data": {"status": "active"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'contract_id'} - ]) - - response = self.app.patch_json('/auctions/some_id/contracts/some_id', {"data": {"status": "active"}}, status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data']["status"], "active") - self.assertEqual(response.json['data']["value"]['amount'], 500) - self.assertEqual(response.json['data']['contractID'], contract['contractID']) - self.assertEqual(response.json['data']['items'], contract['items']) - self.assertEqual(response.json['data']['suppliers'], contract['suppliers']) - self.assertEqual(response.json['data']['dateSigned'], custom_signature_date) - - def test_get_auction_contract(self): - response = self.app.post_json('/auctions/{}/contracts'.format( - self.auction_id), {'data': {'title': 'contract title', 'description': 'contract description', 'awardID': self.award_id}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - contract = response.json['data'] - - response = self.app.get('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id'])) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'], contract) - - response = self.app.get('/auctions/{}/contracts/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'contract_id'} - ]) - - response = self.app.get('/auctions/some_id/contracts/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - def test_get_auction_contracts(self): - response = self.app.post_json('/auctions/{}/contracts'.format( - self.auction_id), {'data': {'title': 'contract title', 'description': 'contract description', 'awardID': self.award_id}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - contract = response.json['data'] - - response = self.app.get('/auctions/{}/contracts'.format(self.auction_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['data'][-1], contract) - - response = self.app.get('/auctions/some_id/contracts', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - @unittest.skip("option not available") class Auction2LotContractResourceTest(BaseAuctionWebTest): initial_status = 'active.qualification' initial_bids = test_bids initial_lots = 2 * test_lots + test_patch_auction_contract = snitch(patch_auction_contract_2_lots) + def setUp(self): super(Auction2LotContractResourceTest, self).setUp() @@ -392,34 +107,8 @@ def setUp(self): self.award_id = award['id'] self.app.patch_json('/auctions/{}/awards/{}'.format(self.auction_id, self.award_id), {"data": {"status": "active"}}) - def test_patch_auction_contract(self): - response = self.app.post_json('/auctions/{}/contracts'.format( - self.auction_id), {'data': {'title': 'contract title', 'description': 'contract description', 'awardID': self.award_id}}) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - contract = response.json['data'] - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertIn("Can't sign contract before stand-still period end (", response.json['errors'][0]["description"]) - - self.set_status('complete', {'status': 'active.awarded'}) - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - - response = self.app.patch_json('/auctions/{}/contracts/{}'.format(self.auction_id, contract['id']), {"data": {"status": "active"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update contract only in active lot status") - -class AuctionContractDocumentResourceTest(BaseAuctionWebTest): +class AuctionContractDocumentResourceTest(BaseAuctionWebTest, AuctionContractDocumentResourceTestMixin): #initial_data = auction_data initial_status = 'active.auction' initial_bids = test_bids @@ -475,284 +164,10 @@ def setUp(self): contract = response.json['data'] self.contract_id = contract['id'] - def test_not_found(self): - response = self.app.post('/auctions/some_id/contracts/some_id/documents', status=404, upload_files=[ - ('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.post('/auctions/{}/contracts/some_id/documents'.format(self.auction_id), status=404, upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'contract_id'} - ]) - - response = self.app.post('/auctions/{}/contracts/{}/documents'.format(self.auction_id, self.contract_id), status=404, upload_files=[ - ('invalid_value', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.get('/auctions/some_id/contracts/some_id/documents', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/contracts/some_id/documents'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'contract_id'} - ]) - - response = self.app.get('/auctions/some_id/contracts/some_id/documents/some_id', status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.get('/auctions/{}/contracts/some_id/documents/some_id'.format(self.auction_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'contract_id'} - ]) - - response = self.app.get('/auctions/{}/contracts/{}/documents/some_id'.format(self.auction_id, self.contract_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'document_id'} - ]) - - response = self.app.put('/auctions/some_id/contracts/some_id/documents/some_id', status=404, - upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'auction_id'} - ]) - - response = self.app.put('/auctions/{}/contracts/some_id/documents/some_id'.format(self.auction_id), status=404, upload_files=[ - ('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'url', u'name': u'contract_id'} - ]) - - response = self.app.put('/auctions/{}/contracts/{}/documents/some_id'.format( - self.auction_id, self.contract_id), status=404, upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'document_id'} - ]) - - def test_create_auction_contract_document(self): - response = self.app.post('/auctions/{}/contracts/{}/documents'.format( - self.auction_id, self.contract_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/contracts/{}/documents'.format(self.auction_id, self.contract_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/contracts/{}/documents?all=true'.format(self.auction_id, self.contract_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"][0]["id"]) - self.assertEqual('name.doc', response.json["data"][0]["title"]) - - response = self.app.get('/auctions/{}/contracts/{}/documents/{}?download=some_id'.format( - self.auction_id, self.contract_id, doc_id), status=404) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': u'url', u'name': u'download'} - ]) - - response = self.app.get('/auctions/{}/contracts/{}/documents/{}?{}'.format( - self.auction_id, self.contract_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 7) - self.assertEqual(response.body, 'content') - - response = self.app.get('/auctions/{}/contracts/{}/documents/{}'.format( - self.auction_id, self.contract_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - auction = self.db.get(self.auction_id) - auction['contracts'][-1]["status"] = "cancelled" - self.db.save(auction) - - response = self.app.post('/auctions/{}/contracts/{}/documents'.format( - self.auction_id, self.contract_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current contract status") - - self.set_status('unsuccessful') - - response = self.app.post('/auctions/{}/contracts/{}/documents'.format( - self.auction_id, self.contract_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't add document in current (unsuccessful) auction status") - - def test_put_auction_contract_document(self): - response = self.app.post('/auctions/{}/contracts/{}/documents'.format( - self.auction_id, self.contract_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put('/auctions/{}/contracts/{}/documents/{}'.format(self.auction_id, self.contract_id, doc_id), - status=404, - upload_files=[('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/{}/contracts/{}/documents/{}'.format( - self.auction_id, self.contract_id, doc_id), upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/contracts/{}/documents/{}?{}'.format( - self.auction_id, self.contract_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content2') - - response = self.app.get('/auctions/{}/contracts/{}/documents/{}'.format( - self.auction_id, self.contract_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('name.doc', response.json["data"]["title"]) - - response = self.app.put('/auctions/{}/contracts/{}/documents/{}'.format( - self.auction_id, self.contract_id, doc_id), 'content3', content_type='application/msword') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.get('/auctions/{}/contracts/{}/documents/{}?{}'.format( - self.auction_id, self.contract_id, doc_id, key)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/msword') - self.assertEqual(response.content_length, 8) - self.assertEqual(response.body, 'content3') - - auction = self.db.get(self.auction_id) - auction['contracts'][-1]["status"] = "cancelled" - self.db.save(auction) - - response = self.app.put('/auctions/{}/contracts/{}/documents/{}'.format( - self.auction_id, self.contract_id, doc_id), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current contract status") - - self.set_status('unsuccessful') - - response = self.app.put('/auctions/{}/contracts/{}/documents/{}'.format( - self.auction_id, self.contract_id, doc_id), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (unsuccessful) auction status") - - def test_patch_auction_contract_document(self): - response = self.app.post('/auctions/{}/contracts/{}/documents'.format( - self.auction_id, self.contract_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.patch_json('/auctions/{}/contracts/{}/documents/{}'.format(self.auction_id, self.contract_id, doc_id), {"data": {"description": "document description"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - - response = self.app.get('/auctions/{}/contracts/{}/documents/{}'.format( - self.auction_id, self.contract_id, doc_id)) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - self.assertEqual('document description', response.json["data"]["description"]) - - auction = self.db.get(self.auction_id) - auction['contracts'][-1]["status"] = "cancelled" - self.db.save(auction) - - response = self.app.patch_json('/auctions/{}/contracts/{}/documents/{}'.format(self.auction_id, self.contract_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current contract status") - - self.set_status('unsuccessful') - - response = self.app.patch_json('/auctions/{}/contracts/{}/documents/{}'.format(self.auction_id, self.contract_id, doc_id), {"data": {"description": "document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can't update document in current (unsuccessful) auction status") @unittest.skip("option not available") -class Auction2LotContractDocumentResourceTest(BaseAuctionWebTest): +class Auction2LotContractDocumentResourceTest(BaseAuctionWebTest, Auction2LotContractDocumentResourceTestMixin): initial_status = 'active.qualification' initial_bids = test_bids initial_lots = 2 * test_lots @@ -774,93 +189,6 @@ def setUp(self): contract = response.json['data'] self.contract_id = contract['id'] - def test_create_auction_contract_document(self): - response = self.app.post('/auctions/{}/contracts/{}/documents'.format( - self.auction_id, self.contract_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - self.assertEqual('name.doc', response.json["data"]["title"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - - response = self.app.post('/auctions/{}/contracts/{}/documents'.format( - self.auction_id, self.contract_id), upload_files=[('file', 'name.doc', 'content')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can add document only in active lot status") - - def test_put_auction_contract_document(self): - response = self.app.post('/auctions/{}/contracts/{}/documents'.format( - self.auction_id, self.contract_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.put('/auctions/{}/contracts/{}/documents/{}'.format(self.auction_id, self.contract_id, doc_id), - status=404, - upload_files=[('invalid_name', 'name.doc', 'content')]) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['status'], 'error') - self.assertEqual(response.json['errors'], [ - {u'description': u'Not Found', u'location': - u'body', u'name': u'file'} - ]) - - response = self.app.put('/auctions/{}/contracts/{}/documents/{}'.format( - self.auction_id, self.contract_id, doc_id), upload_files=[('file', 'name.doc', 'content2')]) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - key = response.json["data"]["url"].split('?')[-1] - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - - response = self.app.put('/auctions/{}/contracts/{}/documents/{}'.format( - self.auction_id, self.contract_id, doc_id), upload_files=[('file', 'name.doc', 'content3')], status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only in active lot status") - - def test_patch_auction_contract_document(self): - response = self.app.post('/auctions/{}/contracts/{}/documents'.format( - self.auction_id, self.contract_id), upload_files=[('file', 'name.doc', 'content')]) - self.assertEqual(response.status, '201 Created') - self.assertEqual(response.content_type, 'application/json') - doc_id = response.json["data"]['id'] - self.assertIn(doc_id, response.headers['Location']) - - response = self.app.patch_json('/auctions/{}/contracts/{}/documents/{}'.format(self.auction_id, self.contract_id, doc_id), {"data": {"description": "document description"}}) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(doc_id, response.json["data"]["id"]) - - response = self.app.post_json('/auctions/{}/cancellations'.format(self.auction_id), {'data': { - 'reason': 'cancellation reason', - 'status': 'active', - "cancellationOf": "lot", - "relatedLot": self.initial_lots[0]['id'] - }}) - - response = self.app.patch_json('/auctions/{}/contracts/{}/documents/{}'.format(self.auction_id, self.contract_id, doc_id), {"data": {"description": "new document description"}}, status=403) - self.assertEqual(response.status, '403 Forbidden') - self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.json['errors'][0]["description"], "Can update document only in active lot status") - class FinancialAuctionContractResourceTest(AuctionContractResourceTest): initial_bids = test_financial_bids From c0ed52173b152ffa52de90e4965d71e7d72b4a08 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Tue, 27 Mar 2018 11:57:29 +0300 Subject: [PATCH 33/45] localize returned from calculate_business_date datetime --- openprocurement/auctions/dgf/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openprocurement/auctions/dgf/models.py b/openprocurement/auctions/dgf/models.py index 3bcab057..c23cc3de 100644 --- a/openprocurement/auctions/dgf/models.py +++ b/openprocurement/auctions/dgf/models.py @@ -234,7 +234,7 @@ def validate_tenderPeriod(self, data, period): def validate_rectificationPeriod(self, data, period): if not (period and period.startDate) or not period.endDate: return - if period.endDate > calculate_business_date(data['tenderPeriod']['endDate'], -MINIMAL_PERIOD_FROM_RECTIFICATION_END, data): + if period.endDate > TZ.localize(calculate_business_date(data['tenderPeriod']['endDate'], -MINIMAL_PERIOD_FROM_RECTIFICATION_END, data).replace(tzinfo=None)): raise ValidationError(u"rectificationPeriod.endDate should come at least 5 working days earlier than tenderPeriod.endDate") def validate_value(self, data, value): From 7cc81a86ad9d8dfa63634cfd29d3f4a02996ccb7 Mon Sep 17 00:00:00 2001 From: Andrew Leitsius Date: Tue, 27 Mar 2018 13:43:20 +0300 Subject: [PATCH 34/45] Fix dep --- openprocurement/auctions/dgf/models.py | 8 ++++---- openprocurement/auctions/dgf/tests/base.py | 3 ++- openprocurement/auctions/dgf/validation.py | 2 +- openprocurement/auctions/dgf/views/other/auction.py | 2 +- openprocurement/auctions/dgf/views/other/bid_document.py | 5 ++++- .../auctions/dgf/views/other/cancellation_document.py | 5 ++++- .../auctions/dgf/views/other/complaint_document.py | 5 ++++- .../auctions/dgf/views/other/tender_document.py | 5 ++++- setup.py | 3 ++- 9 files changed, 26 insertions(+), 12 deletions(-) diff --git a/openprocurement/auctions/dgf/models.py b/openprocurement/auctions/dgf/models.py index 3bcab057..9b7f3b07 100644 --- a/openprocurement/auctions/dgf/models.py +++ b/openprocurement/auctions/dgf/models.py @@ -11,13 +11,14 @@ from pyramid.security import Allow from openprocurement.api.models import ( - BooleanType, ListType, Feature, Period, get_now, TZ, + BooleanType, ListType, Feature, Period, get_now, validate_features_uniq, validate_lots_uniq, Identifier as BaseIdentifier, - Classification, validate_items_uniq, ORA_CODES, Address, Location, - schematics_embedded_role, SANDBOX_MODE, CPV_CODES, IsoDateTimeType + Classification, validate_items_uniq, Address, Location, + schematics_embedded_role, IsoDateTimeType ) from openprocurement.api.utils import calculate_business_date, get_request_from_root from openprocurement.api.interfaces import IAwardingNextCheck +from openprocurement.api.constants import SANDBOX_MODE, CPV_CODES, ORA_CODES, TZ, AUCTIONS_COMPLAINT_STAND_STILL_TIME as COMPLAINT_STAND_STILL_TIME from openprocurement.auctions.core.models import IAuction from openprocurement.auctions.flash.models import ( @@ -33,7 +34,6 @@ IAuction, calc_auction_end_time, edit_role, - COMPLAINT_STAND_STILL_TIME, Administrator_role, dgfCDB2Document as Document, dgfCDB2Item as Item, diff --git a/openprocurement/auctions/dgf/tests/base.py b/openprocurement/auctions/dgf/tests/base.py index 728e535b..6d0f0afb 100644 --- a/openprocurement/auctions/dgf/tests/base.py +++ b/openprocurement/auctions/dgf/tests/base.py @@ -7,7 +7,8 @@ from base64 import b64encode from urllib import urlencode -from openprocurement.api.models import SANDBOX_MODE, get_now +from openprocurement.api.models import get_now +from openprocurement.api.constants import SANDBOX_MODE from openprocurement.api.utils import apply_data_patch from openprocurement.auctions.flash.tests.base import ( BaseWebTest as FlashBaseWebTest, diff --git a/openprocurement/auctions/dgf/validation.py b/openprocurement/auctions/dgf/validation.py index f14c5191..3bde44d2 100644 --- a/openprocurement/auctions/dgf/validation.py +++ b/openprocurement/auctions/dgf/validation.py @@ -11,4 +11,4 @@ def validate_rectification_period_editing(request): if rectificationPeriod.endDate.astimezone(TZ) < get_now(): request.errors.add('body', 'data', 'Auction can be edited only during the rectification period: from ({}) to ({}).'.format(rectificationPeriod.startDate.isoformat(), rectificationPeriod.endDate.isoformat())) request.errors.status = 403 - raise error_handler(request.errors) + raise error_handler(request) diff --git a/openprocurement/auctions/dgf/views/other/auction.py b/openprocurement/auctions/dgf/views/other/auction.py index 0f59eb41..d057138c 100644 --- a/openprocurement/auctions/dgf/views/other/auction.py +++ b/openprocurement/auctions/dgf/views/other/auction.py @@ -2,13 +2,13 @@ from openprocurement.api.utils import ( json_view, context_unpack, - cleanup_bids_for_cancelled_lots, APIResource, ) from openprocurement.auctions.core.utils import ( save_auction, apply_patch, opresource, + cleanup_bids_for_cancelled_lots ) from openprocurement.auctions.dgf.utils import ( invalidate_bids_under_threshold diff --git a/openprocurement/auctions/dgf/views/other/bid_document.py b/openprocurement/auctions/dgf/views/other/bid_document.py index 43d6ad5c..fab06536 100644 --- a/openprocurement/auctions/dgf/views/other/bid_document.py +++ b/openprocurement/auctions/dgf/views/other/bid_document.py @@ -8,10 +8,13 @@ context_unpack, APIResource, ) +from openprocurement.api.validation import ( + validate_patch_document_data, +) + from openprocurement.auctions.core.validation import ( validate_file_update, validate_file_upload, - validate_patch_document_data, ) from openprocurement.auctions.core.utils import ( save_auction, diff --git a/openprocurement/auctions/dgf/views/other/cancellation_document.py b/openprocurement/auctions/dgf/views/other/cancellation_document.py index 13785ac7..1d8a21b2 100644 --- a/openprocurement/auctions/dgf/views/other/cancellation_document.py +++ b/openprocurement/auctions/dgf/views/other/cancellation_document.py @@ -7,10 +7,13 @@ context_unpack, APIResource, ) +from openprocurement.api.validation import ( + validate_patch_document_data, +) + from openprocurement.auctions.core.validation import ( validate_file_update, validate_file_upload, - validate_patch_document_data, ) from openprocurement.auctions.core.utils import ( save_auction, diff --git a/openprocurement/auctions/dgf/views/other/complaint_document.py b/openprocurement/auctions/dgf/views/other/complaint_document.py index 3ccc96f8..64a8bdf1 100644 --- a/openprocurement/auctions/dgf/views/other/complaint_document.py +++ b/openprocurement/auctions/dgf/views/other/complaint_document.py @@ -7,10 +7,13 @@ context_unpack, APIResource, ) +from openprocurement.api.validation import ( + validate_patch_document_data, +) + from openprocurement.auctions.core.validation import ( validate_file_update, validate_file_upload, - validate_patch_document_data, ) from openprocurement.auctions.core.utils import ( save_auction, diff --git a/openprocurement/auctions/dgf/views/other/tender_document.py b/openprocurement/auctions/dgf/views/other/tender_document.py index f23c7c4e..626b96cd 100644 --- a/openprocurement/auctions/dgf/views/other/tender_document.py +++ b/openprocurement/auctions/dgf/views/other/tender_document.py @@ -5,10 +5,13 @@ context_unpack, APIResource, ) +from openprocurement.api.validation import ( + validate_patch_document_data, +) + from openprocurement.auctions.core.validation import ( validate_file_update, validate_file_upload, - validate_patch_document_data, ) from openprocurement.auctions.core.utils import ( save_auction, diff --git a/setup.py b/setup.py index e965b9cd..6e26da0a 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,8 @@ 'auctions.dgf.financial = openprocurement.auctions.dgf.includeme:includeme_financial' ], 'openprocurement.api.migrations': [ - 'auctions = openprocurement.auctions.dgf.migration:migrate_data' + 'auctions.dgf.other = openprocurement.auctions.dgf.migration:migrate_data', + 'auctions.dgf.financial = openprocurement.auctions.dgf.migration:migrate_data' ] } From 287685ec678b1d1b4018e017cdd7412b8260a6c5 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Tue, 27 Mar 2018 17:23:17 +0300 Subject: [PATCH 35/45] Fix tests. Fix validation according to new cornice --- .../auctions/dgf/tests/blanks/bidder_blanks.py | 2 +- .../auctions/dgf/tests/blanks/tender_blanks.py | 11 ++++++----- openprocurement/auctions/dgf/tests/tender.py | 16 ++-------------- openprocurement/auctions/dgf/validation.py | 2 +- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py b/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py index 7b8451af..f5d44247 100644 --- a/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py @@ -42,7 +42,7 @@ def create_auction_bidder_invalid(self): self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.json['status'], 'error') self.assertEqual(response.json['errors'], [ - {u'description': u'Expecting value: line 1 column 1 (char 0)', + {u'description': u'No JSON object could be decoded', u'location': u'body', u'name': u'data'} ]) diff --git a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py index c8b02473..f1a1c4d4 100644 --- a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py @@ -8,7 +8,8 @@ DGF_CDB2_CLASSIFICATION_PRECISELY_FROM as CLASSIFICATION_PRECISELY_FROM, DGF_CDB2_ADDRESS_REQUIRED_FROM as DGF_ADDRESS_REQUIRED_FROM ) -from openprocurement.api.models import get_now, SANDBOX_MODE, TZ +from openprocurement.auctions.core.models import SANDBOX_MODE +from openprocurement.api.models import get_now, TZ from openprocurement.auctions.dgf.tests.base import ( test_auction_maximum_data, test_auction_data, @@ -106,7 +107,7 @@ def create_auction_invalid(self): self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.json['status'], 'error') self.assertEqual(response.json['errors'], [ - {u'description': u'Expecting value: line 1 column 1 (char 0)', + {u'description': u'No JSON object could be decoded', u'location': u'body', u'name': u'data'} ]) @@ -142,7 +143,7 @@ def create_auction_invalid(self): self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.json['status'], 'error') self.assertEqual(response.json['errors'], [ - {u'description': u'Not implemented', u'location': u'data', u'name': u'procurementMethodType'} + {u'description': u'procurementMethodType is not implemented', u'location': u'body', u'name': u'data'} ]) response = self.app.post_json(request_path, {'data': {'invalid_field': 'invalid_value', 'procurementMethodType': self.initial_data['procurementMethodType']}}, status=422) @@ -1006,11 +1007,11 @@ def patch_auction_during_rectification_period(self): self.assertEqual(response.json['data']['items'][0]['unit'], unit_data_edited) response = self.app.patch_json('/auctions/{}'.format(self.auction_id), - {'data': {'items': [{"quantity": auction['items'][0]['quantity'] + 1}]}}) + {'data': {'items': [{"quantity": float(auction['items'][0]['quantity']) + 1}]}}) self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') self.assertNotEqual(response.json['data']['items'][0]['quantity'], auction['items'][0]['quantity']) - self.assertEqual(response.json['data']['items'][0]['quantity'], auction['items'][0]['quantity'] + 1) + self.assertEqual(response.json['data']['items'][0]['quantity'], str(float(auction['items'][0]['quantity']) + 1)) response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'tenderAttempts': auction['tenderAttempts'] + 1}}) diff --git a/openprocurement/auctions/dgf/tests/tender.py b/openprocurement/auctions/dgf/tests/tender.py index c41ab9ac..7d329442 100644 --- a/openprocurement/auctions/dgf/tests/tender.py +++ b/openprocurement/auctions/dgf/tests/tender.py @@ -1,22 +1,10 @@ # -*- coding: utf-8 -*- import re import unittest -from copy import deepcopy -from datetime import timedelta, time -from uuid import uuid4 -from iso8601 import parse_date - -from openprocurement.api.utils import ROUTE_PREFIX -from openprocurement.api.models import get_now, SANDBOX_MODE, TZ -from openprocurement.auctions.dgf.constants import ( - MINIMAL_PERIOD_FROM_RECTIFICATION_END -) + from openprocurement.auctions.dgf.models import DGFOtherAssets, DGFFinancialAssets, DGF_ID_REQUIRED_FROM from openprocurement.auctions.dgf.tests.base import test_auction_maximum_data, test_auction_data, test_financial_auction_data, test_organization, test_financial_organization, BaseWebTest, BaseAuctionWebTest, DEFAULT_ACCELERATION, test_bids, test_financial_bids -from openprocurement.auctions.core.constants import ( - DGF_CDB2_CLASSIFICATION_PRECISELY_FROM as CLASSIFICATION_PRECISELY_FROM, - DGF_CDB2_ADDRESS_REQUIRED_FROM as DGF_ADDRESS_REQUIRED_FROM -) + from openprocurement.auctions.core.tests.base import snitch from openprocurement.auctions.core.tests.blanks.tender_blanks import ( simple_add_auction diff --git a/openprocurement/auctions/dgf/validation.py b/openprocurement/auctions/dgf/validation.py index 3bde44d2..1dba2591 100644 --- a/openprocurement/auctions/dgf/validation.py +++ b/openprocurement/auctions/dgf/validation.py @@ -4,7 +4,7 @@ from openprocurement.auctions.dgf.utils import generate_rectificationPeriod -def validate_rectification_period_editing(request): +def validate_rectification_period_editing(request, **kwargs): if request.context.status == 'active.tendering' and request.authenticated_role not in ['chronograph', 'Administrator']: auction = request.validated['auction'] rectificationPeriod = auction.rectificationPeriod or generate_rectificationPeriod(auction) From 05d8b6e69f72e78ad5a3d8d3b39ee81580191243 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Tue, 27 Mar 2018 18:22:47 +0300 Subject: [PATCH 36/45] Fix import --- openprocurement/auctions/dgf/tests/blanks/tender_blanks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py index f1a1c4d4..3ba0d2dd 100644 --- a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py @@ -8,7 +8,7 @@ DGF_CDB2_CLASSIFICATION_PRECISELY_FROM as CLASSIFICATION_PRECISELY_FROM, DGF_CDB2_ADDRESS_REQUIRED_FROM as DGF_ADDRESS_REQUIRED_FROM ) -from openprocurement.auctions.core.models import SANDBOX_MODE +from openprocurement.api.constants import SANDBOX_MODE from openprocurement.api.models import get_now, TZ from openprocurement.auctions.dgf.tests.base import ( test_auction_maximum_data, From a08a936149ad414c9f1f2169955583c3e5bf8677 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 28 Mar 2018 13:08:20 +0300 Subject: [PATCH 37/45] Use constant for renderer error --- openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py | 4 ++-- openprocurement/auctions/dgf/tests/blanks/tender_blanks.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py b/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py index f5d44247..de9f2d39 100644 --- a/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/bidder_blanks.py @@ -10,6 +10,7 @@ test_financial_bids, test_organization ) +from openprocurement.api.tests.base import JSON_RENDERER_ERROR # AuctionBidderResourceTest @@ -42,8 +43,7 @@ def create_auction_bidder_invalid(self): self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.json['status'], 'error') self.assertEqual(response.json['errors'], [ - {u'description': u'No JSON object could be decoded', - u'location': u'body', u'name': u'data'} + JSON_RENDERER_ERROR ]) response = self.app.post_json(request_path, 'data', status=422) diff --git a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py index 3ba0d2dd..93fb75d5 100644 --- a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py @@ -30,6 +30,7 @@ from openprocurement.auctions.dgf.constants import ( MINIMAL_PERIOD_FROM_RECTIFICATION_END ) +from openprocurement.api.tests.base import JSON_RENDERER_ERROR # AuctionTest @@ -107,8 +108,7 @@ def create_auction_invalid(self): self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.json['status'], 'error') self.assertEqual(response.json['errors'], [ - {u'description': u'No JSON object could be decoded', - u'location': u'body', u'name': u'data'} + JSON_RENDERER_ERROR ]) response = self.app.post_json(request_path, 'data', status=422) From 9da3d42d53b052c3a1637d53f2cef3b06be3e5c2 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 28 Mar 2018 13:26:16 +0300 Subject: [PATCH 38/45] Update buildout.cfg --- buildout.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildout.cfg b/buildout.cfg index dfe9bbc2..2e9b7af0 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -25,6 +25,6 @@ gh=https://github.com/ gh_push=git@github.com: [sources] -openprocurement.api = git ${remotes:gh}openprocurement/openprocurement.api.git pushurl=${remotes:gh_push}openprocurement/openprocurement.api.git branch=a499878011598746_separating_awarding +openprocurement.api = git ${remotes:gh}openprocurement/openprocurement.api.git pushurl=${remotes:gh_push}openprocurement/openprocurement.api.git branch=ea_core_master openprocurement.auctions.core = git ${remotes:gh}openprocurement/openprocurement.auctions.core.git pushurl=${remotes:gh_push}openprocurement/openprocurement.auctions.core.git branch=a499878011598746_separating_awarding openprocurement.auctions.flash = git ${remotes:gh}openprocurement/openprocurement.auctions.flash.git pushurl=${remotes:gh_push}openprocurement/openprocurement.auctions.flash.git branch=a499878011598746_separating_awarding From a7bf647eaba4001f2017ebcd40832ca5af03b77b Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 28 Mar 2018 15:24:51 +0300 Subject: [PATCH 39/45] Fix tests --- openprocurement/auctions/dgf/tests/blanks/tender_blanks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py index 93fb75d5..d0f57a93 100644 --- a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py @@ -1007,11 +1007,11 @@ def patch_auction_during_rectification_period(self): self.assertEqual(response.json['data']['items'][0]['unit'], unit_data_edited) response = self.app.patch_json('/auctions/{}'.format(self.auction_id), - {'data': {'items': [{"quantity": float(auction['items'][0]['quantity']) + 1}]}}) + {'data': {'items': [{"quantity": auction['items'][0]['quantity'] + 1}]}}) self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/json') self.assertNotEqual(response.json['data']['items'][0]['quantity'], auction['items'][0]['quantity']) - self.assertEqual(response.json['data']['items'][0]['quantity'], str(float(auction['items'][0]['quantity']) + 1)) + self.assertEqual(response.json['data']['items'][0]['quantity'], auction['items'][0]['quantity'] + 1) response = self.app.patch_json('/auctions/{}'.format(self.auction_id), {'data': {'tenderAttempts': auction['tenderAttempts'] + 1}}) From 7e21392a84d769e2fb3db88e807c67741d867504 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 28 Mar 2018 16:22:34 +0300 Subject: [PATCH 40/45] Update cornice version --- versions.cfg | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/versions.cfg b/versions.cfg index 49c71d7d..d10ef2d8 100644 --- a/versions.cfg +++ b/versions.cfg @@ -21,7 +21,6 @@ waitress = 0.8.9 zc.recipe.egg = 2.0.3 zope.deprecation = 4.1.1 zope.interface = 4.1.1 - # Required by: # couchdb-schematics==1.1.1 CouchDB = 1.0 @@ -48,7 +47,7 @@ chaussette = 1.2 # Required by: # openprocurement.api==0.8.1 -cornice = 1.2.0.dev0 +cornice = 3.1.0 # Required by: # openprocurement.api==0.8.1 From 1cb8a3464ddb6562e740c3a83970735bc820f2ee Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Fri, 30 Mar 2018 18:50:56 +0300 Subject: [PATCH 41/45] Fix imports --- docs.py | 2 +- openprocurement/auctions/dgf/constants.py | 2 +- openprocurement/auctions/dgf/migration.py | 2 +- openprocurement/auctions/dgf/models.py | 8 +++++--- openprocurement/auctions/dgf/tests/auction.py | 2 +- openprocurement/auctions/dgf/tests/base.py | 2 +- .../auctions/dgf/tests/blanks/chronograph_blanks.py | 2 +- .../auctions/dgf/tests/blanks/migration_blanks.py | 2 +- .../auctions/dgf/tests/blanks/tender_blanks.py | 2 +- openprocurement/auctions/dgf/tests/chronograph.py | 2 +- openprocurement/auctions/dgf/tests/contract.py | 2 +- openprocurement/auctions/dgf/tests/migration.py | 2 +- openprocurement/auctions/dgf/utils.py | 2 +- openprocurement/auctions/dgf/validation.py | 2 +- openprocurement/auctions/dgf/views/other/bid.py | 2 +- openprocurement/auctions/dgf/views/other/bid_document.py | 2 +- openprocurement/auctions/dgf/views/other/complaint.py | 2 +- openprocurement/auctions/dgf/views/other/question.py | 2 +- 18 files changed, 22 insertions(+), 20 deletions(-) diff --git a/docs.py b/docs.py index aeea3ff1..b7cd7305 100755 --- a/docs.py +++ b/docs.py @@ -4,7 +4,7 @@ import os from datetime import timedelta, datetime -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now import openprocurement.auctions.dgf.tests.base as base_test from openprocurement.auctions.flash.tests.base import PrefixedRequestClass from openprocurement.auctions.dgf.tests.base import test_auction_data as base_test_auction_data, test_bids, test_financial_bids diff --git a/openprocurement/auctions/dgf/constants.py b/openprocurement/auctions/dgf/constants.py index 996a5b0f..29f1d478 100644 --- a/openprocurement/auctions/dgf/constants.py +++ b/openprocurement/auctions/dgf/constants.py @@ -1,5 +1,5 @@ from datetime import datetime, timedelta -from openprocurement.api.models import TZ, ORA_CODES +from openprocurement.api.models.auction_models.models import TZ, ORA_CODES def read_json(name): diff --git a/openprocurement/auctions/dgf/migration.py b/openprocurement/auctions/dgf/migration.py index 76872e6e..98788ea6 100644 --- a/openprocurement/auctions/dgf/migration.py +++ b/openprocurement/auctions/dgf/migration.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- import logging -from openprocurement.api.models import get_now, TZ +from openprocurement.api.models.auction_models.models import get_now, TZ from openprocurement.api.traversal import Root from barbecue import chef from uuid import uuid4 diff --git a/openprocurement/auctions/dgf/models.py b/openprocurement/auctions/dgf/models.py index 98cb6f28..9427d276 100644 --- a/openprocurement/auctions/dgf/models.py +++ b/openprocurement/auctions/dgf/models.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from datetime import datetime, timedelta, time -from schematics.types import StringType, URLType, IntType, BaseType +from schematics.types import StringType, URLType, IntType, BaseType, BooleanType from schematics.types.compound import ModelType from schematics.exceptions import ValidationError from schematics.transforms import blacklist, whitelist @@ -10,12 +10,14 @@ from zope.interface import implementer from pyramid.security import Allow -from openprocurement.api.models import ( - BooleanType, ListType, Feature, Period, get_now, +from openprocurement.api.models.auction_models.models import ( + Feature, get_now, validate_features_uniq, validate_lots_uniq, Identifier as BaseIdentifier, Classification, validate_items_uniq, Address, Location, schematics_embedded_role, IsoDateTimeType ) +from openprocurement.api.models.schematics_extender import ListType +from openprocurement.api.models.models import Period from openprocurement.api.utils import calculate_business_date, get_request_from_root from openprocurement.api.interfaces import IAwardingNextCheck from openprocurement.api.constants import SANDBOX_MODE, CPV_CODES, ORA_CODES, TZ, AUCTIONS_COMPLAINT_STAND_STILL_TIME as COMPLAINT_STAND_STILL_TIME diff --git a/openprocurement/auctions/dgf/tests/auction.py b/openprocurement/auctions/dgf/tests/auction.py index 874437af..7e9eb934 100644 --- a/openprocurement/auctions/dgf/tests/auction.py +++ b/openprocurement/auctions/dgf/tests/auction.py @@ -3,7 +3,7 @@ from datetime import timedelta from copy import deepcopy -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now from openprocurement.auctions.dgf.tests.base import ( BaseAuctionWebTest, test_bids, test_lots, test_organization, test_features_auction_data, test_financial_auction_data, test_financial_bids, test_financial_organization, test_auction_data diff --git a/openprocurement/auctions/dgf/tests/base.py b/openprocurement/auctions/dgf/tests/base.py index 6d0f0afb..531a8ed4 100644 --- a/openprocurement/auctions/dgf/tests/base.py +++ b/openprocurement/auctions/dgf/tests/base.py @@ -7,7 +7,7 @@ from base64 import b64encode from urllib import urlencode -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now from openprocurement.api.constants import SANDBOX_MODE from openprocurement.api.utils import apply_data_patch from openprocurement.auctions.flash.tests.base import ( diff --git a/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py b/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py index 74c693c7..d6807b1b 100644 --- a/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from datetime import datetime, timedelta -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now # AuctionSwitchQualificationResourceTest diff --git a/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py b/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py index 974bcac3..0140ce9d 100644 --- a/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now from datetime import timedelta from uuid import uuid4 from copy import deepcopy diff --git a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py index d0f57a93..90bbd923 100644 --- a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py @@ -9,7 +9,7 @@ DGF_CDB2_ADDRESS_REQUIRED_FROM as DGF_ADDRESS_REQUIRED_FROM ) from openprocurement.api.constants import SANDBOX_MODE -from openprocurement.api.models import get_now, TZ +from openprocurement.api.models.auction_models.models import get_now, TZ from openprocurement.auctions.dgf.tests.base import ( test_auction_maximum_data, test_auction_data, diff --git a/openprocurement/auctions/dgf/tests/chronograph.py b/openprocurement/auctions/dgf/tests/chronograph.py index 2670a55b..6660552d 100644 --- a/openprocurement/auctions/dgf/tests/chronograph.py +++ b/openprocurement/auctions/dgf/tests/chronograph.py @@ -15,7 +15,7 @@ switch_to_pending_award, switch_to_complaint_award, ) -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_lots, test_bids, test_financial_auction_data, test_financial_organization, test_financial_bids, test_organization from openprocurement.auctions.dgf.tests.blanks.chronograph_blanks import ( # AuctionSwitchQualificationResourceTest diff --git a/openprocurement/auctions/dgf/tests/contract.py b/openprocurement/auctions/dgf/tests/contract.py index 35408c5f..897d0da7 100644 --- a/openprocurement/auctions/dgf/tests/contract.py +++ b/openprocurement/auctions/dgf/tests/contract.py @@ -20,7 +20,7 @@ patch_auction_contract_2_lots ) -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_auction_data, test_bids, test_lots, test_financial_auction_data, test_financial_bids, test_financial_organization diff --git a/openprocurement/auctions/dgf/tests/migration.py b/openprocurement/auctions/dgf/tests/migration.py index 40f61681..0085eec0 100644 --- a/openprocurement/auctions/dgf/tests/migration.py +++ b/openprocurement/auctions/dgf/tests/migration.py @@ -5,7 +5,7 @@ from uuid import uuid4 from copy import deepcopy -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now from openprocurement.auctions.core.tests.base import snitch from openprocurement.auctions.dgf.migration import migrate_data, get_db_schema_version, set_db_schema_version, SCHEMA_VERSION diff --git a/openprocurement/auctions/dgf/utils.py b/openprocurement/auctions/dgf/utils.py index 61fd2349..d9968db8 100644 --- a/openprocurement/auctions/dgf/utils.py +++ b/openprocurement/auctions/dgf/utils.py @@ -3,7 +3,7 @@ from logging import getLogger from pkg_resources import get_distribution from barbecue import chef -from openprocurement.api.models import get_now, TZ +from openprocurement.api.models.auction_models.models import get_now, TZ from openprocurement.api.utils import ( upload_file as base_upload_file, get_file as base_get_file, DOCUMENT_BLACKLISTED_FIELDS, context_unpack, calculate_business_date diff --git a/openprocurement/auctions/dgf/validation.py b/openprocurement/auctions/dgf/validation.py index 1dba2591..884167d6 100644 --- a/openprocurement/auctions/dgf/validation.py +++ b/openprocurement/auctions/dgf/validation.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from openprocurement.api.utils import error_handler -from openprocurement.api.models import get_now, TZ +from openprocurement.api.models.auction_models.models import get_now, TZ from openprocurement.auctions.dgf.utils import generate_rectificationPeriod diff --git a/openprocurement/auctions/dgf/views/other/bid.py b/openprocurement/auctions/dgf/views/other/bid.py index 933f55a0..0cb9233e 100644 --- a/openprocurement/auctions/dgf/views/other/bid.py +++ b/openprocurement/auctions/dgf/views/other/bid.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now from openprocurement.api.utils import ( json_view, context_unpack, diff --git a/openprocurement/auctions/dgf/views/other/bid_document.py b/openprocurement/auctions/dgf/views/other/bid_document.py index fab06536..cf70ee0f 100644 --- a/openprocurement/auctions/dgf/views/other/bid_document.py +++ b/openprocurement/auctions/dgf/views/other/bid_document.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now from openprocurement.api.utils import ( get_file, upload_file, diff --git a/openprocurement/auctions/dgf/views/other/complaint.py b/openprocurement/auctions/dgf/views/other/complaint.py index 88cea2db..da04e4f9 100644 --- a/openprocurement/auctions/dgf/views/other/complaint.py +++ b/openprocurement/auctions/dgf/views/other/complaint.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now from openprocurement.api.utils import ( context_unpack, json_view, diff --git a/openprocurement/auctions/dgf/views/other/question.py b/openprocurement/auctions/dgf/views/other/question.py index 5088a37e..6744ad48 100644 --- a/openprocurement/auctions/dgf/views/other/question.py +++ b/openprocurement/auctions/dgf/views/other/question.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from openprocurement.api.models import get_now +from openprocurement.api.models.auction_models.models import get_now from openprocurement.api.utils import ( json_view, context_unpack, From d13f3794606411e0973e82c7c250703b13edc7a2 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Mon, 2 Apr 2018 16:15:22 +0300 Subject: [PATCH 42/45] Use imports from right module --- docs.py | 2 +- openprocurement/auctions/dgf/constants.py | 3 ++- openprocurement/auctions/dgf/migration.py | 2 +- openprocurement/auctions/dgf/models.py | 4 ++-- openprocurement/auctions/dgf/tests/auction.py | 2 +- openprocurement/auctions/dgf/tests/base.py | 2 +- .../auctions/dgf/tests/blanks/chronograph_blanks.py | 2 +- openprocurement/auctions/dgf/tests/blanks/migration_blanks.py | 2 +- openprocurement/auctions/dgf/tests/blanks/tender_blanks.py | 4 ++-- openprocurement/auctions/dgf/tests/chronograph.py | 2 +- openprocurement/auctions/dgf/tests/contract.py | 2 +- openprocurement/auctions/dgf/tests/migration.py | 2 +- openprocurement/auctions/dgf/utils.py | 4 ++-- openprocurement/auctions/dgf/validation.py | 3 ++- openprocurement/auctions/dgf/views/other/bid.py | 2 +- openprocurement/auctions/dgf/views/other/bid_document.py | 2 +- openprocurement/auctions/dgf/views/other/complaint.py | 2 +- openprocurement/auctions/dgf/views/other/question.py | 2 +- 18 files changed, 23 insertions(+), 21 deletions(-) diff --git a/docs.py b/docs.py index b7cd7305..c8b855ac 100755 --- a/docs.py +++ b/docs.py @@ -4,7 +4,7 @@ import os from datetime import timedelta, datetime -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now import openprocurement.auctions.dgf.tests.base as base_test from openprocurement.auctions.flash.tests.base import PrefixedRequestClass from openprocurement.auctions.dgf.tests.base import test_auction_data as base_test_auction_data, test_bids, test_financial_bids diff --git a/openprocurement/auctions/dgf/constants.py b/openprocurement/auctions/dgf/constants.py index 29f1d478..443532e7 100644 --- a/openprocurement/auctions/dgf/constants.py +++ b/openprocurement/auctions/dgf/constants.py @@ -1,5 +1,6 @@ from datetime import datetime, timedelta -from openprocurement.api.models.auction_models.models import TZ, ORA_CODES +from openprocurement.api.constants import TZ +from openprocurement.api.models.auction_models.models import ORA_CODES def read_json(name): diff --git a/openprocurement/auctions/dgf/migration.py b/openprocurement/auctions/dgf/migration.py index 98788ea6..aba01db0 100644 --- a/openprocurement/auctions/dgf/migration.py +++ b/openprocurement/auctions/dgf/migration.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- import logging -from openprocurement.api.models.auction_models.models import get_now, TZ +from openprocurement.api.utils import get_now from openprocurement.api.traversal import Root from barbecue import chef from uuid import uuid4 diff --git a/openprocurement/auctions/dgf/models.py b/openprocurement/auctions/dgf/models.py index 9427d276..e8935731 100644 --- a/openprocurement/auctions/dgf/models.py +++ b/openprocurement/auctions/dgf/models.py @@ -11,14 +11,14 @@ from pyramid.security import Allow from openprocurement.api.models.auction_models.models import ( - Feature, get_now, + Feature, validate_features_uniq, validate_lots_uniq, Identifier as BaseIdentifier, Classification, validate_items_uniq, Address, Location, schematics_embedded_role, IsoDateTimeType ) from openprocurement.api.models.schematics_extender import ListType from openprocurement.api.models.models import Period -from openprocurement.api.utils import calculate_business_date, get_request_from_root +from openprocurement.api.utils import calculate_business_date, get_request_from_root, get_now from openprocurement.api.interfaces import IAwardingNextCheck from openprocurement.api.constants import SANDBOX_MODE, CPV_CODES, ORA_CODES, TZ, AUCTIONS_COMPLAINT_STAND_STILL_TIME as COMPLAINT_STAND_STILL_TIME diff --git a/openprocurement/auctions/dgf/tests/auction.py b/openprocurement/auctions/dgf/tests/auction.py index 7e9eb934..2ac4b2ef 100644 --- a/openprocurement/auctions/dgf/tests/auction.py +++ b/openprocurement/auctions/dgf/tests/auction.py @@ -3,7 +3,7 @@ from datetime import timedelta from copy import deepcopy -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now from openprocurement.auctions.dgf.tests.base import ( BaseAuctionWebTest, test_bids, test_lots, test_organization, test_features_auction_data, test_financial_auction_data, test_financial_bids, test_financial_organization, test_auction_data diff --git a/openprocurement/auctions/dgf/tests/base.py b/openprocurement/auctions/dgf/tests/base.py index 531a8ed4..1fbbe72d 100644 --- a/openprocurement/auctions/dgf/tests/base.py +++ b/openprocurement/auctions/dgf/tests/base.py @@ -7,7 +7,7 @@ from base64 import b64encode from urllib import urlencode -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now from openprocurement.api.constants import SANDBOX_MODE from openprocurement.api.utils import apply_data_patch from openprocurement.auctions.flash.tests.base import ( diff --git a/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py b/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py index d6807b1b..fb78fc8b 100644 --- a/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/chronograph_blanks.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from datetime import datetime, timedelta -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now # AuctionSwitchQualificationResourceTest diff --git a/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py b/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py index 0140ce9d..825f0f11 100644 --- a/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/migration_blanks.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now from datetime import timedelta from uuid import uuid4 from copy import deepcopy diff --git a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py index 90bbd923..84bd8596 100644 --- a/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py +++ b/openprocurement/auctions/dgf/tests/blanks/tender_blanks.py @@ -8,8 +8,8 @@ DGF_CDB2_CLASSIFICATION_PRECISELY_FROM as CLASSIFICATION_PRECISELY_FROM, DGF_CDB2_ADDRESS_REQUIRED_FROM as DGF_ADDRESS_REQUIRED_FROM ) -from openprocurement.api.constants import SANDBOX_MODE -from openprocurement.api.models.auction_models.models import get_now, TZ +from openprocurement.api.constants import SANDBOX_MODE, TZ +from openprocurement.api.utils import get_now from openprocurement.auctions.dgf.tests.base import ( test_auction_maximum_data, test_auction_data, diff --git a/openprocurement/auctions/dgf/tests/chronograph.py b/openprocurement/auctions/dgf/tests/chronograph.py index 6660552d..343414a0 100644 --- a/openprocurement/auctions/dgf/tests/chronograph.py +++ b/openprocurement/auctions/dgf/tests/chronograph.py @@ -15,7 +15,7 @@ switch_to_pending_award, switch_to_complaint_award, ) -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_lots, test_bids, test_financial_auction_data, test_financial_organization, test_financial_bids, test_organization from openprocurement.auctions.dgf.tests.blanks.chronograph_blanks import ( # AuctionSwitchQualificationResourceTest diff --git a/openprocurement/auctions/dgf/tests/contract.py b/openprocurement/auctions/dgf/tests/contract.py index 897d0da7..b695cfb2 100644 --- a/openprocurement/auctions/dgf/tests/contract.py +++ b/openprocurement/auctions/dgf/tests/contract.py @@ -20,7 +20,7 @@ patch_auction_contract_2_lots ) -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now from openprocurement.auctions.dgf.tests.base import BaseAuctionWebTest, test_auction_data, test_bids, test_lots, test_financial_auction_data, test_financial_bids, test_financial_organization diff --git a/openprocurement/auctions/dgf/tests/migration.py b/openprocurement/auctions/dgf/tests/migration.py index 0085eec0..16065cb6 100644 --- a/openprocurement/auctions/dgf/tests/migration.py +++ b/openprocurement/auctions/dgf/tests/migration.py @@ -5,7 +5,7 @@ from uuid import uuid4 from copy import deepcopy -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now from openprocurement.auctions.core.tests.base import snitch from openprocurement.auctions.dgf.migration import migrate_data, get_db_schema_version, set_db_schema_version, SCHEMA_VERSION diff --git a/openprocurement/auctions/dgf/utils.py b/openprocurement/auctions/dgf/utils.py index d9968db8..fbbe6e76 100644 --- a/openprocurement/auctions/dgf/utils.py +++ b/openprocurement/auctions/dgf/utils.py @@ -3,10 +3,10 @@ from logging import getLogger from pkg_resources import get_distribution from barbecue import chef -from openprocurement.api.models.auction_models.models import get_now, TZ +from openprocurement.api.constants import TZ from openprocurement.api.utils import ( upload_file as base_upload_file, get_file as base_get_file, - DOCUMENT_BLACKLISTED_FIELDS, context_unpack, calculate_business_date + DOCUMENT_BLACKLISTED_FIELDS, context_unpack, calculate_business_date, get_now ) from openprocurement.auctions.core.utils import ( check_complaint_status, diff --git a/openprocurement/auctions/dgf/validation.py b/openprocurement/auctions/dgf/validation.py index 884167d6..514ae0da 100644 --- a/openprocurement/auctions/dgf/validation.py +++ b/openprocurement/auctions/dgf/validation.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- from openprocurement.api.utils import error_handler -from openprocurement.api.models.auction_models.models import get_now, TZ +from openprocurement.api.utils import get_now from openprocurement.auctions.dgf.utils import generate_rectificationPeriod +from openprocurement.api.constants import TZ def validate_rectification_period_editing(request, **kwargs): diff --git a/openprocurement/auctions/dgf/views/other/bid.py b/openprocurement/auctions/dgf/views/other/bid.py index 0cb9233e..fae67a28 100644 --- a/openprocurement/auctions/dgf/views/other/bid.py +++ b/openprocurement/auctions/dgf/views/other/bid.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now from openprocurement.api.utils import ( json_view, context_unpack, diff --git a/openprocurement/auctions/dgf/views/other/bid_document.py b/openprocurement/auctions/dgf/views/other/bid_document.py index cf70ee0f..a9bf9c7e 100644 --- a/openprocurement/auctions/dgf/views/other/bid_document.py +++ b/openprocurement/auctions/dgf/views/other/bid_document.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now from openprocurement.api.utils import ( get_file, upload_file, diff --git a/openprocurement/auctions/dgf/views/other/complaint.py b/openprocurement/auctions/dgf/views/other/complaint.py index da04e4f9..d7adfd29 100644 --- a/openprocurement/auctions/dgf/views/other/complaint.py +++ b/openprocurement/auctions/dgf/views/other/complaint.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now from openprocurement.api.utils import ( context_unpack, json_view, diff --git a/openprocurement/auctions/dgf/views/other/question.py b/openprocurement/auctions/dgf/views/other/question.py index 6744ad48..263fef1b 100644 --- a/openprocurement/auctions/dgf/views/other/question.py +++ b/openprocurement/auctions/dgf/views/other/question.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from openprocurement.api.models.auction_models.models import get_now +from openprocurement.api.utils import get_now from openprocurement.api.utils import ( json_view, context_unpack, From fc1e1b1c10bf6f04081fa4e81cd4014223f83347 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 4 Apr 2018 18:47:32 +0300 Subject: [PATCH 43/45] Update travis --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eeba2e75..52f67907 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,6 @@ cache: directories: - eggs before_install: - - pip install setuptools==7.0 - python2 bootstrap.py install: - bin/buildout -N From 20448721e3ae30dcda49dc3c1e76bb58befbd08c Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 5 Apr 2018 12:51:36 +0300 Subject: [PATCH 44/45] Use direct path to views in plugins --- openprocurement/auctions/dgf/constants.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openprocurement/auctions/dgf/constants.py b/openprocurement/auctions/dgf/constants.py index 443532e7..c20d6d44 100644 --- a/openprocurement/auctions/dgf/constants.py +++ b/openprocurement/auctions/dgf/constants.py @@ -38,10 +38,12 @@ def read_json(name): FINANCIAL_VIEW_LOCATIONS = [ "openprocurement.auctions.dgf.views.financial", - "openprocurement.auctions.core.plugins", + "openprocurement.auctions.core.plugins.awarding.v2_1.views", + "openprocurement.auctions.core.plugins.contracting.v2_1.views" ] OTHER_VIEW_LOCATIONS = [ "openprocurement.auctions.dgf.views.other", - "openprocurement.auctions.core.plugins", + "openprocurement.auctions.core.plugins.awarding.v2_1.views", + "openprocurement.auctions.core.plugins.contracting.v2_1.views" ] From c0b3090819140f906bd4fa5bed130caf8aea9495 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Thu, 5 Apr 2018 14:04:20 +0300 Subject: [PATCH 45/45] Remove constants for view locations --- openprocurement/auctions/dgf/constants.py | 14 -------------- openprocurement/auctions/dgf/includeme.py | 10 ++-------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/openprocurement/auctions/dgf/constants.py b/openprocurement/auctions/dgf/constants.py index c20d6d44..733600c9 100644 --- a/openprocurement/auctions/dgf/constants.py +++ b/openprocurement/auctions/dgf/constants.py @@ -33,17 +33,3 @@ def read_json(name): ORA_CODES[0:0] = ["UA-IPN", "UA-FIN"] NUMBER_OF_BIDS_TO_BE_QUALIFIED = 2 - -#Views location - -FINANCIAL_VIEW_LOCATIONS = [ - "openprocurement.auctions.dgf.views.financial", - "openprocurement.auctions.core.plugins.awarding.v2_1.views", - "openprocurement.auctions.core.plugins.contracting.v2_1.views" -] - -OTHER_VIEW_LOCATIONS = [ - "openprocurement.auctions.dgf.views.other", - "openprocurement.auctions.core.plugins.awarding.v2_1.views", - "openprocurement.auctions.core.plugins.contracting.v2_1.views" -] diff --git a/openprocurement/auctions/dgf/includeme.py b/openprocurement/auctions/dgf/includeme.py index df4790b3..7401f787 100644 --- a/openprocurement/auctions/dgf/includeme.py +++ b/openprocurement/auctions/dgf/includeme.py @@ -15,17 +15,12 @@ IContentConfigurator, IAwardingNextCheck ) -from openprocurement.auctions.dgf.constants import ( - FINANCIAL_VIEW_LOCATIONS, - OTHER_VIEW_LOCATIONS, -) def includeme_other(config): config.add_auction_procurementMethodType(DGFOtherAssets) - for view_location in OTHER_VIEW_LOCATIONS: - config.scan(view_location) + config.scan('openprocurement.auctions.dgf.views.other') # Register adapters config.registry.registerAdapter( @@ -43,8 +38,7 @@ def includeme_other(config): def includeme_financial(config): config.add_auction_procurementMethodType(DGFFinancialAssets) - for view_location in FINANCIAL_VIEW_LOCATIONS: - config.scan(view_location) + config.scan('openprocurement.auctions.dgf.views.financial') # Register Adapters config.registry.registerAdapter(