article_controllers almostspec'd
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
085e854361
commit
030cc195ba
5 changed files with 283 additions and 6 deletions
|
@ -7,6 +7,7 @@
|
||||||
default: &defaults
|
default: &defaults
|
||||||
multi_coop_install: false
|
multi_coop_install: false
|
||||||
default_scope: 'f'
|
default_scope: 'f'
|
||||||
|
tax_default: 0
|
||||||
|
|
||||||
name: FC Minimal
|
name: FC Minimal
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,19 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe ArticlesController, type: :controller do
|
describe ArticlesController, type: :controller do
|
||||||
let(:user) { create :user, :role_article_meta }
|
let(:user) { create :user, :role_article_meta }
|
||||||
|
let(:article_categoryA) { create :article_category, name: "AAAA" }
|
||||||
|
let(:article_categoryB) { create :article_category, name: "BBBB" }
|
||||||
|
let(:articleA) { create :article, name: 'AAAA', note: "AAAA", unit: '250 g', article_category: article_categoryA, availability: false }
|
||||||
|
let(:articleB) { create :article, name: 'BBBB', note: "BBBB", unit: '500 g', article_category: article_categoryB, availability: true }
|
||||||
|
let(:articleC) { create :article, name: 'CCCC', note: "CCCC", unit: '500 g', article_category: article_categoryB, availability: true }
|
||||||
|
|
||||||
|
let(:supplier) { create :supplier, articles: [articleA, articleB] }
|
||||||
|
let(:order) { create :order }
|
||||||
|
let(:order_article) { create :order_article, order: order, article: articleC }
|
||||||
|
|
||||||
before { login user }
|
before { login user }
|
||||||
|
|
||||||
describe 'GET index' do
|
describe 'GET index' do
|
||||||
let(:article_categoryA) { create :article_category, name: "AAAA" }
|
|
||||||
let(:article_categoryB) { create :article_category, name: "BBBB" }
|
|
||||||
let(:articleA) { create :article, name: 'AAAA', note: "AAAA", unit: '250 g', article_category: article_categoryA, availability: false }
|
|
||||||
let(:articleB) { create :article, name: 'BBBB', note: "BBBB", unit: '500 g', article_category: article_categoryB, availability: true }
|
|
||||||
let(:supplier) { create :supplier, articles: [articleA, articleB] }
|
|
||||||
|
|
||||||
it 'assigns sorting on articles' do
|
it 'assigns sorting on articles' do
|
||||||
sortings = [
|
sortings = [
|
||||||
['name', [articleA, articleB]],
|
['name', [articleA, articleB]],
|
||||||
|
@ -33,5 +36,264 @@ describe ArticlesController, type: :controller do
|
||||||
expect(assigns(:articles).to_a).to eq(sorting[1])
|
expect(assigns(:articles).to_a).to eq(sorting[1])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'triggers an article csv' do
|
||||||
|
get :index, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id }, format: :csv
|
||||||
|
expect(response.header["Content-Type"]).to include("text/csv")
|
||||||
|
expect(response.body).to include(articleA.unit, articleB.unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "new" do
|
||||||
|
it 'renders form for a new article' do
|
||||||
|
get :new, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id }, xhr: true
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "copy" do
|
||||||
|
it 'renders form with copy of an article' do
|
||||||
|
get :copy, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, article_id: articleA.id }, xhr: true
|
||||||
|
expect(assigns(:article).attributes).to eq(articleA.dup.attributes)
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# TODO:
|
||||||
|
|
||||||
|
describe "#create" do
|
||||||
|
it 'creates a new article' do
|
||||||
|
valid_attributes = articleA.attributes.except("id")
|
||||||
|
valid_attributes["name"] = "ABAB"
|
||||||
|
get :create, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, article: valid_attributes }, xhr: true
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails to create a new article an renders #new' do
|
||||||
|
get :create, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, 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 :edit, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, id: articleA.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 :edit_all, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id }, 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 :update, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, id: articleA.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 attributes' do
|
||||||
|
get :update, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, id: articleA.id, article: { name: nil } }, xhr: true
|
||||||
|
expect(response).to render_template('articles/new')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update_all" do
|
||||||
|
xit 'updates all articles' do
|
||||||
|
# never used and controller method bugged
|
||||||
|
get :update_all, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, articles: [articleA, articleB] }
|
||||||
|
puts assigns(:articles).count
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update_selected" do
|
||||||
|
before do
|
||||||
|
order_article
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates selected articles' do
|
||||||
|
get :update_selected, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, selected_articles: [articleA.id, articleB.id] }
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'destroys selected articles' do
|
||||||
|
get :update_selected, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, selected_articles: [articleA.id, articleB.id], selected_action: "destroy" }
|
||||||
|
articleA.reload
|
||||||
|
articleB.reload
|
||||||
|
expect(articleA.deleted? && articleB.deleted?).to be_truthy
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets availability false on selected articles' do
|
||||||
|
get :update_selected, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, selected_articles: [articleA.id, articleB.id], selected_action: "setNotAvailable" }
|
||||||
|
articleA.reload
|
||||||
|
articleB.reload
|
||||||
|
expect(articleA.availability || articleB.availability).to be_falsey
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets availability true on selected articles' do
|
||||||
|
get :update_selected, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, selected_articles: [articleA.id, articleB.id], selected_action: "setAvailable" }
|
||||||
|
articleA.reload
|
||||||
|
articleB.reload
|
||||||
|
expect(articleA.availability && articleB.availability).to be_truthy
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails deletion if one article is in open order' do
|
||||||
|
get :update_selected, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, selected_articles: [articleA.id, articleC.id], selected_action: "destroy" }
|
||||||
|
articleA.reload
|
||||||
|
articleC.reload
|
||||||
|
expect(articleA.deleted? || articleC.deleted?).to be_falsey
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#parse_upload" do
|
||||||
|
let(:file) { fixture_file_upload(Rails.root.join('spec/fixtures/files/upload_test.csv')) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
file
|
||||||
|
end
|
||||||
|
# TODO: Cannot use Rack attributes in controller??
|
||||||
|
# #<NoMethodError: undefined method `original_filename' for
|
||||||
|
# "#<Rack::Test::UploadedFile:0x00005575cef1d238>":String
|
||||||
|
|
||||||
|
xit 'updates particles from spreadsheet' do
|
||||||
|
get :parse_upload, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, articles: { file: file, outlist_absent: "1", convert_units: "1" } }
|
||||||
|
# {articleA.id => articleA, articleB.id => articleB}}
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#sync" do
|
||||||
|
# TODO: double render error in controller
|
||||||
|
xit 'updates particles from spreadsheet' do
|
||||||
|
get :sync, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id }
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#destroy" do
|
||||||
|
before do
|
||||||
|
order_article
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not delete article if order open' do
|
||||||
|
get :destroy, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, id: articleC.id }, xhr: true
|
||||||
|
expect(assigns(:article).deleted?).to be_falsey
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
expect(response).to render_template('articles/destroy')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'deletes article if order closed' do
|
||||||
|
get :destroy, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, id: articleB.id }, xhr: true
|
||||||
|
expect(assigns(:article).deleted?).to be_truthy
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
expect(response).to render_template('articles/destroy')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update_synchronized" do
|
||||||
|
before do
|
||||||
|
order_article
|
||||||
|
articleA
|
||||||
|
articleB
|
||||||
|
articleC
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'deletes articles' do
|
||||||
|
# TODO: double render error in controller
|
||||||
|
get :update_synchronized, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, outlisted_articles: { articleA.id => articleA, articleB.id => articleB } }
|
||||||
|
articleA.reload
|
||||||
|
articleB.reload
|
||||||
|
expect(articleA.deleted? && articleB.deleted?).to be_truthy
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates articles' do
|
||||||
|
get :update_synchronized, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, articles: { articleA.id => { name: "NewNameA" }, articleB.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 :update_synchronized, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, articles: { articleA.id => { unit: "2000 g" }, articleB.id => { name: "AAAA" } } }
|
||||||
|
error_array = [assigns(:updated_articles).first.errors.first, assigns(:updated_articles).last.errors.first]
|
||||||
|
expect(error_array).to include([:name, "name is already taken"])
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does update articles if article with same name was deleted before' do
|
||||||
|
get :update_synchronized, params: {
|
||||||
|
foodcoop: FoodsoftConfig[:default_scope],
|
||||||
|
supplier_id: supplier.id,
|
||||||
|
outlisted_articles: { articleA.id => articleA },
|
||||||
|
articles: {
|
||||||
|
articleA.id => { name: "NewName" },
|
||||||
|
articleB.id => { name: "AAAA" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error_array = [assigns(:updated_articles).first.errors.first, assigns(:updated_articles).last.errors.first]
|
||||||
|
expect(error_array.any?).to be_falsey
|
||||||
|
expect(response).to have_http_status(:redirect)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not delete articles in open order' do
|
||||||
|
get :update_synchronized, params: {
|
||||||
|
foodcoop: FoodsoftConfig[:default_scope],
|
||||||
|
supplier_id: supplier.id,
|
||||||
|
outlisted_articles: { articleC.id => articleC }
|
||||||
|
}
|
||||||
|
articleC.reload
|
||||||
|
expect(articleC.deleted?).to be_falsey
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'assigns updated article_pairs on error' do
|
||||||
|
get :update_synchronized, params: {
|
||||||
|
foodcoop: FoodsoftConfig[:default_scope],
|
||||||
|
supplier_id: supplier.id,
|
||||||
|
articles: { articleA.id => { name: "DDDD" } },
|
||||||
|
outlisted_articles: { articleC.id => articleC }
|
||||||
|
}
|
||||||
|
expect(assigns(:updated_article_pairs).first).to eq([articleA, { name: "DDDD" }])
|
||||||
|
articleC.reload
|
||||||
|
expect(articleC.deleted?).to be_falsey
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates articles in open order' do
|
||||||
|
get :update_synchronized, params: {
|
||||||
|
foodcoop: FoodsoftConfig[:default_scope],
|
||||||
|
supplier_id: supplier.id,
|
||||||
|
articles: { articleC.id => { name: "DDDD" } }
|
||||||
|
}
|
||||||
|
articleC.reload
|
||||||
|
expect(articleC.name).to eq "DDDD"
|
||||||
|
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(:articleS) { create :article, name: 'SSSS', note: "AAAA", unit: '250 g', article_category: article_categoryA, availability: false }
|
||||||
|
|
||||||
|
let(:supplier_with_shared) { create :supplier, articles: [articleS], shared_supplier: shared_supplier }
|
||||||
|
|
||||||
|
it 'renders view with articles' do
|
||||||
|
get :shared, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier_with_shared.id, q: { name_cont_all: "shared" } }, xhr: true
|
||||||
|
expect(assigns(:supplier).shared_supplier.shared_articles.any?).to be_truthy
|
||||||
|
expect(assigns(:articles).any?).to be_truthy
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
8
spec/factories/order_article.rb
Normal file
8
spec/factories/order_article.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
require 'factory_bot'
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :order_article do
|
||||||
|
order { create :order }
|
||||||
|
article { create :article }
|
||||||
|
end
|
||||||
|
end
|
3
spec/fixtures/files/upload_test.csv
vendored
Normal file
3
spec/fixtures/files/upload_test.csv
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
avail.;Order number;Name;Note;Manufacturer;Origin;Unit;Price (net);VAT;Deposit;Unit quantity;"";"";Category
|
||||||
|
"";;AAAA;AAAA;;;500 g;25.55;6.0;0.0;1;"";"";AAAA
|
||||||
|
"";;BBBB;BBBB;;;250 g;12.11;6.0;0.0;2;"";"";BBBB
|
|
3
spec/fixtures/upload_test.csv
vendored
Normal file
3
spec/fixtures/upload_test.csv
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
avail.;Order number;Name;Note;Manufacturer;Origin;Unit;Price (net);VAT;Deposit;Unit quantity;"";"";Category
|
||||||
|
"";;AAAA;AAAA;;;500 g;25.55;6.0;0.0;1;"";"";AAAA
|
||||||
|
"";;BBBB;BBBB;;;250 g;12.11;6.0;0.0;2;"";"";BBBB
|
|
Loading…
Reference in a new issue