@@ -161,7 +178,4 @@ See COPYRIGHT and LICENSE files for more details.
<%= render partial: 'meetings/participants_section' %>
-
- <%= hidden_field_tag "copied_from_meeting_id", params[:copied_from_meeting_id] if params[:copied_from_meeting_id].present? %>
- <%= hidden_field_tag "copied_meeting_agenda_text", params[:copied_meeting_agenda_text] if params[:copied_meeting_agenda_text].present? %>
diff --git a/modules/meeting/app/views/meetings/new.html.erb b/modules/meeting/app/views/meetings/new.html.erb
index 4c345bdc39d3..2c498f663402 100644
--- a/modules/meeting/app/views/meetings/new.html.erb
+++ b/modules/meeting/app/views/meetings/new.html.erb
@@ -26,9 +26,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
See COPYRIGHT and LICENSE files for more details.
++#%>
+<% copy_from = local_assigns[:copy_from] %>
+<% if copy_from %>
+ <% html_title t('meeting.copy.title', title: copy_from.title) %>
+ <%= toolbar title: t('meeting.copy.title', title: copy_from.title) %>
+<% else %>
+ <% html_title t(:label_meeting_new) %>
+ <%= toolbar title: t(:label_meeting_new) %>
+<% end %>
-<% html_title t(:label_meeting_new) %>
-<%= toolbar title: t(:label_meeting_new) %>
<%= labelled_tabular_form_for @meeting,
as: :meeting,
url: {:controller => '/meetings', :action => 'create', :project_id => @project},
@@ -36,7 +42,7 @@ See COPYRIGHT and LICENSE files for more details.
:data => { :controller => 'refresh-on-form-changes',
'refresh-on-form-changes-target': 'form',
'refresh-on-form-changes-turbo-stream-url-value': new_meeting_url }} do |f| -%>
- <%= render :partial => 'form', :locals => { f:, copy: local_assigns[:copy] } %>
+ <%= render :partial => 'form', :locals => { f:, copy_from: } %>
<%= styled_button_tag t(:button_create), class: '-highlight' %>
<%= link_to t(:button_cancel), { :action => 'index', :project_id => @project },
class: 'button' %>
diff --git a/modules/meeting/config/locales/en.yml b/modules/meeting/config/locales/en.yml
index 58a3532f47af..ec4288efb3fd 100644
--- a/modules/meeting/config/locales/en.yml
+++ b/modules/meeting/config/locales/en.yml
@@ -113,6 +113,10 @@ en:
meeting:
+ copy:
+ title: "Copy meeting %{title}"
+ agenda: "Copy agenda"
+ agenda_text: "Copy the agenda of the old meeting"
email:
open_meeting_link: "Open meeting"
invited:
diff --git a/modules/meeting/spec/features/meetings_copy_spec.rb b/modules/meeting/spec/features/meetings_copy_spec.rb
index 48de9243edfa..0aac54cf3949 100644
--- a/modules/meeting/spec/features/meetings_copy_spec.rb
+++ b/modules/meeting/spec/features/meetings_copy_spec.rb
@@ -94,8 +94,6 @@
expect(page)
.to have_field 'Time', with: start_time.strftime("%H:%M")
- choose 'Classic'
-
click_button "Create"
# Be on the new meeting's page with copied over attributes
diff --git a/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb b/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb
index 000556b07c42..fb33994db521 100644
--- a/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb
+++ b/modules/meeting/spec/features/structured_meetings/structured_meeting_crud_spec.rb
@@ -251,7 +251,7 @@
expect(page).to have_css('.flash', text: I18n.t('activerecord.errors.messages.error_conflict'))
end
- it 'can copy the meeting (empty)' do
+ it 'can copy the meeting' do
show_page.expect_toast(message: 'Successful creation')
# Can add and edit a single item
@@ -270,7 +270,7 @@
click_button 'Create'
- expect(page).to have_text 'Your meeting is empty'
+ show_page.expect_agenda_item title: 'My agenda item'
new_meeting = StructuredMeeting.reorder(id: :asc).last
expect(page).to have_current_path "/meetings/#{new_meeting.id}"
end
diff --git a/modules/meeting/spec/requests/meetings_spec.rb b/modules/meeting/spec/requests/meetings_spec.rb
new file mode 100644
index 000000000000..1623a789ca01
--- /dev/null
+++ b/modules/meeting/spec/requests/meetings_spec.rb
@@ -0,0 +1,99 @@
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) 2012-2024 the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+require 'spec_helper'
+
+RSpec.describe 'Meeting requests',
+ :skip_csrf,
+ type: :rails_request do
+
+ shared_let(:project) { create(:project, enabled_module_names: %i[meetings]) }
+ shared_let(:user) { create(:user, member_with_permissions: { project => %i[view_meetings create_meetings] }) }
+
+ before do
+ login_as user
+ end
+
+ describe 'copy' do
+ let(:meeting) { create(:structured_meeting, project:) }
+ let(:base_params) do
+ {
+ copied_from_meeting_id: meeting.id,
+ project_id: project.id,
+ meeting: {
+ title: 'Copied meeting',
+ type: :dynamic
+ }
+ }
+ end
+ let(:params) { {} }
+
+ subject do
+ post meetings_path(project),
+ params: base_params.merge(params)
+
+ Meeting.find_by(title: 'Copied meeting')
+ end
+
+ context 'when copying agenda items' do
+ let!(:agenda_item) { create(:meeting_agenda_item, meeting:, notes: '**foo**') }
+ let(:params) { { copy_agenda: '1' } }
+
+ it 'copies the agenda items' do
+ subject
+
+ expect(response).to be_redirect
+
+ expect(subject).to be_present
+ expect(subject.agenda_items.count).to eq(1)
+ expect(subject.agenda_items.first.notes).to eq('**foo**')
+ end
+ end
+
+ context 'when copying without additional params' do
+ it 'copies the meeting, but not the agenda' do
+ subject
+
+ expect(response).to be_redirect
+
+ expect(subject).to be_present
+ expect(subject.agenda_items).to be_empty
+ end
+ end
+
+ context 'when meeting is not visible' do
+ let(:other_project) { create(:project) }
+ let(:meeting) { create(:meeting, project: other_project) }
+
+ it 'renders a 404' do
+ subject
+ expect(response).to have_http_status(:not_found)
+ end
+ end
+ end
+end