diff options
Diffstat (limited to 't/photostorage/s3.t')
-rw-r--r-- | t/photostorage/s3.t | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/t/photostorage/s3.t b/t/photostorage/s3.t new file mode 100644 index 000000000..fa989374f --- /dev/null +++ b/t/photostorage/s3.t @@ -0,0 +1,164 @@ +#!/usr/bin/env perl +use FixMyStreet::Test; + +use Test::MockModule; +use Path::Tiny 'path'; +use Net::Amazon::S3::Client::Bucket; + +use_ok( 'FixMyStreet::PhotoStorage::S3' ); + +FixMyStreet::override_config { + PHOTO_STORAGE_OPTIONS => { + ACCESS_KEY => 'AKIAMYFAKEACCESSKEY', + SECRET_KEY => '1234/fAk35eCrETkEy', + BUCKET => 'fms-test-photos', + PREFIX => '/uploads', + }, +}, sub { + + my $s3 = FixMyStreet::PhotoStorage::S3->new(); + + subtest "basic attributes are configured correctly" => sub { + ok $s3->client, "N::A::S3::Client created"; + is $s3->client->s3->aws_access_key_id, 'AKIAMYFAKEACCESSKEY', "Correct access key used"; + is $s3->client->s3->aws_secret_access_key, '1234/fAk35eCrETkEy', "Correct secret key used"; + + ok $s3->bucket, "N::A::S3::Bucket created"; + is $s3->bucket->name, 'fms-test-photos', "Correct bucket name configured"; + + is $s3->prefix, '/uploads/', "Correct key prefix with trailing slash"; + }; + + subtest "photos can be stored in S3" => sub { + my $photo_blob = path('t/app/controller/sample.jpg')->slurp; + is $s3->get_fileid($photo_blob), '74e3362283b6ef0c48686fb0e161da4043bbcc97', "File ID calculated correctly"; + is $s3->detect_type($photo_blob), 'jpeg', "File type calculated correctly"; + + my $s3_object = Test::MockModule->new('Net::Amazon::S3::Client::Object'); + my $put_called = 0; + $s3_object->mock('put', sub { + my ($self, $photo) = @_; + is $self->key, '/uploads/74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg', 'Object created with correct key'; + is $self->bucket->name, 'fms-test-photos', 'Object stored in correct bucket'; + is $photo, $photo_blob, 'Correct photo uploaded'; + $put_called = 1; + }); + + is $s3->store_photo($photo_blob), '/uploads/74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg', 'Photo uploaded and correct key returned'; + ok $put_called, "Object::put called"; + }; + + subtest "photos can be retrieved from S3" => sub { + my $photo_blob = path('t/app/controller/sample.jpg')->slurp; + my $key = '/uploads/74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg'; + + my $s3_object = Test::MockModule->new('Net::Amazon::S3::Client::Object'); + my $exists_called = 0; + $s3_object->mock('exists', sub { + my ($self) = @_; + is $self->key, $key, 'Object::exists called with correct key'; + $exists_called = 1; + return 1; + }); + my $get_called = 0; + $s3_object->mock('get', sub { + my ($self) = @_; + is $self->key, $key, 'Object::get called with correct key'; + is $self->bucket->name, 'fms-test-photos', 'Object fetched from correct bucket'; + $get_called = 1; + return $photo_blob; + }); + + my ($photo, $type) = $s3->retrieve_photo($key); + ok $exists_called, "Object::exists called"; + ok $get_called, "Object::get called"; + is $photo, $photo_blob, 'Correct file content returned'; + is $type, 'jpeg', 'Correct file type returned'; + }; + + subtest "init passes if bucket exists" => sub { + my $s3_client = Test::MockModule->new('Net::Amazon::S3::Client'); + my $buckets_called = 0; + $s3_client->mock('buckets', sub { + my $self = shift; + $buckets_called = 1; + return ( + Net::Amazon::S3::Client::Bucket->new( + client => $self, + name => 'fms-test-photos' + ) + ); + }); + + ok $s3->init(), "PhotoStorage::S3::init succeeded"; + ok $buckets_called, "Client::buckets called"; + }; + + subtest "init fails if bucket doesn't exist" => sub { + my $s3_client = Test::MockModule->new('Net::Amazon::S3::Client'); + my $buckets_called = 0; + $s3_client->mock('buckets', sub { + my $self = shift; + $buckets_called = 1; + return ( + Net::Amazon::S3::Client::Bucket->new( + client => $self, + name => 'not-your-bucket' + ) + ); + }); + my $create_bucket_called = 0; + $s3_client->mock('create_bucket', sub { + $create_bucket_called = 1; + }); + + ok !$s3->init(), "PhotoStorage::S3::init failed"; + ok $buckets_called, "Client::buckets called"; + ok !$create_bucket_called, "Client::create_bucket not called"; + }; +}; + +FixMyStreet::override_config { + PHOTO_STORAGE_OPTIONS => { + ACCESS_KEY => 'AKIAMYFAKEACCESSKEY', + SECRET_KEY => '1234/fAk35eCrETkEy', + BUCKET => 'fms-test-photos', + CREATE_BUCKET => 1, + REGION => 'eu-west-3', + }, +}, sub { + + my $s3 = FixMyStreet::PhotoStorage::S3->new(); + + subtest "init creates bucket if CREATE_BUCKET set" => sub { + my $s3_client = Test::MockModule->new('Net::Amazon::S3::Client'); + my $create_bucket_called = 0; + $s3_client->mock('create_bucket', sub { + my ( $self, %conf ) = @_; + $create_bucket_called = 1; + is $conf{name}, "fms-test-photos", "Bucket created with correct name"; + is $conf{location_constraint}, "eu-west-3", "Bucket created in correct region"; + }); + my $buckets_called = 0; + $s3_client->mock('buckets', sub { + my $self = shift; + $buckets_called = 1; + return ( + Net::Amazon::S3::Client::Bucket->new( + client => $self, + name => 'not-your-bucket' + ), + $create_bucket_called ? Net::Amazon::S3::Client::Bucket->new( + client => $self, + name => 'fms-test-photos' + ) : (), + ); + }); + + ok $s3->init(), "PhotoStorage::S3::init succeeded"; + ok $buckets_called, "Client::buckets called"; + ok $create_bucket_called, "Client::create_bucket called"; + }; +}; + +done_testing(); |