enju_circulation 0.3.8 → 0.3.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/checkins_controller.rb +2 -2
  3. data/app/models/checkin.rb +1 -1
  4. data/app/models/checkout.rb +2 -2
  5. data/app/models/checkout_stat_has_user.rb +1 -1
  6. data/app/models/concerns/enju_circulation/enju_item.rb +2 -0
  7. data/app/models/lending_policy.rb +3 -3
  8. data/app/models/manifestation_checkout_stat_transition.rb +1 -1
  9. data/app/models/manifestation_reserve_stat_transition.rb +1 -1
  10. data/app/models/reserve.rb +4 -4
  11. data/app/models/reserve_state_machine.rb +2 -3
  12. data/app/models/reserve_transition.rb +1 -1
  13. data/app/models/user_checkout_stat_transition.rb +1 -1
  14. data/app/models/user_group_has_checkout_type.rb +6 -6
  15. data/app/models/user_reserve_stat_transition.rb +1 -1
  16. data/lib/enju_circulation/version.rb +1 -1
  17. data/spec/controllers/checkins_controller_spec.rb +130 -8
  18. data/spec/controllers/withdraws_controller_spec.rb +26 -0
  19. data/spec/dummy/db/migrate/20200425072340_create_manifestation_custom_properties.rb +12 -0
  20. data/spec/dummy/db/migrate/20200425072349_create_item_custom_properties.rb +12 -0
  21. data/spec/dummy/db/migrate/20200425074758_create_manifestation_custom_values.rb +12 -0
  22. data/spec/dummy/db/migrate/20200425074822_create_item_custom_values.rb +12 -0
  23. data/spec/dummy/db/schema.rb +43 -10
  24. data/spec/fixtures/checkins.yml +1 -1
  25. data/spec/fixtures/checkout_stat_has_users.yml +1 -1
  26. data/spec/fixtures/checkouts.yml +2 -2
  27. data/spec/fixtures/lending_policies.yml +3 -3
  28. data/spec/fixtures/reserve_transitions.yml +1 -1
  29. data/spec/fixtures/reserves.yml +3 -3
  30. data/spec/fixtures/user_group_has_checkout_types.yml +6 -6
  31. data/spec/models/checkin_spec.rb +1 -1
  32. data/spec/models/checkout_spec.rb +2 -2
  33. data/spec/models/checkout_stat_has_user_spec.rb +1 -1
  34. data/spec/models/lending_policy_spec.rb +3 -3
  35. data/spec/models/reserve_spec.rb +3 -3
  36. data/spec/models/user_group_has_checkout_type_spec.rb +6 -6
  37. metadata +383 -347
  38. data/spec/dummy/db/migrate/20191219122214_create_custom_properties.rb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35ebe6b31ee4582069cb7065b429f5a6a54ce1eac81b5af60aa60d11cd774b08
4
- data.tar.gz: 5efc3f26f9703fd0b3bdcf1304b4efaa25364a8effaaa29bb44de4ca0f6af8fd
3
+ metadata.gz: 8acae0635971690b1966d9ec8c5c3f5c608528c624feb76f201ce0cc90b473e4
4
+ data.tar.gz: 60815d7876aee8efe0aba781e33cc919c2ff5af9830761dc1aff778398522bea
5
5
  SHA512:
6
- metadata.gz: c9156fbb9c9d3869ac1ff16d50c186198a8b7dc1db214b571fbc3df857e8f72f10aa3ad03b693efbf20930649aea90eeac58f93f90cce1b6dcaf85a2a0ed7690
7
- data.tar.gz: 2c4523ae4c13ada69225b8173a160cfece61b879dd2c39ffedc70524666ef442eb44108ea362a2cf2865e4d2ce0ca80a6aec950996f0fc713042b549248f35a6
6
+ metadata.gz: ec55abc5f36563dbba595a2984564c1f8f45911acf3fc24fdcddba3c4f0b0b3d66981081638a4ff7d768122ba510196e49d2546af9b4522b928d39d9aad6b1fe
7
+ data.tar.gz: fc0727906cdea3789852dbee7c97684b600f4ca0b5aa143a8c75caff5c5f0f104a3ec6d284bb92c76a3d99121c974261341924a4d3450e94162c0dcde6fd5b9c
@@ -77,12 +77,12 @@ class CheckinsController < ApplicationController
77
77
  end
78
78
  flash[:message] << message if message
79
79
  format.html { redirect_to checkins_url(basket_id: @checkin.basket_id) }
80
- format.json { render json: @checkin, status: :created, location: @checkin }
80
+ format.json { render json: {result: @checkin, messages: flash[:message]}, status: :created, location: @checkin }
81
81
  format.js { redirect_to checkins_url(basket_id: @basket.id, format: :js) }
82
82
  else
83
83
  @checkins = @basket.checkins.page(1)
84
84
  format.html { render action: "new" }
85
- format.json { render json: @checkin.errors, status: :unprocessable_entity }
85
+ format.json { render json: {messages: @checkin.errors}, status: :unprocessable_entity }
86
86
  format.js { render action: "index" }
87
87
  end
88
88
  end
@@ -91,5 +91,5 @@ end
91
91
  # basket_id :integer
92
92
  # created_at :datetime
93
93
  # updated_at :datetime
94
- # lock_version :integer default(0), not null
94
+ # lock_version :integer default("0"), not null
95
95
  #
@@ -174,8 +174,8 @@ end
174
174
  # librarian_id :integer
175
175
  # basket_id :integer
176
176
  # due_date :datetime
177
- # checkout_renewal_count :integer default(0), not null
178
- # lock_version :integer default(0), not null
177
+ # checkout_renewal_count :integer default("0"), not null
178
+ # lock_version :integer default("0"), not null
179
179
  # created_at :datetime
180
180
  # updated_at :datetime
181
181
  # shelf_id :integer
@@ -17,7 +17,7 @@ end
17
17
  # id :integer not null, primary key
18
18
  # user_checkout_stat_id :integer not null
19
19
  # user_id :integer not null
20
- # checkouts_count :integer default(0), not null
20
+ # checkouts_count :integer default("0"), not null
21
21
  # created_at :datetime
22
22
  # updated_at :datetime
23
23
  #
@@ -105,6 +105,8 @@ module EnjuCirculation
105
105
  manifestation.next_reservation.transition_to!(:completed)
106
106
  manifestation.reload
107
107
  end
108
+
109
+ reload
108
110
  update!(circulation_status: CirculationStatus.find_by(name: 'On Loan'))
109
111
  end
110
112
 
@@ -19,10 +19,10 @@ end
19
19
  # id :integer not null, primary key
20
20
  # item_id :integer not null
21
21
  # user_group_id :integer not null
22
- # loan_period :integer default(0), not null
22
+ # loan_period :integer default("0"), not null
23
23
  # fixed_due_date :datetime
24
- # renewal :integer default(0), not null
25
- # fine :integer default(0), not null
24
+ # renewal :integer default("0"), not null
25
+ # fine :integer default("0"), not null
26
26
  # note :text
27
27
  # position :integer
28
28
  # created_at :datetime
@@ -12,7 +12,7 @@ end
12
12
  #
13
13
  # id :integer not null, primary key
14
14
  # to_state :string
15
- # metadata :text default({})
15
+ # metadata :text default("{}")
16
16
  # sort_key :integer
17
17
  # manifestation_checkout_stat_id :integer
18
18
  # created_at :datetime
@@ -12,7 +12,7 @@ end
12
12
  #
13
13
  # id :integer not null, primary key
14
14
  # to_state :string
15
- # metadata :text default({})
15
+ # metadata :text default("{}")
16
16
  # sort_key :integer
17
17
  # manifestation_reserve_stat_id :integer
18
18
  # created_at :datetime
@@ -2,7 +2,7 @@ class Reserve < ApplicationRecord
2
2
  include Statesman::Adapters::ActiveRecordQueries
3
3
  scope :hold, -> { where('item_id IS NOT NULL') }
4
4
  scope :not_hold, -> { where(item_id: nil) }
5
- scope :waiting, -> {not_in_state(:completed, :expired, :retained).where('canceled_at IS NULL AND (expired_at > ? OR expired_at IS NULL)', Time.zone.now).order('reserves.id DESC')}
5
+ scope :waiting, -> {not_in_state(:completed, :expired).where('canceled_at IS NULL AND (expired_at > ? OR expired_at IS NULL)', Time.zone.now).order('reserves.id DESC')}
6
6
  scope :retained, -> {in_state(:retained).where('retained_at IS NOT NULL')}
7
7
  scope :completed, -> {in_state(:completed).where('checked_out_at IS NOT NULL')}
8
8
  scope :canceled, -> {in_state(:canceled).where('canceled_at IS NOT NULL')}
@@ -404,10 +404,10 @@ end
404
404
  # canceled_at :datetime
405
405
  # expired_at :datetime
406
406
  # deleted_at :datetime
407
- # expiration_notice_to_patron :boolean default(FALSE)
408
- # expiration_notice_to_library :boolean default(FALSE)
407
+ # expiration_notice_to_patron :boolean default("0")
408
+ # expiration_notice_to_library :boolean default("0")
409
409
  # pickup_location_id :integer
410
410
  # retained_at :datetime
411
411
  # postponed_at :datetime
412
- # lock_version :integer default(0), not null
412
+ # lock_version :integer default("0"), not null
413
413
  #
@@ -14,16 +14,15 @@ class ReserveStateMachine
14
14
  transition from: :requested, to: [:retained, :canceled, :expired, :completed]
15
15
 
16
16
  after_transition(to: :requested) do |reserve|
17
- reserve.update(request_status_type: RequestStatusType.where(name: 'In Process').first, item_id: nil, retained_at: nil)
17
+ reserve.update(request_status_type: RequestStatusType.find_by(name: 'In Process'), item_id: nil, retained_at: nil)
18
18
  end
19
19
 
20
20
  after_transition(to: :retained) do |reserve|
21
21
  # TODO: 「取り置き中」の状態を正しく表す
22
- reserve.update(request_status_type: RequestStatusType.where(name: 'In Process').first, retained_at: Time.zone.now)
22
+ reserve.update(request_status_type: RequestStatusType.find_by(name: 'In Process'), retained_at: Time.zone.now)
23
23
  Reserve.transaction do
24
24
  if reserve.item
25
25
  other_reserves = reserve.item.reserves.waiting
26
- other_reserves += reserve.item.reserves.in_state(:retained)
27
26
  other_reserves.each{|r|
28
27
  if r != reserve
29
28
  r.transition_to!(:postponed)
@@ -12,7 +12,7 @@ end
12
12
  #
13
13
  # id :integer not null, primary key
14
14
  # to_state :string
15
- # metadata :text default({})
15
+ # metadata :text default("{}")
16
16
  # sort_key :integer
17
17
  # reserve_id :integer
18
18
  # created_at :datetime
@@ -12,7 +12,7 @@ end
12
12
  #
13
13
  # id :integer not null, primary key
14
14
  # to_state :string
15
- # metadata :text default({})
15
+ # metadata :text default("{}")
16
16
  # sort_key :integer
17
17
  # user_checkout_stat_id :integer
18
18
  # created_at :datetime
@@ -71,12 +71,12 @@ end
71
71
  # id :integer not null, primary key
72
72
  # user_group_id :integer not null
73
73
  # checkout_type_id :integer not null
74
- # checkout_limit :integer default(0), not null
75
- # checkout_period :integer default(0), not null
76
- # checkout_renewal_limit :integer default(0), not null
77
- # reservation_limit :integer default(0), not null
78
- # reservation_expired_period :integer default(7), not null
79
- # set_due_date_before_closing_day :boolean default(FALSE), not null
74
+ # checkout_limit :integer default("0"), not null
75
+ # checkout_period :integer default("0"), not null
76
+ # checkout_renewal_limit :integer default("0"), not null
77
+ # reservation_limit :integer default("0"), not null
78
+ # reservation_expired_period :integer default("7"), not null
79
+ # set_due_date_before_closing_day :boolean default("0"), not null
80
80
  # fixed_due_date :datetime
81
81
  # note :text
82
82
  # position :integer
@@ -12,7 +12,7 @@ end
12
12
  #
13
13
  # id :integer not null, primary key
14
14
  # to_state :string
15
- # metadata :text default({})
15
+ # metadata :text default("{}")
16
16
  # sort_key :integer
17
17
  # user_reserve_stat_id :integer
18
18
  # created_at :datetime
@@ -1,3 +1,3 @@
1
1
  module EnjuCirculation
2
- VERSION = "0.3.8".freeze
2
+ VERSION = "0.3.9".freeze
3
3
  end
@@ -201,14 +201,14 @@ describe CheckinsController do
201
201
  it 'redirects to the created checkin' do
202
202
  post :create, params: { checkin: @attrs, basket_id: 9 }
203
203
  response.should redirect_to(checkins_url(basket_id: assigns(:checkin).basket_id))
204
- assigns(:checkin).item.circulation_status.name.should eq 'Available On Shelf'
204
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
205
205
  end
206
206
 
207
207
  it 'should checkin the overdue item' do
208
208
  post :create, params: { checkin: { item_identifier: '00014' }, basket_id: 9 }
209
209
  response.should redirect_to(checkins_url(basket_id: assigns(:checkin).basket_id))
210
210
  assigns(:checkin).checkout.should be_valid
211
- assigns(:checkin).item.circulation_status.name.should eq 'Available On Shelf'
211
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
212
212
  end
213
213
  end
214
214
  end
@@ -249,14 +249,14 @@ describe CheckinsController do
249
249
  it 'should show notification when it is reserved' do
250
250
  post :create, params: { checkin: { item_identifier: '00008' }, basket_id: 9 }
251
251
  flash[:message].to_s.index(I18n.t('item.this_item_is_reserved')).should be_truthy
252
- assigns(:checkin).item.should be_retained
253
- assigns(:checkin).item.circulation_status.name.should eq 'Available On Shelf'
252
+ assigns(:checkin).checkout.item.should be_retained
253
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
254
254
  response.should redirect_to(checkins_url(basket_id: assigns(:basket).id))
255
255
  end
256
256
 
257
257
  it 'should show notification when an item includes supplements' do
258
258
  post :create, params: { checkin: { item_identifier: '00004' }, basket_id: 9 }
259
- assigns(:checkin).item.circulation_status.name.should eq 'Available On Shelf'
259
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
260
260
  flash[:message].to_s.index(I18n.t('item.this_item_include_supplement')).should be_truthy
261
261
  response.should redirect_to(checkins_url(basket_id: assigns(:basket).id))
262
262
  end
@@ -306,6 +306,128 @@ describe CheckinsController do
306
306
  end
307
307
  end
308
308
 
309
+ describe 'POST create (json format)' do
310
+ before(:each) do
311
+ @attrs = { item_identifier: '00003' }
312
+ @invalid_attrs = { item_identifier: 'invalid' }
313
+ request.env["HTTP_ACCEPT"] = 'application/json'
314
+ end
315
+
316
+ describe 'When logged in as Administrator' do
317
+ login_fixture_admin
318
+
319
+ describe 'with valid params' do
320
+ it 'assigns a newly created checkin as @checkin' do
321
+ post :create, params: { checkin: @attrs }
322
+ assigns(:checkin).should be_nil
323
+ end
324
+
325
+ it 'should not create checkin without basket_id' do
326
+ post :create, params: { checkin: @attrs }
327
+ json = JSON.parse(response.body)
328
+ expect(json['error']).to eq('forbidden')
329
+ end
330
+
331
+ describe 'When basket_id is specified' do
332
+ it 'redirects to the created checkin' do
333
+ post :create, params: { checkin: @attrs, basket_id: 9 }
334
+ expect(response).to have_http_status(:created)
335
+ json = JSON.parse(response.body)
336
+ expect(json['result']['basket_id']).to eq(9)
337
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
338
+ end
339
+
340
+ it 'should checkin the overdue item' do
341
+ post :create, params: { checkin: { item_identifier: '00014' }, basket_id: 9 }
342
+ expect(response).to have_http_status(:created)
343
+ assigns(:checkin).checkout.should be_valid
344
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
345
+ end
346
+ end
347
+ end
348
+
349
+ describe 'with invalid params' do
350
+ it 'assigns a newly created but unsaved checkin as @checkin' do
351
+ post :create, params: { checkin: @invalid_attrs }
352
+ assigns(:checkin).should be_nil
353
+ end
354
+
355
+ it 'should be forbidden' do
356
+ post :create, params: { checkin: @invalid_attrs }
357
+ json = JSON.parse(response.body)
358
+ expect(json['error']).to eq('forbidden')
359
+ end
360
+ end
361
+
362
+ it 'should not create checkin without item_id' do
363
+ post :create, params: { checkin: { item_identifier: nil }, basket_id: 9 }
364
+ assigns(:checkin).should_not be_valid
365
+ expect(response).to have_http_status(:unprocessable_entity)
366
+ json = JSON.parse(response.body)
367
+ expect(json['messages']['base']).to match_array([I18n.t('checkin.item_not_found')])
368
+ expect(json['messages']['item_id']).to match_array([I18n.t('errors.messages.blank')])
369
+ end
370
+ end
371
+
372
+ describe 'When logged in as Librarian' do
373
+ login_fixture_librarian
374
+
375
+ describe 'with valid params' do
376
+ it 'assigns a newly created checkin as @checkin' do
377
+ post :create, params: { checkin: @attrs }
378
+ assigns(:checkin).should be_nil
379
+ end
380
+
381
+ it 'should not create checkin without basket_id' do
382
+ post :create, params: { checkin: @attrs }
383
+ json = JSON.parse(response.body)
384
+ expect(json['error']).to eq('forbidden')
385
+ end
386
+
387
+ it 'should show notification when it is reserved' do
388
+ post :create, params: { checkin: { item_identifier: '00008' }, basket_id: 9 }
389
+ flash[:message].to_s.index(I18n.t('item.this_item_is_reserved')).should be_truthy
390
+ assigns(:checkin).checkout.item.should be_retained
391
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
392
+ expect(response).to have_http_status(:created)
393
+ end
394
+
395
+ it 'should show notification when an item includes supplements' do
396
+ post :create, params: { checkin: { item_identifier: '00004' }, basket_id: 9 }
397
+ assigns(:checkin).checkout.item.circulation_status.name.should eq 'Available On Shelf'
398
+ flash[:message].to_s.index(I18n.t('item.this_item_include_supplement')).should be_truthy
399
+ expect(response).to have_http_status(:created)
400
+ end
401
+ end
402
+
403
+ it "should show notice when other library's item is checked in" do
404
+ sign_in users(:librarian2)
405
+ post :create, params: { checkin: { item_identifier: '00009' }, basket_id: 9 }
406
+ assigns(:checkin).should be_valid
407
+ flash[:message].to_s.index(I18n.t('checkin.other_library_item')).should be_truthy
408
+ expect(response).to have_http_status(:created)
409
+ end
410
+ end
411
+
412
+ describe 'When not logged in' do
413
+ before(:each) do
414
+ @attrs = { item_identifier: '00003' }
415
+ @invalid_attrs = { item_identifier: 'invalid' }
416
+ end
417
+
418
+ describe 'with valid params' do
419
+ it 'assigns a newly created checkin as @checkin' do
420
+ post :create, params: { checkin: @attrs }
421
+ end
422
+
423
+ it 'should redirect to new session url' do
424
+ post :create, params: { checkin: @attrs }
425
+ expect(response).to have_http_status(:ok)
426
+ end
427
+ end
428
+ end
429
+ end
430
+
309
431
  describe 'PUT update' do
310
432
  before(:each) do
311
433
  @checkin = checkins(:checkin_00001)
@@ -335,7 +457,7 @@ describe CheckinsController do
335
457
 
336
458
  it "re-renders the 'edit' template" do
337
459
  put :update, params: { id: @checkin.id, checkin: @invalid_attrs }
338
- response.should render_template('edit')
460
+ expect(response).to be_successful
339
461
  end
340
462
 
341
463
  it 'should not update checkin without item_identifier' do
@@ -364,12 +486,12 @@ describe CheckinsController do
364
486
  describe 'with invalid params' do
365
487
  it 'assigns the checkin as @checkin' do
366
488
  put :update, params: { id: @checkin.id, checkin: @invalid_attrs }
367
- assigns(:checkin).should_not be_valid
489
+ expect(assigns(:checkin)).not_to be_valid
368
490
  end
369
491
 
370
492
  it "re-renders the 'edit' template" do
371
493
  put :update, params: { id: @checkin.id, checkin: @invalid_attrs }
372
- response.should render_template('edit')
494
+ expect(response).to be_successful
373
495
  end
374
496
  end
375
497
  end
@@ -0,0 +1,26 @@
1
+ require 'rails_helper'
2
+
3
+ describe WithdrawsController do
4
+ fixtures :all
5
+ let(:valid_attributes) do
6
+ FactoryBot.build(:withdraw).attributes.with_indifferent_access
7
+ end
8
+ let(:valid_create_attributes) do
9
+ { basket_id: Basket.find(valid_attributes[:basket_id]).id,
10
+ withdraw: { item_identifier: Item.find(valid_attributes[:item_id]).item_identifier }}
11
+ end
12
+
13
+ describe 'POST create' do
14
+ describe 'When logged in as Administrator' do
15
+ login_fixture_admin
16
+
17
+ it 'should not withdraw a checked-out item' do
18
+ expect do
19
+ post :create, params: { basket_id: valid_create_attributes[:basket_id], withdraw: { item_identifier: reserves(:reserve_00014).item.item_identifier } }
20
+ end.to change(Withdraw, :count).by(0)
21
+ expect(assigns(:withdraw)).to be_a(Withdraw)
22
+ expect(response).to be_successful
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ class CreateManifestationCustomProperties < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :manifestation_custom_properties do |t|
4
+ t.string :name, null: false, comment: 'ラベル名', index: {unique: true}
5
+ t.text :display_name, null: false, comment: '表示名'
6
+ t.text :note, comment: '備考'
7
+ t.integer :position, default: 1, null: false
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class CreateItemCustomProperties < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :item_custom_properties do |t|
4
+ t.string :name, null: false, comment: 'ラベル名', index: {unique: true}
5
+ t.text :display_name, null: false, comment: '表示名'
6
+ t.text :note, comment: '備考'
7
+ t.integer :position, default: 1, null: false
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end