Last active
March 30, 2019 05:03
-
-
Save ericraio/81f00c17ee274227952128bcb43d59f2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
require "rails_helper" | |
describe ImportService do | |
with_model :FakeModelImport do | |
table do |t| | |
end | |
model do | |
class FakeModelImport::Invalid | |
MISSING_CSV = "MISSING_CSV" | |
INVALID_FAKE_MODELS_THRESHOLD = 2 | |
INVALID_FAKE_MODELS = "INVALID_FAKE_MODELS" | |
end | |
def invalid_fake_models | |
end | |
end | |
end | |
with_model :FakeModel do | |
table do |t| | |
t.string :email | |
t.integer :account_id | |
end | |
model do | |
def custom_fields | |
@custom_fields = {} | |
end | |
end | |
end | |
class FakeService < ImportService | |
def initialize | |
end | |
def record_class | |
FakeModel | |
end | |
end | |
class FakeService2 < ImportService | |
def initialize | |
end | |
end | |
let(:service) { FakeService.new } | |
let(:download_csv) { "header,header,header\nvalue,value,value\nvalue,value,value" } | |
let(:csv) { double("csv") } | |
let(:importer) { double("importer", csv: csv, update_attributes: nil, account_id: 123) } | |
before :each do | |
allow_any_instance_of(FakeModel).to receive(:custom_fields).and_return({}) | |
allow(service).to receive(:importer).and_return(importer) | |
end | |
describe ImportService::Error do | |
it "inherits from StandardError" do | |
expect(ImportService::Error.superclass).to eql StandardError | |
end | |
end | |
describe ".new" do | |
context "when initialized directly" do | |
it "raises an error" do | |
expect do | |
ImportService.new | |
end.to raise_error(ImportService::Error) | |
end | |
end | |
end | |
describe "#importer" do | |
context "when called directly" do | |
it "raises an error" do | |
expect do | |
FakeService2.new.importer | |
end.to raise_error(ImportService::Error) | |
end | |
end | |
end | |
describe "#record_class" do | |
context "when called directly" do | |
it "raises an error" do | |
expect do | |
FakeService2.new.record_class | |
end.to raise_error(ImportService::Error) | |
end | |
end | |
end | |
describe "#process_import" do | |
context "when csv is attached and downloadable is available" do | |
let(:record) { double("record") } | |
before :each do | |
allow(csv).to receive(:attached?).and_return(true) | |
allow(csv).to receive(:download).and_return(download_csv) | |
allow(service).to receive(:build_record_from_row).and_return(record) | |
allow(service).to receive(:save_record_for_import) | |
end | |
context "when the importer sets the first row as headers" do | |
before :each do | |
allow(importer).to receive(:first_row_headers).and_return(true) | |
end | |
it "builds a record from the row" do | |
expect(service).to receive(:build_record_from_row).exactly(2).times | |
service.process_import | |
end | |
it "saves the record for the import" do | |
expect(service).to receive(:save_record_for_import).with(record).exactly(2).times | |
service.process_import | |
end | |
end | |
context "when the importer does not set the first row as headers" do | |
before :each do | |
allow(importer).to receive(:first_row_headers).and_return(false) | |
end | |
it "builds a record from the row" do | |
expect(service).to receive(:build_record_from_row).exactly(3).times | |
service.process_import | |
end | |
it "saves the record for the import" do | |
expect(service).to receive(:save_record_for_import).exactly(3).times | |
service.process_import | |
end | |
end | |
end | |
context "when csv is not attached" do | |
before :each do | |
allow(csv).to receive(:attached?).and_return(false) | |
allow(csv).to receive(:download).and_return(download_csv) | |
end | |
it "updates the attributes" do | |
expect(importer).to receive(:update_attributes).with( | |
status: "invalid", | |
invalid_reason: "MISSING_CSV" | |
) | |
service.process_import | |
end | |
it "does not build or save the records" do | |
expect(service).not_to receive(:build_record_from_row) | |
expect(service).not_to receive(:save_record_for_import) | |
service.process_import | |
end | |
end | |
context "when csv is not downloadable" do | |
before :each do | |
allow(csv).to receive(:attached?).and_return(true) | |
allow(csv).to receive(:download).and_return(false) | |
end | |
it "updates the attributes" do | |
expect(importer).to receive(:update_attributes).with( | |
status: "invalid", | |
invalid_reason: "MISSING_CSV" | |
) | |
service.process_import | |
end | |
it "does not build or save the records" do | |
expect(service).not_to receive(:build_record_from_row) | |
expect(service).not_to receive(:save_record_for_import) | |
service.process_import | |
end | |
end | |
context "when csv is not attached and csv is not downloadable" do | |
before :each do | |
allow(csv).to receive(:attached?).and_return(false) | |
allow(csv).to receive(:download).and_return(false) | |
end | |
it "updates the attributes" do | |
expect(importer).to receive(:update_attributes).with( | |
status: "invalid", | |
invalid_reason: "MISSING_CSV" | |
) | |
service.process_import | |
end | |
it "does not build or save the records" do | |
expect(service).not_to receive(:build_record_from_row) | |
expect(service).not_to receive(:save_record_for_import) | |
service.process_import | |
end | |
end | |
end | |
describe "#build_record_from_row" do | |
let(:row) { ["[email protected]", "", "cycling,pool"] } | |
# | |
# Email is a field defined on the fake model, using email as an example | |
# Interests is a made up field that is meant to test custom fields | |
# | |
it "sets the account id" do | |
allow(importer).to receive(:headers).and_return( | |
"0" => "email", | |
"1" => "", | |
"2" => "interests", | |
"3" => "", | |
) | |
record = service.build_record_from_row(row) | |
expect(record.account_id).to eql importer.account_id | |
end | |
it "sets the email field" do | |
allow(importer).to receive(:headers).and_return( | |
"0" => "email", | |
"1" => "", | |
"2" => "interests", | |
"3" => "", | |
) | |
record = service.build_record_from_row(row) | |
expect(record.email).to eql "[email protected]" | |
end | |
it "sets the interest field as a custom field" do | |
allow(importer).to receive(:headers).and_return( | |
"0" => "email", | |
"1" => "", | |
"2" => "interests", | |
"3" => "", | |
) | |
record = service.build_record_from_row(row) | |
expect(record.custom_fields["interests"]).to eql "cycling,pool" | |
end | |
end | |
describe "#save_record_for_import" do | |
let(:record) { double("record", save: nil) } | |
context "when the record is saved" do | |
before :each do | |
allow(record).to receive(:save).and_return(true) | |
end | |
it "returns true" do | |
expect(service.save_record_for_import(record)).to be_truthy | |
end | |
end | |
context "when the record is not saved" do | |
before :each do | |
allow(record).to receive(:save).and_return(false) | |
allow(service).to receive(:add_record_to_invalidity_list) | |
allow(service).to receive(:update_invalid_status) | |
end | |
it "adds the record to the invalidity list" do | |
expect(service).to receive(:add_record_to_invalidity_list).with(record) | |
service.save_record_for_import(record) | |
end | |
it "updates the invalid status" do | |
expect(service).to receive(:update_invalid_status) | |
service.save_record_for_import(record) | |
end | |
it "returns false" do | |
expect(service.save_record_for_import(record)).to be_falsey | |
end | |
end | |
end | |
describe "#add_record_to_invalidity_list" do | |
it "updates the invalid list" do | |
invalid_list = [] | |
record = double("record", attributes: {}) | |
allow(service).to receive(:invalid_list).and_return(invalid_list) | |
service.add_record_to_invalidity_list(record) | |
expect(invalid_list).to eql [record.attributes] | |
end | |
end | |
describe "#update_invalid_status" do | |
context "when the list is above the threshold" do | |
before :each do | |
allow(service).to receive(:invalid_list).and_return([1, 2, 3, 4]) | |
end | |
it "updates the invalid sttatus and reason" do | |
expect(importer).to receive(:update_attributes).with( | |
status: "invalid", | |
invalid_reason: "INVALID_FAKE_MODELS" | |
) | |
service.update_invalid_status | |
end | |
end | |
context "when the list is not above the threshold" do | |
before :each do | |
allow(service).to receive(:invalid_list).and_return([1]) | |
end | |
it "saves the importer" do | |
expect(importer).to receive(:save) | |
service.update_invalid_status | |
end | |
end | |
end | |
describe "#invalid_list" do | |
it "gets the invalid list" do | |
expect(importer).to receive(:invalid_fake_models) | |
service.invalid_list | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment