foodsoft/spec/controllers/articles_controller_spec.rb
viehlieb 6ce659e78a include foodsoft-article-import
use filetypes for manual uploading bnn, odin, foodsoft file

use opts in .parse

adapt specs to include file format

add specs for odin, bnn, foodsoft files

adapt localize input to remove ',' separator and replace with '.'

remove depr foodsoftfile.rb and spreadsheet.rb

remove todo
2023-02-24 13:05:22 +01:00

348 lines
14 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
describe ArticlesController, type: :controller do
let(:user) { create :user, :role_article_meta }
let(:article_category_a) { create :article_category, name: "AAAA" }
let(:article_category_b) { create :article_category, name: "BBBB" }
let(:article_category_c) { create :article_category, name: "CCCC" }
let(:supplier) { create :supplier}
let(:article_a) { create :article, name: 'AAAA', note: "ZZZZ", unit: '750 g', article_category: article_category_b, availability: false, supplier_id: supplier.id }
let(:article_b) { create :article, name: 'BBBB', note: "XXXX", unit: '500 g', article_category: article_category_a, availability: true, supplier_id: supplier.id }
let(:article_c) { create :article, name: 'CCCC', note: "YYYY", unit: '250 g', article_category: article_category_c, availability: true, supplier_id: supplier.id }
let(:article_no_supplier) { create :article, name: 'no_supplier', note: "no_supplier", unit: '100 g', article_category: article_category_b, availability: true }
let(:order) { create :order }
let(:order2) { create :order }
def get_with_supplier(action, params: {}, xhr: false, format: nil)
params['supplier_id'] = supplier.id
get_with_defaults(action, params: params, xhr: xhr, format: format)
end
def post_with_supplier(action, params: {}, xhr: false, format: nil)
params['supplier_id'] = supplier.id
post_with_defaults(action, params: params, xhr: xhr, format: format)
end
before { login user }
describe 'GET index' do
before do
supplier
article_a
article_b
article_c
supplier.reload
end
it 'assigns sorting on articles' do
sortings = [
['name', [article_a, article_b, article_c]],
['name_reverse', [article_c, article_b, article_a]],
['note', [article_b, article_c, article_a]],
['note_reverse', [article_a, article_c, article_b]],
['unit', [article_c, article_b, article_a]],
['unit_reverse', [article_a, article_b, article_c]],
['article_category', [article_b, article_a, article_c]],
['article_category_reverse', [article_c, article_a, article_b]],
['availability', [article_a, article_b, article_c]],
['availability_reverse', [article_b, article_c, article_a]]
]
sortings.each do |sorting|
get_with_supplier :index, params: { sort: sorting[0] }
expect(response).to have_http_status(:success)
expect(assigns(:articles).to_a).to eq(sorting[1])
end
end
it 'triggers an article csv' do
get_with_supplier :index, format: :csv
expect(response.header['Content-Type']).to include('text/csv')
expect(response.body).to include(article_a.unit, article_b.unit)
end
end
describe 'new' do
it 'renders form for a new article' do
get_with_supplier :new, xhr: true
expect(response).to have_http_status(:success)
end
end
describe 'copy' do
it 'renders form with copy of an article' do
get_with_supplier :copy, params: { article_id: article_a.id }, xhr: true
expect(assigns(:article).attributes).to eq(article_a.dup.attributes)
expect(response).to have_http_status(:success)
end
end
describe '#create' do
it 'creates a new article' do
valid_attributes = article_a.attributes.except('id')
valid_attributes['name'] = 'ABAB'
get_with_supplier :create, params: { article: valid_attributes }, xhr: true
expect(response).to have_http_status(:success)
end
it 'fails to create a new article and renders #new' do
get_with_supplier :create, params: { article: { id: nil } }, xhr: true
expect(response).to have_http_status(:success)
expect(response).to render_template('articles/new')
end
end
describe 'edit' do
it 'opens form to edit article attributes' do
get_with_supplier :edit, params: { id: article_a.id }, xhr: true
expect(response).to have_http_status(:success)
expect(response).to render_template('articles/new')
end
end
describe '#edit all' do
it 'renders edit_all' do
get_with_supplier :edit_all, xhr: true
expect(response).to have_http_status(:success)
expect(response).to render_template('articles/edit_all')
end
end
describe '#update' do
it 'updates article attributes' do
get_with_supplier :update, params: { id: article_a.id, article: { unit: '300 g' } }, xhr: true
expect(assigns(:article).unit).to eq('300 g')
expect(response).to have_http_status(:success)
end
it 'updates article with empty name attribute' do
get_with_supplier :update, params: { id: article_a.id, article: { name: nil } }, xhr: true
expect(response).to render_template('articles/new')
end
end
describe '#update_all' do
it 'updates all articles' do
get_with_supplier :update_all, params: { articles: { "#{article_a.id}": attributes_for(:article), "#{article_b.id}": attributes_for(:article) } }
expect(response).to have_http_status(:redirect)
end
it 'fails on updating all articles' do
get_with_supplier :update_all, params: { articles: { "#{article_a.id}": attributes_for(:article, name: 'ab') } }
expect(response).to have_http_status(:success)
expect(response).to render_template('articles/edit_all')
end
end
describe '#update_selected' do
let(:order_article) { create :order_article, order: order, article: article_no_supplier }
before do
order_article
end
it 'updates selected articles' do
get_with_supplier :update_selected, params: { selected_articles: [article_a.id, article_b.id] }
expect(response).to have_http_status(:redirect)
end
it 'destroys selected articles' do
get_with_supplier :update_selected, params: { selected_articles: [article_a.id, article_b.id], selected_action: 'destroy' }
article_a.reload
article_b.reload
expect(article_a).to be_deleted
expect(article_b).to be_deleted
expect(response).to have_http_status(:redirect)
end
it 'sets availability false on selected articles' do
get_with_supplier :update_selected, params: { selected_articles: [article_a.id, article_b.id], selected_action: 'setNotAvailable' }
article_a.reload
article_b.reload
expect(article_a).not_to be_availability
expect(article_b).not_to be_availability
expect(response).to have_http_status(:redirect)
end
it 'sets availability true on selected articles' do
get_with_supplier :update_selected, params: { selected_articles: [article_a.id, article_b.id], selected_action: 'setAvailable' }
article_a.reload
article_b.reload
expect(article_a).to be_availability
expect(article_b).to be_availability
expect(response).to have_http_status(:redirect)
end
it 'fails deletion if one article is in open order' do
get_with_supplier :update_selected, params: { selected_articles: [article_a.id, article_no_supplier.id], selected_action: 'destroy' }
article_a.reload
article_no_supplier.reload
expect(article_a).not_to be_deleted
expect(article_no_supplier).not_to be_deleted
expect(response).to have_http_status(:redirect)
end
end
describe '#parse_upload' do
let(:file) { Rack::Test::UploadedFile.new(Rails.root.join('spec/fixtures/files/upload_test.csv'), original_filename: 'upload_test.csv') }
it 'updates articles from spreadsheet' do
post_with_supplier :parse_upload, params: { articles: { file: file, outlist_absent: '1', convert_units: '1', type: 'foodsoft' } }
expect(response).to have_http_status(:success)
end
it 'missing file not updates particles from spreadsheet' do
post_with_supplier :parse_upload, params: { articles: { file: nil, outlist_absent: '1', convert_units: '1' } }
expect(response).to have_http_status(:redirect)
expect(flash[:alert]).to match(I18n.t('errors.general_msg', msg: "undefined method `original_filename' for \"\":String").to_s)
end
end
describe '#sync' do
# TODO: double render error in controller
it 'throws double render error' do
expect do
post :sync, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id }
end.to raise_error(AbstractController::DoubleRenderError)
end
xit 'updates particles from spreadsheet' do
post :sync, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, articles: { '#{article_a.id}': attributes_for(:article), '#{article_b.id}': attributes_for(:article) } }
expect(response).to have_http_status(:redirect)
end
end
describe '#destroy' do
let(:order_article) { create :order_article, order: order, article: article_no_supplier }
before do
order_article
end
it 'does not delete article if order open' do
get_with_supplier :destroy, params: { id: article_no_supplier.id }, xhr: true
expect(assigns(:article)).not_to be_deleted
expect(response).to have_http_status(:success)
expect(response).to render_template('articles/destroy')
end
it 'deletes article if order closed' do
get_with_supplier :destroy, params: { id: article_b.id }, xhr: true
expect(assigns(:article)).to be_deleted
expect(response).to have_http_status(:success)
expect(response).to render_template('articles/destroy')
end
end
describe '#update_synchronized' do
let(:order_article) { create :order_article, order: order, article: article_no_supplier }
before do
order_article
article_a
article_b
article_no_supplier
end
it 'deletes articles' do
# TODO: double render error in controller
get_with_supplier :update_synchronized, params: { outlisted_articles: { article_a.id => article_a, article_b.id => article_b } }
article_a.reload
article_b.reload
expect(article_a).to be_deleted
expect(article_b).to be_deleted
expect(response).to have_http_status(:redirect)
end
it 'updates articles' do
get_with_supplier :update_synchronized, params: { articles: { article_a.id => { name: 'NewNameA' }, article_b.id => { name: 'NewNameB' } } }
expect(assigns(:updated_articles).first.name).to eq 'NewNameA'
expect(response).to have_http_status(:redirect)
end
it 'does not update articles if article with same name exists' do
get_with_supplier :update_synchronized, params: { articles: { article_a.id => { unit: '2000 g' }, article_b.id => { name: 'AAAA' } } }
error_array = [assigns(:updated_articles).first.errors.first, assigns(:updated_articles).last.errors.first]
expect(error_array).to include(ActiveModel::Error)
expect(response).to have_http_status(:success)
end
it 'does update articles if article with same name was deleted before' do
get_with_supplier :update_synchronized, params: {
outlisted_articles: { article_a.id => article_a },
articles: {
article_a.id => { name: 'NewName' },
article_b.id => { name: 'AAAA' }
}
}
error_array = [assigns(:updated_articles).first.errors.first, assigns(:updated_articles).last.errors.first]
expect(error_array).not_to be_any
expect(response).to have_http_status(:redirect)
end
it 'does not delete articles in open order' do
get_with_supplier :update_synchronized, params: { outlisted_articles: { article_no_supplier.id => article_no_supplier } }
article_no_supplier.reload
expect(article_no_supplier).not_to be_deleted
expect(response).to have_http_status(:success)
end
it 'assigns updated article_pairs on error' do
get_with_supplier :update_synchronized, params: {
articles: { article_a.id => { name: 'EEEE' } },
outlisted_articles: { article_no_supplier.id => article_no_supplier }
}
expect(assigns(:updated_article_pairs).first).to eq([article_a, { name: 'EEEE' }])
article_no_supplier.reload
expect(article_no_supplier).not_to be_deleted
expect(response).to have_http_status(:success)
end
it 'updates articles in open order' do
get_with_supplier :update_synchronized, params: { articles: { article_no_supplier.id => { name: 'EEEE' } } }
article_no_supplier.reload
expect(article_no_supplier.name).to eq 'EEEE'
expect(response).to have_http_status(:redirect)
end
end
describe '#shared' do
let(:shared_supplier) { create :shared_supplier, shared_articles: [shared_article] }
let(:shared_article) { create :shared_article, name: 'shared' }
let(:article_s) { create :article, name: 'SSSS', note: 'AAAA', unit: '250 g', article_category: article_category_a, availability: false }
let(:supplier_with_shared) { create :supplier, shared_supplier: shared_supplier }
it 'renders view with articles' do
get_with_defaults :shared, params: { supplier_id: supplier_with_shared.id, name_cont_all_joined: 'shared' }, xhr: true
expect(assigns(:supplier).shared_supplier.shared_articles).to be_any
expect(assigns(:articles)).to be_any
expect(response).to have_http_status(:success)
end
end
describe '#import' do
let(:shared_supplier) { create :shared_supplier, shared_articles: [shared_article] }
let(:shared_article) { create :shared_article, name: 'shared' }
before do
shared_article
article_category_a
end
it 'fills form with article details' do
get_with_supplier :import, params: { article_category_id: article_category_b.id, direct: 'true', shared_article_id: shared_article.id }, xhr: true
expect(assigns(:article)).not_to be_nil
expect(response).to have_http_status(:success)
expect(response).to render_template(:create)
end
it 'does redirect to :new if param :direct not set' do
get_with_supplier :import, params: { article_category_id: article_category_b.id, shared_article_id: shared_article.id }, xhr: true
expect(assigns(:article)).not_to be_nil
expect(response).to have_http_status(:success)
expect(response).to render_template(:new)
end
end
end