from io import StringIO
from mock import patch
from datetime import datetime, timedelta
from django.test import TestCase

from corehq.blobs.exceptions import NotFound
from corehq.blobs.tasks import delete_expired_blobs
from corehq.blobs.tests.util import TemporaryFilesystemBlobDB
from corehq.blobs.models import BlobExpiration


class BlobExpireTest(TestCase):

    identifier = 'blob-identifier'
    bucket = 'blob-bucket'

    @classmethod
    def setUpClass(cls):
        cls.db = TemporaryFilesystemBlobDB()

    @classmethod
    def tearDownClass(cls):
        BlobExpiration.objects.all().delete()
        cls.db.close()

    def tearDown(self):
        if self.db.exists(self.identifier, self.bucket):
            self.db.delete(self.identifier, self.bucket)

    def test_blob_expires(self):
        now = datetime(2017, 1, 1)

        with patch('corehq.blobs.util._utcnow', return_value=now):
            self.db.put(StringIO(u'content'), self.identifier, bucket=self.bucket, timeout=60)

        self.assertIsNotNone(self.db.get(self.identifier, self.bucket))
        with patch('corehq.blobs.tasks._utcnow', return_value=now + timedelta(minutes=61)):
            delete_expired_blobs()

        with self.assertRaises(NotFound):
            self.db.get(self.identifier, self.bucket)

    def test_blob_does_not_expire(self):
        now = datetime(2017, 1, 1)

        with patch('corehq.blobs.util._utcnow', return_value=now):
            self.db.put(StringIO(u'content'), self.identifier, bucket=self.bucket, timeout=60)

        self.assertIsNotNone(self.db.get(self.identifier, self.bucket))
        with patch('corehq.blobs.tasks._utcnow', return_value=now + timedelta(minutes=30)):
            delete_expired_blobs()

        self.assertIsNotNone(self.db.get(self.identifier, self.bucket))

@@ -1782,28 +1782,1174 @@
 f.identifier, self.bucket))%0A
+%0A    def test_duplicate_identifier_expire(self):%0A        now = datetime(2017, 1, 1)%0A%0A        with patch('corehq.blobs.util._utcnow', return_value=now):%0A            self.db.put(StringIO(u'content'), self.identifier, bucket=self.bucket, timeout=60)%0A%0A        self.assertIsNotNone(self.db.get(self.identifier, self.bucket))%0A        with patch('corehq.blobs.tasks._utcnow', return_value=now + timedelta(minutes=61)):%0A            delete_expired_blobs()%0A%0A        with self.assertRaises(NotFound):%0A            self.db.get(self.identifier, self.bucket)%0A%0A        now = datetime(2018, 1, 1)%0A        # Put another blob a year later with the same identifier%0A        with patch('corehq.blobs.util._utcnow', return_value=now):%0A            self.db.put(StringIO(u'content'), self.identifier, bucket=self.bucket, timeout=60)%0A%0A        # Even though there is an old BlobExpiration record for that bucket/identifier,%0A        # we should not delete delete the new blob%0A        with patch('corehq.blobs.tasks._utcnow', return_value=now + timedelta(minutes=0)):%0A            delete_expired_blobs()%0A%0A        self.assertIsNotNone(self.db.get(self.identifier, self.bucket))%0A

Test duplicate identifier