defra_ruby_aws 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8f98773dfc3468b835ccb7120609f527544bb794
4
+ data.tar.gz: 450ba740fa675f36bcd7b1c072524e06306e0f0f
5
+ SHA512:
6
+ metadata.gz: bce99a5fbe92846cdf796771c153b3a90d2fef9459458f87f89e6626b24011c3bff84f5a42ba8ef4e457fa9bc297e4c59e8774fffdb958d0573fc6a46f524fd3
7
+ data.tar.gz: 27d93f4cc90f7d8eb5445017a990215afec9e345d9121dd04243fd734854cfd8362c7c1403b7c8891199b26a236b0871c526b345075cd12c730957b28eba9f86
data/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # DefraRuby::Aws
2
+
3
+ [![Build Status](https://travis-ci.com/DEFRA/defra-ruby-aws.svg?branch=master)](https://travis-ci.com/DEFRA/defra-ruby-aws)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/4541a29b2c675b03a5ed/maintainability)](https://codeclimate.com/github/DEFRA/defra-ruby-aws/maintainability)
5
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/4541a29b2c675b03a5ed/test_coverage)](https://codeclimate.com/github/DEFRA/defra-ruby-aws/test_coverage)
6
+ [![security](https://hakiri.io/github/DEFRA/defra-ruby-aws/master.svg)](https://hakiri.io/github/DEFRA/defra-ruby-aws/master)
7
+ [![Gem Version](https://badge.fury.io/rb/defra_ruby_aws.svg)](https://badge.fury.io/rb/defra_ruby_aws)
8
+ [![Licence](https://img.shields.io/badge/Licence-OGLv3-blue.svg)](http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3)
9
+
10
+ Package of Ruby helpers for connecting Rails applications to AWS S3.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile
15
+
16
+ ```ruby
17
+ gem 'defra_ruby_aws'
18
+ ```
19
+
20
+ And then update your dependencies by calling
21
+
22
+ ```bash
23
+ bundle install
24
+ ```
25
+
26
+ ## Configuration
27
+
28
+ Add a new bucket with:
29
+
30
+ ```ruby
31
+ # config/initializers/defra_ruby_aws.rb
32
+ require "defra_ruby/aws"
33
+
34
+ DefraRuby::Aws.configure do |config|
35
+ config.buckets = [{
36
+ # bucket's name, required
37
+ name: "defra-ruby-aws",
38
+ # AWS bucket access credentials, required
39
+ credentials: {
40
+ access_key_id: "ACCESS_KEY_ID",
41
+ secret_access_key: "SECRET_ACCESS_KEY"
42
+ },
43
+ # optional - Default to "eu-west-1"
44
+ region: "eu-west-1"
45
+ }]
46
+ end
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ ### Upload a file
52
+
53
+ ```ruby
54
+ file_to_upload = Tempfile.new("test-upload-file.csv")
55
+ bucket = DefraRuby::Aws.get_bucket("defra-ruby-aws")
56
+ response = bucket.load(file_to_upload)
57
+
58
+ if response.successful?
59
+ # Do something
60
+ else
61
+ response.error # return the failure error
62
+ # Do something else
63
+ end
64
+ ```
65
+
66
+ ### Generate a presigned URL for download
67
+
68
+ ```ruby
69
+ bucket = DefraRuby::Aws.get_bucket("defra-ruby-aws")
70
+ presigned_url = bucket.presigned_url("test-upload-file.csv")
71
+ ```
72
+
73
+ ## Contributing to this project
74
+
75
+ If you have an idea you'd like to contribute please log an issue.
76
+
77
+ All contributions should be submitted via a pull request.
78
+
79
+ ## License
80
+
81
+ THIS INFORMATION IS LICENSED UNDER THE CONDITIONS OF THE OPEN GOVERNMENT LICENCE found at:
82
+
83
+ http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3
84
+
85
+ The following attribution statement MUST be cited in your products and applications when using this information.
86
+
87
+ > Contains public sector information licensed under the Open Government license v3
88
+
89
+ ### About the license
90
+
91
+ The Open Government Licence (OGL) was developed by the Controller of Her Majesty's Stationery Office (HMSO) to enable information providers in the public sector to license the use and re-use of their information under a common open licence.
92
+
93
+ It is designed to encourage use and re-use of information freely and flexibly, with only a few conditions.
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "bundler/setup"
5
+ rescue LoadError
6
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
7
+ end
8
+
9
+ Bundler::GemHelper.install_tasks
10
+
11
+ # This is wrapped to prevent an error when rake is called in environments where
12
+ # rspec may not be available, e.g. production. As such we don't need to handle
13
+ # the error.
14
+ # rubocop:disable Lint/HandleExceptions
15
+ begin
16
+ require "rspec/core/rake_task"
17
+
18
+ RSpec::Core::RakeTask.new(:spec)
19
+
20
+ task default: :spec
21
+ rescue LoadError
22
+ # no rspec available
23
+ end
24
+
25
+ begin
26
+ require "github_changelog_generator/task"
27
+
28
+ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
29
+ end
30
+ rescue LoadError
31
+ # no changelog available
32
+ end
33
+ # rubocop:enable Lint/HandleExceptions
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "defra_ruby/aws"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/defra_ruby.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "defra_ruby/aws"
4
+
5
+ module DefraRuby
6
+ # The Defra Ruby packages namespace.
7
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "aws/bucket"
4
+ require_relative "aws/response"
5
+ require_relative "aws/configuration"
6
+
7
+ require_relative "aws/services/concerns/has_aws_bucket_configuration"
8
+ require_relative "aws/services/bucket_loader_service"
9
+ require_relative "aws/services/presigned_url_service"
10
+
11
+ module DefraRuby
12
+ module Aws
13
+ class << self
14
+ attr_accessor :configuration
15
+
16
+ def configure
17
+ require "aws-sdk-s3"
18
+
19
+ self.configuration ||= Configuration.new
20
+ yield(configuration)
21
+ end
22
+
23
+ def get_bucket(bucket_name)
24
+ configuration.buckets.select do |bucket|
25
+ bucket.bucket_name == bucket_name
26
+ end.first
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Aws
5
+ class Bucket
6
+ attr_reader :bucket_name, :credentials, :region
7
+
8
+ def initialize(configs)
9
+ @credentials = configs[:credentials]
10
+ @bucket_name = configs[:name]
11
+ @region = setup_region(configs[:region])
12
+
13
+ validate!
14
+ end
15
+
16
+ def access_key_id
17
+ credentials[:access_key_id]
18
+ end
19
+
20
+ def secret_access_key
21
+ credentials[:secret_access_key]
22
+ end
23
+
24
+ def load(file)
25
+ BucketLoaderService.run(self, file)
26
+ end
27
+
28
+ def presigned_url(file_name)
29
+ PresignedUrlService.run(self, file_name)
30
+ end
31
+
32
+ private
33
+
34
+ attr_writer :region
35
+
36
+ def setup_region(region)
37
+ return default_region if region.nil? || region.empty?
38
+
39
+ region
40
+ end
41
+
42
+ def default_region
43
+ "eu-west-1"
44
+ end
45
+
46
+ def validate!
47
+ validate_presence_of_name!
48
+ validate_presence_of_credentials!
49
+ end
50
+
51
+ def validate_presence_of_name!
52
+ raise_not_valid_name if bucket_name.nil? || bucket_name.empty?
53
+ end
54
+
55
+ def validate_presence_of_credentials!
56
+ raise_missing_credentials if empty?(credentials)
57
+ raise_missing_access_key if empty?(access_key_id)
58
+ raise_missing_secret_access_key if empty?(secret_access_key)
59
+ end
60
+
61
+ def raise_not_valid_name
62
+ raise("DefraRuby::Aws buckets configurations: missing bucket name")
63
+ end
64
+
65
+ def raise_missing_credentials
66
+ raise("DefraRuby::Aws buckets configurations: missing credentials for bucket #{bucket_name}")
67
+ end
68
+
69
+ def raise_missing_access_key
70
+ raise("DefraRuby::Aws buckets configurations: missing access key id for bucket #{bucket_name}")
71
+ end
72
+
73
+ def raise_missing_secret_access_key
74
+ raise("DefraRuby::Aws buckets configurations: missing secret access key for bucket #{bucket_name}")
75
+ end
76
+
77
+ def empty?(object)
78
+ object.nil? || object.empty?
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Aws
5
+ class Configuration
6
+ attr_reader :buckets
7
+
8
+ def initialize
9
+ @buckets = {}
10
+ end
11
+
12
+ def buckets=(buckets_configurations)
13
+ @buckets = buckets_configurations.map do |configs|
14
+ Bucket.new(configs)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Aws
5
+ class Response
6
+ attr_reader :error
7
+
8
+ def initialize(response_exe)
9
+ @success = true
10
+ @error = nil
11
+
12
+ capture_response(response_exe)
13
+ end
14
+
15
+ def successful?
16
+ success
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :success
22
+
23
+ def capture_response(response_exe)
24
+ response_exe.call
25
+ rescue StandardError => e
26
+ @error = e
27
+ @success = false
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Aws
5
+ class BucketLoaderService
6
+ include HasAwsBucketConfiguration
7
+
8
+ def self.run(bucket, file)
9
+ new(bucket, file).run
10
+ end
11
+
12
+ def initialize(bucket, file)
13
+ @bucket = bucket
14
+ @file = file
15
+ end
16
+
17
+ def run
18
+ Response.new(response_exe)
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :bucket, :file
24
+
25
+ def response_exe
26
+ lambda do
27
+ s3_bucket.object(File.basename(file.path)).upload_file(file.path, server_side_encryption: :AES256)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Aws
5
+ module HasAwsBucketConfiguration
6
+ def s3_bucket
7
+ s3.bucket(bucket.bucket_name)
8
+ end
9
+
10
+ def s3
11
+ ::Aws::S3::Resource.new(
12
+ region: bucket.region,
13
+ credentials: aws_credentials
14
+ )
15
+ end
16
+
17
+ def aws_credentials
18
+ ::Aws::Credentials.new(bucket.access_key_id, bucket.secret_access_key)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Aws
5
+ class PresignedUrlService
6
+ include HasAwsBucketConfiguration
7
+
8
+ def self.run(bucket, file_name)
9
+ new(bucket, file_name).run
10
+ end
11
+
12
+ def initialize(bucket, file_name)
13
+ @bucket = bucket
14
+ @file_name = file_name
15
+ end
16
+
17
+ def run
18
+ s3_bucket.object(file_name).presigned_url(
19
+ :get,
20
+ expires_in: 20 * 60, # 20 minutes in seconds
21
+ secure: true,
22
+ response_content_type: "text/csv",
23
+ response_content_disposition: "attachment; filename=#{file_name}"
24
+ )
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :bucket, :file_name
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Aws
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe DefraRuby::Aws do
4
+ it "has a version number" do
5
+ expect(DefraRuby::Aws::VERSION).not_to be nil
6
+ end
7
+ end
data/spec/examples.txt ADDED
@@ -0,0 +1,17 @@
1
+ example_id | status | run_time |
2
+ ----------------------------------------------------------------------- | ------ | --------------- |
3
+ ./spec/defra_ruby_aws_spec.rb[1:1] | passed | 0.00122 seconds |
4
+ ./spec/features/upload_file_to_bucket_spec.rb[1:1] | passed | 0.0124 seconds |
5
+ ./spec/features/upload_file_to_bucket_spec.rb[1:2] | passed | 0.00574 seconds |
6
+ ./spec/lib/defra_ruby/aws/bucket_spec.rb[1:1:1:1] | passed | 0.00174 seconds |
7
+ ./spec/lib/defra_ruby/aws/bucket_spec.rb[1:1:2:1] | passed | 0.0001 seconds |
8
+ ./spec/lib/defra_ruby/aws/bucket_spec.rb[1:1:3:1] | passed | 0.00017 seconds |
9
+ ./spec/lib/defra_ruby/aws/bucket_spec.rb[1:1:4:1] | passed | 0.00014 seconds |
10
+ ./spec/lib/defra_ruby/aws/bucket_spec.rb[1:2:1] | passed | 0.00213 seconds |
11
+ ./spec/lib/defra_ruby/aws/configuration_spec.rb[1:1:1] | passed | 0.00061 seconds |
12
+ ./spec/lib/defra_ruby/aws/response_spec.rb[1:1:1:1] | passed | 0.00011 seconds |
13
+ ./spec/lib/defra_ruby/aws/response_spec.rb[1:1:2:1] | passed | 0.00014 seconds |
14
+ ./spec/lib/defra_ruby/aws/response_spec.rb[1:2:1:1] | passed | 0.0001 seconds |
15
+ ./spec/lib/defra_ruby/aws/response_spec.rb[1:2:2:1] | passed | 0.00011 seconds |
16
+ ./spec/lib/defra_ruby/aws/services/bucket_loader_service_spec.rb[1:1:1] | passed | 0.01269 seconds |
17
+ ./spec/lib/defra_ruby/aws/services/presigned_url_service_spec.rb[1:1:1] | passed | 0.00368 seconds |
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe "Defra Ruby AWS" do
6
+ it "Upload a file to an AWS bucket" do
7
+ configure_gem
8
+ stub_successful_request
9
+
10
+ bucket = DefraRuby::Aws.get_bucket("bulk-test")
11
+ response = bucket.load(Tempfile.new("test-bucket-load.test"))
12
+
13
+ expect(response).to be_successful
14
+ end
15
+
16
+ it "fails gracefully" do
17
+ configure_gem
18
+ stub_failing_request
19
+
20
+ bucket = DefraRuby::Aws.get_bucket("bulk-test")
21
+ response = bucket.load(Tempfile.new("test-bucket-load.test"))
22
+
23
+ expect(response).to_not be_successful
24
+ expect(response.error).to be_a(Aws::S3::Errors::Forbidden)
25
+ end
26
+
27
+ def configure_gem
28
+ DefraRuby::Aws.configure do |config|
29
+ config.buckets = [{
30
+ name: "bulk-test",
31
+ credentials: {
32
+ access_key_id: "ACCESS_KEY_ID",
33
+ secret_access_key: "SECRET_ACCESS_KEY"
34
+ }
35
+ }]
36
+ end
37
+ end
38
+
39
+ def stub_successful_request
40
+ stub_request(:put, %r{https:\/\/bulk-test\.s3\.eu-west-1\.amazonaws\.com\/test-bucket-load\..+})
41
+ end
42
+
43
+ def stub_failing_request
44
+ stub_request(
45
+ :put,
46
+ %r{https:\/\/bulk-test\.s3\.eu-west-1\.amazonaws\.com\/test-bucket-load\..+}
47
+ ).to_return(
48
+ status: 403
49
+ )
50
+ end
51
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module DefraRuby
6
+ module Aws
7
+ RSpec.describe Bucket do
8
+ subject(:bucket) { described_class.new(configs) }
9
+
10
+ describe "#initialize" do
11
+ context "when a name configuration is missing" do
12
+ let(:configs) do
13
+ {
14
+ name: nil,
15
+ credentials: {}
16
+ }
17
+ end
18
+
19
+ it "raises an error" do
20
+ expect { bucket }.to raise_error("DefraRuby::Aws buckets configurations: missing bucket name")
21
+ end
22
+ end
23
+
24
+ context "when credentials configuration is missing" do
25
+ let(:configs) do
26
+ {
27
+ name: "foo",
28
+ credentials: {}
29
+ }
30
+ end
31
+
32
+ it "raises an error" do
33
+ expect { bucket }.to raise_error("DefraRuby::Aws buckets configurations: missing credentials for bucket foo")
34
+ end
35
+ end
36
+
37
+ context "when credentials access key id is missing" do
38
+ let(:configs) do
39
+ {
40
+ name: "foo",
41
+ credentials: {
42
+ secret_access_key: "secret"
43
+ }
44
+ }
45
+ end
46
+
47
+ it "raises an error" do
48
+ expect { bucket }.to raise_error("DefraRuby::Aws buckets configurations: missing access key id for bucket foo")
49
+ end
50
+ end
51
+
52
+ context "when credentials secret access key is missing" do
53
+ let(:configs) do
54
+ {
55
+ name: "foo",
56
+ credentials: {
57
+ access_key_id: "access_key"
58
+ }
59
+ }
60
+ end
61
+
62
+ it "raises an error" do
63
+ expect { bucket }.to raise_error("DefraRuby::Aws buckets configurations: missing secret access key for bucket foo")
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "#load" do
69
+ let(:configs) do
70
+ {
71
+ name: "foo",
72
+ credentials: {
73
+ secret_access_key: "secret",
74
+ access_key_id: "access_key"
75
+ }
76
+ }
77
+ end
78
+
79
+ it "loads the given file to the s3 bucket" do
80
+ result = double(:result)
81
+ file = double(:file)
82
+
83
+ expect(BucketLoaderService).to receive(:run).with(bucket, file).and_return(result)
84
+ expect(bucket.load(file)).to eq(result)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module DefraRuby
6
+ module Aws
7
+ RSpec.describe Configuration do
8
+ subject(:configuration) { described_class.new }
9
+
10
+ describe "#buckets=" do
11
+ let(:buckets) { %i[foo bar baz] }
12
+
13
+ it "creates a list of buckets" do
14
+ expect(Bucket).to receive(:new).with(:foo)
15
+ expect(Bucket).to receive(:new).with(:bar)
16
+ expect(Bucket).to receive(:new).with(:baz)
17
+
18
+ configuration.buckets = buckets
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module DefraRuby
6
+ module Aws
7
+ RSpec.describe Response do
8
+ subject(:response) { described_class.new(response_exe) }
9
+
10
+ describe "#successful?" do
11
+ context "when the response throws an error" do
12
+ let(:response_exe) { -> { raise "Boom!" } }
13
+
14
+ it "returns false" do
15
+ expect(response).to_not be_successful
16
+ end
17
+ end
18
+
19
+ context "when the response don't throw an error" do
20
+ let(:response_exe) { -> {} }
21
+
22
+ it "returns true" do
23
+ expect(response).to be_successful
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "#error" do
29
+ context "when the response throws an error" do
30
+ let(:response_exe) { -> { raise StandardError, "Boom!" } }
31
+
32
+ it "returns the error" do
33
+ expect(response.error).to be_a(StandardError)
34
+ end
35
+ end
36
+
37
+ context "when the response don't throw an error" do
38
+ let(:response_exe) { -> {} }
39
+
40
+ it "returns a nil object" do
41
+ expect(response.error).to be_nil
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module DefraRuby
6
+ module Aws
7
+ RSpec.describe BucketLoaderService do
8
+ describe "#run" do
9
+ let(:configs) do
10
+ {
11
+ credentials: {
12
+ access_key_id: "key_id",
13
+ secret_access_key: "secret"
14
+ },
15
+ name: "bulk"
16
+ }
17
+ end
18
+ let(:bucket) { Bucket.new(configs) }
19
+
20
+ it "loads the given file to the s3 bucket" do
21
+ aws_resource = double(:aws_resource)
22
+ s3_bucket = double(:s3_bulk_bucket)
23
+ file = double(:file, path: "foo/bar/baz/test.csv")
24
+ s3_object = double(:s3_object)
25
+ result = double(:result)
26
+
27
+ expect(::Aws::S3::Resource).to receive(:new).and_return(aws_resource)
28
+ expect(aws_resource).to receive(:bucket).with("bulk").and_return(s3_bucket)
29
+ expect(s3_bucket).to receive(:object).with("test.csv").and_return(s3_object)
30
+ expect(s3_object).to receive(:upload_file).with("foo/bar/baz/test.csv", server_side_encryption: :AES256).and_return(result)
31
+
32
+ expect(described_class.run(bucket, file)).to be_a(Response)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module DefraRuby
6
+ module Aws
7
+ RSpec.describe PresignedUrlService do
8
+ describe ".run" do
9
+ let(:configs) do
10
+ {
11
+ name: "test",
12
+ credentials: {
13
+ access_key_id: "123",
14
+ secret_access_key: "Secret"
15
+ }
16
+ }
17
+ end
18
+ let(:bucket) { Bucket.new(configs) }
19
+ let(:presigned_url) { described_class.run(bucket, "testfile.csv") }
20
+
21
+ it "returns a presigned url for a given file in the bucket" do
22
+ expect(presigned_url).to include("https://test.s3.eu-west-1.amazonaws.com/testfile.csv")
23
+ expect(presigned_url).to include("response-content-disposition=attachment")
24
+ expect(presigned_url).to include("response-content-type=text%2Fcsv")
25
+ expect(presigned_url).to include("Amz-Expires")
26
+ expect(presigned_url).to include("Amz-Credential")
27
+ expect(presigned_url).to include("Amz-Signature")
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/setup"
4
+
5
+ # Require and run our simplecov initializer as the very first thing we do.
6
+ # This is as per its docs https://github.com/colszowka/simplecov#getting-started
7
+ require "./spec/support/simplecov"
8
+
9
+ # Requires supporting ruby files with custom matchers and macros, etc, in
10
+ # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
11
+ # run as spec files by default. This means that files in spec/support that end
12
+ # in _spec.rb will both be required and run as specs, causing the specs to be
13
+ # run twice. It is recommended that you do not name files matching this glob to
14
+ # end with _spec.rb. You can configure this pattern with the --pattern
15
+ # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
16
+ #
17
+ # We make an exception for simplecov because that will already have been
18
+ # required and run at the very top of spec_helper.rb
19
+ support_files = Dir["./spec/support/**/*.rb"].reject { |file| file == "./spec/support/simplecov.rb" }
20
+ support_files.each { |f| require f }
21
+
22
+ RSpec.configure do |config|
23
+ # rspec-expectations config goes here. You can use an alternate
24
+ # assertion/expectation library such as wrong or the stdlib/minitest
25
+ # assertions if you prefer.
26
+ config.expect_with :rspec do |expectations|
27
+ # This option will default to `true` in RSpec 4. It makes the `description`
28
+ # and `failure_message` of custom matchers include text for helper methods
29
+ # defined using `chain`, e.g.:
30
+ # be_bigger_than(2).and_smaller_than(4).description
31
+ # # => "be bigger than 2 and smaller than 4"
32
+ # ...rather than:
33
+ # # => "be bigger than 2"
34
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
35
+ end
36
+
37
+ # rspec-mocks config goes here. You can use an alternate test double
38
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
39
+ config.mock_with :rspec do |mocks|
40
+ # Prevents you from mocking or stubbing a method that does not exist on
41
+ # a real object. This is generally recommended, and will default to
42
+ # `true` in RSpec 4.
43
+ mocks.verify_partial_doubles = true
44
+ end
45
+
46
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
47
+ # have no way to turn it off -- the option exists only for backwards
48
+ # compatibility in RSpec 3). It causes shared context metadata to be
49
+ # inherited by the metadata hash of host groups and examples, rather than
50
+ # triggering implicit auto-inclusion in groups with matching metadata.
51
+ config.shared_context_metadata_behavior = :apply_to_host_groups
52
+
53
+ # This allows you to limit a spec run to individual examples or groups
54
+ # you care about by tagging them with `:focus` metadata. When nothing
55
+ # is tagged with `:focus`, all examples get run. RSpec also provides
56
+ # aliases for `it`, `describe`, and `context` that include `:focus`
57
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
58
+ config.filter_run_when_matching :focus
59
+
60
+ # Allows RSpec to persist some state between runs in order to support
61
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
62
+ # you configure your source control system to ignore this file.
63
+ config.example_status_persistence_file_path = "spec/examples.txt"
64
+
65
+ # Limits the available syntax to the non-monkey patched syntax that is
66
+ # recommended. For more details, see:
67
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
68
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
69
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
70
+ config.disable_monkey_patching!
71
+
72
+ # Run specs in random order to surface order dependencies. If you find an
73
+ # order dependency and want to debug it, you can fix the order by providing
74
+ # the seed, which is printed after each run.
75
+ # --seed 1234
76
+ config.order = :random
77
+
78
+ # Seed global randomization in this process using the `--seed` CLI option.
79
+ # Setting this allows you to use `--seed` to deterministically reproduce
80
+ # test failures related to randomization by passing the same `--seed` value
81
+ # as the one that triggered the failure.
82
+ Kernel.srand config.seed
83
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Gem that allows us to integrate with AWS S3 (cloud storage)
4
+ require "aws-sdk-s3"
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Load env vars from a text file
4
+ require "dotenv/load"
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Support debugging in the tests. Add `binding.pry` wherever you want execution
4
+ # to stop and the debugger to kick in.
5
+ # Details on the debugging commands can be found here
6
+ # https://github.com/deivid-rodriguez/pry-byebug#commands
7
+ require "pry-byebug"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "simplecov"
4
+
5
+ # We start it with the rails param to ensure it includes coverage for all code
6
+ # started by the rails app, and not just the files touched by our unit tests.
7
+ # This gives us the most accurate assessment of our unit test coverage
8
+ # https://github.com/colszowka/simplecov#getting-started
9
+ SimpleCov.start do
10
+ # The version file is simply just that, so we do not feel the need to ensure
11
+ # we have a test for it
12
+ add_filter "lib/defra_ruby/aws/version"
13
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Library for stubbing and setting expectations on HTTP requests in Ruby
4
+ require "webmock/rspec"
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: defra_ruby_aws
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Defra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-06-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-s3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: defra_ruby_style
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dotenv
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: github_changelog_generator
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Package of AWS features commonly used in Defra Rails based digital services
140
+ email:
141
+ - alan.cruikshanks@environment-agency.gov.uk
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - README.md
147
+ - Rakefile
148
+ - bin/console
149
+ - bin/setup
150
+ - lib/defra_ruby.rb
151
+ - lib/defra_ruby/aws.rb
152
+ - lib/defra_ruby/aws/bucket.rb
153
+ - lib/defra_ruby/aws/configuration.rb
154
+ - lib/defra_ruby/aws/response.rb
155
+ - lib/defra_ruby/aws/services/bucket_loader_service.rb
156
+ - lib/defra_ruby/aws/services/concerns/has_aws_bucket_configuration.rb
157
+ - lib/defra_ruby/aws/services/presigned_url_service.rb
158
+ - lib/defra_ruby/aws/version.rb
159
+ - spec/defra_ruby_aws_spec.rb
160
+ - spec/examples.txt
161
+ - spec/features/upload_file_to_bucket_spec.rb
162
+ - spec/lib/defra_ruby/aws/bucket_spec.rb
163
+ - spec/lib/defra_ruby/aws/configuration_spec.rb
164
+ - spec/lib/defra_ruby/aws/response_spec.rb
165
+ - spec/lib/defra_ruby/aws/services/bucket_loader_service_spec.rb
166
+ - spec/lib/defra_ruby/aws/services/presigned_url_service_spec.rb
167
+ - spec/spec_helper.rb
168
+ - spec/support/aws_sdk_s3.rb
169
+ - spec/support/dotenv.rb
170
+ - spec/support/pry.rb
171
+ - spec/support/simplecov.rb
172
+ - spec/support/webmock.rb
173
+ homepage: https://github.com/DEFRA/defra-ruby-aws
174
+ licenses:
175
+ - The Open Government Licence (OGL) Version 3
176
+ metadata:
177
+ allowed_push_host: https://rubygems.org
178
+ post_install_message:
179
+ rdoc_options: []
180
+ require_paths:
181
+ - lib
182
+ required_ruby_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ requirements: []
193
+ rubyforge_project:
194
+ rubygems_version: 2.6.13
195
+ signing_key:
196
+ specification_version: 4
197
+ summary: Defra ruby on rails AWS helpers
198
+ test_files:
199
+ - spec/defra_ruby_aws_spec.rb
200
+ - spec/spec_helper.rb
201
+ - spec/examples.txt
202
+ - spec/features/upload_file_to_bucket_spec.rb
203
+ - spec/support/aws_sdk_s3.rb
204
+ - spec/support/simplecov.rb
205
+ - spec/support/webmock.rb
206
+ - spec/support/pry.rb
207
+ - spec/support/dotenv.rb
208
+ - spec/lib/defra_ruby/aws/configuration_spec.rb
209
+ - spec/lib/defra_ruby/aws/response_spec.rb
210
+ - spec/lib/defra_ruby/aws/bucket_spec.rb
211
+ - spec/lib/defra_ruby/aws/services/bucket_loader_service_spec.rb
212
+ - spec/lib/defra_ruby/aws/services/presigned_url_service_spec.rb