Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload Images in Moments #1444

Merged
merged 14 commits into from
Jun 25, 2019
Prev Previous commit
Next Next commit
write specs for backend api end point
bmwachajr committed Jun 21, 2019
commit 91534e423a7bec482ca6d9aef101e15e1081daaf
15 changes: 11 additions & 4 deletions app/controllers/moments_controller.rb
Original file line number Diff line number Diff line change
@@ -4,11 +4,10 @@ class MomentsController < ApplicationController
include MomentsHelper
include MomentsStatsHelper
include MomentsFormHelper
include CloudinaryService
include Shared

before_action :set_moment, only: %i[show edit update destroy]
before_action :load_viewers, only: %i[new edit create update]
before_action :set_moment, only: %i[show edit update destroy picture]
before_action :load_viewers, only: %i[new edit create update picture]

# GET /moments
# GET /moments.json
@@ -75,7 +74,15 @@ def destroy
# POST /moments/1/picture.json
def picture
moment = set_moment(params[:moment_id])
bmwachajr marked this conversation as resolved.
Show resolved Hide resolved
CloudinaryService.()
# Set picture_id
cloudinary_response = CloudinaryService.upload(file, 'options')
moment.picture_id =
if cloudinary_response?
cloudinary_response["public_id"]
else
cloudinary_response
end
moment.save!
end

private
62 changes: 13 additions & 49 deletions app/services/cloudinary_service.rb
Original file line number Diff line number Diff line change
@@ -3,59 +3,23 @@
include ReactOnRailsHelper

class CloudinaryService
# Future task: Optimize Cloudinary image size based on responsive layout
DEFAULT_SIZE = 150

class << self
def upload(file, options = {})
# to do: better exception handling
Cloudinary::Uploader.upload(file, options = {})
# to do: add exception handling
begin
Cloudinary::Uploader.upload(file, options)
rescue => exception
nil
end
end

# def normalize_url(path)
# # prod, uploaded to cloudinary
# if cloudinary_src path
# get_cloudinary_url(path, 'upload')
# # prod, remotely fetched by cloudinary
# elsif path.present? && Rails.env.production?
# get_cloudinary_url(path, 'fetch')
# # dev environment
# else
# path
# end
# end

# private

# def cloudinary_src(path)
# path&.include?('.cloudinary.com')
# end

# def get_cloudinary_image_id(path)
# path.split('/').last.split('.').first
# end

# def get_cloudinary_url(path, type)
# id_or_url = get_cloudinary_image_id(path)
# type == 'fetch' && id_or_url = get_local_url(path)
# cl_image_path(id_or_url, claudinary_params(type))
# end

# def claudinary_params(type)
# { type: type,
# format: 'jpg',
# quality: 'auto:good',
# width: DEFAULT_SIZE,
# height: DEFAULT_SIZE,
# crop: 'fill',
# dpr: 'auto',
# client_hints: true,
# sign_url: true }
# end

# def get_local_url(path)
# "#{Rails.application.config.force_ssl ? 'https' : 'http'}://"\
# "#{Rails.application.config.action_controller.asset_host}#{path}"
# end
def delete(public_id, options = {})
begin
Cloudinary::Uploader.destroy(public_id, options)
rescue => exception
nil
end
end
end
end
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@
end

resources :moments do
post 'picture', to: 'moment#picture', as: 'picture'
post 'picture', to: 'moments#picture', as: 'picture'
end

resources :secret_shares, only: %i[create show destroy]
85 changes: 85 additions & 0 deletions spec/services/cloudinary_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# frozen_string_literal: true
FILENAME = "moment.jpeg"
FILE_PATH = "/public/uploads/tmp/moment"
bmwachajr marked this conversation as resolved.
Show resolved Hide resolved
OPTIONS = {}

describe CloudinaryService do
subject { described_class }

describe '#upload' do
context 'has no options' do
it 'returns json response from cloudinary' do
file = File.new(File.join(::Rails.root.to_s, FILE_PATH, FILENAME))
response = subject.upload(file)
# byebug

expect(response).to have_key("public_id")
expect(response).to have_key("secure_url")
expect(response).to have_key("signature")
expect(response["original_filename"]).to eq("moment")
end
end

context 'has options' do
it 'returns json response from cloudinary' do
file = File.new(File.join(::Rails.root.to_s, FILE_PATH, FILENAME))
response = subject.upload(file, OPTIONS)

expect(response).to have_key("public_id")
expect(response).to have_key("secure_url")
expect(response).to have_key("signature")
expect(response["original_filename"]).to eq("moment")
end
end

context 'it gracefully fails' do
it 'returns nil' do
file = File.new(File.join(::Rails.root.to_s, FILE_PATH, FILENAME))
response = subject.upload(nil, OPTIONS)
expect(response).to be nil
end
end
end

describe '#delete' do
context 'has no options' do
it 'returns success json response from cloudinary' do
# upload image
file = File.new(File.join(::Rails.root.to_s, FILE_PATH, FILENAME))
uploaded_file = subject.upload(file)
expect(uploaded_file).to have_key("public_id")
expect(uploaded_file).to have_key("secure_url")

# delete image
response = subject.delete(uploaded_file["public_id"])
expect(response).to eq({"result"=>"ok"})
end
end

context 'has options' do
it 'returns json response from cloudinary' do
# upload image
file = File.new(File.join(::Rails.root.to_s, FILE_PATH, FILENAME))
uploaded_file = subject.upload(file)
expect(uploaded_file).to have_key("public_id")
expect(uploaded_file).to have_key("secure_url")

response = subject.delete(uploaded_file["public_id"], OPTIONS)
expect(response).to eq({"result"=>"ok"})
end
end

context 'gracefully fails' do
it 'returns not found' do
# upload image
file = File.new(File.join(::Rails.root.to_s, FILE_PATH, FILENAME))
uploaded_file = subject.upload(file)
expect(uploaded_file).to have_key("public_id")
expect(uploaded_file).to have_key("secure_url")

response = subject.delete("untitled", OPTIONS)
expect(response).to eq({"result"=>"not found"})
end
end
end
end