summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/pixelated/adapter/mailstore/leap_attachment_store.py10
-rw-r--r--service/test/unit/adapter/mailstore/test_leap_attachment_store.py21
2 files changed, 28 insertions, 3 deletions
diff --git a/service/pixelated/adapter/mailstore/leap_attachment_store.py b/service/pixelated/adapter/mailstore/leap_attachment_store.py
index 86121db9..982d9222 100644
--- a/service/pixelated/adapter/mailstore/leap_attachment_store.py
+++ b/service/pixelated/adapter/mailstore/leap_attachment_store.py
@@ -17,7 +17,7 @@ class LeapAttachmentStore(object):
@defer.inlineCallbacks
def get_mail_attachment(self, attachment_id):
results = yield self.soledad.get_from_index('by-type-and-payloadhash', 'cnt', attachment_id) if attachment_id else []
- if len(results):
+ if results:
content = ContentDocWrapper(**results[0].content)
defer.returnValue({'content-type': content.content_type, 'content': self._try_decode(
content.raw, content.content_transfer_encoding)})
@@ -27,8 +27,12 @@ class LeapAttachmentStore(object):
@defer.inlineCallbacks
def add_attachment(self, content, content_type):
cdoc = self._attachment_to_cdoc(content, content_type)
- yield self.soledad.create_doc(cdoc.serialize(), doc_id=cdoc.phash)
- defer.returnValue(cdoc.phash)
+ attachment_id = cdoc.phash
+ try:
+ yield self.get_mail_attachment(attachment_id)
+ except ValueError:
+ yield self.soledad.create_doc(cdoc.serialize(), doc_id=attachment_id)
+ defer.returnValue(attachment_id)
def _try_decode(self, raw, encoding):
encoding = encoding.lower()
diff --git a/service/test/unit/adapter/mailstore/test_leap_attachment_store.py b/service/test/unit/adapter/mailstore/test_leap_attachment_store.py
index 172cceb6..4e9b56b1 100644
--- a/service/test/unit/adapter/mailstore/test_leap_attachment_store.py
+++ b/service/test/unit/adapter/mailstore/test_leap_attachment_store.py
@@ -16,6 +16,7 @@
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
import json
from uuid import uuid4
+import u1db
from leap.mail.adaptors.soledad_indexes import MAIL_INDEXES
from leap.soledad.common.document import SoledadDocument
@@ -68,6 +69,26 @@ class TestLeapAttachmentStore(TestCase):
verify(self.soledad).create_doc(cdoc_serialized, doc_id=attachment_id)
@defer.inlineCallbacks
+ def test_store_attachment_twice_does_not_cause_exception(self):
+ attachment_id = '9863729729D2E2EE8E52F0A7115CE33AD18DDA4B58E49AE08DD092D1C8E699B0'
+ content = 'this is some attachment content'
+ content_type = 'text/plain'
+ cdoc_serialized = {'content_transfer_encoding': 'base64', 'lkf': [], 'content_disposition': 'attachment',
+ 'ctype': '', 'raw': 'dGhpcyBpcyBzb21lIGF0dGFjaG1lbnQgY29udGVudA==',
+ 'phash': '9863729729D2E2EE8E52F0A7115CE33AD18DDA4B58E49AE08DD092D1C8E699B0',
+ 'content_type': 'text/plain', 'type': 'cnt'}
+ doc = SoledadDocument(json=json.dumps({'content_type': content_type, 'raw': content}))
+ when(self.soledad).get_from_index('by-type-and-payloadhash', 'cnt', attachment_id).thenReturn(defer.succeed([doc]))
+
+ store = LeapAttachmentStore(self.soledad)
+
+ when(self.soledad).create_doc(cdoc_serialized, doc_id=attachment_id).thenRaise(u1db.errors.RevisionConflict())
+
+ actual_attachment_id = yield store.add_attachment(content, content_type)
+
+ self.assertEqual(attachment_id, actual_attachment_id)
+
+ @defer.inlineCallbacks
def test_get_mail_attachment_different_content_encodings(self):
attachment_id = '1B0A9AAD9E153D24265395203C53884506ABA276394B9FEC02B214BF9E77E48E'
encoding_examples = [('', 'asdf', 'asdf'),