1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-30 19:52:20 +01:00

(bug) create recurrent event

Also: (test) test trainings API
Also: (test) test create recurrent event
This commit is contained in:
Sylvain 2022-11-24 13:02:25 +01:00
parent 5d1c70a26e
commit 2cf18c277c
10 changed files with 188 additions and 26 deletions

View File

@ -3,7 +3,7 @@
- Accounting data is now built each night and saved in database - Accounting data is now built each night and saved in database
- OpenAPI endpoint to fetch accounting data - OpenAPI endpoint to fetch accounting data
- Fix a bug: providing an array of attributes to filter OpenApi data, results in error - Fix a bug: providing an array of attributes to filter OpenApi data, results in error
- [TODO DEPLOY] `rails fablab:maintenance:build_accounting_lines` - [TODO DEPLOY] `rails fablab:setup:build_accounting_lines`
- Add reservation deadline parameter (#414) - Add reservation deadline parameter (#414)
- Fix a bug: unable to run test in negavtive timezones (#425) - Fix a bug: unable to run test in negavtive timezones (#425)

View File

@ -114,7 +114,7 @@ class Event < ApplicationRecord
r = Recurrence.new(every: recurrence, on: on, starts: availability.start_at + 1.day, until: recurrence_end_at) r = Recurrence.new(every: recurrence, on: on, starts: availability.start_at + 1.day, until: recurrence_end_at)
r.events.each do |date| r.events.each do |date|
Event::CreateEventService.create_occurence(event, date) Event::CreateEventService.create_occurence(self, date)
end end
update(recurrence_id: id) update(recurrence_id: id)
end end

View File

@ -2,12 +2,14 @@
# Provides helper methods to create new Events and its recurring occurrences # Provides helper methods to create new Events and its recurring occurrences
class Event::CreateEventService class Event::CreateEventService
extend ApplicationHelper
class << self class << self
def create_occurence(event, date) def create_occurence(event, date)
service = Availabilities::CreateAvailabilitiesService.new service = Availabilities::CreateAvailabilitiesService.new
occurrence = Event.new( occurrence = Event.new(
recurrence: 'none', recurrence: 'none',
title: title, title: event.title,
description: event.description, description: event.description,
event_image: occurrence_image(event), event_image: occurrence_image(event),
event_files: occurrence_files(event), event_files: occurrence_files(event),
@ -21,7 +23,8 @@ class Event::CreateEventService
amount: event.amount, amount: event.amount,
event_price_categories: occurrence_price_categories(event), event_price_categories: occurrence_price_categories(event),
nb_total_places: event.nb_total_places, nb_total_places: event.nb_total_places,
recurrence_id: event.id recurrence_id: event.id,
advanced_accounting: occurrence_advanced_accounting(event)
) )
occurrence.save occurrence.save
service.create_slots(occurrence.availability) service.create_slots(occurrence.availability)
@ -60,5 +63,9 @@ class Event::CreateEventService
EventPriceCategory.new(price_category_id: epc.price_category_id, amount: epc.amount) EventPriceCategory.new(price_category_id: epc.price_category_id, amount: epc.amount)
end end
end end
def occurrence_advanced_accounting(event)
AdvancedAccounting.new(code: event.advanced_accounting.code, analytical_section: event.advanced_accounting.analytical_section)
end
end end
end end

BIN
test/fixtures/files/event/Skateboard.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -8,7 +8,6 @@ class AuthProvidersTest < ActionDispatch::IntegrationTest
login_as(@admin, scope: :user) login_as(@admin, scope: :user)
end end
test 'create an auth external provider and activate it' do test 'create an auth external provider and activate it' do
name = 'GitHub' name = 'GitHub'
post '/api/auth_providers', post '/api/auth_providers',
@ -21,8 +20,8 @@ class AuthProvidersTest < ActionDispatch::IntegrationTest
token_endpoint: 'access_token', token_endpoint: 'access_token',
base_url: 'https://github.com/login/oauth/', base_url: 'https://github.com/login/oauth/',
profile_url: 'https://github.com/settings/profile', profile_url: 'https://github.com/settings/profile',
client_id: ENV.fetch('OAUTH_CLIENT_ID') { 'github-oauth-app-id' }, client_id: ENV.fetch('OAUTH_CLIENT_ID', 'github-oauth-app-id'),
client_secret: ENV.fetch('OAUTH_CLIENT_SECRET') { 'github-oauth-app-secret' } client_secret: ENV.fetch('OAUTH_CLIENT_SECRET', 'github-oauth-app-secret')
}, },
auth_provider_mappings_attributes: [ auth_provider_mappings_attributes: [
{ {
@ -49,12 +48,12 @@ class AuthProvidersTest < ActionDispatch::IntegrationTest
assert_equal Mime[:json], response.content_type assert_equal Mime[:json], response.content_type
# Check the provider was correctly created # Check the provider was correctly created
db_provider = OAuth2Provider.includes(:auth_provider).where('auth_providers.name': name).first.auth_provider db_provider = OAuth2Provider.includes(:auth_provider).where('auth_providers.name': name).first&.auth_provider
assert_not_nil db_provider assert_not_nil db_provider
provider = json_response(response.body) provider = json_response(response.body)
assert_equal name, provider[:name] assert_equal name, provider[:name]
assert_equal db_provider.id, provider[:id] assert_equal db_provider&.id, provider[:id]
assert_equal 'pending', provider[:status] assert_equal 'pending', provider[:status]
assert_equal 2, provider[:auth_provider_mappings_attributes].length assert_equal 2, provider[:auth_provider_mappings_attributes].length
@ -62,9 +61,9 @@ class AuthProvidersTest < ActionDispatch::IntegrationTest
Fablab::Application.load_tasks if Rake::Task.tasks.empty? Fablab::Application.load_tasks if Rake::Task.tasks.empty?
Rake::Task['fablab:auth:switch_provider'].invoke(name) Rake::Task['fablab:auth:switch_provider'].invoke(name)
db_provider.reload db_provider&.reload
assert_equal 'active', db_provider.status assert_equal 'active', db_provider&.status
assert_equal AuthProvider.active.id, db_provider.id assert_equal AuthProvider.active.id, db_provider&.id
User.all.each do |u| User.all.each do |u|
assert_not_nil u.auth_token assert_not_nil u.auth_token
end end

View File

@ -37,10 +37,10 @@ class Events::AsAdminTest < ActionDispatch::IntegrationTest
assert_not_nil e, 'Event was not created in database' assert_not_nil e, 'Event was not created in database'
# Check the remaining free places are not defined # Check the remaining free places are not defined
assert_nil e.nb_free_places, "Free places shouldn't be defined" assert_nil e&.nb_free_places, "Free places shouldn't be defined"
# Then, modify the event to set a nb of places # Then, modify the event to set a nb of places
put "/api/events/#{e.id}", put "/api/events/#{e&.id}",
params: { params: {
event: { event: {
title: 'OpenLab discovery day', title: 'OpenLab discovery day',
@ -61,8 +61,8 @@ class Events::AsAdminTest < ActionDispatch::IntegrationTest
# Check the places numbers were updated successfully # Check the places numbers were updated successfully
e = Event.where(id: event[:id]).first e = Event.where(id: event[:id]).first
assert_equal 10, e.nb_total_places, 'Total number of places was not updated' assert_equal 10, e&.nb_total_places, 'Total number of places was not updated'
assert_equal 10, e.nb_free_places, 'Number of free places was not updated' assert_equal 10, e&.nb_free_places, 'Number of free places was not updated'
# Now, let's make a reservation on this event # Now, let's make a reservation on this event
post '/api/local_payment/confirm_payment', post '/api/local_payment/confirm_payment',
@ -71,12 +71,12 @@ class Events::AsAdminTest < ActionDispatch::IntegrationTest
items: [ items: [
{ {
reservation: { reservation: {
reservable_id: e.id, reservable_id: e&.id,
reservable_type: 'Event', reservable_type: 'Event',
nb_reserve_places: 2, nb_reserve_places: 2,
slots_reservations_attributes: [ slots_reservations_attributes: [
{ {
slot_id: e.availability.slots.first.id, slot_id: e&.availability&.slots&.first&.id,
offered: false offered: false
} }
] ]
@ -92,10 +92,10 @@ class Events::AsAdminTest < ActionDispatch::IntegrationTest
# Check the remaining places were updated successfully # Check the remaining places were updated successfully
e = Event.where(id: event[:id]).first e = Event.where(id: event[:id]).first
assert_equal 8, e.nb_free_places, 'Number of free places was not updated' assert_equal 8, e&.nb_free_places, 'Number of free places was not updated'
# Finally, modify the event to add some places # Finally, modify the event to add some places
put "/api/events/#{e.id}", put "/api/events/#{e&.id}",
params: { params: {
event: { event: {
title: 'OpenLab discovery day', title: 'OpenLab discovery day',
@ -116,8 +116,8 @@ class Events::AsAdminTest < ActionDispatch::IntegrationTest
# Check the places numbers were updated successfully # Check the places numbers were updated successfully
e = Event.where(id: event[:id]).first e = Event.where(id: event[:id]).first
assert_equal 20, e.nb_total_places, 'Total number of places was not updated' assert_equal 20, e&.nb_total_places, 'Total number of places was not updated'
assert_equal 18, e.nb_free_places, 'Number of free places was not updated' assert_equal 18, e&.nb_free_places, 'Number of free places was not updated'
end end
test 'create event with custom price and reserve it with success' do test 'create event with custom price and reserve it with success' do
@ -201,7 +201,7 @@ class Events::AsAdminTest < ActionDispatch::IntegrationTest
# Check the remaining places were updated successfully # Check the remaining places were updated successfully
e = Event.where(id: event[:id]).first e = Event.where(id: event[:id]).first
assert_equal 2, e.nb_free_places, 'Number of free places was not updated' assert_equal 2, e&.nb_free_places, 'Number of free places was not updated'
# Check the resulting invoice generation and it has right price # Check the resulting invoice generation and it has right price
assert_invoice_pdf i assert_invoice_pdf i

View File

@ -78,8 +78,8 @@ class Events::AsUserTest < ActionDispatch::IntegrationTest
# invoice assertions # invoice assertions
invoice = reservation.original_invoice invoice = reservation.original_invoice
refute invoice.payment_gateway_object.blank? assert_not invoice.payment_gateway_object.blank?
refute invoice.total.blank? assert_not invoice.total.blank?
assert_equal 43_350, invoice.total # total minus coupon assert_equal 43_350, invoice.total # total minus coupon
# invoice_items assertions # invoice_items assertions
@ -97,7 +97,7 @@ class Events::AsUserTest < ActionDispatch::IntegrationTest
VCR.use_cassette('reserve_event_with_many_prices_and_payment_means_retrieve_invoice_from_stripe') do VCR.use_cassette('reserve_event_with_many_prices_and_payment_means_retrieve_invoice_from_stripe') do
stp_intent = invoice.payment_gateway_object.gateway_object.retrieve stp_intent = invoice.payment_gateway_object.gateway_object.retrieve
assert_equal stp_intent.amount, (invoice.total - invoice.wallet_amount) # total minus coupon minus wallet = amount really paid by the user assert_equal stp_intent.amount, (invoice.total - invoice.wallet_amount) # total minus coupon minus wallet = amount really paid
end end
# wallet assertions # wallet assertions

View File

@ -0,0 +1,76 @@
# frozen_string_literal: true
require 'test_helper'
module Events; end
class Events::RecurrenceTest < ActionDispatch::IntegrationTest
def setup
@admin = User.find_by(username: 'admin')
login_as(@admin, scope: :user)
end
test 'create a recurrent event' do
name = 'Make your skatebord'
post '/api/events',
params: {
event: {
title: name,
event_image_attributes: {
attachment: fixture_file_upload('/files/event/Skateboard.jpg')
},
description: 'Come make you own skatebord from stratch...',
start_date: 1.week.from_now.utc,
end_date: 1.week.from_now.utc,
all_day: true,
amount: 20,
event_theme_ids: [1],
category_id: 2,
age_range_id: 1,
recurrence: 'week',
recurrence_end_at: 10.weeks.from_now.utc,
event_files_attributes: [
{ attachment: fixture_file_upload('/files/document.pdf', 'document/pdf', true) },
{ attachment: fixture_file_upload('/files/document2.pdf', 'document/pdf', true) }
],
event_price_categories_attributes: [
{ price_category_id: 1, amount: 10 },
{ price_category_id: 2, amount: 15 }
],
advanced_accounting_attributes: {
code: '706300',
analytical_section: '9A54C'
}
}
},
headers: upload_headers
# Check response format & status
assert_equal 201, response.status, response.body
assert_equal Mime[:json], response.content_type
# Check the events were correctly created
db_events = Event.where(title: name)
assert_equal 10, db_events.count
assert(db_events.all? { |event| !event.event_image.attachment.nil? })
assert(db_events.all? { |event| !event.description.empty? })
assert(db_events.all? { |event| event.availability.start_at.to_date >= 1.week.from_now.to_date })
assert(db_events.all? { |event| event.availability.start_at.to_date <= 10.weeks.from_now.end_of_day.to_date })
assert(db_events.all? { |event| event.availability.end_at.to_date >= 1.week.from_now.to_date })
assert(db_events.all? { |event| event.availability.end_at.to_date <= 10.weeks.from_now.end_of_day.to_date })
assert(db_events.all?(&:all_day?))
assert(db_events.all? { |event| event.amount == 2000 })
assert(db_events.all? { |event| event.event_theme_ids == [1] })
assert(db_events.all? { |event| event.category_id == 2 })
assert(db_events.all? { |event| event.age_range_id == 1 })
assert(db_events.all? { |event| event.event_files.count == 2 })
assert(db_events.all? { |event| !event.event_files[0].attachment.nil? })
assert(db_events.all? { |event| !event.event_files[1].attachment.nil? })
assert(db_events.all? { |event| event.event_price_categories[0].price_category_id == 1 })
assert(db_events.all? { |event| event.event_price_categories[0].amount == 1000 })
assert(db_events.all? { |event| event.event_price_categories[1].price_category_id == 2 })
assert(db_events.all? { |event| event.event_price_categories[1].amount == 1500 })
assert(db_events.all? { |event| event.advanced_accounting.code == '706300' })
assert(db_events.all? { |event| event.advanced_accounting.analytical_section == '9A54C' })
end
end

View File

@ -0,0 +1,80 @@
# frozen_string_literal: true
require 'test_helper'
class TrainingsTest < ActionDispatch::IntegrationTest
def setup
@admin = User.find_by(username: 'admin')
login_as(@admin, scope: :user)
end
test 'create a training' do
name = 'First aid training'
post '/api/trainings',
params: {
training: {
name: name,
training_image_attributes: {
attachment: fixture_file_upload('/files/trainings/first-aid.jpg')
},
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore...',
machine_ids: [],
nb_total_places: 10,
public_page: true,
disabled: false,
advanced_accounting_attributes: {
code: '706200',
analytical_section: '9A41B'
}
}
},
headers: upload_headers
# Check response format & status
assert_equal 201, response.status, response.body
assert_equal Mime[:json], response.content_type
# Check the training was correctly created
db_training = Training.where(name: name).first
assert_not_nil db_training
assert_not_nil db_training.training_image.attachment
assert_equal name, db_training.name
assert_equal 10, db_training.nb_total_places
assert_empty db_training.machine_ids
assert_not_empty db_training.description
assert db_training.public_page
assert_not db_training.disabled
assert_equal '706200', db_training.advanced_accounting.code
assert_equal '9A41B', db_training.advanced_accounting.analytical_section
end
test 'update a training' do
description = '<p>lorem ipsum <strong>dolor</strong> sit amet</p>'
put '/api/trainings/3',
params: {
training: {
description: description,
public_page: false
}
}.to_json,
headers: default_headers
# Check response format & status
assert_equal 200, response.status, response.body
assert_equal Mime[:json], response.content_type
# Check the training was correctly updated
db_training = Training.find(3)
assert_equal description, db_training.description
assert_not db_training.public_page
training = json_response(response.body)
assert_equal description, training[:description]
assert_not training[:public_page]
end
test 'delete a training' do
delete '/api/trainings/4', headers: default_headers
assert_response :success
assert_empty response.body
end
end