Skip to content

Commit

Permalink
wip: Add controller tests
Browse files Browse the repository at this point in the history
Co-authored-by: viehlieb <pf@pragma-shift.net>
Co-authored-by: Tobias Kneuker <tk@pragma-shift.net>
  • Loading branch information
3 people committed Dec 5, 2022
1 parent 44583c3 commit 433f74d
Show file tree
Hide file tree
Showing 12 changed files with 916 additions and 14 deletions.
12 changes: 12 additions & 0 deletions spec/controllers/application_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

require 'spec_helper'

describe ApplicationController, type: :controller do
describe 'current' do
it 'returns current ApplicationController' do
described_class.new.send(:store_controller)
expect(described_class.current).to be_instance_of described_class
end
end
end
336 changes: 336 additions & 0 deletions spec/controllers/articles_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,336 @@
# 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_a) { create :article, name: 'AAAA', note: 'AAAA', unit: '250 g', article_category: article_category_a, availability: false }
let(:article_b) { create :article, name: 'BBBB', note: 'BBBB', unit: '500 g', article_category: article_category_b, availability: true }
let(:article_c) { create :article, name: 'CCCC', note: 'CCCC', unit: '500 g', article_category: article_category_b, availability: true }

let(:supplier) { create :supplier, articles: [article_a, article_b] }
let(:order) { create :order }

before { login user }

describe 'GET index' do
it 'assigns sorting on articles' do
sortings = [
['name', [article_a, article_b]],
['name_reverse', [article_b, article_a]],
['unit', [article_a, article_b]],
['unit_reverse', [article_b, article_a]],
['article_category', [article_a, article_b]],
['article_category_reverse', [article_b, article_a]],
['note', [article_a, article_b]],
['note_reverse', [article_b, article_a]],
['availability', [article_a, article_b]],
['availability_reverse', [article_b, article_a]]
]
sortings.each do |sorting|
get :index, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, 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 :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(article_a.unit, article_b.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: 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 :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 and 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: 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 :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: 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 :update, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, 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 :update_all, 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

it 'fails on updating all articles' do
get :update_all, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, 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_c }

before do
order_article
end

it 'updates selected articles' do
get :update_selected, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, selected_articles: [article_a.id, article_b.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: [article_a.id, article_b.id], selected_action: 'destroy' }
article_a.reload
article_b.reload
expect(article_a.deleted? && article_b.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: [article_a.id, article_b.id], selected_action: 'setNotAvailable' }
article_a.reload
article_b.reload
expect(article_a.availability || article_b.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: [article_a.id, article_b.id], selected_action: 'setAvailable' }
article_a.reload
article_b.reload
expect(article_a.availability && article_b.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: [article_a.id, article_c.id], selected_action: 'destroy' }
article_a.reload
article_c.reload
expect(article_a.deleted? || article_c.deleted?).to be_falsey
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 particles from spreadsheet' do
post :parse_upload, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, articles: { file: file, outlist_absent: '1', convert_units: '1' } }
expect(response).to have_http_status(:success)
end

it 'missing file not updates particles from spreadsheet' do
post :parse_upload, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, 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) } }
puts "XXX flash #{flash.inspect}"
expect(response).to have_http_status(:redirect)
end
end

describe '#destroy' do
let(:order_article) { create :order_article, order: order, article: article_c }

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: article_c.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 :destroy, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, 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_c }

before do
order_article
article_a
article_b
article_c
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: { article_a.id => article_a, article_b.id => article_b } }
article_a.reload
article_b.reload
expect(article_a.deleted? && article_b.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: { 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 :update_synchronized, params: { foodcoop: FoodsoftConfig[:default_scope], supplier_id: supplier.id, 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([: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: { 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 :update_synchronized, params: {
foodcoop: FoodsoftConfig[:default_scope],
supplier_id: supplier.id,
outlisted_articles: { article_c.id => article_c }
}
article_c.reload
expect(article_c).not_to be_deleted
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: { article_a.id => { name: 'DDDD' } },
outlisted_articles: { article_c.id => article_c }
}
expect(assigns(:updated_article_pairs).first).to eq([article_a, { name: 'DDDD' }])
article_c.reload
expect(article_c).not_to be_deleted
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: { article_c.id => { name: 'DDDD' } }
}
article_c.reload
expect(article_c.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(:article_s) { create :article, name: 'SSSS', note: 'AAAA', unit: '250 g', article_category: article_category_a, availability: false }

let(:supplier_with_shared) { create :supplier, articles: [article_s], shared_supplier: shared_supplier }

it 'renders view with articles' do
get :shared, params: { foodcoop: FoodsoftConfig[:default_scope], 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 :import, params: { foodcoop: FoodsoftConfig[:default_scope], article_category_id: article_category_b.id, direct: 'true', supplier_id: supplier.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(:create)
end

it 'does redirect to :new if param :direct not set' do
get :import, params: { foodcoop: FoodsoftConfig[:default_scope], article_category_id: article_category_b.id, supplier_id: supplier.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

0 comments on commit 433f74d

Please sign in to comment.