diff --git a/Gemfile b/Gemfile index 53812ac36..e5475f7e3 100644 --- a/Gemfile +++ b/Gemfile @@ -125,6 +125,7 @@ group :test do gem 'shoulda' gem 'shoulda-matchers' gem 'mock_redis', '~> 0.11' + gem 'webmock' gem 'rake' gem 'test_after_commit' gem 'timecop' diff --git a/Gemfile.lock b/Gemfile.lock index bbcc0f646..f7fb70257 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,6 +76,7 @@ GEM multi_json (~> 1.3) thread_safe (~> 0.1) tzinfo (~> 0.3.37) + addressable (2.3.6) airbrake (3.1.16) builder multi_json @@ -137,6 +138,8 @@ GEM sass (= 3.2.14) compass-rails (1.1.6) compass (>= 0.12.2) + crack (0.4.2) + safe_yaml (~> 1.0.0) creole (0.5.0) daemons (1.1.9) debug_inspector (0.0.2) @@ -418,6 +421,7 @@ GEM i18n (>= 0.5.0) rvm-capistrano (1.5.1) capistrano (~> 2.15.4) + safe_yaml (1.0.3) sanitize (2.0.6) nokogiri (>= 1.4.4) sass (3.2.14) @@ -493,6 +497,9 @@ GEM rack (>= 1.0.0) warden (1.2.3) rack (>= 1.0) + webmock (1.18.0) + addressable (>= 2.3.6) + crack (>= 0.3.2) whenever (0.9.2) activesupport (>= 2.3.4) chronic (>= 0.6.3) @@ -598,6 +605,7 @@ DEPENDENCIES timecop uglifier (~> 2.4) underscore-rails + webmock whenever (~> 0.9.0) wikicloth will_paginate (~> 3.0.5) diff --git a/app/services/file_store_service.rb b/app/services/file_store_service.rb index ba812a486..f25411d51 100644 --- a/app/services/file_store_service.rb +++ b/app/services/file_store_service.rb @@ -3,14 +3,14 @@ module FileStoreService URL = APP_CONFIG['file_store_url'] - attr_accessor :sha1, :file + attr_accessor :sha1, :data # @param [String] sha1 # @param [Hash] data: # - [String] path - path to file # - [String] fullname - file name def initialize(sha1: nil, data: {}) - @sha1, @file = sha1, file + @sha1, @data = sha1, data end def exist? @@ -25,11 +25,11 @@ module FileStoreService end def save - sha1 = Digest::SHA1.hexdigest(File.read(data[:path])) + sha1 = Digest::SHA1.hexdigest(::File.read(data[:path])) return sha1 if exist? resource = RestClient::Resource.new("#{URL}/api/v1/upload", user: token) - file = File.new(data[:path]) + file = ::File.new(data[:path]) # Hook for RestClient # See: [RestClient::Payload#create_file_field](https://github.com/rest-client/rest-client/blob/master/lib/restclient/payload.rb#L202-L215) file.define_singleton_method(:original_filename) { data[:fullname] } diff --git a/spec/services/file_store_service_spec.rb b/spec/services/file_store_service_spec.rb new file mode 100644 index 000000000..d7f781926 --- /dev/null +++ b/spec/services/file_store_service_spec.rb @@ -0,0 +1,82 @@ +require 'spec_helper' + +describe FileStoreService::File do + + let(:sha1) { 'test-sha1' } + + context '#exist?' do + let(:response) { [ { file_name: 'test.log', sha1_hash: sha1 } ].to_json } + let(:url) { "http://file-store.rosalinux.ru/api/v1/file_stores.json?hash=#{sha1}" } + + subject { FileStoreService::File.new(sha1: sha1) } + + it 'returns true if file exists' do + stub_request(:get, url).to_return(body: response) + expect(subject.exist?).to be_true + end + + it 'returns false if file does not exist' do + stub_request(:get, url).to_return(body: '[]') + expect(subject.exist?).to be_false + end + + it 'returns false on error' do + stub_request(:get, url).to_raise(StandardError) + expect(subject.exist?).to be_false + end + end + + context '#save' do + let(:data) { { path: 'test-path', fullname: 'test-fullname' } } + let(:file) { double(:file) } + + before do + allow(Digest::SHA1).to receive(:hexdigest).and_return(sha1) + allow(File).to receive(:read).and_return(file) + end + + subject { FileStoreService::File.new(data: data) } + + it 'returns sha1 if file already exists on FS' do + allow(subject).to receive(:exist?).and_return(true) + expect(subject.save).to eq sha1 + end + + context 'file does not exist on FS' do + let(:url) { "http://test-token:@file-store.rosalinux.ru/api/v1/upload" } + let(:response) { { sha1_hash: sha1 }.to_json } + + before do + allow(subject).to receive(:exist?).and_return(false) + allow(File).to receive(:new).and_return(file) + allow(subject).to receive(:token).and_return('test-token') + end + + it 'returns sha1 if response code - 422' do + stub_request(:post, url).to_raise(RestClient::UnprocessableEntity) + expect(subject.save).to eq sha1 + end + + it 'returns nil on error' do + stub_request(:post, url).to_raise(StandardError) + expect(subject.save).to be_nil + end + + it 'returns sha1 on success' do + stub_request(:post, url).to_return(body: response) + expect(subject.save).to eq sha1 + end + end + end + + context '#destroy' do + let(:url) { "http://file-store.rosalinux.ru/api/v1/file_stores/#{sha1}.json" } + + it 'not raise errors' do + stub_request(:delete, url).to_raise(StandardError) + expect {subject.destroy }.to_not raise_error + end + + end + +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dcae6ef9d..daa2a7cc8 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,6 +2,7 @@ ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' +require 'webmock/rspec' # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories.