Skip to content

Commit

Permalink
Add test for saving files using bytes/strings and File/ContentFile.
Browse files Browse the repository at this point in the history
2 of these tests currently fail due to issue jschneier#708.
They use moto to mock s3 at a lower level and actually get the right error to surface.
  • Loading branch information
LincolnPuzey committed Jul 27, 2020
1 parent 7dc38ce commit edd441c
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
5 changes: 5 additions & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@
SECRET_KEY = 'hailthesunshine'

USE_TZ = True


AWS_STORAGE_BUCKET_NAME = "test_bucket"
AWS_ACCESS_KEY_ID = "testing_key_id"
AWS_SECRET_ACCESS_KEY = "testing_access_key"
61 changes: 60 additions & 1 deletion tests/test_s3boto3.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@
import pickle
import threading
from datetime import datetime
from io import BytesIO, StringIO
from textwrap import dedent
from unittest import mock, skipIf
from urllib.parse import urlparse

from boto3 import resource
from botocore.exceptions import ClientError
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.files.base import ContentFile
from django.core.files.base import ContentFile, File
from django.test import TestCase, override_settings
from django.utils.timezone import is_aware, utc
from moto import mock_s3

from storages.backends import s3boto3

Expand Down Expand Up @@ -642,3 +645,59 @@ def test_override_init_argument(self):
self.assertEqual(storage.location, 'foo1')
storage = s3boto3.S3Boto3Storage(location='foo2')
self.assertEqual(storage.location, 'foo2')


@mock_s3
class S3Boto3StorageTestsWithMoto(TestCase):
"""
These tests use the moto library to mock S3, rather than unittest.mock.
This is better because more of boto3's internal code will be run in tests.
For example this issue
https://github.com/jschneier/django-storages/issues/708
wouldn't be caught using unittest.mock, since the error occurs in boto3's internals.
Using mock_s3 as a class decorator automatically decorates methods,
but NOT classmethods or staticmethods.
"""
@classmethod
@mock_s3
def setUpClass(cls):
super().setUpClass()
# create a bucket specified in settings.
cls.bucket = resource("s3").Bucket(settings.AWS_STORAGE_BUCKET_NAME)
cls.bucket.create()
# create a S3Boto3Storage backend instance.
cls.s3boto3_storage = s3boto3.S3Boto3Storage()

def test_save_bytes_file(self):
self.s3boto3_storage.save("bytes_file.txt", File(BytesIO(b"foo1")))

self.assertEqual(
b"foo1",
self.bucket.Object("bytes_file.txt").get()['Body'].read(),
)

def test_save_string_file(self):
self.s3boto3_storage.save("string_file.txt", File(StringIO("foo2")))

self.assertEqual(
b"foo2",
self.bucket.Object("string_file.txt").get()['Body'].read(),
)

def test_save_bytes_content(self):
self.s3boto3_storage.save("bytes_content.txt", ContentFile(b"foo3"))

self.assertEqual(
b"foo3",
self.bucket.Object("bytes_content.txt").get()['Body'].read(),
)

def test_save_string_content(self):
self.s3boto3_storage.save("string_content.txt", ContentFile("foo4"))

self.assertEqual(
b"foo4",
self.bucket.Object("string_content.txt").get()['Body'].read(),
)

0 comments on commit edd441c

Please sign in to comment.