Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/document_service'
Browse files Browse the repository at this point in the history
  • Loading branch information
kroman0 committed Oct 6, 2016
2 parents 86c15d6 + 76dd098 commit 055cdc7
Show file tree
Hide file tree
Showing 10 changed files with 612 additions and 137 deletions.
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
language: python
sudo: false
sudo: required
before_script:
- sudo add-apt-repository ppa:chris-lea/libsodium -y
- sudo apt-get -qq update
- sudo apt-get install libsodium13 -y
python:
- "2.7"
services:
Expand Down
55 changes: 55 additions & 0 deletions openprocurement/contracting/api/migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
import logging
from openprocurement.contracting.api.traversal import Root
from openprocurement.contracting.api.models import Contract

LOGGER = logging.getLogger(__name__)
SCHEMA_VERSION = 1
SCHEMA_DOC = 'openprocurement_contracts_schema'


def get_db_schema_version(db):
schema_doc = db.get(SCHEMA_DOC, {"_id": SCHEMA_DOC})
return schema_doc.get("version", SCHEMA_VERSION - 1)


def set_db_schema_version(db, version):
schema_doc = db.get(SCHEMA_DOC, {"_id": SCHEMA_DOC})
schema_doc["version"] = version
db.save(schema_doc)


def migrate_data(registry, destination=None):
if registry.settings.get('plugins') and 'contracting' not in registry.settings['plugins'].split(','):
return
cur_version = get_db_schema_version(registry.db)
if cur_version == SCHEMA_VERSION:
return cur_version
for step in xrange(cur_version, destination or SCHEMA_VERSION):
LOGGER.info("Migrate openprocurement contracts schema from {} to {}".format(step, step + 1), extra={'MESSAGE_ID': 'migrate_data'})
migration_func = globals().get('from{}to{}'.format(step, step + 1))
if migration_func:
migration_func(registry)
set_db_schema_version(registry.db, step + 1)


def from0to1(registry):
class Request(object):
def __init__(self, registry):
self.registry = registry
results = registry.db.iterview('contracts/all', 2 ** 10, include_docs=True)
docs = []
request = Request(registry)
root = Root(request)
for i in results:
doc = i.doc
if doc.get('documents'):
contract = Contract(doc)
contract.__parent__ = root
doc = contract.to_primitive()
docs.append(doc)
if len(docs) >= 2 ** 7:
registry.db.update(docs)
docs = []
if docs:
registry.db.update(docs)
41 changes: 37 additions & 4 deletions openprocurement/contracting/api/tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
import os
import unittest
import webtest
from uuid import uuid4
from base64 import b64encode
from copy import deepcopy
from datetime import datetime

from openprocurement.api.utils import VERSION
from openprocurement.api.utils import VERSION, SESSION
from openprocurement.api.models import get_now

from requests.models import Response
from urllib import urlencode
from uuid import uuid4

now = datetime.now()

Expand Down Expand Up @@ -143,6 +144,7 @@ class BaseWebTest(unittest.TestCase):
It setups the database before each test and delete it after.
"""
initial_auth = ('Basic', ('token', ''))
docservice = False

def setUp(self):
self.app = webtest.TestApp(
Expand All @@ -151,8 +153,39 @@ def setUp(self):
self.app.authorization = self.initial_auth
self.couchdb_server = self.app.app.registry.couchdb_server
self.db = self.app.app.registry.db
if self.docservice:
self.setUpDS()

def setUpDS(self):
self.app.app.registry.docservice_url = 'http://localhost'
test = self
def request(method, url, **kwargs):
response = Response()
if method == 'POST' and '/upload' in url:
url = test.generate_docservice_url()
response.status_code = 200
response.encoding = 'application/json'
response._content = '{{"data":{{"url":"{url}","hash":"md5:{md5}","format":"application/msword","title":"name.doc"}},"get_url":"{url}"}}'.format(url=url, md5='0'*32)
response.reason = '200 OK'
return response

self._srequest = SESSION.request
SESSION.request = request

def generate_docservice_url(self):
uuid = uuid4().hex
key = self.app.app.registry.docservice_key
keyid = key.hex_vk()[:8]
signature = b64encode(key.signature("{}\0{}".format(uuid, '0' * 32)))
query = {'Signature': signature, 'KeyID': keyid}
return "http://localhost/get/{}?{}".format(uuid, urlencode(query))

def tearDownDS(self):
SESSION.request = self._srequest

def tearDown(self):
if self.docservice:
self.tearDownDS()
del self.couchdb_server[self.db.name]


Expand Down
26 changes: 25 additions & 1 deletion openprocurement/contracting/api/tests/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from openprocurement.api import ROUTE_PREFIX
from openprocurement.contracting.api.models import Contract
from openprocurement.contracting.api.tests.base import (
test_contract_data, BaseWebTest, BaseContractWebTest)
test_contract_data, BaseWebTest, BaseContractWebTest, documents)
from openprocurement.api.models import get_now


Expand Down Expand Up @@ -509,6 +509,30 @@ def test_create_contract(self):
self.assertEqual(response.status, '403 Forbidden')


class ContractWDocumentsWithDSResourceTest(BaseWebTest):
docservice = True

def test_create_contract_w_documents(self):
data = deepcopy(test_contract_data)
data['documents'] = documents
response = self.app.post_json('/contracts', {"data": data})
self.assertEqual(response.status, '201 Created')
self.assertEqual(response.content_type, 'application/json')
contract = response.json['data']
self.assertEqual(contract['status'], 'active')

self.assertIn('Signature=', response.json["data"]['documents'][-1]["url"])
self.assertIn('KeyID=', response.json["data"]['documents'][-1]["url"])
self.assertNotIn('Expires=', response.json["data"]['documents'][-1]["url"])

contract = self.db.get(contract['id'])
self.assertIn('Prefix=ce536c5f46d543ec81ffa86ce4c77c8b%2F9c8b66120d4c415cb334bbad33f94ba9', contract['documents'][-1]["url"])
self.assertIn('/da839a4c3d7a41d2852d17f90aa14f47?', contract['documents'][-1]["url"])
self.assertIn('Signature=', contract['documents'][-1]["url"])
self.assertIn('KeyID=', contract['documents'][-1]["url"])
self.assertNotIn('Expires=', contract['documents'][-1]["url"])


class ContractResource4BrokersTest(BaseContractWebTest):
""" contract resource test """
initial_auth = ('Basic', ('broker', ''))
Expand Down

0 comments on commit 055cdc7

Please sign in to comment.