Skip to content

Commit

Permalink
Separate out media and row decorators
Browse files Browse the repository at this point in the history
  • Loading branch information
noelledusahel committed Oct 28, 2019
1 parent 649b88e commit e1df6a6
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 19 deletions.
47 changes: 47 additions & 0 deletions app/decorators/file_import/place_row_decorator.rb
@@ -0,0 +1,47 @@
class FileImport::PlaceRowDecorator
METHODS_EXCEPT = [:media, :to_h]
def initialize(row)
@row = row.map { |_, value| value.to_s }
end

def name
at(0)
end

def type_of_place
at(1)
end

def description
at(2)
end

def region
at(3)
end

def long
at(4)
end

def lat
at(5)
end

def media
::PlacePhotoDecorator.new(at(6).strip)
end

def to_h
(public_methods(false) - METHODS_EXCEPT).inject({}) do |accumulator, method_name|
accumulator[method_name] = public_send(method_name)
accumulator
end
end

private

def at(index)
@row[index]
end
end
21 changes: 21 additions & 0 deletions app/decorators/place_photo_decorator.rb
@@ -0,0 +1,21 @@
class PlacePhotoDecorator
def initialize(filename)
@filename = filename
end

def attachable?
File.exist?(path)
end

def blob_data
if attachable?
{io: File.open(path), filename: @filename}
end
end

private

def path
Rails.root.join(::Place::MEDIA_PATH, @filename)
end
end
14 changes: 4 additions & 10 deletions app/models/place.rb
Expand Up @@ -11,16 +11,10 @@ class Place < ApplicationRecord

def self.import_csv(filename)
CSV.parse(filename, headers: true) do |row|
place = Place.find_or_create_by(name: row[0])
place.lat = row[5].to_f
place.long = row[4].to_f
place.type_of_place = row[1]
place.description = row[2]
place.region = row[3]
if row[6] && File.exist?(Rails.root.join('media', row[6]))
file = File.open(Rails.root.join('media',row[6]))
place.photo.attach(io: file, filename: row[6])
end
decorator = FileImport::PlaceRowDecorator.new(row)
place = Place.find_or_create_by(decorator.to_h)
place.photo.attach(decorator.media.blob_data) if decorator.media.attachable?

place.save
end
end
Expand Down
2 changes: 2 additions & 0 deletions spec/fixtures/files/place_without_media.csv
@@ -0,0 +1,2 @@
name,type_of_place,description,region,long,lat,media
Iacitata,Community Center,"Iacitata is a restaurant and cultural space that hosts education around indigenous food and farming.",brazil,-48.502270,-1.454980,amazon.jpg
56 changes: 47 additions & 9 deletions spec/models/place_spec.rb
@@ -1,6 +1,4 @@
require 'rails_helper'
require 'csv'


RSpec.describe Place, type: :model do
describe 'associations' do
Expand All @@ -9,11 +7,11 @@
end

describe 'import_csv' do
it 'is tested against fixture file' do
it 'is tested against fixture file' do
expect(file_fixture('place_with_media.csv').read).not_to be_empty
end

it 'imports csv' do
it 'imports csv with media' do
fixture_data = file_fixture('place_with_media.csv').read
described_class.import_csv(fixture_data)

Expand All @@ -26,24 +24,64 @@
expect(place.region).to eq csv[3]
expect(place.long).to eq csv[4].to_f
expect(place.lat).to eq csv[5].to_f
expect(place.photo.filename.to_s).to eq csv[6]
end

it 'attaches photo' do
it 'does not fail when media is not present' do
fixture_data = file_fixture('place_without_media.csv').read
described_class.import_csv(fixture_data)

place = described_class.first
csv = CSV.parse(fixture_data, headers: true).first
expect(csv[6]).not_to be_nil
end

end

describe '#photo_format' do
it 'should have a prefix' do
context 'when the attachment is not located in an image folder' do
it 'should add an error' do
fixture_data = file_fixture('place_with_media.csv').read
described_class.import_csv(fixture_data)
place = described_class.first
place.photo.blob.content_type = "file/png"
place.photo_format

expect(place.photo.blob.content_type.start_with?('image/')).to be(false)
expect(place.errors.count).to eq(1)
end
end

context 'when the attachment is located in an image folder' do
it 'should not add an error' do
fixture_data = file_fixture('place_with_media.csv').read
described_class.import_csv(fixture_data)
place = described_class.first
place.photo_format

expect(place.photo.blob.content_type.start_with?('image/')).to be(true)
expect(place.errors.count).to eq(0)
end
end
end

describe 'photo_url' do
it 'should return a url path' do
fixture_data = file_fixture('place_with_media.csv').read
described_class.import_csv(fixture_data)
place = described_class.first
file_name = place.photo.filename.to_s

expect(place.photo_url).to be_truthy
expect(place.photo_url.include?(file_name)).to be(true)
end
end

describe 'point_geojson' do
it 'should return a geoJson point' do
fixture_data = file_fixture('place_with_media.csv').read
described_class.import_csv(fixture_data)
place = described_class.first
expect(place.point_geojson.keys).to include('properties')
end
end

pending "add some examples to (or delete) #{__FILE__}"
end

0 comments on commit e1df6a6

Please sign in to comment.