0

I'm trying to provide a redirect to an s3 presigned url generated via boto3, it looks like it should work but I want to write a testcase for it.

I've checked with something similar to what's below. The test_redirect_to_presigned_url() fails with a test_bucket/testfile.png not found. While the test_motos3_presigned_url works as expected.

from django.test import TestCase
from django.test import Client


class MotoS3TestCase(TestCase):
    def setUp(self):
        self.mock = mock_s3()
        self.mock.start()
        self.bucket_name = 'test_bucket'
        self.conn = boto3.resource('s3')
        self.conn.create_bucket(Bucket=self.bucket_name)
        self.s3 = boto3.client('s3')

    def tearDown(self):
        self.mock.stop()

    def test_redirect_to_presigned_url(self):
        client = Client()
        response = client.get('/url/to/view/', follow=True)   
        self.assertTrue(response.status_code == 200, f'response: {response}, response.content: {response.content}')         

    def test_motos3_presigned_url(self):
        keyname = 'testfile.png'  
        self.s3.upload_fileobj(io.BytesIO(b'somefile content'), self.bucket_name, keyname)
        params = {
            'Bucket': self.bucket_name,
            'Key': keyname,
        }

        presigned_url = self.s3.generate_presigned_url(
            ClientMethod='get_object',
            Params=params,
            ExpiresIn=3600,
            HttpMethod='GET'
        )
        import requests
        response = requests.get(presigned_url)

        self.assertTrue(response.status_code == 200, f'response: {response}, response.content: {response.content}')

views.py

import boto3
from django.http import HttpResponseRedirect


def redirect_to_presigned_url(request):
    s3 = boto3.client('s3')
    keyname = 'testfile.png'  
    bucket_name = 'test_bucket'
    s3.upload_fileobj(io.BytesIO(b'somefile content'), bucket_name, keyname)
    params = {
                'Bucket': bucket_name,
                'Key': keyname,
    }

    presigned_url = s3.generate_presigned_url(
                ClientMethod='get_object',
                Params=params,
                ExpiresIn=3600,
                HttpMethod='GET'
    )
    return HttpResponseRedirect(redirect_to=presigned_url)

It appears that moto doesn't integrate well with the django test client. On redirect attempt, moto seems to be returning a 404 does not exist.

So even though I've added the object, I'm not able to redirect to that object using the generated presigned_url.

Is there a good why I can create a testcase to check this redirect?

monkut
  • 42,176
  • 24
  • 124
  • 155
  • is self.bucket_name actually declared in views.py? hard to tell what is going on bc the views.py file seems to not be real code – grrrrrr Oct 02 '18 at 19:08
  • Yes, this just sample code, and runs without syntax errors... – monkut Oct 03 '18 at 00:34
  • still a little unclear on whats going on, but my inclination is that this has to do with your use of mock. my guess is the mock scope doesn't reach the view and therefore you are getting different results – grrrrrr Oct 03 '18 at 21:31
  • Ok, I've added a bit more context. I'll try to get the exact error later. – monkut Oct 04 '18 at 23:59

0 Answers0