Skip to content

Instantly share code, notes, and snippets.

@anoopprasad
Forked from rokumatsumoto/0_Gemfile
Created June 21, 2024 06:41
Show Gist options
  • Save anoopprasad/b4aa4e37dd4ba35df6b470f70c657bc5 to your computer and use it in GitHub Desktop.
Save anoopprasad/b4aa4e37dd4ba35df6b470f70c657bc5 to your computer and use it in GitHub Desktop.

Revisions

  1. @rokumatsumoto rokumatsumoto revised this gist May 9, 2020. 8 changed files with 0 additions and 0 deletions.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
  2. @rokumatsumoto rokumatsumoto created this gist May 9, 2020.
    2 changes: 2 additions & 0 deletions Gemfile
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    # Gemfile
    gem 'aws-sdk-s3'
    15 changes: 15 additions & 0 deletions aws.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    # config/initializers/aws.rb

    credentials = Aws::Credentials.new(
    Boyutluseyler.config[:direct_upload_access_key_id],
    Boyutluseyler.config[:direct_upload_secret_access_key]
    )

    # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Resource.html
    DIRECT_UPLOAD_RESOURCE = Aws::S3::Resource.new(
    stub_responses: Rails.env.test?,
    region: Boyutluseyler.config[:direct_upload_region],
    credentials: credentials
    )

    DIRECT_UPLOAD_BUCKET = DIRECT_UPLOAD_RESOURCE.bucket(Boyutluseyler.config[:direct_upload_bucket_name])
    25 changes: 25 additions & 0 deletions bucket.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,25 @@
    # lib/object_storage/direct_upload/bucket.rb

    # frozen_string_literal: true

    # Wrapper class for AWS::S3::Bucket

    require_relative 'presigned_post'

    module ObjectStorage
    module DirectUpload
    class Bucket
    class << self
    delegate :object, to: :bucket

    def bucket
    @bucket ||= DIRECT_UPLOAD_BUCKET
    end

    def presigned_post(policy)
    PresignedPost.new(bucket, policy).create
    end
    end
    end
    end
    end
    31 changes: 31 additions & 0 deletions build_service.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,31 @@
    # app/services/blueprints/build_service.rb

    # frozen_string_literal: true

    module Blueprints
    class BuildService < Blueprints::BaseService
    prepend ValidatesRemoteObject

    def execute
    validate!

    Blueprint.new.tap do |b|
    b.url = remote_object.public_url
    b.url_path = remote_object.key
    b.size = remote_object.size
    b.content_type = remote_object.content_type
    b.thumb_url = ''
    end
    end

    private

    def validate!
    raise ValidationError, 'File not found' unless remote_object_exists?
    end

    def bucket
    ObjectStorage::DirectUpload::Bucket
    end
    end
    end
    48 changes: 48 additions & 0 deletions build_service_spec.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,48 @@
    # spec/services/blueprints/build_service_spec.rb

    # frozen_string_literal: true

    require 'spec_helper'

    RSpec.describe Blueprints::BuildService do
    describe 'modules' do
    it { is_expected.to include_module(ValidatesRemoteObject) }
    end

    describe '#execute' do
    subject(:service) { described_class.new(user, params) }

    let(:user) { build_stubbed(:user) }
    let(:params) { { key: 'model.stl' } }
    let(:validation_error) { described_class::ValidationError }

    context 'when the remote object is not exist' do
    before do
    stub_direct_upload_bucket_object_is_not_exist
    end

    after do
    stub_direct_upload_bucket_object_exists # default stub behavior
    end

    it 'raises a file not found error' do
    expect { service.execute }.to raise_error(validation_error, 'File not found')
    end
    end

    context 'when the remote object exists' do
    it 'builds a blueprint without saving it' do
    direct_upload_bucket = class_double(ObjectStorage::DirectUpload::Bucket).as_stubbed_const
    # stubbing Aws::S3::Object
    remote_object = double(key: 'model.stl', size: 1, content_type: 'model/stl',
    public_url: 'http://foo.com/model.stl', exists?: true)
    allow(direct_upload_bucket).to receive(:object).and_return(remote_object)

    result = service.execute

    expect(result).to be_valid
    expect(result).not_to be_persisted
    end
    end
    end
    end
    5 changes: 5 additions & 0 deletions spec_helper.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    # spec/spec_helper.rb

    RSpec.configure do |config|
    config.include StubAWSResponses
    end
    27 changes: 27 additions & 0 deletions stub_aws_responses.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    # spec/support/helpers/stub_aws_responses.rb

    # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Resource.html
    # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html

    # Stubbing the AWS SDK
    # https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/stubbing.html
    # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ClientStubs.html
    # https://aws.amazon.com/blogs/developer/advanced-client-stubbing-in-the-aws-sdk-for-ruby-version-3/
    # https://stelligent.com/2016/04/14/using-stubs-for-the-aws-sdk-for-ruby-2/
    # https://semaphoreci.com/community/tutorials/stubbing-the-aws-sdk

    module StubAWSResponses
    def stub_direct_upload_bucket_object_is_not_exist
    DIRECT_UPLOAD_RESOURCE.client.stub_responses(:head_object,
    status_code: 404,
    headers: {},
    body: '')
    end

    def stub_direct_upload_bucket_object_exists
    DIRECT_UPLOAD_RESOURCE.client.stub_responses(:head_object,
    status_code: 200,
    headers: {},
    body: '')
    end
    end
    21 changes: 21 additions & 0 deletions validates_remote_object.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,21 @@
    # app/services/concerns/validates_remote_object.rb

    # frozen_string_literal: true

    module ValidatesRemoteObject
    # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#exists%3F-instance_method
    delegate :exists?, to: :remote_object, prefix: true

    def remote_object
    @remote_object ||= bucket.object(key)
    end

    def bucket
    super || (raise NotImplementedError,
    '"bucket" must be implemented and return an Aws::S3::Bucket')
    end

    def key
    params[:key] || (raise ArgumentError, 'Key needs to be specified')
    end
    end