diff --git a/app/controllers/power_distribution_units_controller.rb b/app/controllers/power_distribution_units_controller.rb new file mode 100644 index 000000000..bd7b1666b --- /dev/null +++ b/app/controllers/power_distribution_units_controller.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +class PowerDistributionUnitsController < ApplicationController + before_action :set_pdu, only: %i[show edit update destroy destroy_connections] + + def index + @pdus = Server.only_pdus.includes(:frame, :room, :islet, bay: :frames, modele: :category) + .references(:room, :islet, :bay, modele: :category) + .order(:name) + @filter = ProcessorFilter.new(@pdus, params) + + @pdus = @filter.results + @search_params = search_params + + respond_to do |format| + format.json + format.html { @pagy, @pdus = pagy(@pdus) } + end + end + + def show; end + + def new + @pdu = Server.new + end + + def edit; end + + def create + @pdu = Server.new(pdu_params) + + respond_to do |format| + if @pdu.save + format.html { redirect_to power_distribution_unit_path(@pdu), notice: t(".flashes.created") } + format.json { render :show, status: :created, location: @pdu } + else + format.html { render :new } + format.json { render json: @pdu.errors, status: :unprocessable_entity } + end + end + end + + def update + respond_to do |format| + if @pdu.update(pdu_params) + format.html { redirect_to power_distribution_unit_path(@pdu), notice: t(".flashes.updated") } + format.json { render :show, status: :ok, location: @pdu } + else + format.html { render :edit } + format.json { render json: @pdu.errors, status: :unprocessable_entity } + end + end + end + + def destroy + respond_to do |format| + if @pdu.destroy + format.html { redirect_to power_distribution_units_path(search_params), notice: t(".flashes.destroyed") } + format.json { head :no_content } + else + format.html { redirect_to power_distribution_units_path(search_params), alert: t(".flashes.not_destroyed") } + format.json { head :bad_request } + end + end + end + + def duplicate + @original_pdu = Server.friendly.find(params[:id].to_s.downcase) + @pdu = @original_pdu.deep_dup + end + + def destroy_connections + if @pdu.destroy_connections! + flash[:notice] = t(".flashes.connections_destroyed") + else + flash[:alert] = t(".flashes.connections_not_destroyed") + end + + redirect_to power_distribution_unit_path(@pdu) + end + + private + + def set_pdu + @pdu = Server.friendly_find_by_numero_or_name(params[:id]) + end + + def pdu_params + params.expect( + power_distribution_unit: [ + :photo, :comment, :position, :frame_id, :gestion_id, :fc_futur, :rj45_cm, :name, :modele_id, :numero, :critique, + :domaine_id, :fc_total, :fc_utilise, :rj45_total, :rj45_utilise, :rj45_futur, :ipmi_utilise, :ipmi_futur, + :ipmi_dedie, + :frame, # TODO: Check if it should be removed or if it's used somewhere + { cards_attributes: [%i[composant_id card_type_id twin_card_id orientation name first_position _destroy id]] }, + { documents_attributes: [%i[document id _destroy]] }, + ] + ) + end + + def search_params + params.permit(:sort, :sort_by, :page, :per_page, :q, + network_types: [], bay_ids: [], islet_ids: [], room_ids: [], frame_ids: [], cluster_ids: [], + gestion_ids: [], domaine_ids: [], modele_ids: [], server_state_ids: [], stack_ids: []) + end +end diff --git a/app/controllers/servers_controller.rb b/app/controllers/servers_controller.rb index 42fbfe2a3..21fd34a61 100644 --- a/app/controllers/servers_controller.rb +++ b/app/controllers/servers_controller.rb @@ -13,7 +13,7 @@ def index logger.warn("DEPRECATION WARNING: Search with 'name' is now deprecated. Use 'q' instead.") end - @servers = Server.includes(:frame, :room, :islet, bay: :frames, modele: :category) + @servers = Server.no_pdus.includes(:frame, :room, :islet, bay: :frames, modele: :category) .references(:room, :islet, :bay, modele: :category) .order(:name) @filter = ProcessorFilter.new(@servers, params) @@ -27,27 +27,6 @@ def index end end - def grid - @servers = ServersGrid.new(params[:servers_grid]) - end - - def sort - room = Room.find_by_name(params[:room]) unless params[:room].include?('non ') - frame = room.frames.where('islets.name = ? AND frames.name = ?', params[:islet], params[:frame]).first - positions = params[:positions].split(',') - - params[:server].each_with_index do |id, index| - if positions[index].present? - server = Server.find_by_id(id) - new_params = { position: positions[index] } - new_params[:frame_id] = frame.id if frame.present? - - server.update(new_params) - end - end if params[:server].present? - head :ok # render empty body, status only - end - def show; end def new @@ -82,6 +61,39 @@ def update end end + def destroy + respond_to do |format| + if @server.destroy + format.html { redirect_to servers_path(search_params), notice: t(".flashes.destroyed") } + format.json { head :no_content } + else + format.html { redirect_to servers_path(search_params), alert: t(".flashes.not_destroyed") } + format.json { head :bad_request } + end + end + end + + def grid + @servers = ServersGrid.new(params[:servers_grid]) + end + + def sort + room = Room.find_by_name(params[:room]) unless params[:room].include?('non ') + frame = room.frames.where('islets.name = ? AND frames.name = ?', params[:islet], params[:frame]).first + positions = params[:positions].split(',') + + params[:server].each_with_index do |id, index| + if positions[index].present? + server = Server.find_by_id(id) + new_params = { position: positions[index] } + new_params[:frame_id] = frame.id if frame.present? + + server.update(new_params) + end + end if params[:server].present? + head :ok # render empty body, status only + end + def import_csv; end def import @@ -96,18 +108,6 @@ def import end end - def destroy - respond_to do |format| - if @server.destroy - format.html { redirect_to servers_path(search_params), notice: t(".flashes.destroyed") } - format.json { head :no_content } - else - format.html { redirect_to servers_path(search_params), alert: t(".flashes.not_destroyed") } - format.json { head :bad_request } - end - end - end - def duplicate @original_server = Server.friendly.find(params[:id].to_s.downcase) @server = @original_server.deep_dup diff --git a/app/models/modele.rb b/app/models/modele.rb index dfdf3c9c9..56b55ee3c 100644 --- a/app/models/modele.rb +++ b/app/models/modele.rb @@ -24,6 +24,8 @@ class Modele < ApplicationRecord scope :sorted, -> { order(:name) } scope :with_servers, -> { joins(:servers).uniq } scope :glpi_synchronizable, -> { where(category: Category.glpi_synchronizable) } + scope :no_pdus, -> { joins(:category).where("categories.name<>'Pdu'") } + scope :only_pdus, -> { joins(:category).where("categories.name='Pdu'").order(:name) } def self.all_sorted Modele.includes(:manufacturer).all.sort { |f1, f2| f1.name_with_brand.capitalize <=> f2.name_with_brand.capitalize } diff --git a/app/models/server.rb b/app/models/server.rb index e680d2951..8b1f559a6 100644 --- a/app/models/server.rb +++ b/app/models/server.rb @@ -40,23 +40,23 @@ class Server < ApplicationRecord validate :validate_network_types_values accepts_nested_attributes_for :cards, - :allow_destroy => true, - :reject_if => :all_blank + allow_destroy: true, + reject_if: :all_blank accepts_nested_attributes_for :disks, - :allow_destroy => true, - :reject_if => :all_blank + allow_destroy: true, + reject_if: :all_blank accepts_nested_attributes_for :memory_components, - :allow_destroy => true, - :reject_if => :all_blank + allow_destroy: true, + reject_if: :all_blank accepts_nested_attributes_for :documents, - :allow_destroy => true, - :reject_if => :all_blank + allow_destroy: true, + reject_if: :all_blank normalizes :network_types, with: ->(values) { values.compact_blank } before_create :set_default_network_types - scope :sorted, -> { order(:position => :desc) } + scope :sorted, -> { order(position: :desc) } scope :sorted_by_name, -> { order('LOWER(name) ASC') } scope :glpi_synchronizable, -> { joins(modele: :category).merge(Modele.glpi_synchronizable) } diff --git a/app/views/cables/index.html.erb b/app/views/cables/index.html.erb index c7f53034b..f104e65ee 100644 --- a/app/views/cables/index.html.erb +++ b/app/views/cables/index.html.erb @@ -97,7 +97,7 @@ <%= cable.decorated.server_connected_with_link(from_connection, from: true) %> <%= cable.decorated.draw_port(from_connection) %> -
+
<%= cable.decorated.draw_port(to_connection) %>
<%= cable.decorated.server_connected_with_link(to_connection) %> diff --git a/app/views/layouts/_sidebar.html.erb b/app/views/layouts/_sidebar.html.erb index 5c6b5c515..004c4dc33 100644 --- a/app/views/layouts/_sidebar.html.erb +++ b/app/views/layouts/_sidebar.html.erb @@ -45,7 +45,7 @@ - + +
  • + <%= link_to t("power_distribution_units.index.title"), + power_distribution_units_path, + class: class_names("mydcim-sidebar-links-link d-inline-block rounded", + active: controller.controller_name == "power_distribution_units") %> +
  • <%= link_to AirConditioner.model_name.human.pluralize, air_conditioners_path, diff --git a/app/views/power_distribution_units/_form.html.erb b/app/views/power_distribution_units/_form.html.erb new file mode 100644 index 000000000..e4680c28e --- /dev/null +++ b/app/views/power_distribution_units/_form.html.erb @@ -0,0 +1,192 @@ +<% + is_edit = controller.action_name == "edit" + is_new = !is_edit + + dynamic_url = is_edit ? power_distribution_unit_path(@pdu) : power_distribution_units_path +%> + +<%= form_for(@pdu, as: :power_distribution_unit, + url: dynamic_url, + html: { class: "col-12 col-md-10 col-lg-8 mx-auto", role: "form" }) do |f| %> + <%= render FormErrorsComponent.new(@pdu) %> + + <%= render CardComponent.new(extra_classes: "bg-body-tertiary") do |card| %> + <% card.with_header do %> + <%= t("show.cards.identification") %> + <% end %> + +
    +
    + <%= f.label :name, class: "form-label" %> + <%= f.text_field :name, class: "form-control" %> +
    +
    + <% end %> + + <%= render CardComponent.new(extra_classes: "mt-4 bg-body-tertiary") do |card| %> + <% card.with_header do %> + <%= Modele.model_name.human %> + <% end %> + +
    +
    + <%= f.label :modele_id, class: "form-label" %> + <%= f.collection_select(:modele_id, + Modele.only_pdus.all_sorted, + :id, + :name_with_brand, + { prompt: true, include_blank: false }, + { + class: "form-select", + data: { controller: "select" }, + placeholder: t("select.placeholder") + }) + %> +
    +
    + <% end %> + + <%= render CardComponent.new(extra_classes: "mt-4 bg-body-tertiary") do |card| %> + <% card.with_header do %> + <%= t("show.cards.features") %> + <% end %> + +
    +
    + <%= f.label :numero, class: "form-label" %> + <%= f.text_field :numero, class: "form-control" %> +
    +
    + <% end %> + + <%= render CardComponent.new(type: :primary, extra_classes: "mt-4 bg-body-tertiary") do |card| %> + <% card.with_header do %> + <%= t("layouts.sidebar.location.title") %> + <% end %> + +
    +
    + <%= f.label :frame_id, class: "form-label" %> + <%= f.collection_select(:frame_id, + Frame.all_sorted, + :id, + :name_with_room_and_islet, + { prompt: true, include_blank: false }, + { + class: "form-select", + data: { controller: "select" }, + placeholder: t("select.placeholder") + }) + %> +
    +
    + <% end %> + + <%= render CardComponent.new(type: :success, extra_classes: "mt-4 bg-body-tertiary") do |card| %> + <% card.with_header do %> + <%= t("layouts.sidebar.exploitation.title") %> + <% end %> + +
    +
    + <%= f.label :gestion_id, class: "form-label" %> + <%= f.collection_select(:gestion_id, + Gestion.sorted, + :id, + :name, + { prompt: true, include_blank: true }, + { + class: "form-select", + data: { controller: "select" }, + placeholder: t("select.placeholder") + }) + %> +
    +
    + <% end %> + + + <% if @pdu.modele %> + <% @pdu.modele.enclosures.each do |enclosure| %> +
    + + + <%= render CardComponent.new(extra_classes: "bg-body") do |card| %> + <% card.with_header do %> + <%= "#{Enclosure.model_name.human} #{enclosure.position}" %> + <% end %> + +
    + <% cards = @pdu.cards.select { |c| c.composant.enclosure == enclosure } + .sort_by! { |c| c.composant.position } %> + <%= f.fields_for :cards, cards do |card_fields| %> + <%= render partial: "servers/card_fields", locals: { f: card_fields, server: @pdu, enclosure: enclosure } %> + <% end %> + +
    +
    + + <% card.with_footer do %> + + <% end %> + <% end %> +
    + <% end %> + <% end %> + + <%= render CardComponent.new(extra_classes: "bg-body-tertiary mt-4") do |card| %> +
    + <%= f.label :comment, class: "form-label" %> + <%= f.text_area :comment, class: "form-control" %> +
    + <% end %> + +
    + + + <%= render CardComponent.new(extra_classes: "bg-body-tertiary") do |card| %> + <% card.with_header do %> + <%= f.label :documents %> + <% end %> + + <%= f.fields_for :documents do |document_fields| %> + <%= render partial: "servers/document_fields", locals: { f: document_fields } %> + <% end %> + +
    + + + <% end %> +
    + + <%= render CardComponent.new(extra_classes: "bg-body-tertiary mt-4") do |card| %> +
    + <%= f.label :photo, class: "form-label" %> + <%= f.file_field :photo, class: "form-control" %> + + <% if @pdu.photo.attached? %> + <%= image_tag @pdu.photo.representation(resize_to_limit: [200, 200]), class: "ms-0 mt-2" %> + <% end %> +
    + <% end %> + + <%#= render Form::ActionsComponent.new(f) %> +
    + <%= link_to(t("action.cancel"), dynamic_url, class: "btn btn-outline-secondary me-2") %> + <%= f.submit(class: class_names("btn", 'btn-info': is_edit, 'btn-success': is_new)) %> +
    +<% end %> diff --git a/app/views/power_distribution_units/duplicate.html.erb b/app/views/power_distribution_units/duplicate.html.erb new file mode 100644 index 000000000..7b333f880 --- /dev/null +++ b/app/views/power_distribution_units/duplicate.html.erb @@ -0,0 +1,26 @@ +<% provide(:title, "#{t("power_distribution_units.index.title")} | #{@original_pdu.name} | #{t("action.duplicate")}") %> +<% breadcrumb_steps = { + t("power_distribution_units.index.title") => power_distribution_units_path, + @original_pdu.name => power_distribution_unit_path(@original_pdu), + t("action.duplicate") => "" +} %> + +<%#= render Page::HeadingComponent.new( + resource: @original_pdu, title: t(".title", pdu_name: @original_pdu.name), breadcrumb_steps: +) %> +<%= render Page::HeadingComponent.new( + title: t(".title", pdu_name: @original_pdu.name), breadcrumb_steps:, back_button_url: power_distribution_units_path +) do |heading| %> + <% heading.with_right_content do %> +
    + <%= render ButtonComponent.new(t("action.show"), + url: power_distribution_unit_path(@original_pdu), + variant: :primary, + icon: "eye", + is_responsive: true) %> +
    + <% end %> +<% end %> +
    + <%= render "form" %> +
    diff --git a/app/views/power_distribution_units/edit.html.erb b/app/views/power_distribution_units/edit.html.erb new file mode 100644 index 000000000..7c9d6cf03 --- /dev/null +++ b/app/views/power_distribution_units/edit.html.erb @@ -0,0 +1,23 @@ +<% provide(:title, "#{t("power_distribution_units.index.title")} | #{@pdu.name} | #{t(".title")}") %> +<% breadcrumb_steps = { + t("power_distribution_units.index.title") => power_distribution_units_path, # TODO: prefer use ActiveRecord translation of Modele name + @pdu.name => power_distribution_unit_path(@pdu), + t("action.edit") => "" +} %> + +<%= render Page::HeadingComponent.new( + title: t(".title"), breadcrumb_steps:, back_button_url: power_distribution_unit_path(@pdu) +) do |heading| %> + <% heading.with_right_content do %> +
    + <%= render ButtonComponent.new(t("action.show"), + url: power_distribution_unit_path(@pdu), + variant: :primary, + icon: "eye", + is_responsive: true) %> +
    + <% end %> +<% end %> +
    + <%= render "form" %> +
    diff --git a/app/views/power_distribution_units/index.html.erb b/app/views/power_distribution_units/index.html.erb new file mode 100644 index 000000000..acd911416 --- /dev/null +++ b/app/views/power_distribution_units/index.html.erb @@ -0,0 +1,146 @@ +<% provide(:title, t(".title")) # TODO: prefer use ActiveRecord translation of Modele name %> + +<%= render Page::HeadingComponent.new(title: t(".title"), breadcrumb_steps: { t(".title") => "" } ) do |heading| %> + <% heading.with_right_content do %> + <%= render ButtonComponent.new(t(".new_power_distributon_unit"), + url: new_power_distribution_unit_path, + variant: :success, + icon: "plus-lg", + is_responsive: true) %> + <% end %> +<% end %> + +
    + <%= render FilterComponent.new(@filter) do |c| %> + <% c.with_form do |f| %> +
    +
    + <%= f.text_field :q, class: "form-control", placeholder: t("filters.placeholder.search") %> + <%= f.label :q %> +
    +
    + +
    +
    + <%= f.collection_select(:room_ids, Room.order(:name), + :id, + :name, + { prompt: true, multiple: true }, + { class: "form-select", data: { controller: :select } }) %> + <%= f.label :room_ids %> +
    +
    + +
    +
    + <%= f.collection_select(:islet_ids, Islet.sorted, + :id, + :name_with_room, + { prompt: true, multiple: true }, + { class: "form-select", data: { controller: :select } }) %> + <%= f.label :islet_ids %> +
    +
    + +
    +
    + <%= f.collection_select(:bay_ids, Bay.sorted, + :id, + :to_s, + { prompt: true, multiple: true }, + { class: "form-select", data: { controller: :select } }) %> + <%= f.label :bay_ids %> +
    +
    + +
    +
    + <%= f.collection_select(:frame_ids, Frame.order(:name), + :id, + :name, + { prompt: true, multiple: true }, + { class: "form-select", data: { controller: :select } }) %> + <%= f.label :frame_ids %> +
    +
    + +
    +
    + <%= f.collection_select(:modele_ids, Modele.only_pdus.sorted, + :id, + :name, + { prompt: true, multiple: true }, + { class: "form-select", data: { controller: :select } }) %> + <%= f.label :modele_ids %> +
    +
    + +
    +
    + <%= f.collection_select(:gestion_ids, Gestion.sorted, + :id, + :name, + { prompt: true, multiple: true }, + { class: "form-select", data: { controller: :select } }) %> + <%= f.label :gestion_ids %> +
    +
    + <% end %> + <% end %> + + <%= turbo_frame_tag(dom_id(Server, :table), data: { turbo_action: :advance }) do %> +
    + <%= render List::DataTableComponent.new(@pdus) do |table| %> + <% table.with_column(Server.human_attribute_name(:name), sort_by: :name) do |pdu| %> + <%= link_to pdu.name, power_distribution_unit_path(pdu), class: "fw-bold", data: { turbo_frame: :_top } %> + <% end %> + + <% table.with_column(Server.human_attribute_name(:numero), sort_by: :numero) do |pdu| %> + <%= link_to pdu.numero, power_distribution_unit_path(pdu), class: "fw-bold", data: { turbo_frame: :_top } %> + <% end %> + + <% table.with_column(Server.human_attribute_name(:room), sort_by: :"rooms.name") do |pdu| %> + <%= link_to pdu.room, room_path(pdu.room), data: { turbo_frame: :_top } if pdu.room %> + <% end %> + + <% table.with_column(Islet.model_name.human, sort_by: :"islets.name") do |pdu| %> + <%= link_to pdu.islet, islet_path(pdu.islet), data: { turbo_frame: :_top } if pdu.islet %> + <% end %> + + <% table.with_column(Bay.model_name.human, sort_by: :"bays.id") do |pdu| %> + <%= link_to pdu.bay, bay_path(pdu.bay), data: { turbo_frame: :_top } if pdu.bay %> + <% end %> + + <% table.with_column(style: "min-width: 100px; width: 100px") do |pdu| %> +
    + <%= link_to duplicate_power_distribution_unit_path(pdu), class: "btn btn-success", data: { turbo_frame: :_top } do %> + " aria-hidden="true" + data-controller="tooltip" + data-bs-placement="left"> + <%= t("action.duplicate") %> + <% end %> + <%= link_to edit_power_distribution_unit_path(pdu), class: "btn btn-info", data: { turbo_frame: :_top } do %> + " aria-hidden="true" + data-controller="tooltip" + data-bs-placement="left"> + <%= t("action.edit") %> + <% end %> + <%= link_to power_distribution_unit_path(pdu, @search_params), + method: :delete, + data: { turbo_frame: :_top, confirm: t("action.confirm") }, + class: "btn btn-danger" do %> + " aria-hidden="true" + data-controller="tooltip" + data-bs-placement="left"> + <%= t("action.delete") %> + <% end %> +
    + <% end %> + <% end %> + + <% if @pagy.pages > 1 %> + <%== pagy_bootstrap_nav(@pagy) %> + <% end %> +
    + <% end %> +
    diff --git a/app/views/power_distribution_units/index.json.jbuilder b/app/views/power_distribution_units/index.json.jbuilder new file mode 100644 index 000000000..20474a8b7 --- /dev/null +++ b/app/views/power_distribution_units/index.json.jbuilder @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +json.array!(@pdus) do |pdu| + json.extract! pdu, :id, :name, :modele_id, + :numero, :cluster, :critique + json.url power_distribution_unit_url(pdu, format: :json) +end diff --git a/app/views/power_distribution_units/new.html.erb b/app/views/power_distribution_units/new.html.erb new file mode 100644 index 000000000..b6add08e4 --- /dev/null +++ b/app/views/power_distribution_units/new.html.erb @@ -0,0 +1,14 @@ +<% provide(:title, "#{t("power_distribution_units.index.title")} | #{t("action.create")}") # TODO: prefer use ActiveRecord translation of Modele name %> +<% breadcrumb_steps = { + t("power_distribution_units.index.title") => power_distribution_units_path, + t("action.create") => "" +} %> + +<%#= render Page::HeadingNewComponent.new(resource: @server, title: t(".title"), breadcrumb_steps:) %> +<%= render Page::HeadingComponent.new( + title: t(".title"), breadcrumb_steps:, back_button_url: power_distribution_units_path +) %> + +
    + <%= render "form" %> +
    diff --git a/app/views/power_distribution_units/show.html.erb b/app/views/power_distribution_units/show.html.erb new file mode 100644 index 000000000..4a6cb5724 --- /dev/null +++ b/app/views/power_distribution_units/show.html.erb @@ -0,0 +1,375 @@ +<% title = @pdu.name %> +<% provide(:title, "#{t("power_distribution_units.index.title")} | #{title}") %> + +<% breadcrumb_steps = { + t("power_distribution_units.index.title") => power_distribution_units_path, # TODO: prefer use ActiveRecord translation of Modele name + @pdu.name => "" +} %> + +<%#<%= render Page::HeadingShowComponent.new(resource: @pdu, title: title, breadcrumb_steps:) do |heading| %> + <%#<% heading.with_extra_buttons do %> + <%#<%= render ButtonComponent.new(t("action.duplicate"), + url: duplicate_power_distribution_unit_path(@pdu.slug), + variant: :success, + icon: "copy", + is_responsive: true, + extra_classes: "me-2") %> + <% # end %> +<% # end %> + +<%= render Page::HeadingComponent.new( + title: title, breadcrumb_steps:, back_button_url: power_distribution_units_path +) do |heading| %> + <% heading.with_right_content do %> +
    + <%= render ButtonComponent.new(t("action.duplicate"), + url: duplicate_power_distribution_unit_path(@pdu.slug), + variant: :success, + icon: "copy", + is_responsive: true, + extra_classes: "me-2") %> + <%= render ButtonComponent.new(t("action.edit"), + url: edit_power_distribution_unit_path(@pdu.slug), + variant: :info, + icon: "pencil", + is_responsive: true, + extra_classes: "me-2") %> +
    + <% end %> +<% end %> + +
    + +
    +
    +
    +
    + <% bgModeleColor = define_background_color(server: @pdu, mode: params["bg"]) %> +
    " + style="background-color:<%= bgModeleColor %> !important;"> + <%= render partial: "servers/draw_server_compact_front", locals: { server: @pdu } %> +
    + +
    + + <%= render partial: "servers/draw_server_compact", locals: { server: @pdu } %> + +
    +
    + + <% if @pdu.comment.present? %> +
    +
    + <%= @pdu.comment %> +
    +
    + <% end %> + +
    +
    + <%= render CardComponent.new do |card| %> + <% card.with_header do %> + <%= t("show.cards.identification") %> + <% end %> + +
    +
    <%= Server.human_attribute_name(:name) %>
    +
    <%= @pdu.name %>
    +
    + <% end %> + + <%= render CardComponent.new(extra_classes: "mt-4") do |card| %> + <% card.with_header do %> + <%= Modele.model_name.human %> + <% end %> + +
    +
    <%= Modele.model_name.human %>
    +
    + <%= link_to @pdu.modele, modele_path(@pdu.modele) if @pdu.modele.try(:name) %> +
    + +
    <%= Manufacturer.model_name.human %>
    +
    + <% if @pdu.modele&.manufacturer.present? %> + <%= link_to @pdu.modele.manufacturer, manufacturer_path(@pdu.modele.manufacturer) %> + <% end %> + <% if (documentation_url = @pdu.documentation_url).present? %> + ( + <%= link_to t(".documentation"), documentation_url, target: :_blank, rel: :noopener %> + ) + <% end %> +
    + +
    <%= Modele.human_attribute_name(:nb_elts) %>
    +
    <%= @pdu.modele.try(:nb_elts) %>
    + +
    <%= Architecture.model_name.human %>
    +
    + <% if @pdu.modele&.architecture.present? %> + <%= link_to @pdu.modele.architecture, architecture_path(@pdu.modele.architecture) %> + <% end %> +
    +
    + <% end %> + + <%= render CardComponent.new(extra_classes: "mt-4") do |card| %> + <% card.with_header do %> + <%= t("show.cards.features") %> + <% end %> + +
    +
    <%= Server.human_attribute_name(:numero) %>
    +
    <%= @pdu.try(:numero) %>
    + +
    <%= Card.model_name.human.pluralize %>
    +
    + <% @pdu.modele.composants.ordered.slots.each do |slot| %> + <% @pdu.cards.where(:composant_id => slot.id).each do |card| %> +
    + <%= card.composant.name ? card.composant.name : card.composant.position %> + : + <%= "#{card.card_type.try(:name)} (#{card.card_type.try(:port_quantity)}#{card.card_type.try(:port_type).try(:name)})" %> +
    + <% end %> + <% end if @pdu.modele.present? %> +
    +
    + <% end %> + + <%= render CardComponent.new(type: :success, extra_classes: "mt-4") do |card| %> + <% card.with_header do %> + <%= t("layouts.sidebar.exploitation.title") %> + <% end %> + +
    +
    <%= Gestion.model_name.human %>
    +
    <%= link_to_if @pdu.gestion, @pdu.gestion %>
    +
    + <% end %> + + <% if @pdu.photo.attached? %> + + <%= render CardComponent.new(extra_classes: "mt-4 d-none d-lg-flex") do |card| %> + <% card.with_header do %> + <%= Server.human_attribute_name(:photo) %> + <% end %> + + <%= link_to @pdu.photo, rel: :noopener, target: :_blank do %> + <%= image_tag @pdu.photo.representation(resize_to_limit: [1200, 1200]), class: "w-100" %> + <% end %> + <% end %> + <% end %> +
    + +
    + <%= render CardComponent.new(type: :primary) do |card| %> + <% card.with_header do %> + <%= t("layouts.sidebar.location.title") %> + <% end %> + +
    +
    <%= Site.model_name.human %>
    +
    <%= link_to @pdu.room.site, site_path(@pdu.room.site) %>
    + +
    <%= Room.model_name.human %>
    +
    + <%= link_to @pdu.room.try(:name), @pdu.room %> + <%= link_to visualization_room_path(@pdu.room), + class: "btn btn-primary btn-sm", + data: { turbo_frame: :_top } do %> + + <%= t("visualization.title") %> + <% end %> +
    + +
    <%= Islet.model_name.human %>
    +
    + <%= link_to @pdu.islet.name_with_room, islet_path(@pdu.islet) %> + <%= link_to visualization_room_path(@pdu.room, islet: @pdu.islet.name), + class: "btn btn-primary btn-sm", + data: { turbo_frame: :_top } do %> + + <%= t("visualization.title") %> + <% end %> +
    + +
    <%= Bay.model_name.human %>
    +
    + <%= link_to @pdu.bay, bay_path(@pdu.bay) %> + <%= link_to visualization_bay_path(@pdu.bay), + class: "btn btn-primary btn-sm", + data: { turbo_frame: :_top } do %> + + <%= t("visualization.title") %> + <% end %> +
    + +
    <%= Frame.model_name.human %>
    +
    + <%= link_to @pdu.frame.try(:name), frame_path(@pdu.frame) %> + <%= link_to visualization_frame_path(@pdu.frame), + class: "btn btn-primary btn-sm", + data: { turbo_frame: :_top } do %> + + <%= t("visualization.title") %> + <% end %> +
    +
    + <% end %> + + <%= render CardComponent.new(extra_classes: "mt-4") do |card| %> + <% card.with_header do %> + <%= t(".glpi_data") %> + <% end %> + <% + begin + Timeout.timeout(3) do + client = GlpiClient.new + computer = client.computer(serial: Rails.env.production? ? @pdu.numero : "AZERTY") %> + <% if computer.present? %> +
    +
    <%= t("glpi.computer.name") %>
    +
    <%= computer.name %>
    + +
    <%= t("glpi.computer.id") %>
    +
    <%= computer.id %>
    + +
    <%= t("glpi.computer.serial") %>
    +
    <%= computer.serial %>
    + +
    <%= t("glpi.computer.contact") %>
    +
    <%= computer.contact %>
    +
    +
    +
    <%= t("glpi.computer.disks_count") %>
    +
    <%= computer.hard_drives&.size %>
    + +
    <%= t("glpi.computer.disks_capacity") %>
    +
    <%= number_to_human_size(computer.hard_drives_total_capacity * 1048576) %>
    + +
    <%= t("glpi.computer.memories_count") %>
    +
    <%= computer.memories&.size %>
    + +
    <%= t("glpi.computer.memories_total") %>
    +
    <%= number_to_human_size(computer.memories_total_size * 1048576) %>
    + +
    <%= t("glpi.computer.cpus") %>
    +
    + <%= computer.processors.group_by { |p| p[1]["designation"] } + .map { |designation, processors| "#{processors.size} x #{designation}" } + .join(", ") %> +
    +
    + <% card.with_footer do %> + <%= link_to t(".glpi_visit_page"), + "#{Rails.application.credentials.glpi_url}/front/computer.form.php?id=#{computer.id}", + target: :_blank %> + <% end %> + <% else %> + <%= t(".no_match_serial", serial: @pdu.numero) %> + <% end %> + <% end + rescue Timeout::Error => e + Rails.logger.warn "WARNING: couldn't get GLPI data because the operation timed out" + rescue Exception => e + Rails.logger.warn "WARNING: couldn't get GLPI data because of an error: #{e.message}" %> + <%= t(".glpi_connection_error") %> :
    <%= e&.message.to_s %>
    + <% end %> + <% end %> + + <% if @pdu.photo.attached? %> + + <%= render CardComponent.new(extra_classes: "d-lg-none mt-4") do |card| %> + <% card.with_header do %> + <%= Server.human_attribute_name(:photo) %> + <% end %> + + <%= link_to @pdu.photo, rel: :noopener, target: :_blank do %> + <%= image_tag @pdu.photo.representation(resize_to_limit: [1200, 1200]), class: "w-100" %> + <% end %> + <% end %> + <% end %> + + <% if @pdu.documents.present? %> + <%= render CardComponent.new(extra_classes: "mt-4") do |card| %> + <% card.with_header do %> + <%= t(".attached_documents") %> + <% end %> +
      + <% @pdu.documents.each do |doc| %> + <%- next unless doc.document.present? %> +
    • + <%= link_to(doc.document.metadata["filename"], doc.document_url, { target: :_blank }) %> +
    • + <% end %> +
    + <% end %> + <% end %> +
    +
    + + <%= render ChangelogEntries::ObjectListComponent.new(@pdu) %> +
    +
    + <%= render HasManyTurboFrameComponent.new( + Connection.model_name.human.pluralize, + url: cables_path(server_ids: @pdu.id), + frame_id: dom_id(Connection, :table), + extra_classes: "bg-body-tertiary" + ) do |c| %> + <% c.with_actions do %> + <%= render ButtonComponent.new(t(".destroy_connections"), + url: destroy_connections_server_path(@pdu), + icon: "trash", + variant: :danger, + size: :sm, + data: { confirm: t(".destroy_connections_confirmation") }) %> + <% end %> + <% end %> +
    +
    + +<%= render "ports/modal_edit_port" %> diff --git a/app/views/power_distribution_units/show.json.jbuilder b/app/views/power_distribution_units/show.json.jbuilder new file mode 100644 index 000000000..bafaeef1f --- /dev/null +++ b/app/views/power_distribution_units/show.json.jbuilder @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +json.extract! @pdu, :id, :name, :modele, :numero, :critique, :domaine, :gestion, :created_at, :updated_at + +json.cards @pdu.cards do |card| + json.extract! card, :id, :name, :first_position, :orientation, :card_type_id, :composant_id, :twin_card_id + json.ports card.ports.order(:position), :id, :position, :vlans, :color, :cablename +end diff --git a/app/views/servers/_form.html.erb b/app/views/servers/_form.html.erb index 03d31bfbe..c78362cd7 100644 --- a/app/views/servers/_form.html.erb +++ b/app/views/servers/_form.html.erb @@ -23,7 +23,7 @@
    <%= f.label :modele_id, class: "form-label" %> <%= f.collection_select(:modele_id, - Modele.all_sorted, + Modele.no_pdus.all_sorted, :id, :name_with_brand, { prompt: true, include_blank: false }, diff --git a/app/views/servers/index.html.erb b/app/views/servers/index.html.erb index 20d6b2a9b..234403414 100644 --- a/app/views/servers/index.html.erb +++ b/app/views/servers/index.html.erb @@ -80,7 +80,7 @@
    - <%= f.collection_select(:modele_ids, Modele.sorted, + <%= f.collection_select(:modele_ids, Modele.no_pdus.sorted, :id, :name, { prompt: true, multiple: true }, diff --git a/app/views/servers/show.html.erb b/app/views/servers/show.html.erb index 179211b65..78572a6cc 100644 --- a/app/views/servers/show.html.erb +++ b/app/views/servers/show.html.erb @@ -8,20 +8,18 @@ <%= render Page::HeadingShowComponent.new(resource: @server, title: title, breadcrumb_steps:) do |heading| %> <% heading.with_extra_buttons do %> - <% if @server.is_not_a_pdu? %> - <%= render ButtonComponent.new(t("action.move"), - url: new_move_path(server_id: @server.id), - variant: :outline_primary, - icon: "box-seam", - is_responsive: true, - extra_classes: "me-2", - aria: { hidden: true }, - data: { - controller: "tooltip", - bs_placement: :bottom, - tooltip_title: t(".moves_cta_tooltip") - }) %> - <% end %> + <%= render ButtonComponent.new(t("action.move"), + url: new_move_path(server_id: @server.id), + variant: :outline_primary, + icon: "box-seam", + is_responsive: true, + extra_classes: "me-2", + aria: { hidden: true }, + data: { + controller: "tooltip", + bs_placement: :bottom, + tooltip_title: t(".moves_cta_tooltip") + }) %> <%= render ButtonComponent.new(t("action.duplicate"), url: duplicate_server_path(@server.slug), variant: :success, @@ -105,7 +103,9 @@
    <%= Modele.model_name.human %>
    - <%= link_to @server.modele, modele_path(@server.modele) if @server.modele.try(:name) %> + <% if @server.modele.present? %> + <%= link_to @server.modele, modele_path(@server.modele) %> + <% end %>
    <%= Category.model_name.human %>
    @@ -113,7 +113,9 @@
    <%= Manufacturer.model_name.human %>
    - <%= link_to @server.modele.try(:manufacturer), manufacturer_path(@server.modele.try(:manufacturer)) %> + <% if @server.modele&.manufacturer.present? %> + <%= link_to @server.modele.manufacturer, manufacturer_path(@server.modele.manufacturer) %> + <% end %> <% if (documentation_url = @server.documentation_url).present? %> ( <%= link_to t(".documentation"), documentation_url, target: :_blank, rel: :noopener %> @@ -129,7 +131,7 @@ <%= link_to @server.modele.try(:architecture), architecture_path(@server.modele.try(:architecture)) %>
    -
    <%= t(".nb_u") %>
    +
    <%= Server.human_attribute_name(:u) %>
    <%= @server.modele.try(:u) %>
    <%= Server.human_attribute_name(:network_types) %>
    @@ -148,9 +150,11 @@
    <%= Server.human_attribute_name(:critique) %>
    - "> - <%= t("boolean.#{@server.critique}") %> - + <% if @server.critique.present? %> + "> + <%= t("boolean.#{@server.critique}") %> + + <% end %>
    <%= ServerState.model_name.human %>
    diff --git a/config/locales/activerecord.fr.yml b/config/locales/activerecord.fr.yml index d709db9b4..f6a87383b 100644 --- a/config/locales/activerecord.fr.yml +++ b/config/locales/activerecord.fr.yml @@ -110,6 +110,7 @@ fr: photo: Photo frame: Châssis span: Slots + u: Nb de U site: name: Nom description: Description diff --git a/config/locales/en.yml b/config/locales/en.yml index 8b5b761dd..4bb97f835 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -19,6 +19,43 @@ en: edit: title: Change your password + power_distribution_units: + index: + title: PDUs + new_power_distributon_unit: Add a PDU + show: + documentation: Documentation + attached_documents: "Attached documents:" + glpi_data: GLPI data + glpi_visit_page: See the PDU page on GLPI + no_match_serial: "No match for this serial number: %{serial}" + glpi_connection_error: "Problem connecting to GLPI :" + destroy_connections: Delete connections + destroy_connections_confirmation: Can you confirm that you want to remove all connections from this PDU? + new: + title: Add a PDU + create: + flashes: + created: The PDU has been successfully created. + form: + add_card: Add a card + add_document: Add an attached document + edit: + title: Modify PDU + delete_confirmation: All data concerning this PDU will be deleted, along with all associated connections. Would you like to confirm? + update: + flashes: + updated: The PDU has been successfully updated. + duplicate: + title: Duplicate PDU %{pdu_name} + destroy: + flashes: + destroyed: The PDU has been deleted. + not_destroyed: An error occurred while deleting the PDU. + flashes: + connections_destroyed: The connections have been removed. + connections_not_destroyed: An error prevented connections from being deleted. + rooms: action_buttons: caption: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index daec8f7a6..12f7042a3 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -483,7 +483,6 @@ fr: sync_with_external_apps: Synchroniser avec GLPI show: back_to_bay: Baie %{name} - nb_u: Nb de U documentation: Documentation attached_documents: "Documents attachés :" glpi_data: Données GLPI @@ -530,6 +529,42 @@ fr: memories_count: Nombre de barettes memories_total: Ram totale cpus: Processeurs + power_distribution_units: + index: + title: PDUs + new_power_distributon_unit: Ajouter un PDU + show: + documentation: Documentation + attached_documents: "Documents attachés :" + glpi_data: Données GLPI + glpi_visit_page: Voir la page de la machine sur GLPI + no_match_serial: "Aucune correspondance pour ce numéro de série : %{serial}" + glpi_connection_error: "Problème lors de la connexion à GLPI :" + destroy_connections: Supprimer les connexions + destroy_connections_confirmation: Confirmez-vous vouloir supprimer toutes les connections de ce PDU ? + new: + title: Ajouter un PDU + create: + flashes: + created: Le PDU a été créé avec succès. + form: + add_card: Ajouter une carte + add_document: Ajouter une pièce jointe + edit: + title: Modifier le PDU + delete_confirmation: Toutes les données concernant ce PDU seront supprimées, ainsi que toutes les connexions associées. Souhaitez-vous confirmer ? + update: + flashes: + updated: Le PDU a été mis à jour avec succès. + duplicate: + title: Dupliquer le PDU %{pdu_name} + destroy: + flashes: + destroyed: Le PDU a bien été supprimé. + not_destroyed: Une erreur est survenue lors de la suppression du PDU. + flashes: + connections_destroyed: Les connexions ont été supprimées. + connections_not_destroyed: Une erreur a empêché la suppression des connexions. frames: coupled_frame_label: Châssis couplé à no_coupled_frame: Aucun châssis couplé. diff --git a/config/routes.rb b/config/routes.rb index 32a888efb..569731b1a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -61,6 +61,12 @@ get :destroy_connections end end + resources :power_distribution_units do + member do + get :duplicate + get :destroy_connections + end + end resources :servers_grids, only: [:index] resources :card_types diff --git a/spec/requests/power_distribution_units_request_spec.rb b/spec/requests/power_distribution_units_request_spec.rb new file mode 100644 index 000000000..a71f1a68a --- /dev/null +++ b/spec/requests/power_distribution_units_request_spec.rb @@ -0,0 +1,230 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe "/power_distribution_units" do + let(:pdu) { servers(:pdu) } + let(:pdu2) { Server.create(name: "PDU 2", frame_id: 2, modele_id: 3, numero: "PDU_2") } + let(:server) { servers(:one) } + + before do + sign_in users(:one) + + pdu.save + server.save + pdu2 + end + + describe "GET /index" do + before { get power_distribution_units_path } + + it { expect(response).to have_http_status(:success) } + it { expect(response).to render_template(:index) } + it { expect(response.body).to include(pdu.name) } + it { expect(response.body).to include(pdu2.name) } + it { expect(response.body).not_to include(server.name) } + + context "when searching on name" do + before { get power_distribution_units_path(q: "PDU_FRAME") } + + it { expect(response).to have_http_status(:success) } + it { expect(response).to render_template(:index) } + it { expect(response.body).to include(pdu.name) } + it { expect(response.body).not_to include(pdu2.name) } + it { expect(response.body).not_to include(server.name) } + end + end + + describe "GET /show" do + before { get power_distribution_unit_path(pdu) } + + it { expect(response).to have_http_status(:success) } + it { expect(response).to render_template(:show) } + it { expect(response.body).to include(pdu.name) } + + context "when using id" do + before { get power_distribution_unit_path(pdu.id) } + + it { expect(response).to have_http_status(:success) } + end + + context "when using name" do + before { get power_distribution_unit_path(pdu.name) } + + it { expect(response).to render_template(:show) } + end + + context "when using serial number" do + before { get power_distribution_unit_path(pdu.numero) } + + it { expect(response).to render_template(:show) } + end + + context "with an id not set" do + it { expect { get power_distribution_unit_path("unknown-id") }.to raise_error(ActiveRecord::RecordNotFound) } + end + end + + describe "GET /new" do + before { get new_power_distribution_unit_path } + + it { expect(response).to have_http_status(:success) } + it { expect(response).to render_template(:new) } + end + + describe "GET /duplicate" do + before { get duplicate_power_distribution_unit_path(pdu) } + + it { expect(response).to have_http_status(:success) } + it { expect(response).to render_template(:duplicate) } + end + + describe "POST /create" do + context "with valid parameters" do + let(:valid_attributes) do + pdu.attributes.except(%w[id numero name]).merge(numero: "new_numero", name: "NewServerName") + end + + it "creates a new PDU" do + expect do + post power_distribution_units_path, params: { power_distribution_unit: valid_attributes } + end.to change(Server, :count).by(1) + end + + it "redirects to the created pdu" do + post power_distribution_units_path, params: { power_distribution_unit: valid_attributes } + expect(response).to redirect_to(power_distribution_unit_path(assigns(:pdu))) + end + end + + context "with invalid parameters" do + let(:invalid_attributes) { { name: "" } } + + it "does not create a new PDU without attributes" do + expect { post power_distribution_units_path, params: { power_distribution_unit: {} } } + .to raise_error(ActionController::ParameterMissing) + end + + it "does not create a new PDU without parameters" do + expect { post power_distribution_units_path, params: {} } + .to raise_error(ActionController::ParameterMissing) + end + + it "does not create a new PDU with invalid parameters" do + post power_distribution_units_path, params: { power_distribution_unit: invalid_attributes } + expect(response).to render_template(:new) + end + end + end + + describe "GET /edit" do + before { get edit_power_distribution_unit_path(pdu) } + + it { expect(response).to have_http_status(:success) } + it { expect(response).to render_template(:edit) } + end + + describe "PATCH /update" do + context "with valid parameters" do + let(:new_attributes) { pdu.attributes.except("name").merge(name: "New name") } + + it :aggregate_failures do # rubocop:disable RSpec/ExampleLength + patch power_distribution_unit_path(pdu), params: { power_distribution_unit: new_attributes } + pdu.reload + assigns(:pdu).reload + + expect(response).to be_redirection + expect(response).to redirect_to(power_distribution_unit_path(assigns(:pdu))) + expect(pdu.name).to eq(new_attributes[:name]) + + # old name should continue to work + get power_distribution_unit_path("PDU_FRAME-1_A") + expect(response).to have_http_status(:success) + expect(pdu).to eq(assigns(:pdu)) + end + + it "does update cards in a server", :aggregate_failures do # rubocop:disable RSpec/ExampleLength + patch power_distribution_unit_path(pdu), params: { + power_distribution_unit: { + name: pdu.name, + cards_attributes: [{ id: 7, composant_id: 1, twin_card_id: 2, orientation: "lr-td" }] + } + } + + assigns(:pdu).reload + pdu.reload + + expect(response).to be_redirection + expect(response).to redirect_to(power_distribution_unit_path(assigns(:pdu))) + + # Test new card + get power_distribution_unit_path(pdu) + expect(response).to have_http_status(:success) + expect(pdu).to eq(assigns(:pdu)) + expect(Card.find(7).twin_card_id).to eq 2 + + # Test twin card + expect(Card.find(2).twin_card_id).to eq 7 + end + end + + context "with invalid parameters" do + it "does not update a PDU without attributes" do + expect { patch power_distribution_unit_path(pdu), params: { power_distribution_unit: {} } } + .to raise_error(ActionController::ParameterMissing) + end + + it "does not update a PDU without parameters" do + expect { patch power_distribution_unit_path(pdu), params: {} } + .to raise_error(ActionController::ParameterMissing) + end + + it "does not update a PDU with invalid parameters", :aggregate_failures do + patch power_distribution_unit_path(pdu), params: { power_distribution_unit: { name: "" } } + + expect(response).to render_template(:edit) + end + end + end + + describe "DELETE /destroy" do + context "with a pdu without association" do + it "destroys the requested pdu" do + expect do + delete power_distribution_unit_path(pdu2) + end.to change(Server, :count).by(-1) + end + + it "redirects to the pdus list" do + delete power_distribution_unit_path(pdu2) + expect(response).to redirect_to(power_distribution_units_path) + end + + it "redirects to the pdus list and keep params" do + delete power_distribution_unit_path(pdu2, params: { sort: "asc", sort_by: "rooms.name" }) + expect(response).to redirect_to(power_distribution_units_path({ sort: "asc", sort_by: "rooms.name" })) + end + end + + context "with a pdu with association" do + it "does not destroy the requested pdu" do + expect do + delete power_distribution_unit_path(pdu) + end.not_to change(Server, :count) + end + + it "redirects to the pdus list" do + delete power_distribution_unit_path(pdu) + expect(response).to redirect_to(power_distribution_units_path) + end + end + end + + describe "GET /destroy_connections" do + before { get destroy_connections_power_distribution_unit_path(pdu) } + + it { expect(response).to have_http_status(:redirect) } + it { expect(pdu.connections.count).to be_zero } + it { expect(flash[:notice]).to be_present } + end +end diff --git a/spec/requests/servers_request_spec.rb b/spec/requests/servers_request_spec.rb index 6a5c2f654..da93cb79a 100644 --- a/spec/requests/servers_request_spec.rb +++ b/spec/requests/servers_request_spec.rb @@ -5,12 +5,12 @@ RSpec.describe "/servers" do let(:server) { servers(:one) } let(:server2) { servers(:two) } + let(:pdu) { servers(:pdu) } before do sign_in users(:one) server.save! - server2.save! end describe "GET /index" do @@ -20,6 +20,7 @@ it { expect(response).to render_template(:index) } it { expect(response.body).to include(server.name) } it { expect(response.body).to include(server2.name) } + it { expect(response.body).not_to include(pdu.name) } context "when searching on name" do before { get servers_path(q: "ServerName1") } diff --git a/test/controllers/disks_controller_test.rb b/test/controllers/disks_controller_test.rb index 6da815ee7..f080c2735 100644 --- a/test/controllers/disks_controller_test.rb +++ b/test/controllers/disks_controller_test.rb @@ -24,7 +24,7 @@ class DisksControllerTest < ActionController::TestCase post :create, params: { disk: { disk_type_id: @disk.disk_type_id, quantity: @disk.quantity, server_id: @disk.server_id } } end - assert_redirected_to server_path(@disk.server_id) + assert_redirected_to server_path(@disk.server) end test "should show disk" do @@ -39,7 +39,7 @@ class DisksControllerTest < ActionController::TestCase test "should update disk" do patch :update, params: { id: @disk, disk: { disk_type_id: @disk.disk_type_id, quantity: @disk.quantity, server_id: @disk.server_id } } - assert_redirected_to server_path(@disk.server_id) + assert_redirected_to server_path(@disk.server) end test "should destroy disk" do diff --git a/test/controllers/memory_components_controller_test.rb b/test/controllers/memory_components_controller_test.rb index c7428948a..b3cac1f67 100644 --- a/test/controllers/memory_components_controller_test.rb +++ b/test/controllers/memory_components_controller_test.rb @@ -24,7 +24,7 @@ class MemoryComponentsControllerTest < ActionController::TestCase post :create, params: { memory_component: { memory_type_id: @memory_component.memory_type_id, quantity: @memory_component.quantity, server_id: @memory_component.server_id } } end - assert_redirected_to server_path(@memory_component.server_id) + assert_redirected_to server_path(@memory_component.server) end test "should show memory_component" do @@ -39,7 +39,7 @@ class MemoryComponentsControllerTest < ActionController::TestCase test "should update memory_component" do patch :update, params: { id: @memory_component, memory_component: { memory_type_id: @memory_component.memory_type_id, quantity: @memory_component.quantity, server_id: @memory_component.server_id } } - assert_redirected_to server_path(@memory_component.server_id) + assert_redirected_to server_path(@memory_component.server) end test "should destroy memory_component" do diff --git a/test/fixtures/cards.yml b/test/fixtures/cards.yml index 566512b0b..532629a4c 100644 --- a/test/fixtures/cards.yml +++ b/test/fixtures/cards.yml @@ -51,3 +51,12 @@ six: name: CardIPMI twin_card_id: orientation: "lr-td" + +seven: + id: 7 + card_type_id: 4 + server_id: 3 + composant_id: 4 + name: CardAlim + twin_card_id: + orientation: "lr-td" diff --git a/test/fixtures/documents.yml b/test/fixtures/documents.yml index 66b70d7eb..a8277c87a 100644 --- a/test/fixtures/documents.yml +++ b/test/fixtures/documents.yml @@ -7,3 +7,7 @@ one: two: id: 2 server_id: 1 + +three: + id: 3 + server_id: 3 diff --git a/test/fixtures/servers.yml b/test/fixtures/servers.yml index df40b033e..5be5ec9ec 100644 --- a/test/fixtures/servers.yml +++ b/test/fixtures/servers.yml @@ -4,6 +4,7 @@ one: id: 1 frame_id: 1 name: ServerName1 + slug: servername1 modele_id: 1 numero: CZ31535FEY critique: false @@ -49,6 +50,7 @@ pdu: modele_id: 3 side: right color: B + numero: pdu_frame_1 with_cluster: frame_id: 1 diff --git a/test/models/server_test.rb b/test/models/server_test.rb index 1ee946ac2..75d232bf1 100644 --- a/test/models/server_test.rb +++ b/test/models/server_test.rb @@ -8,13 +8,16 @@ class ServerTest < ActiveSupport::TestCase refute_includes Server.only_pdus, servers(:one) end - test 'scope no_puds' do + test 'scope no_pdus' do refute_includes Server.no_pdus, servers(:pdu) assert_includes Server.no_pdus, servers(:one) end test '#documentation_url with no documentation_url value on manufacturer' do - assert_nil servers(:pdu).documentation_url + server = servers(:pdu) + server.numero = nil + + assert_nil server.documentation_url end test '#documentation_url with no numero value on manufacturer' do