mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-03-23 14:19:52 +01:00
Merge branch 'dev' for release X.Y.Z
This commit is contained in:
commit
6d9a81cf90
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,5 +1,18 @@
|
||||
# Changelog Fab-manager
|
||||
|
||||
## v6.1.1 2023 September 28
|
||||
|
||||
- Fix a bug: unable to sync projects with openprojects
|
||||
- Fix a bug: public availabilities (no user) was buggy (server error)
|
||||
- Fix a bug: unable to generate statistic
|
||||
- Fix a bug: rss/projects was failing with project without image
|
||||
- improvement : performance of members#show and reservations#index
|
||||
|
||||
- [TODO DEPLOY] `rails fablab:openlab:bulk_export`
|
||||
- [TODO DEPLOY] `rails fablab:openlab:bulk_update`
|
||||
- [TODO DEPLOY] `rails fablab:es:build_stats`
|
||||
- [TODO DEPLOY] `rails fablab:maintenance:regenerate_statistics[2023,6]`
|
||||
|
||||
## v6.1.0 2023 September 25
|
||||
|
||||
- improves api/notification controller to avoid failing when there is a notification with wrong notification_type in db
|
||||
|
@ -16,8 +16,10 @@ class API::ReservationsController < API::APIController
|
||||
where_clause[:reservable_id] = params[:reservable_id] if params[:reservable_id]
|
||||
|
||||
@reservations = Reservation.where(where_clause)
|
||||
.preload(:reservable, :booking_users, :tickets, { statistic_profile: { user: :profile }, slots_reservations: :slot })
|
||||
elsif params[:reservable_id] && params[:reservable_type] && (current_user.admin? || current_user.manager?)
|
||||
@reservations = Reservation.where(params.permit(:reservable_id, :reservable_type))
|
||||
.preload(:reservable, :booking_users, :tickets, { statistic_profile: { user: :profile }, slots_reservations: :slot })
|
||||
else
|
||||
@reservations = []
|
||||
end
|
||||
|
@ -39,6 +39,10 @@
|
||||
grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
|
||||
gap: 3.2rem;
|
||||
& > span { grid-column: 1/-1;}
|
||||
& > a {
|
||||
grid-column: 1/-1;
|
||||
justify-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
|
@ -126,8 +126,7 @@
|
||||
<p class="name">{{project.name}}</p>
|
||||
<span class="openlab" ng-if="openlab.searchOverWholeNetwork"><i class="fa fa-tag"></i> {{ project.app_name }}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<a class="btn btn-warning" ng-click="loadMore()" ng-if="projectsPagination.hasNextPage()" translate>{{ 'app.public.projects_list.load_next_projects' }}</a>
|
||||
<a class="fab-button is-secondary" ng-click="loadMore()" ng-if="projectsPagination.hasNextPage()" translate>{{ 'app.public.projects_list.load_next_projects' }}</a>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -40,7 +40,6 @@ class Availabilities::AvailabilitiesService
|
||||
|
||||
if @level == 'slot'
|
||||
slots = availabilities.map(&:slots).flatten
|
||||
|
||||
blocked_slots = Slots::InterblockingService.new.blocked_slots_for_machines(machines, slots)
|
||||
flag_or_remove_blocked_slots(slots, blocked_slots, @current_user)
|
||||
else
|
||||
@ -141,7 +140,7 @@ class Availabilities::AvailabilitiesService
|
||||
end
|
||||
|
||||
def flag_or_remove_blocked_slots(slots, blocked_slots, user)
|
||||
if user.admin? || user.manager?
|
||||
if user && (user.admin? || user.manager?)
|
||||
blocked_slots.each do |slot|
|
||||
slot.is_blocked = true
|
||||
end
|
||||
|
@ -3,8 +3,6 @@
|
||||
# Provides methods to sync projects on OpenLab
|
||||
class OpenLabService
|
||||
class << self
|
||||
include ActionView::Helpers::SanitizeHelper
|
||||
|
||||
def to_hash(project)
|
||||
{
|
||||
id: project.id,
|
||||
@ -20,9 +18,9 @@ class OpenLabService
|
||||
steps_body: steps_body(project),
|
||||
image_path: project.project_image&.attachment&.medium&.url,
|
||||
project_path: "/#!/projects/#{project.slug}",
|
||||
updated_at: project.updated_at.to_s(:iso8601),
|
||||
created_at: project.created_at.to_s(:iso8601),
|
||||
published_at: project.published_at.to_s(:iso8601)
|
||||
updated_at: project.updated_at.to_fs(:iso8601),
|
||||
created_at: project.created_at.to_fs(:iso8601),
|
||||
published_at: project.published_at.to_fs(:iso8601)
|
||||
}
|
||||
end
|
||||
|
||||
@ -32,7 +30,7 @@ class OpenLabService
|
||||
.gsub("\r\n", ' ').gsub("\n\r", ' ')
|
||||
.gsub("\n", ' ').gsub("\r", ' ').gsub("\t", ' ')
|
||||
|
||||
strip_tags(concatenated_steps).strip
|
||||
ActionController::Base.helpers.strip_tags(concatenated_steps).strip
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -17,7 +17,7 @@ class Statistics::BuilderService
|
||||
private
|
||||
|
||||
def default_options
|
||||
yesterday = Time.current
|
||||
yesterday = 1.day.ago
|
||||
{
|
||||
start_date: yesterday.beginning_of_day,
|
||||
end_date: yesterday.end_of_day
|
||||
|
@ -10,7 +10,8 @@ json.trainings @member.trainings do |t|
|
||||
json.id t.id
|
||||
json.name t.name
|
||||
end
|
||||
json.training_reservations @member.reservations.where(reservable_type: 'Training').map(&:slots_reservations).flatten do |sr|
|
||||
reservations = @member.reservations.where(reservable_type: 'Training').preload(slots_reservations: [:slot, reservation: :reservable])
|
||||
json.training_reservations reservations.select { |r| r.reservable_type == "Training" }.map(&:slots_reservations).flatten do |sr|
|
||||
json.id sr.id
|
||||
json.start_at sr.slot.start_at
|
||||
json.end_at sr.slot.end_at
|
||||
@ -19,7 +20,7 @@ json.training_reservations @member.reservations.where(reservable_type: 'Training
|
||||
json.is_valid @member.statistic_profile.training_ids.include?(sr.reservation.reservable_id)
|
||||
json.canceled_at sr.canceled_at
|
||||
end
|
||||
json.machine_reservations @member.reservations.where(reservable_type: 'Machine').map(&:slots_reservations).flatten do |sr|
|
||||
json.machine_reservations reservations.select { |r| r.reservable_type == "Machine" }.map(&:slots_reservations).flatten do |sr|
|
||||
json.id sr.id
|
||||
json.start_at sr.slot.start_at
|
||||
json.end_at sr.slot.end_at
|
||||
@ -27,7 +28,7 @@ json.machine_reservations @member.reservations.where(reservable_type: 'Machine')
|
||||
json.reservable_type 'Machine'
|
||||
json.canceled_at sr.canceled_at
|
||||
end
|
||||
json.space_reservations @member.reservations.where(reservable_type: 'Space').map(&:slots_reservations).flatten do |sr|
|
||||
json.space_reservations reservations.select { |r| r.reservable_type == "Space" }.map(&:slots_reservations).flatten do |sr|
|
||||
json.id sr.id
|
||||
json.start_at sr.slot.start_at
|
||||
json.end_at sr.slot.end_at
|
||||
|
@ -22,7 +22,9 @@ xml.rss version: '2.0', 'xmlns:xCal' => 'urn:ietf:params:xml:ns:xcal' do
|
||||
xml.xCal :dtend do
|
||||
xml.text! event.availability.end_at.strftime('%FT%T%:z')
|
||||
end
|
||||
xml.enclosure url: root_url + event.event_image.attachment.large.url, length: event.event_image.attachment.large.size, type: event.event_image.attachment.content_type if event.event_image
|
||||
if event.event_image&.attachment?
|
||||
xml.enclosure url: root_url + event.event_image.attachment.large.url, length: event.event_image.attachment.large.size, type: event.event_image.attachment.content_type
|
||||
end
|
||||
xml.category event.category.name
|
||||
end
|
||||
end
|
||||
|
@ -17,7 +17,9 @@ xml.rss version: '2.0' do
|
||||
xml.link root_url + '#!/projects/' + project.slug
|
||||
xml.author project.author&.user&.profile&.full_name
|
||||
xml.description project.description
|
||||
xml.enclosure url: root_url + project.project_image.attachment.large.url, length: project.project_image.attachment.large.size, type: project.project_image.attachment.content_type if project.project_image
|
||||
if project.project_image&.attachment?
|
||||
xml.enclosure url: root_url + project.project_image.attachment.large.url, length: project.project_image.attachment.large.size, type: project.project_image.attachment.content_type
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fab-manager",
|
||||
"version": "6.1.0",
|
||||
"version": "6.1.1",
|
||||
"description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.",
|
||||
"keywords": [
|
||||
"fablab",
|
||||
|
@ -3,7 +3,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class Availabilities::AsPublicTest < ActionDispatch::IntegrationTest
|
||||
test 'get public machines availabilities if machines module is active' do
|
||||
test "[level == 'availability'] get public machines availabilities if machines module is active" do
|
||||
start_date = Time.current.to_date
|
||||
end_date = 7.days.from_now.to_date
|
||||
|
||||
@ -24,6 +24,24 @@ class Availabilities::AsPublicTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test "[level == 'slot'] get public machines availabilities if machines module is active" do
|
||||
start_date = Time.current.to_date
|
||||
end_date = start_date + 1.day
|
||||
|
||||
get "/api/availabilities/public?start=#{start_date}&end=#{end_date}&timezone=Europe%2FParis&#{all_machines}"
|
||||
|
||||
# Check response format & status
|
||||
assert_equal 200, response.status
|
||||
assert_match Mime[:json].to_s, response.content_type
|
||||
|
||||
# Check the correct availabilities was returned
|
||||
availabilities = json_response(response.body)
|
||||
assert_not_empty availabilities, 'no availabilities were found'
|
||||
availabilities.each do |a|
|
||||
assert_not_empty a[:machine_ids]
|
||||
end
|
||||
end
|
||||
|
||||
test 'get anymore machines availabilities if machines module is inactive' do
|
||||
Setting.set('machines_module', false)
|
||||
start_date = Time.current.to_date
|
||||
@ -61,6 +79,45 @@ class Availabilities::AsPublicTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test "[level == 'availability'] get public spaces availabilities" do
|
||||
start_date = Time.current.to_date
|
||||
end_date = 7.days.from_now.to_date
|
||||
|
||||
get "/api/availabilities/public?start=#{start_date}&end=#{end_date}&timezone=Europe%2FParis&#{all_spaces}"
|
||||
|
||||
# Check response format & status
|
||||
assert_equal 200, response.status
|
||||
assert_match Mime[:json].to_s, response.content_type
|
||||
|
||||
# Check the correct availabilities was returned
|
||||
availabilities = json_response(response.body)
|
||||
assert_not_empty availabilities, 'no availabilities were found'
|
||||
availabilities.each_with_index do |a, index|
|
||||
assert_not_nil a, "availability #{index} was unexpectedly nil"
|
||||
assert_equal 'space', a[:available_type], "availability #{index} is not a space availability"
|
||||
assert Time.zone.parse(a[:start]) > start_date, "availability #{index} starts before the requested period"
|
||||
assert Time.zone.parse(a[:end]) < end_date, "availability #{index} ends after the requested period"
|
||||
end
|
||||
end
|
||||
|
||||
test "[level == 'slot'] get public spaces availabilities" do
|
||||
start_date = Time.current.to_date
|
||||
end_date = start_date + 1.day
|
||||
|
||||
get "/api/availabilities/public?start=#{start_date}&end=#{end_date}&timezone=Europe%2FParis&#{all_spaces}"
|
||||
|
||||
# Check response format & status
|
||||
assert_equal 200, response.status
|
||||
assert_match Mime[:json].to_s, response.content_type
|
||||
|
||||
# Check the correct availabilities was returned
|
||||
availabilities = json_response(response.body)
|
||||
assert_not_empty availabilities, 'no availabilities were found'
|
||||
availabilities.each do |a|
|
||||
assert_not_nil a[:space_id]
|
||||
end
|
||||
end
|
||||
|
||||
test 'get public spaces availabilities' do
|
||||
start_date = Time.current.to_date
|
||||
end_date = 7.days.from_now.to_date
|
||||
|
13
test/integration/rss/events_test.rb
Normal file
13
test/integration/rss/events_test.rb
Normal file
@ -0,0 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'test_helper'
|
||||
module Rss; end
|
||||
|
||||
class Rss::EventsTestTest < ActionDispatch::IntegrationTest
|
||||
test '#index' do
|
||||
get rss_events_path
|
||||
|
||||
assert_response :success
|
||||
assert Nokogiri::XML(response.body).errors.empty?
|
||||
end
|
||||
end
|
13
test/integration/rss/projects_test.rb
Normal file
13
test/integration/rss/projects_test.rb
Normal file
@ -0,0 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'test_helper'
|
||||
module Rss; end
|
||||
|
||||
class Rss::ProjectsTestTest < ActionDispatch::IntegrationTest
|
||||
test '#index' do
|
||||
get rss_projects_path
|
||||
|
||||
assert_response :success
|
||||
assert Nokogiri::XML(response.body).errors.empty?
|
||||
end
|
||||
end
|
16
test/services/open_lab_service_test.rb
Normal file
16
test/services/open_lab_service_test.rb
Normal file
@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
# In the following tests, amounts are expressed in centimes, ie. 1000 = 1000 cts = 10,00 EUR
|
||||
class OpenLabServiceTest < ActiveSupport::TestCase
|
||||
test "do not raise any error" do
|
||||
h = nil
|
||||
|
||||
assert_nothing_raised do
|
||||
h = OpenLabService.to_hash(projects(:project_1))
|
||||
end
|
||||
|
||||
assert_instance_of Hash, h
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user